vymmodel.cpp
author insilmaril
Thu, 05 Mar 2009 09:33:30 +0000
branchrelease-1-12-maintained
changeset 58 89dd2219982f
parent 57 d045ba89798e
child 59 1c550f80c43b
permissions -rw-r--r--
Additional check if save works
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@57
   123
MapCenterObj *VymModel::getMapCenterNum (int i)
insilmaril@57
   124
{
insilmaril@57
   125
	cout << "MCO i="<<i<<"  count="<<mapCenters.count()<<endl;
insilmaril@57
   126
	if (i>mapCenters.count()-1 || i<0)
insilmaril@57
   127
		return NULL;
insilmaril@57
   128
	else
insilmaril@57
   129
		return mapCenters.at(i);
insilmaril@57
   130
}
insilmaril@57
   131
insilmaril@57
   132
int VymModel::countMapCenters()
insilmaril@57
   133
{
insilmaril@57
   134
	return mapCenters.count();
insilmaril@57
   135
}
insilmaril@57
   136
insilmaril@40
   137
BranchObj* VymModel::first()
insilmaril@40
   138
{
insilmaril@40
   139
	if (mapCenters.count()>0) 
insilmaril@40
   140
		return mapCenters.first();
insilmaril@40
   141
	else	
insilmaril@40
   142
		return NULL;
insilmaril@40
   143
}
insilmaril@40
   144
	
insilmaril@40
   145
BranchObj* VymModel::next(BranchObj *bo_start)
insilmaril@40
   146
{
insilmaril@40
   147
	BranchObj *rbo;
insilmaril@40
   148
	BranchObj *bo=bo_start;
insilmaril@40
   149
	if (bo)
insilmaril@40
   150
	{
insilmaril@40
   151
		// Try to find next branch in current MapCenter
insilmaril@40
   152
		rbo=bo->next();
insilmaril@40
   153
		if (rbo) return rbo;
insilmaril@40
   154
insilmaril@40
   155
		// Try to find MapCenter of bo
insilmaril@40
   156
		while (bo->getDepth()>0) bo=(BranchObj*)bo->getParObj();
insilmaril@40
   157
insilmaril@40
   158
		// Try to find next MapCenter
insilmaril@40
   159
		int i=mapCenters.indexOf ((MapCenterObj*)bo);
insilmaril@40
   160
		if (i+2 > mapCenters.count() || i<0) return NULL;
insilmaril@40
   161
		if (mapCenters.at(i+1)!=bo_start)
insilmaril@40
   162
			return mapCenters.at(i+1);
insilmaril@40
   163
	} 
insilmaril@40
   164
	return NULL;
insilmaril@40
   165
}
insilmaril@40
   166
insilmaril@40
   167
LinkableMapObj* VymModel::findMapObj(QPointF p, LinkableMapObj *excludeLMO)
insilmaril@40
   168
{
insilmaril@40
   169
	LinkableMapObj *lmo;
insilmaril@40
   170
insilmaril@40
   171
	for (int i=0;i<mapCenters.count(); i++)
insilmaril@40
   172
	{
insilmaril@40
   173
		lmo=mapCenters.at(i)->findMapObj (p,excludeLMO);
insilmaril@40
   174
		if (lmo) return lmo;
insilmaril@40
   175
	}
insilmaril@40
   176
	return NULL;
insilmaril@40
   177
}
insilmaril@40
   178
insilmaril@40
   179
LinkableMapObj* VymModel::findObjBySelect(const QString &s)
insilmaril@40
   180
{
insilmaril@40
   181
	LinkableMapObj *lmo;
insilmaril@40
   182
	if (!s.isEmpty() )
insilmaril@40
   183
	{
insilmaril@40
   184
		QString part;
insilmaril@40
   185
		QString typ;
insilmaril@40
   186
		QString num;
insilmaril@40
   187
		part=s.section(",",0,0);
insilmaril@40
   188
		typ=part.left (2);
insilmaril@40
   189
		num=part.right(part.length() - 3);
insilmaril@40
   190
		if (typ=="mc" && num.toInt()>=0 && num.toInt() <mapCenters.count() )
insilmaril@40
   191
			return mapCenters.at(num.toInt() );
insilmaril@40
   192
	}		
insilmaril@40
   193
insilmaril@40
   194
	for (int i=0; i<mapCenters.count(); i++)
insilmaril@40
   195
	{
insilmaril@40
   196
		lmo=mapCenters.at(i)->findObjBySelect(s);
insilmaril@40
   197
		if (lmo) return lmo;
insilmaril@40
   198
	}	
insilmaril@40
   199
	return NULL;
insilmaril@40
   200
}
insilmaril@40
   201
