BaseObject.cc

00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                              OpenFlipper                                  *
00004  *      Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openflipper.org                             *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------*
00008  *  This file is part of OpenFlipper.                                        *
00009  *                                                                           *
00010  *  OpenFlipper is free software: you can redistribute it and/or modify      *
00011  *  it under the terms of the GNU Lesser General Public License as           *
00012  *  published by the Free Software Foundation, either version 3 of           *
00013  *  the License, or (at your option) any later version with the              *
00014  *  following exceptions:                                                    *
00015  *                                                                           *
00016  *  If other files instantiate templates or use macros                       *
00017  *  or inline functions from this file, or you compile this file and         *
00018  *  link it with other files to produce an executable, this file does        *
00019  *  not by itself cause the resulting executable to be covered by the        *
00020  *  GNU Lesser General Public License. This exception does not however       *
00021  *  invalidate any other reasons why the executable file might be            *
00022  *  covered by the GNU Lesser General Public License.                        *
00023  *                                                                           *
00024  *  OpenFlipper is distributed in the hope that it will be useful,           *
00025  *  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
00026  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
00027  *  GNU Lesser General Public License for more details.                      *
00028  *                                                                           *
00029  *  You should have received a copy of the GNU LesserGeneral Public          *
00030  *  License along with OpenFlipper. If not,                                  *
00031  *  see <http://www.gnu.org/licenses/>.                                      *
00032  *                                                                           *
00033 \*===========================================================================*/
00034 
00035 /*===========================================================================*\
00036  *                                                                           *
00037  *   $Revision: 8694 $                                                         *
00038  *   $Author: wilden $                                                      *
00039  *   $Date: 2010-03-09 18:49:22 +0100 (Di, 09. Mär 2010) $                   *
00040  *                                                                           *
00041 \*===========================================================================*/
00042 
00043 
00044 
00045 
00046 //=============================================================================
00047 //
00048 //  MyTypes
00049 //
00050 //=============================================================================
00051 
00052 #define BASEOBJECT_C
00053 
00054 
00055 //== INCLUDES =================================================================
00056 
00057 #include "BaseObjectCore.hh"
00058 #include "Types.hh"
00059 #include <OpenFlipper/BasePlugin/PluginFunctionsCore.hh>
00060 #include <OpenFlipper/BasePlugin/PluginFunctions.hh>
00061 
00062 
00063 //== TYPEDEFS =================================================================
00064 
00065 //== Variables =================================================================
00066 
00067 static ObjectManager objectManager_;
00068 
00069 //== CLASS DEFINITION =========================================================
00070 
00074 static int idGenerator = 1;
00075 
00076 BaseObject::BaseObject(const BaseObject& _object) :
00077   QObject() 
00078 {
00079   id_           = idGenerator;
00080   ++idGenerator;
00081   persistentId_ = _object.persistentId_;
00082   objectType_   = _object.objectType_;
00083   flags_ = _object.flags_;
00084   visible_ = _object.visible_;
00085   parentItem_ = 0;
00086   childItems_.clear();
00087   name_ = "Copy of " + _object.name_;
00088 
00089   dataMap_.clear();
00090   
00091   // Iterate over all per Object datas and try to copy them
00092   QMap< QString, PerObjectData* >::const_iterator mapIter = _object.dataMap_.begin();  
00093   while ( mapIter != _object.dataMap_.end() ) {
00094     // Try to get a copy of the object.
00095     PerObjectData* copiedData = mapIter.value()->copyPerObjectData();
00096     
00097     if ( copiedData ) {
00098       dataMap_.insert(mapIter.key(),copiedData);
00099     } else {
00100       std::cerr << "Failed to copy per Object Data: " << mapIter.key().toStdString() << std::endl;
00101     }
00102     
00103     mapIter++;
00104   }
00105   
00106   // If the pointer is 0 then we are creating the objectroot
00107   if ( PluginFunctions::objectRoot() ) {
00108     setParent(PluginFunctions::objectRoot());
00109     PluginFunctions::objectRoot()->appendChild(this);
00110     PluginFunctions::increaseObjectCount();
00111   }
00112   
00113   // Add object to object container
00114   PluginFunctions::addObjectToMap( id(), this );
00115   
00116   objectManager_.objectCreated(id());
00117 }
00118 
00119 BaseObject::BaseObject(BaseObject* _parent) :
00120   QObject() ,
00121   id_(-1),
00122   persistentId_(-1),
00123   objectType_(DATA_UNKNOWN),
00124   flags_(),
00125   visible_(true),
00126   parentItem_(_parent),
00127   name_("NONAME")
00128 {
00129   id_ = idGenerator;
00130   ++ idGenerator;
00131   
00132   // If the pointer is 0 then something went wrong or we are the root node
00133   if ( _parent ) {
00134     
00135     _parent->appendChild(this);
00136     PluginFunctions::increaseObjectCount();
00137     
00138   } else {
00139     
00140     if ( PluginFunctions::objectRoot() ) {
00141       setParent(PluginFunctions::objectRoot());
00142       PluginFunctions::objectRoot()->appendChild(this);
00143       PluginFunctions::increaseObjectCount();
00144     }
00145     
00146   }
00147   
00148   // Add object to object container
00149   PluginFunctions::addObjectToMap( id(), this );
00150   
00151   objectManager_.objectCreated(id());
00152 }
00153 
00154 
00155 BaseObject::~BaseObject() {
00156 
00157   deleteData();
00158   
00159   PluginFunctions::decreaseObjectCount();
00160   
00161   if ( target() )
00162     PluginFunctions::decreaseTargetCount();
00163   
00164   objectManager_.objectDeleted(id());
00165 
00166 }
00167 
00168 
00169 // ===============================================================================
00170 // Object Identification
00171 // ===============================================================================
00172 
00173 int BaseObject::id() {
00174   return id_;
00175 }
00176 
00177 int BaseObject::persistentId() {
00178   return persistentId_;
00179 }
00180 
00181 void BaseObject::persistentId( int _id ) {
00182   persistentId_ = _id;
00183 }
00184 
00185 
00186 // ===============================================================================
00187 // Data
00188 // ===============================================================================
00189 
00190 void BaseObject::cleanup() {
00191   persistentId_ = -1;
00192 
00193   flags_.clear();
00194 
00195   visible_    = true;
00196   name_       = "NONAME";
00197 }
00198 
00199 // ===============================================================================
00200 // Data Type Handling
00201 // ===============================================================================
00202 
00203 bool BaseObject::dataType(DataType _type) {
00204   if ( _type == DATA_ALL ) {
00205     return true;
00206   }
00207 
00208   return ( objectType_ & _type);
00209 }
00210 
00211 DataType BaseObject::dataType() {
00212   return BaseObject::objectType_;
00213 }
00214 
00215 void BaseObject::setDataType(DataType _type) {
00216   if ( objectType_ != DATA_UNKNOWN )
00217     std::cerr << "BaseObect : overwriting data type" << std::endl;
00218   objectType_ = _type;
00219 }
00220 
00221 // ===============================================================================
00222 // Object Information
00223 // ===============================================================================
00224 
00225 
00226 QString BaseObject::getObjectinfo() {
00227   QString output;
00228 
00229   output += "Info for Object with id " + QString::number(id()) +"\n";
00230   output += "Object is : ";
00231   if ( target() )
00232     output += "target ";
00233   if ( source() )
00234     output += " source";
00235 
00236   if ( visible() )
00237     output += " visible";
00238   else
00239     output += " invisible";
00240 
00241   output +="\n";
00242 
00243   return output;
00244 }
00245 
00246 void BaseObject::printObjectInfo() {
00247   std::cout << getObjectinfo().toStdString();
00248 }
00249 
00250 
00251 // ===============================================================================
00252 // flag Handling
00253 // ===============================================================================
00254 
00255 bool BaseObject::target() {
00256   return flag("target");
00257 }
00258 
00259 void BaseObject::target(bool _target) {
00260   if ( target() != _target ) {
00261     
00262     if ( _target )
00263       PluginFunctions::increaseTargetCount();
00264     else
00265       PluginFunctions::decreaseTargetCount();
00266   }
00267   
00268   setFlag("target", _target);
00269   
00270 }
00271 
00272 bool BaseObject::source() {
00273   return flag("source");
00274 }
00275 
00276 void BaseObject::source(bool _source) {
00277   if ( source() != _source ) {
00278     setFlag("source", _source);
00279   }
00280 }
00281 
00282 bool BaseObject::flag(QString _flag)
00283 {
00284   return flags_.contains(_flag);
00285 }
00286 
00287 void BaseObject::setFlag(QString _flag, bool _set)
00288 {
00289   bool emitted = false;
00290   
00291   if (flags_.contains(_flag))
00292   {
00293     if (!_set) {
00294       flags_.removeAll(_flag);
00295       emit objectSelectionChanged(id());
00296       emitted = true;
00297     }
00298   }
00299   else
00300   {
00301     if (_set) {
00302       flags_ << _flag;
00303       emit objectSelectionChanged(id());
00304       emitted = true;
00305     }
00306   }
00307   
00308   //always emit if its a group
00309   if ( !emitted && isGroup() )
00310     emit objectSelectionChanged(id());
00311 }
00312 
00313 QStringList BaseObject::flags()
00314 {
00315   return flags_;
00316 }
00317 
00318 // ===============================================================================
00319 // Object visualization
00320 // ===============================================================================
00321 
00322 bool BaseObject::visible() {
00323   return visible_;
00324 }
00325 
00326 void BaseObject::visible(bool _visible) {
00327   // Only do something if this is really a change
00328   if (  visible_ != _visible ) {
00329     visible_ = _visible;
00330     
00331     emit visibilityChanged( id() );
00332     
00333   } else {
00334     
00335     //always emit if its a group
00336     if ( isGroup() )
00337       emit visibilityChanged( id() );
00338   }
00339 }
00340 
00341 // ===============================================================================
00342 // ===============================================================================
00343 // Tree Structure :
00344 // ===============================================================================
00345 // ===============================================================================
00346 
00347 BaseObject* BaseObject::last() {
00348   //indexOf
00349 
00350 //   // Visit child item of this node
00351 //   if ( childItems_.size() > 0 ) {
00352 //      return childItems_[0];
00353 //   }
00354 //
00355 //   // No Child Item so visit the next child of the parentItem_
00356 //   if ( parentItem_ ) {
00357 //
00358 //     BaseObject* parentPointer = parentItem_;
00359 //     BaseObject* thisPointer   = this;
00360 //
00361 //     // while we are not at the root node
00362 //     while ( parentPointer ) {
00363 //
00364 //       // If there is an unvisited child of the parent, return this one
00365 //       if ( parentPointer->childCount() > ( thisPointer->row() + 1) ) {
00366 //         return parentPointer->childItems_[ thisPointer->row() + 1 ];
00367 //       }
00368 //
00369 //       // Go to the next level
00370 //       thisPointer   = parentPointer;
00371 //       parentPointer = parentPointer->parentItem_;
00372 //
00373 //     }
00374 //
00375 //     return thisPointer;
00376 //   }
00377 //
00378 //   return this;
00379   std::cerr << "Last not implemented yet! " << std::endl;
00380   return 0;
00381 
00382 }
00383 
00384 // ===============================================================================
00385 // ===============================================================================
00386 
00387 BaseObject* BaseObject::next() {
00388   // Visit child item of this node
00389   if ( childItems_.size() > 0 ) {
00390      return childItems_[0];
00391   }
00392 
00393   // No Child Item so visit the next child of the parentItem_
00394   if ( parentItem_ ) {
00395 
00396     BaseObject* parentPointer = parentItem_;
00397     BaseObject* thisPointer   = this;
00398 
00399     // while we are not at the root node
00400     while ( parentPointer ) {
00401 
00402       // If there is an unvisited child of the parent, return this one
00403       if ( parentPointer->childCount() > ( thisPointer->row() + 1) ) {
00404         return parentPointer->childItems_[ thisPointer->row() + 1 ];
00405       }
00406 
00407       // Go to the next level
00408       thisPointer   = parentPointer;
00409       parentPointer = parentPointer->parentItem_;
00410 
00411     }
00412 
00413     return thisPointer;
00414   }
00415 
00416   return this;
00417 
00418 }
00419 
00420 // ===============================================================================
00421 // ===============================================================================
00422 
00423 int BaseObject::level() {
00424   int level = 0;
00425   BaseObject* current = this;
00426 
00427   // Go up and count the levels to the root node
00428   while ( current->parent() != 0 ) {
00429     level++;
00430     current = current->parent();
00431   }
00432 
00433   return level;
00434 }
00435 
00436 // ===============================================================================
00437 // Parent
00438 // ===============================================================================
00439 
00440 int BaseObject::row() const
00441 {
00442     if (parentItem_)
00443         return parentItem_->childItems_.indexOf(const_cast<BaseObject*>(this));
00444 
00445     return 0;
00446 }
00447 
00448 BaseObject* BaseObject::parent()
00449 {
00450   return parentItem_;
00451 }
00452 
00454 void BaseObject::setParent(BaseObject* _parent) {
00455   // remove this child from the old parents list
00456   if ( parentItem_ != 0 ) {
00457     parentItem_->removeChild(this);
00458    
00459     if ( !_parent->childItems_.contains(this) )
00460       _parent->appendChild(this);
00461   }
00462   
00463   // Store new parent
00464   parentItem_ = _parent;
00465   
00466   // Tell other plugins about this change
00467   emit objectPropertiesChanged(id());
00468 }
00469 
00470 
00471 // ===============================================================================
00472 // Children
00473 // ===============================================================================
00474 
00475 void BaseObject::appendChild(BaseObject *item)
00476 {
00477   if ( !childItems_.contains(item) )
00478     childItems_.append(item);
00479   else 
00480     std::cerr << "Warning! Trying to append a child twice! Remove the append calls from your File plugin!" << std::endl;
00481 }
00482 
00483 BaseObject *BaseObject::child(int row)
00484 {
00485     return childItems_.value(row);
00486 }
00487 
00488 int BaseObject::childCount() const
00489 {
00490     return childItems_.count();
00491 }
00492 
00493 BaseObject* BaseObject::childExists(int _objectId) {
00494 
00495   // Check if this object has the requested id
00496   if ( id_ == _objectId )
00497     return this;
00498 
00499   // search in children
00500   for ( int i = 0 ; i < childItems_.size(); ++i ) {
00501     BaseObject* tmp = childItems_[i]->childExists(_objectId);
00502     if ( tmp != 0)
00503       return tmp;
00504   }
00505 
00506   return 0;
00507 }
00508 
00509 BaseObject* BaseObject::childExists(QString _name) {
00510 
00511   // Check if this object has the requested id
00512   if ( name() == _name )
00513     return this;
00514 
00515   // search in children
00516   for ( int i = 0 ; i < childItems_.size(); ++i ) {
00517     BaseObject* tmp = childItems_[i]->childExists(_name);
00518     if ( tmp != 0)
00519       return tmp;
00520   }
00521 
00522   return 0;
00523 }
00524 
00525 void BaseObject::removeChild( BaseObject* _item ) {
00526 
00527   bool found = false;
00528   QList<BaseObject*>::iterator i;
00529   for (i = childItems_.begin(); i != childItems_.end(); ++i) {
00530      if ( *i == _item ) {
00531         found = true;
00532         break;
00533      }
00534   }
00535 
00536   if ( !found ) {
00537     std::cerr << "Illegal remove request" << std::endl;
00538     return;
00539   }
00540 
00541   childItems_.erase(i);
00542 }
00543 
00544 QList< BaseObject* > BaseObject::getLeafs() {
00545 
00546   QList< BaseObject* > items;
00547 
00548   for ( int i = 0 ; i < childItems_.size(); ++i ) {
00549     items = items + childItems_[i]->getLeafs();
00550   }
00551 
00552   // If we are a leave...
00553   if ( childCount() == 0 )
00554     items.push_back(this);
00555 
00556   return items;
00557 }
00558 
00559 void BaseObject::deleteSubtree() {
00560 
00561   // call function for all children of this node
00562   for ( int i = 0 ; i < childItems_.size(); ++i) {
00563 
00564     // remove the subtree recursively
00565     childItems_[i]->deleteSubtree();
00566 
00567     // delete child
00568     delete childItems_[i];
00569   }
00570 
00571   // clear the array
00572   childItems_.clear();
00573 }
00574 
00575 
00576 // TreeItem* TreeItem::inConsistent() {
00577 //
00578 //   BaseObjectData* object;
00579 //
00580 //   // If id is -1 this is a group or rootitem so dont stop here
00581 //   if ( (objectId_ != -1) && !PluginFunctions::getObject(objectId_,object)  )
00582 //     return this;
00583 //
00584 //   for ( int i = 0 ; i < childItems.size(); ++i ) {
00585 //     TreeItem* tmp = childItems[i]->inConsistent();
00586 //     if ( tmp != 0)
00587 //       return tmp;
00588 //   }
00589 //
00590 //   return 0;
00591 // }
00592 
00593 // ===============================================================================
00594 // Grouping
00595 // ===============================================================================
00596 int BaseObject::group() {
00597   // Skip root node
00598   if ( parent() == 0 )
00599     return -1;
00600 
00601   // Dont count root node as a group
00602   if ( parent()->parent() == 0 )
00603     return -1;
00604 
00605   // Only consider groups
00606   if ( !parent()->dataType(DATA_GROUP) )
00607     return -1;
00608 
00609   // Get the group id
00610   return ( parent()->id() );
00611 
00612 }
00613 
00614 bool BaseObject::isGroup() {
00615 //   return ( (childItems_.size() > 0) || dataType(DATA_GROUP) ) ;
00616   return ( dataType(DATA_GROUP) ) ;
00617 };
00618 
00619 
00620 bool BaseObject::isInGroup( int _id ) {
00621   BaseObject* current = this;
00622 
00623   // Go up and check for the group id
00624   do {
00625 
00626     // Check if we found the id
00627     if ( current->id() == _id )
00628       return true;
00629 
00630     // Move on to parent object
00631     current = current->parent();
00632   } while ( current != 0 );
00633 
00634   return false;
00635 }
00636 
00637 bool BaseObject::isInGroup( QString _name ) {
00638   BaseObject* current = this;
00639 
00640   // Go up and check for the group name
00641   do {
00642 
00643     // Check if this object is a group and if it has the serach name
00644     if ( current->dataType( DATA_GROUP ) && (current->name() == _name) )
00645       return true;
00646 
00647     // Move on to parent object
00648     current = current->parent();
00649 
00650   } while ( current != 0 );
00651 
00652   return false;
00653 }
00654 
00655 std::vector< int > BaseObject::getGroupIds() {
00656   std::vector< int > groups;
00657 
00658   BaseObject* current = this;
00659 
00660   // Go up and collect all groups in the given order
00661   do {
00662 
00663     // collect only groups
00664     if ( current->dataType( DATA_GROUP ) )
00665       // Skip the root Object
00666       if ( current->parent() != 0 )
00667         groups.push_back( current->id() );
00668 
00669     // Move on to parent object
00670     current = current->parent();
00671   } while ( current != 0 );
00672 
00673   return groups;
00674 }
00675 
00676 QStringList BaseObject::getGroupNames() {
00677   QStringList groups;
00678 
00679   BaseObject* current = this;
00680 
00681   // Go up and collect all groups in the given order
00682   do {
00683 
00684     // collect only groups
00685     if ( current->dataType( DATA_GROUP ) )
00686       // Skip the root Object
00687       if ( current->parent() != 0 )
00688         groups.push_back( current->name() );
00689 
00690     // Move on to parent object
00691     current = current->parent();
00692   } while ( current != 0 );
00693 
00694   return groups;
00695 }
00696 
00697 // ===============================================================================
00698 // Name
00699 // ===============================================================================
00700 QString BaseObject::name() {
00701   return name_;
00702 }
00703 
00704 void BaseObject::setName(QString _name ) {
00705   name_ = _name;
00706   
00707   // Tell plugins about the name change
00708   emit objectPropertiesChanged(id());
00709 }
00710 
00711 // ===============================================================================
00712 // Content
00713 // ===============================================================================
00714 void BaseObject::update(UpdateType _type) {
00715 }
00716 
00717 void BaseObject::dumpTree() {
00718 
00719   // Add spaces to visualize level
00720   for ( int i = 0 ; i < level() ; ++i  )
00721     std::cerr << "   ";
00722 
00723   std::cerr << "Node ";
00724   std::cerr << std::string(name().toAscii());
00725 
00726   std::cerr << " with id : ";
00727   std::cerr << id();
00728 
00729   // Write the type of this Object
00730   std::cerr << " and type " << typeName(dataType()).toStdString()  <<  std::endl;
00731 
00732   // call function for all children of this node
00733   for ( int i = 0 ; i < childItems_.size(); ++i)
00734     childItems_[i]->dumpTree();
00735 
00736 }
00737 
00738 BaseObject* BaseObject::copy() {
00739   std::cerr << "Copy not supported by this Object" << std::endl;
00740   return  0;
00741 }
00742 
00743 
00744 // ===============================================================================
00745 // per Object data functions
00746 // ===============================================================================
00747 
00748 void
00749 BaseObject::
00750 setObjectData( QString _dataName , PerObjectData* _data ) {
00751   dataMap_.insert( _dataName, _data );
00752 }
00753 
00754 void
00755 BaseObject::
00756 clearObjectData( QString _dataName ) {
00757   if (dataMap_.contains(_dataName))
00758     dataMap_.remove(_dataName);
00759 }
00760 
00761 
00762 bool
00763 BaseObject::
00764 hasObjectData( QString _dataName )
00765 {
00766   return dataMap_.contains(_dataName);
00767 }
00768 
00769 
00770 PerObjectData*
00771 BaseObject::
00772 objectData( QString _dataName ) {
00773   if (dataMap_.contains(_dataName))
00774     return dataMap_.value(_dataName);
00775   else
00776     return 0;
00777 }
00778 
00779 void
00780 BaseObject::
00781 deleteData() {
00782 
00783   QMapIterator<QString, PerObjectData* > i(dataMap_);
00784   while (i.hasNext()) {
00785       i.next();
00786       delete i.value();
00787   }
00788 
00789   dataMap_.clear();
00790 
00791 }
00792 
00793 
00794 
00795 ObjectManager::ObjectManager() {
00796 }
00797 
00798 ObjectManager::~ObjectManager() {
00799   
00800 }
00801     
00802 void ObjectManager::objectCreated(int _objectId) 
00803 {
00804   emit newObject(_objectId);
00805 }
00806 
00807 void ObjectManager::objectDeleted(int _objectId) 
00808 {
00809   // Remove deleted object from object container
00810   PluginFunctions::removeObjectFromMap( _objectId );
00811     
00812   emit deletedObject(_objectId);
00813 }
00814 
00815 
00816 ObjectManager* getObjectManager() {
00817   return &objectManager_;
00818 }
00819 
00820 
00821 
00822 
00823 //=============================================================================

acg pic Project OpenFlipper, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .