File indexing completed on 2024-12-29 05:09:42

0001 /***************************************************************************
0002  *     Copyright (C) 2009 by Renaud Guezennec                             *
0003  *   https://rolisteam.org/contact                   *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify     *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 
0021 #include <QDebug>
0022 
0023 #include <QFileDialog>
0024 #include <QInputDialog>
0025 #include <QMenu>
0026 #include <QMouseEvent>
0027 #include <QOpenGLWidget>
0028 
0029 #include "controller/view_controller/imageselectorcontroller.h"
0030 #include "controller/view_controller/vectorialmapcontroller.h"
0031 #include "mediacontainers/mediacontainer.h"
0032 #include "rgraphicsview.h"
0033 #include "rwidgets/dialogs/imageselectordialog.h"
0034 
0035 bool isNormalItem(const vmap::VisualItemController* itemCtrl)
0036 {
0037     if(!itemCtrl)
0038         return false;
0039 
0040     auto layer= itemCtrl->layer();
0041     return !(layer == Core::Layer::GRIDLAYER || layer == Core::Layer::FOG);
0042 }
0043 
0044 RGraphicsView::RGraphicsView(VectorialMapController* ctrl, QWidget* parent)
0045     : QGraphicsView(parent), m_ctrl(ctrl), m_centerOnItem(nullptr)
0046 {
0047     m_counterZoom= 0;
0048 
0049     setAcceptDrops(true);
0050     setAlignment((Qt::AlignLeft | Qt::AlignTop));
0051     m_preferences= PreferencesManager::getInstance();
0052     setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
0053 
0054     // fitInView(sceneRect(),Qt::KeepAspectRatio);
0055     setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
0056     setRubberBandSelectionMode(Qt::IntersectsItemBoundingRect);
0057     setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing);
0058     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0059     setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
0060 
0061     createAction();
0062 }
0063 
0064 void RGraphicsView::mousePressEvent(QMouseEvent* event)
0065 {
0066     if(m_ctrl->tool() != Core::HANDLER)
0067     {
0068         setDragMode(QGraphicsView::NoDrag);
0069         QGraphicsView::mousePressEvent(event);
0070         return;
0071     }
0072 
0073     // if(event->button() == Qt::RightButton)
0074     //        return;
0075 
0076     if(event->button() == Qt::LeftButton)
0077     {
0078         QList<QGraphicsItem*> list= items(event->pos());
0079 
0080         list.erase(std::remove_if(list.begin(), list.end(),
0081                                   [](const QGraphicsItem* item)
0082                                   { return !isNormalItem(dynamic_cast<const vmap::VisualItemController*>(item)); }),
0083                    list.end());
0084         if(!list.isEmpty() && event->modifiers() == Qt::NoModifier)
0085         {
0086             setDragMode(QGraphicsView::NoDrag);
0087         }
0088         else if(event->modifiers() & Qt::ShiftModifier)
0089         {
0090             setDragMode(QGraphicsView::ScrollHandDrag);
0091             // m_lastPoint= mapToScene(event->pos());
0092         }
0093         else
0094         {
0095             setDragMode(QGraphicsView::RubberBandDrag);
0096         }
0097     }
0098     QGraphicsView::mousePressEvent(event);
0099 }
0100 
0101 void RGraphicsView::wheelEvent(QWheelEvent* event)
0102 {
0103     if(event->modifiers() & Qt::ShiftModifier)
0104     {
0105         double angle= event->angleDelta().y();
0106         double factor= qPow(1.0015, angle);
0107 
0108         auto targetViewportPos= event->position();
0109         auto targetScenePos= event->scenePosition();
0110         m_ctrl->setZoomLevel(m_ctrl->zoomLevel() * factor);
0111         scale(factor, factor);
0112         centerOn(targetScenePos);
0113         QPointF deltaViewportPos= targetViewportPos - QPointF(viewport()->width() / 2.0, viewport()->height() / 2.0);
0114         QPointF viewportCenter= mapFromScene(targetScenePos) - deltaViewportPos;
0115         centerOn(mapToScene(viewportCenter.toPoint()));
0116 
0117         return;
0118     }
0119     else
0120         QGraphicsView::wheelEvent(event);
0121 }
0122 
0123 QList<ItemToControllerInfo> extractVisualItem(const QList<QGraphicsItem*>& itemList, bool upChild= true)
0124 {
0125     QList<ItemToControllerInfo> list;
0126     for(QGraphicsItem* item : itemList)
0127     {
0128         VisualItem* vItem= dynamic_cast<VisualItem*>(item);
0129         if(!vItem && upChild)
0130         {
0131             ChildPointItem* childItem= dynamic_cast<ChildPointItem*>(item);
0132             if(nullptr != childItem)
0133             {
0134                 QGraphicsItem* item2= childItem->parentItem();
0135                 vItem= dynamic_cast<VisualItem*>(item2);
0136             }
0137         }
0138 
0139         if(nullptr == vItem)
0140             continue;
0141 
0142         auto ctrl= vItem->controller();
0143         bool isNormal= isNormalItem(ctrl);
0144 
0145         auto it= std::find_if(std::begin(list), std::end(list),
0146                               [ctrl](const ItemToControllerInfo& item) { return ctrl == item.ctrl; });
0147 
0148         if(isNormal && (it == std::end(list)))
0149         {
0150             list.append({ctrl, vItem});
0151         }
0152     }
0153     return list;
0154 }
0155 
0156 QList<vmap::VisualItemController*> convertInfoToCtrl(const QList<ItemToControllerInfo>& selectedItems)
0157 {
0158     QList<vmap::VisualItemController*> ctrls;
0159     std::transform(std::begin(selectedItems), std::end(selectedItems), std::back_inserter(ctrls),
0160                    [](const ItemToControllerInfo& item) { return item.ctrl; });
0161 
0162     return ctrls;
0163 }
0164 
0165 QList<ItemToControllerInfo> RGraphicsView::selection()
0166 {
0167     return extractVisualItem(scene()->selectedItems());
0168 }
0169 
0170 void RGraphicsView::contextMenuEvent(QContextMenuEvent* event)
0171 {
0172     bool licenseToModify= false;
0173 
0174     m_menuPoint= event->pos();
0175 
0176     if((m_ctrl->localGM()) || (m_ctrl->permission() == Core::PC_ALL))
0177     {
0178         licenseToModify= true;
0179     }
0180 
0181     if(!m_ctrl->idle())
0182         QGraphicsView::contextMenuEvent(event);
0183 
0184     auto selectedItems= selection();
0185     QList<vmap::VisualItemController*> underMouseCtrls;
0186     QList<ItemToControllerInfo> visualItemUnderMouse;
0187     if(selectedItems.isEmpty())
0188     {
0189         auto itemUnderMouse= items(m_menuPoint);
0190         visualItemUnderMouse= extractVisualItem(itemUnderMouse);
0191 
0192         if(!visualItemUnderMouse.isEmpty())
0193         {
0194             selectedItems.append(visualItemUnderMouse.first());
0195         }
0196         std::transform(std::begin(visualItemUnderMouse), std::end(visualItemUnderMouse),
0197                        std::back_inserter(underMouseCtrls), [](const ItemToControllerInfo& item) { return item.ctrl; });
0198     }
0199     QMenu menu;
0200     auto parentWid= dynamic_cast<MediaContainer*>(parentWidget());
0201     // Empty list
0202 
0203     QAction* resetRotationAct= nullptr;
0204     QAction* rightRotationAct= nullptr;
0205     QAction* leftRotationAct= nullptr;
0206     QAction* angleRotationAct= nullptr;
0207 
0208     if(licenseToModify && !selectedItems.isEmpty())
0209     {
0210         int n= selectedItems.size();
0211         menu.addSection(tr("%n item(s)", "", n));
0212 
0213         bool groundL= false, objectL= false, characterL= false, gmLayer= false;
0214         if(selectedItems.size() == 1)
0215         {
0216             auto item= selectedItems.first();
0217             item.item->addActionContextMenu(menu);
0218 
0219             auto layer= item.ctrl->layer();
0220             switch(layer)
0221             {
0222             case Core::Layer::GROUND:
0223                 groundL= true;
0224                 break;
0225             case Core::Layer::OBJECT:
0226                 objectL= true;
0227                 break;
0228             case Core::Layer::CHARACTER_LAYER:
0229                 characterL= true;
0230                 break;
0231             case Core::Layer::GAMEMASTER_LAYER:
0232                 gmLayer= true;
0233                 break;
0234             default:
0235                 break;
0236             }
0237         }
0238 
0239         menu.addAction(m_dupplicate);
0240 
0241         auto overlapping= menu.addMenu(tr("Overlapping"));
0242         overlapping->addAction(m_backOrderAction);
0243         overlapping->addAction(m_lowerAction);
0244         overlapping->addAction(m_raiseAction);
0245         overlapping->addAction(m_frontOrderAction);
0246 
0247         QMenu* rotationMenu= menu.addMenu(tr("Rotate"));
0248         resetRotationAct= rotationMenu->addAction(tr("To 360"));
0249         rightRotationAct= rotationMenu->addAction(tr("Right"));
0250         leftRotationAct= rotationMenu->addAction(tr("Left"));
0251         angleRotationAct= rotationMenu->addAction(tr("Set Angleā€¦"));
0252 
0253         QMenu* setLayerMenu= menu.addMenu(tr("Set Layer"));
0254         setLayerMenu->addAction(m_putGroundLayer);
0255         m_putGroundLayer->setChecked(groundL);
0256         setLayerMenu->addAction(m_putObjectLayer);
0257         m_putObjectLayer->setChecked(objectL);
0258         setLayerMenu->addAction(m_putCharacterLayer);
0259         m_putCharacterLayer->setChecked(characterL);
0260         setLayerMenu->addAction(m_putGMLayer);
0261         m_putGMLayer->setChecked(gmLayer);
0262 
0263         QMenu* harmonizeMenu= menu.addMenu(tr("Normalize Size"));
0264         harmonizeMenu->addAction(m_normalizeSizeAverage);
0265         harmonizeMenu->addAction(m_normalizeSizeUnderMouse);
0266         harmonizeMenu->addAction(m_normalizeSizeBigger);
0267         harmonizeMenu->addAction(m_normalizeSizeSmaller);
0268 
0269         menu.addAction(m_lockSize);
0270         menu.addAction(m_removeSelection);
0271     }
0272 
0273     menu.addSection(tr("Map"));
0274 
0275     switch(m_ctrl->layer())
0276     {
0277     case Core::Layer::OBJECT:
0278         m_editObjectLayer->setChecked(true);
0279         break;
0280     case Core::Layer::GROUND:
0281         m_editGroundLayer->setChecked(true);
0282         break;
0283     case Core::Layer::CHARACTER_LAYER:
0284         m_editCharacterLayer->setChecked(true);
0285         break;
0286     default:
0287         break;
0288     }
0289     if(licenseToModify)
0290     {
0291         QMenu* editLayer= menu.addMenu(tr("Edit Layer"));
0292         editLayer->addAction(m_editGroundLayer);
0293         editLayer->addAction(m_editObjectLayer);
0294         editLayer->addAction(m_editCharacterLayer);
0295         editLayer->addAction(m_editGameMasterLayer);
0296 
0297         QMenu* changeVibility= menu.addMenu(tr("Change Visibility"));
0298         changeVibility->addAction(m_hiddenVisibility);
0299         changeVibility->addAction(m_characterVisibility);
0300         changeVibility->addAction(m_allVisibility);
0301 
0302         QMenu* rollInit= menu.addMenu(tr("Roll Init"));
0303         rollInit->addAction(m_rollInitOnAllNpc);
0304         rollInit->addAction(m_rollInitOnAllCharacter);
0305         if(!selectedItems.isEmpty())
0306             rollInit->addAction(m_rollInitOnSelection);
0307 
0308         QMenu* cleanInit= menu.addMenu(tr("Clear Init"));
0309         cleanInit->addAction(m_cleanInitOnAllNpc);
0310         cleanInit->addAction(m_cleanInitOnAllCharacter);
0311         if(!selectedItems.isEmpty())
0312             cleanInit->addAction(m_cleanInitOnSelection);
0313     }
0314     auto zoom= menu.addMenu(tr("Zoom"));
0315     zoom->addAction(m_zoomIn);
0316     zoom->addAction(m_zoomOut);
0317     zoom->addAction(m_zoomInMax);
0318     zoom->addAction(m_zoomNormal);
0319     zoom->addAction(m_zoomOutMax);
0320     zoom->addAction(m_zoomCenterOnItem);
0321     m_centerOnItem= itemAt(m_menuPoint);
0322     if(nullptr == m_centerOnItem)
0323     {
0324         m_zoomCenterOnItem->setVisible(false);
0325     }
0326     else
0327     {
0328         m_zoomCenterOnItem->setVisible(true);
0329     }
0330     if(licenseToModify)
0331     {
0332         menu.addSeparator();
0333         menu.addAction(m_importImage);
0334         menu.addSeparator();
0335     }
0336 
0337     if(nullptr != parentWid)
0338     {
0339         parentWid->addActionToMenu(menu);
0340     }
0341     if(licenseToModify)
0342     {
0343         menu.addAction(m_properties);
0344     }
0345 
0346     QAction* selectedAction= menu.exec(event->globalPos());
0347 
0348     if(nullptr == selectedAction)
0349         return;
0350 
0351     if(selectedItems.empty())
0352         return;
0353 
0354     QList<vmap::VisualItemController*> ctrls= convertInfoToCtrl(selectedItems);
0355 
0356     if(resetRotationAct == selectedAction)
0357     {
0358         setRotation(ctrls, 0);
0359     }
0360     else if(selectedAction == rightRotationAct)
0361     {
0362         setRotation(ctrls, 90);
0363     }
0364     else if(selectedAction == leftRotationAct)
0365     {
0366         setRotation(ctrls, 270);
0367     }
0368     else if(m_dupplicate == selectedAction)
0369     {
0370         m_ctrl->dupplicateItem(ctrls);
0371     }
0372     else if(selectedAction == m_lockSize)
0373     {
0374         lockItems(ctrls);
0375     }
0376     else if(selectedAction == angleRotationAct)
0377     {
0378         int angle= QInputDialog::getInt(this, tr("Rotation Value ?"),
0379                                         tr("Please, set the rotation angle you want [0-360]"), 0, 0, 360);
0380         setRotation(ctrls, angle);
0381     }
0382     else if(m_normalizeSizeBigger == selectedAction || m_normalizeSizeAverage == selectedAction
0383             || m_normalizeSizeUnderMouse == selectedAction || m_normalizeSizeSmaller == selectedAction)
0384     {
0385         m_ctrl->normalizeSize(ctrls, static_cast<VectorialMapController::Method>(selectedAction->data().toInt()),
0386                               mapToScene(m_menuPoint));
0387     }
0388     else if((m_backOrderAction == selectedAction) || (m_frontOrderAction == selectedAction)
0389             || (m_lowerAction == selectedAction) || (m_raiseAction == selectedAction))
0390     {
0391         if(!selectedItems.isEmpty())
0392         {
0393             auto first= selectedItems[0];
0394             auto order= static_cast<VectorialMapController::StackOrder>(selectedAction->data().toInt());
0395             auto under= items(first.item->boundingRect().toRect().translated(first.item->pos().toPoint()));
0396             auto visualItem= extractVisualItem(under);
0397 
0398             if(order == VectorialMapController::StackOrder::RAISE)
0399             {
0400                 bool startChanges= false;
0401                 QList<ItemToControllerInfo> res;
0402                 for(auto it= visualItem.rbegin(); it != visualItem.rend(); ++it)
0403                 {
0404                     auto i= *it;
0405                     if(i.item == first.item)
0406                     {
0407                         startChanges= true;
0408                         continue;
0409                     }
0410                     if(!startChanges)
0411                         continue;
0412                     res << i;
0413                     // i.item->stackBefore(first.item);
0414                 }
0415                 stackBefore({res}, {first});
0416             }
0417             else if(order == VectorialMapController::StackOrder::LOWER)
0418             {
0419                 QList<ItemToControllerInfo> res;
0420                 for(auto i : visualItem)
0421                 {
0422                     if(i.item == first.item)
0423                         continue;
0424                     // first.item->stackBefore(i.item);
0425                     res << i;
0426                 }
0427                 stackBefore({first}, {res});
0428             }
0429             else if(order == VectorialMapController::StackOrder::BACK)
0430             {
0431                 auto sortedItems= extractVisualItem(items(), false);
0432                 if(sortedItems.empty())
0433                     return;
0434                 stackBefore({first}, {sortedItems.last()});
0435                 // first.item->stackBefore(sortedItems.last().item);
0436             }
0437             else if(order == VectorialMapController::StackOrder::FRONT)
0438             {
0439                 auto sortedItems= extractVisualItem(items(), false);
0440                 if(sortedItems.empty())
0441                     return;
0442                 bool startChanges= false;
0443                 QList<ItemToControllerInfo> res;
0444                 for(auto it= sortedItems.rbegin(); it != sortedItems.rend(); ++it)
0445                 {
0446                     auto i= *it;
0447                     if(i.item == first.item)
0448                     {
0449                         startChanges= true;
0450                         continue;
0451                     }
0452                     if(!startChanges)
0453                         continue;
0454                     // i.item->stackBefore(first.item);
0455                     res << i;
0456                 }
0457                 stackBefore({res}, {first});
0458             }
0459         }
0460     }
0461     else if((selectedAction == m_putCharacterLayer) || (selectedAction == m_putObjectLayer)
0462             || (selectedAction == m_putGroundLayer) || (selectedAction == m_putGMLayer))
0463     {
0464         setItemLayer(ctrls, static_cast<Core::Layer>(selectedAction->data().toInt()));
0465     }
0466 }
0467 void RGraphicsView::centerOnItem()
0468 {
0469     if(!m_centerOnItem)
0470         return;
0471 
0472     QRectF rect= m_centerOnItem->mapToScene(m_centerOnItem->boundingRect()).boundingRect();
0473     QRectF rect2= mapToScene(sceneRect().toRect()).boundingRect();
0474 
0475     if(rect2.contains(rect))
0476         return;
0477 
0478     qreal dx= rect.center().x() - rect2.center().x();
0479     qreal dy= rect.center().y() - rect2.center().y();
0480 
0481     rect2.translate(dx, dy);
0482     setSceneRect(rect2);
0483 }
0484 
0485 void RGraphicsView::setRotation(const QList<vmap::VisualItemController*>& list, int value)
0486 {
0487     std::for_each(list.begin(), list.end(), [value](vmap::VisualItemController* ctrl) { ctrl->setRotation(value); });
0488 }
0489 
0490 void RGraphicsView::lockItems(const QList<vmap::VisualItemController*>& list)
0491 {
0492     auto locked= std::all_of(list.begin(), list.end(), [](vmap::VisualItemController* ctrl) { return ctrl->locked(); });
0493     bool val= locked ? false : true;
0494     std::for_each(list.begin(), list.end(), [val](vmap::VisualItemController* ctrl) { ctrl->setLocked(val); });
0495 }
0496 
0497 void RGraphicsView::setItemLayer(const QList<vmap::VisualItemController*>& list, Core::Layer layer)
0498 {
0499     std::for_each(list.begin(), list.end(), [layer](vmap::VisualItemController* ctrl) { ctrl->setLayer(layer); });
0500 }
0501 
0502 void RGraphicsView::createAction()
0503 {
0504     // ZOOM MANAGEMENT
0505     m_zoomNormal= new QAction(tr("Zoom to Normal"), this);
0506     m_zoomInMax= new QAction(tr("Zoom In Max"), this);
0507     m_zoomOutMax= new QAction(tr("Zoom Out Max"), this);
0508     m_zoomCenterOnItem= new QAction(tr("Center on Item"), this);
0509 
0510     m_zoomIn= new QAction(tr("Zoom In"), this);
0511     m_zoomIn->setShortcut(QKeySequence("+"));
0512 
0513     m_zoomOut= new QAction(tr("Zoom Out"), this);
0514     m_zoomOut->setShortcut(QKeySequence("-"));
0515 
0516     m_removeSelection= new QAction(tr("Remove"), this);
0517     m_removeSelection->setShortcut(QKeySequence(QKeySequence::Delete));
0518     addAction(m_removeSelection);
0519     connect(m_removeSelection, &QAction::triggered, this,
0520             [this]()
0521             {
0522                 auto selec= selection();
0523                 m_ctrl->aboutToRemove(convertInfoToCtrl(selec));
0524             });
0525 
0526     m_importImage= new QAction(tr("Import Image"), this);
0527 
0528     connect(m_zoomNormal, SIGNAL(triggered()), this, SLOT(setZoomFactor()));
0529     connect(m_zoomCenterOnItem, SIGNAL(triggered(bool)), this, SLOT(centerOnItem()));
0530     connect(m_zoomInMax, SIGNAL(triggered()), this, SLOT(setZoomFactor()));
0531     connect(m_zoomOutMax, SIGNAL(triggered()), this, SLOT(setZoomFactor()));
0532     connect(m_importImage, SIGNAL(triggered()), this, SLOT(addImageToMap()));
0533     connect(m_zoomOut, SIGNAL(triggered()), this, SLOT(setZoomFactor()));
0534     connect(m_zoomIn, SIGNAL(triggered()), this, SLOT(setZoomFactor()));
0535 
0536     m_backOrderAction= new QAction(tr("Back"));
0537     m_backOrderAction->setIcon(QIcon::fromTheme("action-order-back"));
0538     m_backOrderAction->setData(VectorialMapController::BACK);
0539 
0540     m_frontOrderAction= new QAction(tr("Front"));
0541     m_frontOrderAction->setIcon(QIcon::fromTheme("action-order-front"));
0542     m_frontOrderAction->setData(VectorialMapController::FRONT);
0543 
0544     m_lowerAction= new QAction(tr("Lower"));
0545     m_lowerAction->setIcon(QIcon::fromTheme("action-order-lower"));
0546     m_lowerAction->setData(VectorialMapController::LOWER);
0547 
0548     m_raiseAction= new QAction(tr("Raise"));
0549     m_raiseAction->setIcon(QIcon::fromTheme("action-order-raise"));
0550     m_raiseAction->setData(VectorialMapController::RAISE);
0551 
0552     m_normalizeSizeAverage= new QAction(tr("Average"), this);
0553     m_normalizeSizeAverage->setData(VectorialMapController::Average);
0554 
0555     m_normalizeSizeUnderMouse= new QAction(tr("As undermouse item"), this);
0556     m_normalizeSizeUnderMouse->setData(VectorialMapController::UnderMouse);
0557 
0558     m_normalizeSizeBigger= new QAction(tr("As the Bigger"), this);
0559     m_normalizeSizeBigger->setData(VectorialMapController::Bigger);
0560 
0561     m_normalizeSizeSmaller= new QAction(tr("As the Smaller"), this);
0562     m_normalizeSizeSmaller->setData(VectorialMapController::Smaller);
0563 
0564     m_lockSize= new QAction(tr("Lock/Unlock Item Geometry"), this);
0565     m_dupplicate= new QAction(tr("Duplicate Item"), this);
0566 
0567     addAction(m_zoomNormal);
0568     addAction(m_zoomInMax);
0569     addAction(m_zoomOutMax);
0570     addAction(m_zoomOut);
0571     addAction(m_zoomIn);
0572     addAction(m_dupplicate);
0573 
0574     // PROPERTIES
0575     m_properties= new QAction(tr("Properties"), this);
0576     // connect(m_properties, &QAction::triggered, this, &RGraphicsView::showMapProperties);
0577 
0578     // Layers
0579     QActionGroup* group= new QActionGroup(this);
0580     m_editGroundLayer= new QAction(tr("Ground"), this);
0581     m_editGroundLayer->setData(static_cast<int>(Core::Layer::GROUND));
0582     m_editGroundLayer->setCheckable(true);
0583     m_editObjectLayer= new QAction(tr("Object"), this);
0584     m_editObjectLayer->setData(static_cast<int>(Core::Layer::OBJECT));
0585     m_editObjectLayer->setCheckable(true);
0586     m_editCharacterLayer= new QAction(tr("Character"), this);
0587     m_editCharacterLayer->setData(static_cast<int>(Core::Layer::CHARACTER_LAYER));
0588     m_editCharacterLayer->setCheckable(true);
0589     m_editGameMasterLayer= new QAction(tr("GameMaster"), this);
0590     m_editGameMasterLayer->setData(static_cast<int>(Core::Layer::GAMEMASTER_LAYER));
0591     m_editGameMasterLayer->setCheckable(true);
0592 
0593     group->addAction(m_editGroundLayer);
0594     group->addAction(m_editObjectLayer);
0595     group->addAction(m_editCharacterLayer);
0596     group->addAction(m_editGameMasterLayer);
0597 
0598     m_putGroundLayer= new QAction(tr("Ground"), this);
0599     m_putGroundLayer->setData(static_cast<int>(Core::Layer::GROUND));
0600     m_putGroundLayer->setCheckable(true);
0601     m_putObjectLayer= new QAction(tr("Object"), this);
0602     m_putObjectLayer->setData(static_cast<int>(Core::Layer::OBJECT));
0603     m_putObjectLayer->setCheckable(true);
0604     m_putCharacterLayer= new QAction(tr("Character"), this);
0605     m_putCharacterLayer->setData(static_cast<int>(Core::Layer::CHARACTER_LAYER));
0606     m_putCharacterLayer->setCheckable(true);
0607     m_putGMLayer= new QAction(tr("GameMaster"), this);
0608     m_putGMLayer->setData(static_cast<int>(Core::Layer::GAMEMASTER_LAYER));
0609     m_putGMLayer->setCheckable(true);
0610 
0611     connect(m_editGroundLayer, &QAction::triggered, this, &RGraphicsView::changeLayer);
0612     connect(m_editObjectLayer, &QAction::triggered, this, &RGraphicsView::changeLayer);
0613     connect(m_editCharacterLayer, &QAction::triggered, this, &RGraphicsView::changeLayer);
0614     connect(m_editGameMasterLayer, &QAction::triggered, this, &RGraphicsView::changeLayer);
0615 
0616     QActionGroup* group2= new QActionGroup(this);
0617     m_allVisibility= new QAction(tr("All"), this);
0618     m_allVisibility->setCheckable(true);
0619     m_allVisibility->setData(Core::ALL);
0620     m_hiddenVisibility= new QAction(tr("Hidden"), this);
0621     m_hiddenVisibility->setCheckable(true);
0622     m_hiddenVisibility->setChecked(true);
0623     m_hiddenVisibility->setData(Core::HIDDEN);
0624     m_characterVisibility= new QAction(tr("Fog Of War"), this);
0625     m_characterVisibility->setData(Core::FOGOFWAR);
0626     m_characterVisibility->setCheckable(true);
0627 
0628     group2->addAction(m_allVisibility);
0629     group2->addAction(m_hiddenVisibility);
0630     group2->addAction(m_characterVisibility);
0631 
0632     connect(m_allVisibility, &QAction::triggered, this, &RGraphicsView::changeVisibility);
0633     connect(m_hiddenVisibility, &QAction::triggered, this, &RGraphicsView::changeVisibility);
0634     connect(m_characterVisibility, &QAction::triggered, this, &RGraphicsView::changeVisibility);
0635 
0636     m_rollInitOnAllNpc= new QAction(tr("All Npcs"), this);
0637     m_rollInitOnAllNpc->setToolTip(tr("Roll Initiative on All Npcs"));
0638     m_rollInitOnAllNpc->setData(Core::CharacterScope::AllNPC);
0639     connect(m_rollInitOnAllNpc, &QAction::triggered, this, &RGraphicsView::rollInit);
0640 
0641     m_rollInitOnSelection= new QAction(tr("Selection"), this);
0642     m_rollInitOnSelection->setToolTip(tr("Roll Initiative on Selection"));
0643     m_rollInitOnSelection->setData(Core::CharacterScope::SelectionOnly);
0644     connect(m_rollInitOnSelection, &QAction::triggered, this, &RGraphicsView::rollInit);
0645 
0646     m_rollInitOnAllCharacter= new QAction(tr("All Characters"), this);
0647     m_rollInitOnAllCharacter->setToolTip(tr("Roll Initiative on All Characters"));
0648     m_rollInitOnAllCharacter->setData(Core::CharacterScope::AllCharacter);
0649     connect(m_rollInitOnAllCharacter, &QAction::triggered, this, &RGraphicsView::rollInit);
0650 
0651     m_cleanInitOnAllNpc= new QAction(tr("All Npcs"), this);
0652     m_cleanInitOnAllNpc->setToolTip(tr("Clear Initiative on All Npcs"));
0653     m_cleanInitOnAllNpc->setData(Core::CharacterScope::AllNPC);
0654     connect(m_cleanInitOnAllNpc, &QAction::triggered, this, &RGraphicsView::cleanInit);
0655 
0656     m_cleanInitOnSelection= new QAction(tr("Selection"), this);
0657     m_cleanInitOnSelection->setToolTip(tr("Clear Initiative on Selection"));
0658     m_cleanInitOnSelection->setData(Core::CharacterScope::SelectionOnly);
0659     connect(m_cleanInitOnSelection, &QAction::triggered, this, &RGraphicsView::cleanInit);
0660 
0661     m_cleanInitOnAllCharacter= new QAction(tr("All Characters"), this);
0662     m_cleanInitOnAllCharacter->setToolTip(tr("Clear Initiative on All Characters"));
0663     m_cleanInitOnAllCharacter->setData(Core::CharacterScope::AllCharacter);
0664     connect(m_cleanInitOnAllCharacter, &QAction::triggered, this, &RGraphicsView::cleanInit);
0665 }
0666 
0667 void RGraphicsView::rollInit()
0668 {
0669     auto act= qobject_cast<QAction*>(sender());
0670     m_ctrl->rollInit(act->data().value<Core::CharacterScope>());
0671 }
0672 void RGraphicsView::cleanInit()
0673 {
0674     auto act= qobject_cast<QAction*>(sender());
0675     m_ctrl->cleanUpInit(act->data().value<Core::CharacterScope>());
0676 }
0677 
0678 void RGraphicsView::changeLayer()
0679 {
0680     QAction* act= qobject_cast<QAction*>(sender());
0681 
0682     if(static_cast<Core::Layer>(act->data().toInt()) != m_ctrl->layer())
0683     {
0684         m_ctrl->setLayer(static_cast<Core::Layer>(act->data().toInt()));
0685     }
0686 }
0687 void RGraphicsView::changeVisibility()
0688 {
0689     QAction* act= qobject_cast<QAction*>(sender());
0690     m_ctrl->setVisibility(static_cast<Core::VisibilityMode>(act->data().toInt()));
0691 }
0692 
0693 void RGraphicsView::setZoomFactor()
0694 {
0695     QAction* senderAct= qobject_cast<QAction*>(sender());
0696     int destination= 0;
0697     int step= 0;
0698     if(senderAct == m_zoomInMax)
0699     {
0700         destination= 20;
0701         step= 1;
0702     }
0703     else if(senderAct == m_zoomNormal)
0704     {
0705         destination= 0;
0706         if(m_counterZoom > 0)
0707         {
0708             step= -1;
0709         }
0710         else
0711         {
0712             step= 1;
0713         }
0714     }
0715     else if(senderAct == m_zoomOutMax)
0716     {
0717         destination= -20;
0718         step= -1;
0719     }
0720     else if(senderAct == m_zoomIn)
0721     {
0722         destination= m_counterZoom + 1;
0723         step= 1;
0724     }
0725     else if(senderAct == m_zoomOut)
0726     {
0727         destination= m_counterZoom - 1;
0728         step= -1;
0729     }
0730     if(destination > 20)
0731     {
0732         destination= 20;
0733     }
0734     else if(destination < -20)
0735     {
0736         destination= -20;
0737     }
0738     double scaleFactor= 1.1;
0739     double realFactor= 1.0;
0740     while(destination != m_counterZoom)
0741     {
0742         if(step > 0)
0743         {
0744             realFactor= realFactor * scaleFactor;
0745         }
0746         else
0747         {
0748             realFactor= realFactor * (1.0 / scaleFactor);
0749         }
0750         m_counterZoom+= step;
0751     }
0752     scale(realFactor, realFactor);
0753     updateSizeToController();
0754 }
0755 void RGraphicsView::currentToolChanged(Core::SelectableTool selectedtool)
0756 {
0757     m_currentTool= selectedtool;
0758 }
0759 
0760 void RGraphicsView::updateSizeToController()
0761 {
0762     emit updateVisualZone();
0763     // auto rect= frameRect();
0764     // auto poly= mapToScene(rect);
0765     // m_ctrl->setVisualRect(poly.boundingRect());
0766 }
0767 
0768 void RGraphicsView::stackBefore(const QList<ItemToControllerInfo>& first, const QList<ItemToControllerInfo>& second)
0769 {
0770     m_ctrl->addCommand(new ChangeStackOrderVMapCommand(m_ctrl, first, second));
0771 }
0772 
0773 void RGraphicsView::resizeEvent(QResizeEvent* event)
0774 {
0775     updateSizeToController();
0776 
0777     setResizeAnchor(QGraphicsView::NoAnchor);
0778     setTransformationAnchor(QGraphicsView::NoAnchor);
0779     QGraphicsView::resizeEvent(event);
0780 }
0781 
0782 void RGraphicsView::addImageToMap()
0783 {
0784     ImageSelectorController ctrl(false, ImageSelectorController::All, ImageSelectorController::AnyShape,
0785                                  m_preferences->value("ImageDirectory", QDir::homePath()).toString());
0786     ImageSelectorDialog dialog(&ctrl, this);
0787 
0788     if(QDialog::Accepted != dialog.exec())
0789         return;
0790 
0791     // TODO use the image
0792 }