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