insilmaril@40
   202
LinkableMapObj* VymModel::findID (const QString &s)
insilmaril@40
   203
{
insilmaril@40
   204
	LinkableMapObj *lmo;
insilmaril@40
   205
	for (int i=0; i<mapCenters.count(); i++)
insilmaril@40
   206
	{
insilmaril@40
   207
		lmo=mapCenters.at(i)->findID (s);
insilmaril@40
   208
		if (lmo) return lmo;
insilmaril@40
   209
	}	
insilmaril@40
   210
	return NULL;
insilmaril@40
   211
}
insilmaril@40
   212
insilmaril@40
   213
QString VymModel::saveToDir (const QString &tmpdir,const QString &prefix, int verbose, const QPointF &offset)
insilmaril@40
   214
{
insilmaril@40
   215
    QString s;
insilmaril@40
   216
insilmaril@40
   217
	for (int i=0; i<mapCenters.count(); i++)
insilmaril@40
   218
		s+=mapCenters.at(i)->saveToDir (tmpdir,prefix,verbose,offset);
insilmaril@40
   219
    return s;
insilmaril@40
   220
}
insilmaril@40
   221
insilmaril@40
   222
insilmaril@40
   223
//////////////////////////////////////////////
insilmaril@40
   224
// View related
insilmaril@40
   225
//////////////////////////////////////////////
insilmaril@40
   226
insilmaril@40
   227
void VymModel::updateRelPositions()
insilmaril@40
   228
{
insilmaril@40
   229
	for (int i=0; i<mapCenters.count(); i++)
insilmaril@40
   230
		mapCenters.at(i)->updateRelPositions();
insilmaril@40
   231
}
insilmaril@40
   232
insilmaril@40
   233
void VymModel::reposition()
insilmaril@40
   234
{
insilmaril@40
   235
	for (int i=0;i<mapCenters.count(); i++)
insilmaril@40
   236
		mapCenters.at(i)->reposition();	//	for positioning heading
insilmaril@40
   237
}
insilmaril@40
   238
insilmaril@40
   239
QPolygonF VymModel::shape(BranchObj *bo)
insilmaril@40
   240
{
insilmaril@40
   241
	// Creating (arbitrary) shapes
insilmaril@40
   242
insilmaril@40
   243
	QPolygonF p;
insilmaril@40
   244
	QRectF rb=bo->getBBox();
insilmaril@40
   245
	if (bo->getDepth()==0)
insilmaril@40
   246
	{
insilmaril@40
   247
		// Just take BBox of this mapCenter
insilmaril@40
   248
		p<<rb.topLeft()<<rb.topRight()<<rb.bottomRight()<<rb.bottomLeft();
insilmaril@40
   249
		return p;
insilmaril@40
   250
	}
insilmaril@40
   251
insilmaril@40
   252
	// Take union of BBox and TotalBBox 
insilmaril@40
   253
insilmaril@40
   254
	QRectF ra=bo->getTotalBBox();
insilmaril@40
   255
	if (bo->getOrientation()==LinkableMapObj::LeftOfCenter)
insilmaril@40
   256
		p   <<ra.bottomLeft()
insilmaril@40
   257
			<<ra.topLeft()
insilmaril@40
   258
			<<QPointF (rb.topLeft().x(), ra.topLeft().y() )
insilmaril@40
   259
			<<rb.topRight()
insilmaril@40
   260
			<<rb.bottomRight()
insilmaril@40
   261
			<<QPointF (rb.bottomLeft().x(), ra.bottomLeft().y() ) ;
insilmaril@40
   262
	else		
insilmaril@40
   263
		p   <<ra.bottomRight()
insilmaril@40
   264
			<<ra.topRight()
insilmaril@40
   265
			<<QPointF (rb.topRight().x(), ra.topRight().y() )
insilmaril@40
   266
			<<rb.topLeft()
insilmaril@40
   267
			<<rb.bottomLeft()
insilmaril@40
   268
			<<QPointF (rb.bottomRight().x(), ra.bottomRight().y() ) ;
insilmaril@40
   269
	return p;		
insilmaril@40
   270
insilmaril@40
   271
}
insilmaril@40
   272
