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