File indexing completed on 2024-12-08 06:46:41

0001 /***************************************************************************
0002                                cmapzone.cpp
0003                              -------------------
0004     begin                : Sat Mar 10 2001
0005     copyright            : (C) 2001 by Kmud Developer Team
0006     email                : kmud-devel@kmud.de
0007  ***************************************************************************/
0008 
0009 /***************************************************************************
0010  *                                                                         *
0011  *   This program is free software; you can redistribute it and/or modify  *
0012  *   it under the terms of the GNU General Public License as published by  *
0013  *   the Free Software Foundation; either version 2 of the License, or     *
0014  *   (at your option) any later version.                                   *
0015  *                                                                         *
0016  ***************************************************************************/
0017 
0018 #include "cmapzone.h"
0019 
0020 #include <KLocalizedString>
0021 
0022 #include <qfontmetrics.h>
0023 #include <QDebug>
0024 #include <QFontDatabase>
0025 
0026 #include "cmapmanager.h"
0027 #include "cmaplevel.h"
0028 #include "cmaptext.h"
0029 #include "cmappath.h"
0030 #include "cmapelementutil.h"
0031 
0032 CMapZone::CMapZone(CMapManager *manager) : CMapElement(manager,QRect(-1,-1,0,0),nullptr)
0033 {
0034   label  = i18n("Unnamed Zone");
0035   m_room_id_count = 0;
0036   m_text_id_count = 0;  
0037   manager->m_zoneCount ++;
0038   m_ID = manager->m_zoneCount;
0039   description = "";
0040 
0041   color = QColor(192,192,192);
0042   backgroundCol = QColor(192,192,192);
0043   useDefaultCol = true;
0044   useDefaultBackground = true;
0045 
0046   textRemove();
0047 
0048   // Set the root zone if not already set
0049   if (!manager->getMapData()->rootZone)  // can't use getZone() here, as we'd end up in a loop
0050     manager->getMapData()->rootZone = this;
0051   manager->createLevel(UP);
0052 }
0053 
0054 CMapZone::~CMapZone()
0055 {
0056   //FIXME_jp : when this is undone there are extra levels, this needs fixing
0057   // Delete the levels in the zone
0058   while (levelCount()) {
0059     qWarning() << "deleteing a zone and found levels that should already have been deleted!!";
0060     delete firstLevel();
0061   }
0062 }
0063 
0064 void CMapZone::setLevel(CMapLevel *level)
0065 {
0066   CMapElement::setLevel(level);
0067 }
0068 
0069 
0070 void CMapZone::setLabel(QString zoneLabel)
0071 {
0072     label = zoneLabel;
0073 }
0074 
0075 void CMapZone::dragPaint(QPoint offset,QPainter *p,CMapZone *)
0076 {
0077   p->setPen(QColor(255, 255, 255, 128));
0078   p->setBrush(QColor(0, 255, 255, 64));
0079     p->drawRect(getX() + offset.x(),getY() + offset.y(),getWidth(),getHeight());
0080 }
0081 
0082 /** This is used to paint the sub boxes displayed when the element is painted */
0083 void CMapZone::paintSubBox(QPainter *p,int x,int y,int width,int height)
0084 {
0085     QColor background;
0086 
0087     if (getUseDefaultCol())
0088     {
0089         background = getManager()->getMapData()->defaultZoneColor;
0090     }
0091     else
0092     {
0093         background = getColor();
0094     }
0095 
0096     p->setPen(Qt::white);
0097     p->drawLine(x,y,x+width,y);
0098     p->drawLine(x,y,x,y+height);
0099     p->setPen(Qt::black);
0100     p->drawLine(x+1,y+height,x+width,y+height);
0101     p->drawLine(x+width,y+1,x+width,y+height);
0102 
0103     p->setBrush(background);
0104     p->setPen(background);
0105 
0106     p->drawRect(x+1,y+1,width-1,height-1);
0107 }
0108 
0109 /** Used to paint the element at a given location and size
0110   * @param p The painer to paint the element to
0111   * @param pos The position to paint the elmenet
0112   * @param size The size the element should be draw
0113   * @param zone The current zone being viewed */
0114 void CMapZone::paintElementResize(QPainter *p,QPoint pos,QSize size,CMapZone *)
0115 {
0116     signed int y1,x1;
0117 
0118     x1 = pos.x()+1;
0119     y1 = pos.y()+1;
0120 
0121     int boxWidth = size.width()/2;
0122     int boxHeight = size.height()/2;
0123     int boxOffsetX = boxWidth/2-1;
0124     int boxOffsetY = boxHeight/2-1;
0125     boxWidth--;
0126     boxHeight--;
0127 
0128     paintSubBox(p,x1,y1,boxWidth,boxHeight);
0129     paintSubBox(p,x1+boxOffsetX,y1+boxOffsetY,boxWidth,boxHeight);
0130     paintSubBox(p,x1+boxOffsetX+boxOffsetX,y1+boxOffsetY+boxOffsetY,boxWidth,boxHeight);
0131 }
0132 
0133 void CMapZone::lowerPaint(QPainter *p,CMapZone *)
0134 {
0135     signed int y1,x1;
0136 
0137     x1 = getX()+1-5;
0138     y1 = getY()+1-5;
0139     int boxWidth = getSize().width()/2;
0140     int boxHeight = getSize().height()/2;
0141     int boxOffsetX = boxWidth/2-1;
0142     int boxOffsetY = boxHeight/2-1;
0143     boxWidth--;
0144     boxHeight--;
0145 
0146     p->setPen(getManager()->getMapData()->lowerZoneColor);
0147     QBrush brush(getManager()->getMapData()->lowerZoneColor);
0148     brush.setStyle(Qt::Dense3Pattern);
0149     p->setBrush(brush);
0150     p->drawRect(x1,y1,boxWidth,boxHeight);
0151     p->drawRect(x1+boxOffsetX,y1+boxOffsetY,boxWidth,boxHeight);
0152     p->drawRect(x1+boxOffsetX+boxOffsetX,y1+boxOffsetY+boxOffsetY,boxWidth,boxHeight);
0153 }
0154 
0155 void CMapZone::higherPaint(QPainter *p,CMapZone *)
0156 {
0157     signed int y1,x1;
0158 
0159     x1 = getX()+6;
0160     y1 = getY()+6;
0161     int boxWidth = getSize().width()/2;
0162     int boxHeight = getSize().height()/2;
0163     int boxOffsetX = boxWidth/2-1;
0164     int boxOffsetY = boxHeight/2-1;
0165     boxWidth--;
0166     boxHeight--;
0167 
0168     p->setPen(getManager()->getMapData()->higherZoneColor);
0169     QBrush brush(getManager()->getMapData()->higherZoneColor);
0170     brush.setStyle(Qt::Dense3Pattern);
0171     p->setBrush(brush);
0172     p->drawRect(x1,y1,boxWidth,boxHeight);
0173     p->drawRect(x1+boxOffsetX,y1+boxOffsetY,boxWidth,boxHeight);
0174     p->drawRect(x1+boxOffsetX+boxOffsetX,y1+boxOffsetY+boxOffsetY,boxWidth,boxHeight);
0175 }
0176 
0177 CMapElement *CMapZone::copy(void)
0178 {
0179   return nullptr;
0180 }
0181 
0182 void CMapZone::setLabelPosition(labelPosTyp pos)
0183 {
0184     if (getLabel()=="") pos=HIDE;
0185 
0186     if (pos!=HIDE)
0187     {
0188         labelPosition = pos;
0189         QPoint p;
0190 
0191         QFont font = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
0192 
0193         QFontMetrics fm(font);
0194         int width = fm.horizontalAdvance(getLabel());
0195         int height = fm.height();
0196 
0197         switch (pos)
0198         {
0199             case CUSTOM    : break;
0200             case NORTH     : p.setX((getX()+(getWidth()/2)) -(width /2)); p.setY(getY() - height -  10); break;
0201             case NORTHEAST : p.setX(getHighX()+10); p.setY(getY() - height - 10); break;
0202             case EAST      : p.setX(getHighX()+10); p.setY((getY()+(getHeight()/2)) - (height/2)); break;
0203             case SOUTHEAST : p.setX(getHighX()+10); p.setY(getHighY() + 10); break;
0204             case SOUTH     : p.setX((getX()+(getWidth()/2)) -(width /2)); p.setY(getHighY() + 10); break;
0205             case SOUTHWEST : p.setX(getX()-width-10); p.setY(getHighY() + 10); break;
0206             case WEST      : p.setX(getX()-width-10); p.setY((getY()+(getHeight()/2)) - (height/2)); break;
0207             case NORTHWEST : p.setX(getX()-width-10); p.setY(getY() - height -  10); break;
0208                         default :
0209                              return;
0210         }
0211 
0212     }
0213 }
0214 
0215 void CMapZone::setLabelPosition(labelPosTyp pos,CMapText *text)
0216 {
0217     if (getLabel()=="" || text == nullptr) pos=HIDE;
0218     setLabelPosition(pos);
0219 }
0220 
0221 void CMapZone::geometryChanged(void)
0222 {
0223     setLabelPosition(getLabelPosition());
0224 }
0225 
0226 void CMapZone::textRemove(void)
0227 {
0228     labelPosition = HIDE;
0229 }
0230 
0231 /** Used to load the properties of the element from a list of properties */
0232 void CMapZone::loadProperties(KConfigGroup properties)
0233 {
0234     CMapElement::loadProperties(properties);
0235     setLabel(properties.readEntry("Label",getLabel()));
0236     setDescription(properties.readEntry("Description",getDescription()));
0237 
0238     QColor color=getColor();
0239     color=properties.readEntry("Color",color);
0240     setColor(color);
0241     setUseDefaultCol(properties.readEntry("DefaultColor",getUseDefaultCol()));
0242 
0243     QColor bgcol=getBackgroundColor();
0244     bgcol=properties.readEntry("BackgroundColor",bgcol);
0245     setBackgroundColor(bgcol);
0246     setUseDefaultBackground(properties.readEntry("DefaultBackground",getUseDefaultBackground()));
0247 
0248     setZoneID(properties.readEntry("ZoneID",m_ID));
0249 
0250     setLabelPosition((CMapZone::labelPosTyp)properties.readEntry("LabelPos",(int)getLabelPosition()));
0251 }
0252 
0253 /** Used to save the properties of the element to a list of properties */
0254 void CMapZone::saveProperties(KConfigGroup properties)
0255 {
0256     CMapElement::saveProperties(properties);
0257     properties.writeEntry("Label",getLabel());
0258     properties.writeEntry("Description",getDescription());
0259     properties.writeEntry("Color",getColor());
0260     properties.writeEntry("DefaultColor",getUseDefaultCol());
0261     properties.writeEntry("BackgroundColor",getBackgroundColor());
0262     properties.writeEntry("LabelPos",(int)getLabelPosition());
0263     properties.writeEntry("ZoneID",getZoneID());
0264 }
0265 
0266 /** Used to save the element as an XML object 
0267   * @param properties The XML object to save the properties too */
0268 void CMapZone::saveQDomElement(QDomDocument *doc,QDomElement *properties)
0269 {
0270     CMapElement::saveQDomElement(doc,properties);
0271     
0272     properties->setAttribute("Label",getLabel());
0273     properties->setAttribute("Description",getDescription());
0274     writeColor(doc,properties,"Color",getColor());  
0275     writeColor(doc,properties,"BackgroundColor",getBackgroundColor());
0276     properties->setAttribute("DefaultColor",getUseDefaultCol());
0277     properties->setAttribute("LabelPos",(int)getLabelPosition());
0278     properties->setAttribute("ZoneID",getZoneID());
0279     properties->setAttribute("NumLevels",levelCount());
0280     if (getUseDefaultCol())
0281     {
0282         properties->setAttribute("UseDefaultCol","true");
0283     }
0284     else
0285     {
0286         properties->setAttribute("UseDefaultCol","false");
0287     }
0288 
0289 }
0290 
0291 /** Used to load the properties from a XML object
0292   * @param properties The XML object to load the properties from */  
0293 void CMapZone::loadQDomElement(QDomElement *properties)
0294 {
0295     CMapElement::loadQDomElement(properties);
0296 
0297     setLabel(properties->attribute("Label",getLabel()));
0298     setDescription(properties->attribute("Description",getDescription()));  
0299     setUseDefaultCol(readBool(properties,"UseDefaultCol",getUseDefaultCol()));
0300     // setLabelPosition((labelPosTyp)readInt(properties,"LabelPos",(int)getLabelPosition()));
0301     setZoneID(readInt(properties,"ZoneID",getZoneID()));
0302     setColor(readColor(properties,"Color",getColor()));
0303     setBackgroundColor(readColor(properties,"BackgroundColor",getBackgroundColor()));
0304 
0305 }
0306 
0307 
0308 void CMapZone::setZoneID(unsigned int id)
0309 {
0310     if (id > getManager()->m_zoneCount)
0311       getManager()->m_zoneCount = id;
0312 
0313     m_ID = id;
0314 }
0315 
0316 void CMapZone::setUseDefaultCol(bool b)
0317 {
0318     useDefaultCol = b;
0319 }
0320 
0321 bool CMapZone::getUseDefaultCol(void)
0322 {
0323     return useDefaultCol;
0324 }
0325 
0326 void CMapZone::setUseDefaultBackground(bool b)
0327 {
0328     useDefaultBackground = b;
0329 }
0330 
0331 bool CMapZone::getUseDefaultBackground(void)
0332 {
0333     return true;
0334 }
0335 
0336 void CMapZone::setColor(QColor col)
0337 {
0338     color = col;
0339 }
0340 
0341 QColor CMapZone::getColor(void)
0342 {
0343     return color;
0344 }
0345 
0346 void CMapZone::setBackgroundColor(QColor col)
0347 {
0348     backgroundCol = col;
0349 }
0350 
0351 QColor CMapZone::getBackgroundColor(void)
0352 {
0353     return backgroundCol;
0354 }
0355 
0356 unsigned int CMapZone::levelCount() const
0357 {
0358   return mapLevelModel.rowCount();
0359 }
0360 
0361 CMapLevel *CMapZone::getLevel(int idx) const
0362 {
0363   QModelIndex index = mapLevelModel.index(idx, 0);
0364   if (!index.isValid()) return nullptr;
0365   CMapLevel *lvl = static_cast<CMapLevel*>(index.data(Qt::UserRole + 1).value<void *>());
0366   return lvl;
0367 }
0368 
0369 int CMapZone::levelIndex(const CMapLevel *level) const
0370 {
0371   for (unsigned int i = 0; i < levelCount(); ++i)
0372     if (getLevel(i) == level)
0373       return i;
0374   return -1;
0375 }
0376 
0377 void CMapZone::addLevel(CMapLevel *level)
0378 {
0379   insertLevel(level, -1);
0380 }
0381 
0382 void CMapZone::insertLevel(CMapLevel *level, int pos)
0383 {
0384   QStandardItem *item = new QStandardItem(level->getName());
0385   item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
0386   item->setData(QVariant::fromValue((void *) level), Qt::UserRole + 1);
0387 
0388   if ((pos >= 0) && (pos < (int)levelCount()))
0389     mapLevelModel.insertRow(pos, item);
0390   else
0391     mapLevelModel.appendRow(item);
0392 }
0393 
0394 void CMapZone::removeLevel(CMapLevel *level)
0395 {
0396   int idx = levelIndex(level);
0397   if (idx < 0) return;
0398   mapLevelModel.removeRows(idx, 1);
0399 }
0400 
0401 void CMapZone::setLevelName(CMapLevel *level, const QString &name)
0402 {
0403   int idx = levelIndex(level);
0404   if (idx < 0) return;
0405 
0406   QStandardItem *item = mapLevelModel.item(idx);
0407   if (item && (item->text() != name)) item->setText(name);
0408 }
0409