insilmaril@40
   273
void VymModel::moveAway(LinkableMapObj *lmo)
insilmaril@40
   274
{
insilmaril@40
   275
	// Autolayout:
insilmaril@40
   276
	//
insilmaril@40
   277
	// Move all branches and MapCenters away from lmo 
insilmaril@40
   278
	// to avoid collisions 
insilmaril@40
   279
insilmaril@40
   280
	QPolygonF pA;
insilmaril@40
   281
	QPolygonF pB;
insilmaril@40
   282
insilmaril@40
   283
	BranchObj *boA=(BranchObj*)lmo;
insilmaril@40
   284
	BranchObj *boB;
insilmaril@40
   285
	for (int i=0; i<mapCenters.count(); i++)
insilmaril@40
   286
	{
insilmaril@40
   287
		boB=mapCenters.at(i);
insilmaril@40
   288
		pA=shape (boA);
insilmaril@40
   289
		pB=shape (boB);
insilmaril@40
   290
		PolygonCollisionResult r = PolygonCollision(pA, pB, QPoint(0,0));
insilmaril@40
   291
		cout <<"------->"
insilmaril@40
   292
			<<"="<<r.intersect
insilmaril@40
   293
			<<"  ("<<qPrintable(boA->getHeading() )<<")"
insilmaril@40
   294
			<<"  with ("<< qPrintable (boB->getHeading() )
insilmaril@40
   295
			<<")  willIntersect"
insilmaril@40
   296
			<<r.willIntersect 
insilmaril@40
   297
			<<"  minT="<<r.minTranslation<<endl<<endl;
insilmaril@40
   298
	}
insilmaril@40
   299
}
insilmaril@40
   300
insilmaril@40
   301
void VymModel::animate()
insilmaril@40
   302
{
insilmaril@40
   303
	animationTimer->stop();
insilmaril@40
   304
	BranchObj *bo;
insilmaril@40
   305
	int i=0;
insilmaril@40
   306
	while (i<animObjList.size() )
insilmaril@40
   307
	{
insilmaril@40
   308
		bo=(BranchObj*)animObjList.at(i);
insilmaril@40
   309
		if (!bo->animate())
insilmaril@40
   310
		{
insilmaril@40
   311
			if (i>=0) animObjList.removeAt(i);
insilmaril@40
   312
			i--;
insilmaril@40
   313
		}
insilmaril@40
   314
		bo->reposition();
insilmaril@40
   315
		i++;
insilmaril@40
   316
	} 
insilmaril@40
   317
	mapEditor->updateSelection();
insilmaril@40
   318
	mapScene->update();
insilmaril@43
   319
	if (!animObjList.isEmpty() ) animationTimer->start();
insilmaril@40
   320
}
insilmaril@40
   321
insilmaril@40
   322
insilmaril@40
   323
void VymModel::startAnimation(const QPointF &start, const QPointF &dest)
insilmaril@40
   324
{
insilmaril@40
   325
	BranchObj *bo=getSelectedBranch();
insilmaril@40
   326
	if (bo && bo->getDepth()>0) 
insilmaril@40
   327
	{
insilmaril@40
   328
		AnimPoint ap;
insilmaril@40
   329
		ap.setStart (start);
insilmaril@40
   330
		ap.setDest  (dest);
insilmaril@40
   331
		ap.setTicks (animationTicks);
insilmaril@40
   332
		ap.setAnimated (true);
insilmaril@40
   333
		bo->setAnimation (ap);
insilmaril@40
   334
		animObjList.append( bo );
insilmaril@40
   335
		animationTimer->setSingleShot (true);
insilmaril@40
   336
		animationTimer->start(animationInterval);
insilmaril@40
   337
	}
insilmaril@40
   338
}
insilmaril@40
   339
