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