insilmaril@40
   340
void VymModel::stopAnimation(MapObj *mo)
insilmaril@40
   341
{
insilmaril@40
   342
	int i=animObjList.indexOf(mo);
insilmaril@40
   343
    if (i>=0)
insilmaril@40
   344
		animObjList.removeAt (i);
insilmaril@40
   345
}
insilmaril@40
   346
insilmaril@40
   347
//////////////////////////////////////////////
insilmaril@40
   348
// Selection related
insilmaril@40
   349
//////////////////////////////////////////////
insilmaril@40
   350
insilmaril@40
   351
insilmaril@40
   352
// Only as long as we dont have Model/View yet
insilmaril@40
   353
LinkableMapObj* VymModel::getSelection()
insilmaril@40
   354
{
insilmaril@40
   355
	return mapEditor->getSelection();
insilmaril@40
   356
}
insilmaril@40
   357
BranchObj* VymModel::getSelectedBranch()
insilmaril@40
   358
{
insilmaril@40
   359
	return mapEditor->getSelectedBranch();
insilmaril@40
   360
}
insilmaril@40
   361
insilmaril@40
   362
insilmaril@40
   363
bool VymModel::select (const QString &s)
insilmaril@40
   364
{
insilmaril@40
   365
	return mapEditor->select (s);
insilmaril@40
   366
}
insilmaril@40
   367
insilmaril@40
   368
QString VymModel::getSelectString (LinkableMapObj *lmo)
insilmaril@40
   369
{
insilmaril@40
   370
	QString s;
insilmaril@40
   371
	if (!lmo) return s;
insilmaril@40
   372
	if (typeid(*lmo)==typeid(BranchObj) ||
insilmaril@40
   373
		typeid(*lmo)==typeid(MapCenterObj) )
insilmaril@40
   374
	{	
insilmaril@40
   375
		LinkableMapObj *par=lmo->getParObj();
insilmaril@40
   376
		if (par)
insilmaril@40
   377
		{
insilmaril@40
   378
			if (lmo->getDepth() ==1)
insilmaril@40
   379
				// Mainbranch, return 
insilmaril@40
   380
				s= "bo:" + QString("%1").arg(((BranchObj*)lmo)->getNum());
insilmaril@40
   381
			else	
insilmaril@40
   382
				// Branch, call myself recursively
insilmaril@40
   383
				s= getSelectString(par) + ",bo:" + QString("%1").arg(((BranchObj*)lmo)->getNum());
insilmaril@40
   384
		} else
insilmaril@40
   385
		{
insilmaril@40
   386
			// MapCenter
insilmaril@40
   387
			int i=mapCenters.indexOf ((MapCenterObj*)lmo);
insilmaril@40
   388
			if (i>=0) s=QString("mc:%1").arg(i);
insilmaril@40
   389
		}	
insilmaril@40
   390
	}	
insilmaril@40
   391
	return s;
insilmaril@40
   392
insilmaril@40
   393
}
insilmaril@40
   394
insilmaril@40
   395
	
insilmaril@40
   396
void VymModel::setHideTmp (HideTmpMode mode)
insilmaril@40
   397
{
insilmaril@40
   398
	for (int i=0;i<mapCenters.count(); i++)
insilmaril@40
   399
		mapCenters.at(i)->setHideTmp (mode);	
insilmaril@40
   400
}
insilmaril@40
   401
insilmaril@40
   402
QRectF VymModel::getTotalBBox()
insilmaril@40
   403
{
insilmaril@40
   404
	QRectF r;
insilmaril@40
   405
	for (int i=0;i<mapCenters.count(); i++)
insilmaril@40
   406
		r=addBBox (mapCenters.at(i)->getTotalBBox(), r);
insilmaril@40
   407
	return r;	
insilmaril@40
   408
}
insilmaril@40
   409