diff --git a/plugins/mapper/cmapclipboard.h b/plugins/mapper/cmapclipboard.h index 01d7e05..68c3f4e 100644 --- a/plugins/mapper/cmapclipboard.h +++ b/plugins/mapper/cmapclipboard.h @@ -1,92 +1,91 @@ /*************************************************************************** cmapclipboard.h ------------------- begin : Wed Jul 3 2002 copyright : (C) 2002 by Kmud Developer Team email : kmud-devel@kmud.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CMAPCLIPBOARD_H #define CMAPCLIPBOARD_H #include -#include #include class KAction; class CMapManager; class KMemConfig; class CMapZone; class CMapPath; class CMapView; /**This class contains all the mapper clipboard code *@author Kmud Developer Team */ class CMapClipboard : public QObject { Q_OBJECT public: CMapClipboard(CMapManager *mapManager, CMapView *view, QObject *parent=0); ~CMapClipboard(); public: /** This method is used to set the enabled start of the actions */ void enableActions(bool enabled); public slots: /** This method is called to copy the selected elements into the clipboard */ void slotCopy(); /** This method is called to copy the selected elements into the clipboard, then delete them */ void slotCut(); /** This method is called to paste the elements in the clipboard onto the current map */ void slotPaste(); /** This slot is called to delete all the selected objects in the current view */ void slotDelete(void); /** This slot is called when the select all menu option is selected */ void slotSelectAll(void); /** This slot is called when the unselect all menu option is selected */ void slotUnselectAll(void); /** This slot is called when the invert selection menu option is called */ void slotInvertSelection(void); private: /** This is used to create the clipboard actions */ void initActions(void); /** This method is used to copy a path to the clipboard */ void copyPath(int *pathGroup,CMapPath *path); /** This method is used to paste elements that are not paths or linked text elements */ void pasteElements(); /** This method is used to paste path elements */ void pastePaths(); /** This method is used to update linked text elements with the correct properties from the clibboard */ void pasteLinks(); private: KMemConfig *m_clipboard; CMapManager *m_mapManager; CMapView *m_view; QObject *m_parent; KAction *m_editSelectAll; KAction *m_editUnselectAll; KAction *m_editSelectInvert; KAction *m_editDelete; KAction *m_editCopy; KAction *m_editCut; KAction *m_editPaste; }; #endif diff --git a/plugins/mapper/cmapmanager.cpp b/plugins/mapper/cmapmanager.cpp index e2dc401..c968df6 100644 --- a/plugins/mapper/cmapmanager.cpp +++ b/plugins/mapper/cmapmanager.cpp @@ -1,1859 +1,1858 @@ /********************************************f******************************* mapmanager.cpp - description ------------------- begin : Wed Mar 7 2001 copyright : (C) 2001 by KMud Development Team (C) 2007 Tomas Mecir email : kmud-devel@kmud.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "cmapmanager.h" #include #include #include #include #include #include #include #include #include #include #include #include -#include #include #include "cmapzone.h" #include "cmappath.h" #include "cmaptext.h" #include "cmaproom.h" #include "cmapview.h" #include "cmaplevel.h" #include "cmapview.h" #include "cmaptoolbase.h" #include "cmappluginbase.h" #include "cmapzonemanager.h" #include "cmapcmdelementcreate.h" #include "cmapcmdelementdelete.h" #include "cmapcmdelementproperties.h" #include "cmapcmdgroup.h" #include "cmapcmdmovemap.h" #include "cmapcmdmoveplayer.h" #include "cmapcmdleveldelete.h" #include "cmapcmdlevelcreate.h" #include "cmapcmdtogglepathtwoway.h" #include "cmapfilefilterbase.h" #include "kmuddy_mapper.h" #include "filefilters/cmapfilefilterxml.h" #include "dialogs/dlgmaproomproperties.h" #include "dialogs/dlgmappathproperties.h" #include "dialogs/dlgmaptextproperties.h" #include "dialogs/dlgspeedwalkprogress.h" #include "dialogs/dlgmapspeedwalk.h" #include "dialogs/dlgmapcolor.h" #include "dialogs/dlgmapdirections.h" #include "dialogs/dlgmapmovement.h" #include "cactionmanager.h" #include "cdialoglist.h" #include "cglobalsettings.h" #include "cstatus.h" CMapManager::CMapManager (QWidget *parent, KMuddyMapper *mapper, int sessId) : cActionBase ("map-manager", 0), m_sessId (sessId), mapperPlugin (mapper) { kDebug() << "constructor begins"; // register action handlers addEventHandler ("dialog-create", 50, PT_STRING); addEventHandler ("dialog-save", 50, PT_STRING); mapData = new CMapData(); // Setup vars loginRoom = NULL; currentRoom = NULL; elementEdit = NULL; /** Create undo/redo history */ commandHistory = new KUndoStack(); //FIXME_jp: Needs to be configurable commandHistory->setUndoLimit(30); commandHistory->clear(); historyGroup = NULL; m_commandsActive = true; initFileFilters(); activeView = 0; setDefaultOptions(); speedwalkActive = false; pathToWalk.setAutoDelete(true); speedwalkProgressDlg = new DlgSpeedwalkProgress(); speedwalkProgressDlg->hide(); connect(speedwalkProgressDlg,SIGNAL(abortSpeedwalk()),this,SLOT(slotAbortSpeedwalk())); m_zoneCount = 0; m_levelCount = 0; m_zoneManager = NULL; setUndoActive (false); createNewMap(); // because some things break if a map doesn't exist activeView = new CMapView(this, parent); m_zoneManager = new CMapZoneManager(sessId, this); if (!m_zoneManager->zonesModel()->rowCount()) m_zoneManager->createZone (i18n ("Map #1")); m_zoneManager->loadZone(0); initPlugins(); activeView->initGUI(); readOptions(); openMapView (); setUndoActive (true); kDebug() << "constructor ends"; } CMapManager::~CMapManager() { kDebug() << "CMapManager::~CMapManager() start"; removeEventHandler ("dialog-create"); removeEventHandler ("dialog-save"); if (mapData) delete mapData; mapData = 0; delete m_zoneManager; delete activeView; if (commandHistory) delete commandHistory; kDebug() << "CMapManager::~CMapManager() end"; } KComponentData CMapManager::instance () { return mapperPlugin->componentData(); } void CMapManager::eventStringHandler (QString event, int, QString &par1, const QString &) { if (event == "dialog-create") { if (par1 == "profile-prefs") createProfileConfigPanes (); else if (par1 == "app-prefs") createGlobalConfigPanes (); } if (event == "dialog-save") { if (par1 == "profile-prefs") { } else if (par1 == "app-prefs") { // TODO: the first two should be profile prefs mapDirection->slotOkPressed(); mapMovement->slotOkPressed(); mapColor->slotOkPressed(); mapSpeedwalk->slotOkPressed(); saveGlobalConfig (); } } } void CMapManager::createProfileConfigPanes () { /*KPageDialog *dlg = */(KPageDialog *) cDialogList::self()->getDialog ("profile-prefs"); for (CMapPluginBase *plugin = getPluginList()->first(); plugin!=0; plugin = getPluginList()->next()) plugin->createProfileConfigPanes(); } void CMapManager::createGlobalConfigPanes () { KPageDialog *dlg = (KPageDialog *) cDialogList::self()->getDialog ("app-prefs"); KPageWidgetItem *item; QFrame *frmdir = new QFrame (dlg); item = dlg->addPage (frmdir, i18n ("Mapper: Directions")); item->setIcon (KIcon ("gear")); QFrame *frmmovement = new QFrame (dlg); item = dlg->addPage (frmmovement, i18n ("Mapper: Movement")); item->setIcon (KIcon ("run")); QFrame *frmcolor = new QFrame (dlg); item = dlg->addPage (frmcolor, i18n ("Mapper: Colors")); item->setIcon (KIcon ("colorize")); QFrame *frmspeedwalk = new QFrame (dlg); item = dlg->addPage (frmspeedwalk, i18n ("Mapper: Speedwalk")); item->setIcon (KIcon ("launch")); QVBoxLayout *dirlayout = new QVBoxLayout (frmdir); QVBoxLayout *movementlayout = new QVBoxLayout (frmmovement); QVBoxLayout *colorlayout = new QVBoxLayout (frmcolor); QVBoxLayout *speedwalklayout = new QVBoxLayout (frmspeedwalk); mapDirection = new DlgMapDirections (this, frmdir); mapMovement = new DlgMapMovement (this, frmmovement); mapColor = new DlgMapColor(this, frmcolor); mapSpeedwalk = new DlgMapSpeedwalk(this, frmspeedwalk); dirlayout->addWidget (mapDirection); movementlayout->addWidget (mapMovement); colorlayout->addWidget (mapColor); speedwalklayout->addWidget (mapSpeedwalk); for (CMapPluginBase *plugin = getPluginList()->first(); plugin!=0; plugin = getPluginList()->next()) plugin->createGlobalConfigPanes(); } QList CMapManager::createPropertyPanes(elementTyp type,CMapElement *element,QWidget *parent) { QList res; for (CMapPluginBase *plugin = getPluginList()->first(); plugin!=0; plugin = getPluginList()->next()) res.append(plugin->createPropertyPanes(type, element, parent)); return res; } /** This method tells the plugins that the mapper wants to add a room to the speedwalk list * @param room The room to add to the speedwalk list */ void CMapManager::addSpeedwalkRoom(CMapRoom *room) { for (CMapPluginBase *plugin=getPluginList()->first();plugin!=0; plugin=getPluginList()->next()) { plugin->addSpeedwalkRoom(room); } } /** This will setup the import/export file filters */ void CMapManager::initFileFilters() { m_fileFilter.setAutoDelete(true); m_fileFilter.append(new CMapFileFilterXML(this)); } #include "plugins/standard/cmappluginstandard.h" #include "plugins/speedwalk/cmappluginspeedwalk.h" /** Used to create the plugins */ void CMapManager::initPlugins() { int pluginCount = 0; toolList.setAutoDelete(false); toolList.clear(); pluginList.setAutoDelete(false); pluginList.clear(); kDebug() << "Loading Static Plugins...\n"; // These used to be plug-ins, but now I'm linking them in statically, and just pretend that they are plug-ins. // This is because linking to the mapper part is causing issues. CMapPluginBase *plugin; plugin = new CMapPluginStandard (activeView); pluginList.append (plugin); plugin = new CMapPluginSpeedwalk (activeView); pluginList.append (plugin); for (plugin = pluginList.first(); plugin!=0; plugin = pluginList.next()) { kDebug() << "Tools in plugin : " << plugin->getToolList()->count(); foreach (CMapToolBase *tool, *plugin->getToolList()) { toolList.append(tool); } // getActiveView()->insertChildClient(plugin); pluginCount++; } kDebug() << "Finished loading " << pluginCount << " plugins\n"; kDebug() << "Finished loading " << toolList.count() << " tools\n"; if (toolList.count() > 0) { currentTool = toolList.first(); currentTool->setChecked(true); } else { kWarning() << "No tools loaded!\n"; currentTool = NULL; } if (pluginCount==0) { kWarning() << "No plugins loaded!\n"; } kDebug() << "XML File : " << activeView->xmlFile(); } /** Used to get a list of the plugins */ Q3PtrList *CMapManager::getPluginList() { return &pluginList; } /** Used to get a pointer to the map data */ CMapData *CMapManager::getMapData() const { return mapData; } CMapZone *CMapManager::getZone(bool noCreate) { CMapZone *zone = mapData->rootZone; if ((!zone) && (!noCreate)) zone = new CMapZone(this); return zone; } /** Used to create a new view of the map */ void CMapManager::openMapView() { if (loginRoom) activeView->showPosition(QPoint(loginRoom->getX(),loginRoom->getY()),loginRoom->getLevel()); else { CMapRoom *firstRoom = findFirstRoom(NULL); if (firstRoom) displayLevel(firstRoom->getLevel(), true); } } void CMapManager::displayLevel(CMapLevel *level, bool centerView) { CMapView *mapView = getActiveView(); mapView->showPosition(level, centerView); } /** This method is used to covert cords so that they snap to the grid */ QPoint CMapManager::cordsSnapGrid(QPoint oldPos) { QPoint newPos; int oldx = (int)(oldPos.x() / mapData->gridSize.width()); int oldy = (int)(oldPos.y() / mapData->gridSize.height()); newPos.setX( oldx * mapData->gridSize.width()); newPos.setY( oldy * mapData->gridSize.height()); return newPos; } /** * Used to create a new view of the a given level and * center the view on the given position. */ void CMapManager::openNewMapView(QPoint pos,CMapLevel *level) { CMapView *mapView = getActiveView(); mapView->showPosition(pos,level); } /** Used to set properties of the view widget */ void CMapManager::setPropertiesAllViews(QCursor *cursor,bool mouseTracking) { activeView->setCursor(*cursor); activeView->setMouseTracking(mouseTracking); } /** Used to unselect all the elements in a level */ void CMapManager::unselectElements(CMapLevel *level) { QList lst = level->getAllElements(); foreach (CMapElement *element, lst) { element->setSelected(false); element->setEditMode(false); } } /** Used to convert a text direction to a direction type */ QString CMapManager::directionToText(directionTyp dir, QString specialCmd, bool shortName) { if ((uint)dir < NUM_DIRECTIONS) { if (shortName && ((uint)dir < NUM_DIRECTIONS / 2)) dir = (directionTyp) ((int)dir + NUM_DIRECTIONS / 2); return mapData->directions[dir]; } else { return specialCmd; } } /** Used to convert a direction type to a text direction */ directionTyp CMapManager::textToDirection(QString text) { directionTyp dir = SPECIAL; for (uint i = 0; i < NUM_DIRECTIONS; ++i) { if (text == mapData->directions[i]) { if (i>9) { dir = (directionTyp)(i-10); } else { dir = (directionTyp)i; } break; } } return dir; } /** Used to set the login room */ void CMapManager::setLoginRoom(CMapRoom *room) { openCommandGroup(i18n("Change Login Room")); if (loginRoom) { CMapCmdElementProperties *cmdRemove = new CMapCmdElementProperties(this,i18n("Remove Login Room Status"),loginRoom); cmdRemove->getOrgProperties().writeEntry("Login",true); cmdRemove->getNewProperties().writeEntry("Login",false); addCommand(cmdRemove); } CMapCmdElementProperties *cmdSet = new CMapCmdElementProperties(this,i18n("Set Login Room Status"),room); cmdSet->getOrgProperties().writeEntry("Login",false); cmdSet->getNewProperties().writeEntry("Login",true); addCommand(cmdSet); closeCommandGroup(); } /** Uesd to return the login room */ CMapRoom *CMapManager::getLoginRoom() { return loginRoom; } /** Should only be called by CMapRoom.setCurrentRoom() */ void CMapManager::setCurrentRoomWithoutUndo(CMapRoom *room) { currentRoom = room; } /** Should only be called by CMapRoom.setLoginRoom() */ void CMapManager::setLoginRoomWithoutUndo(CMapRoom *room) { loginRoom = room; } /** Used to set the current room */ void CMapManager::setCurrentRoom(CMapRoom *room) { openCommandGroup(i18n("Change Current Room")); CMapCmdElementProperties *cmdRemove = new CMapCmdElementProperties(this,i18n("Remove Current Room Status"),currentRoom); cmdRemove->getOrgProperties().writeEntry("Current",true); cmdRemove->getNewProperties().writeEntry("Current",false); addCommand(cmdRemove); CMapCmdElementProperties *cmdSet = new CMapCmdElementProperties(this,i18n("Set Current Room Status"),room); cmdSet->getOrgProperties().writeEntry("Current",false); cmdSet->getNewProperties().writeEntry("Current",true); addCommand(cmdSet); closeCommandGroup(); } /** Uesd to return the current room */ CMapRoom *CMapManager::getCurrentRoom() { return currentRoom; } /** This method is used to find a element from a list of properties * @param properties The list of proerties * @return The element if it's found otherwise NULL */ CMapElement *CMapManager::findElement(KConfigGroup properties) { elementTyp type = (elementTyp)properties.readEntry("Type",(uint)OTHER); if (type == OTHER) return NULL; if (type==PATH) { CMapLevel *srcLevel = findLevel(properties.readEntry("SrcLevel",-1)); CMapRoom *srcRoom = srcLevel->findRoom(properties.readEntry("SrcRoom",-1)); if (!srcRoom) return NULL; directionTyp srcDir = (directionTyp)properties.readEntry("SrcDir",0); QString specialCommand = properties.readEntry("SpecialCmdSrc",""); return srcRoom->getPathDirection(srcDir,specialCommand); } CMapLevel *level = findLevel(properties.readEntry("Level",-5)); if (!level) return NULL; if (type == ROOM) { CMapRoom *room = level->findRoom(properties.readEntry("RoomID",-5)); return room; } int x = properties.readEntry("X",-5); int y = properties.readEntry("Y",-5); foreach (CMapText *text, *level->getTextList()) if ((text->getX()==x) && (text->getY()==y)) return text; return NULL; } /** Used to erase the map. This will erase all elements and can't be undone */ void CMapManager::eraseMap(void) { if (!mapData->rootZone) return; eraseZone(mapData->rootZone); delete mapData->rootZone; mapData->rootZone = NULL; m_zoneCount = 0; m_levelCount = 0; if (activeView) activeView->setLevel(NULL); for (CMapPluginBase *plugin = getPluginList()->first(); plugin!=0; plugin = getPluginList()->next()) { plugin->mapErased(); } loginRoom = NULL; currentRoom = NULL; elementEdit = NULL; } void CMapManager::eraseZone(CMapZone *zone) { if (zone == 0) return; QList levels; for (unsigned int idx = 0; idx < zone->levelCount(); ++idx) levels.append(zone->getLevel(idx)); foreach (CMapLevel *level, levels) { // TODO: this seems to not delete things correctly foreach (CMapRoom *room, *level->getRoomList()) { room->getPathList()->clear(); room->getConnectingPathList()->clear(); } level->getRoomList()->clear(); level->getTextList()->clear(); delete level; } } /** Create new bottom or top level depending on the given direction */ CMapLevel *CMapManager::createLevel(directionTyp dir) { CMapLevel *result = NULL; CMapCmdLevelCreate *cmd = NULL; int pos = (dir == UP) ? getZone()->levelCount() : 0; if (getUndoActive()) { cmd = new CMapCmdLevelCreate(this,i18n("Create Level"),pos); addCommand(cmd); result = cmd->getLevel(); } else { result = new CMapLevel(this, pos); } return result; } /** This is used to find a level with a given id * @param id The id of the level to find * @return Null if no level is found otherwise a pointer to the level */ CMapLevel *CMapManager::findLevel(unsigned int id) { CMapZone *zone = getZone(); for (unsigned int idx = 0; idx < zone->levelCount(); ++idx) { CMapLevel *level = zone->getLevel(idx); if (level->getLevelID() == id) return level; } return NULL; } /** Create new map */ void CMapManager::createNewMap() { // Create the root zone getMapData()->rootZone = NULL; CMapZone *zone = getZone(); // Create a empty room in the first level of the new zone CMapRoom *room = CMapElementUtil::createRoom(this, QPoint(2 * mapData->gridSize.width(),2 * mapData->gridSize.height()),zone->firstLevel()); setCurrentRoomWithoutUndo(room); setLoginRoomWithoutUndo(room); if (!activeView) return; if (currentRoom) activeView->showPosition(currentRoom->getLowPos(),zone->firstLevel()); if (activeView->getCurrentlyViewedLevel()==NULL) activeView->showPosition(loginRoom,true); for (CMapPluginBase *plugin = getPluginList()->first(); plugin!=0; plugin = getPluginList()->next()) { plugin->newMapCreated(); } activeView->changed(); } /** Used to create a new room that can be undone/redone * @param pos The position to create the room * @param level The level to create the room in */ void CMapManager::createRoom(QPoint pos,CMapLevel *level) { if (getUndoActive()) { KMemConfig properties; KConfigGroup props = properties.group("Properties"); props.writeEntry("Type",(int)ROOM); props.writeEntry("X",pos.x()); props.writeEntry("Y",pos.y()); props.writeEntry("Level",level->getLevelID()); CMapCmdElementCreate *command = new CMapCmdElementCreate(this,i18n("Create Room")); command->addElement(&properties); addCommand(command); } else { CMapElementUtil::createRoom(this, pos, level); } } /** Used to create a new text label */ void CMapManager::createText(QPoint pos,CMapLevel *level,QString str) { if (getUndoActive()) { KMemConfig properties; KConfigGroup props = properties.group("Properties"); props.writeEntry("Type",(int)TEXT); props.writeEntry("X",pos.x()); props.writeEntry("Y",pos.y()); if (level) { props.writeEntry("Level",level->getLevelID()); } props.writeEntry("Text",str); CMapCmdElementCreate *command = new CMapCmdElementCreate(this,i18n("Create Text")); command->addElement(&properties); addCommand(command); } else { CMapElementUtil::createText(this, pos, level, str); } } /** Used to create a new text label */ void CMapManager::createText(QPoint pos,CMapLevel *level,QString str,QFont font,QColor col) { if (getUndoActive()) { KMemConfig properties; KConfigGroup props = properties.group("Properties"); props.writeEntry("Type",(int)TEXT); props.writeEntry("X",pos.x()); props.writeEntry("Y",pos.y()); if (level) { props.writeEntry("Level",level->getLevelID()); } props.writeEntry("Text",str); props.writeEntry("Font",font); props.writeEntry("Color",col); CMapCmdElementCreate *command = new CMapCmdElementCreate(this,i18n("Create Text")); command->addElement(&properties); addCommand(command); } else { CMapElementUtil::createText(this, pos, level, str, font, col); } } /** Used to create a new path*/ CMapPath *CMapManager::createPath(QPoint srcPos,CMapLevel *srcLevel,directionTyp srcDir, QPoint destPos,CMapLevel *destLevel,directionTyp destDir) { CMapRoom *room=NULL; CMapRoom *srcRoom=NULL; CMapRoom *destRoom=NULL; if (!srcLevel || !destLevel) return NULL; foreach (room, *srcLevel->getRoomList()) { if (room->getLowPos() == srcPos) { srcRoom = room; break; } } foreach (room, *destLevel->getRoomList()) { if (room->getLowPos() == destPos) { destRoom = room; break; } } return createPath(srcRoom,srcDir,destRoom,destDir); } CMapPath *CMapManager::createPath(CMapRoom *srcRoom,CMapRoom *destRoom) { CMapPath *result = NULL; KMemConfig properties; KConfigGroup props = properties.group("Properties"); // Auto-set the directions if possible directionTyp srcDir = srcRoom->bestDirectionToRoom(destRoom); directionTyp destDir = getOpsiteDirection(srcDir); if (srcDir != SPECIAL) { // nothing if there is an exit already if (srcRoom->getPathDirection(srcDir, QString())) srcDir = SPECIAL; if (destRoom->getPathDirection(destDir, QString())) destDir = SPECIAL; } props.writeEntry("SrcDir", (int) srcDir); props.writeEntry("DestDir", (int) destDir); DlgMapPathProperties d(this,props,false); if (!d.exec()) return NULL; srcDir = (directionTyp)props.readEntry("SrcDir",0); destDir = (directionTyp)props.readEntry("DestDir",0); QString specialCmdSrc = props.readEntry("SpecialCmdSrc"); QString specialCmdDest = props.readEntry("SpecialCmdDest"); if (srcRoom->getPathDirection(srcDir,specialCmdSrc) || destRoom->getPathDirection(destDir,specialCmdDest)) { KMessageBox::information (NULL,i18n("A path already exists at this location"),i18n("KMuddy Mapper")); return NULL; } // create props.writeEntry("Type",(int)PATH); props.writeEntry("SrcRoom",srcRoom->getRoomID()); props.writeEntry("SrcDir",(int)srcDir); props.writeEntry("SrcLevel",srcRoom->getLevel()->getLevelID()); props.writeEntry("DestRoom",destRoom->getRoomID()); props.writeEntry("DestDir",(int)destDir); props.writeEntry("DestLevel",destRoom->getLevel()->getLevelID()); CMapCmdElementCreate *command = new CMapCmdElementCreate(this,i18n("Create Path")); command->addElement(&properties); addCommand(command); QList *elements=command->getElements(); foreach (CMapElement *el, *elements) if (el->getElementType()==PATH) result = (CMapPath *)el; return result; } /** Used to create a new path*/ CMapPath *CMapManager::createPath (CMapRoom *srcRoom,directionTyp srcDir,CMapRoom *destRoom,directionTyp destDir,bool undoable, bool twoWay) { // FIXME_jp : Allow this to call lowlevel mapper methods when undo is not active // but becarefull of second stage stuff CMapPath *result = NULL; KMemConfig properties; KConfigGroup props = properties.group("Properties"); props.writeEntry("Type",(int)PATH); props.writeEntry("SrcRoom",srcRoom->getRoomID()); props.writeEntry("SrcLevel",srcRoom->getLevel()->getLevelID()); props.writeEntry("SrcDir",(int)srcDir); props.writeEntry("DestRoom",destRoom->getRoomID()); props.writeEntry("DestLevel",destRoom->getLevel()->getLevelID()); props.writeEntry("DestDir",(int)destDir); props.writeEntry("PathTwoWay",twoWay); CMapCmdElementCreate *command = new CMapCmdElementCreate(this,i18n("Create Path")); command->addElement(&properties); bool active = getUndoActive(); if (!undoable) { setUndoActive(false); } addCommand(command); if (!undoable) { setUndoActive(active); } QList *elements=command->getElements(); foreach (CMapElement *el, *elements) if (el->getElementType()==PATH) result = (CMapPath *)el; return result; } /** Find the first room in the map, if one can't be found then create one */ CMapRoom *CMapManager::findFirstRoom(CMapRoom *existingRoom) { CMapZone *zone = getZone(); for (unsigned int idx = 0; idx < zone->levelCount(); ++idx) { CMapLevel *level = zone->getLevel(idx); foreach (CMapRoom *room, *level->getRoomList()) if (room!=existingRoom) return room; } // If we get to this point then no room was found so create one return CMapElementUtil::createRoom(this, QPoint(2 * mapData->gridSize.width(),2 * mapData->gridSize.height()), getZone()->firstLevel()); } void CMapManager::deleteLevel(CMapLevel *level) { //FIXME_jp: Check to see what happens when all levels are deleted. // It may be nessecary to create a new one. // Delete the level CMapCmdLevelDelete *cmd = new CMapCmdLevelDelete(this,i18n("Delete Level"),level); addCommand(cmd); } /** Check to see if a string is a valid move command * @param dirCmd The command that was typed * @return True, if a valid command otherwise false */ bool CMapManager::validMoveCmd(QString dirCmd) { if (dirCmd.isEmpty()) return false; // check for directions for (uint i = 0; i < NUM_DIRECTIONS; ++i) if (mapData->directions[i] == dirCmd) return true; if (currentRoom) foreach (CMapPath *path, *currentRoom->getPathList()) if (path->getSpecialExit() && (path->getSpecialCmd()==dirCmd)) return true; return false; } /** Used to delete a element from the map, should not be used by deleteElement as * it does not use groups */ // FIXME_jp : This method can be removed if the deleteElement method is recursive void CMapManager::deleteElementWithoutGroup(CMapElement *element,bool delOpsite) { KMemConfig properties; element->saveProperties(properties.group("Properties")); CMapCmdElementDelete *command = new CMapCmdElementDelete(this,i18n("Delete Element"),delOpsite); command->addElement(&properties); addCommand(command); } /** Used to delete a element from the map */ void CMapManager::deleteElement(CMapElement *element,bool delOpsite) { openCommandGroup(i18n("Delete Element")); // If the element is a room, then we also need to delete all its paths if (element->getElementType()==ROOM) { CMapRoom *room = (CMapRoom *)element; if (room->getLinkedElement()) { deleteElementWithoutGroup(room->getLinkedElement(),true); } QList wipePaths; // Delete the paths for the room foreach (CMapPath *path, *room->getPathList()) if (!wipePaths.contains(path)) wipePaths.push_back(path); // Delete any paths connecting with this room foreach (CMapPath *path, *room->getConnectingPathList()) if (!wipePaths.contains(path)) wipePaths.push_back(path); foreach (CMapPath *path, wipePaths) deleteElementWithoutGroup(path,false); } if (element->getElementType() == ZONE) { // Delete the levels in the zone CMapZone *zone = (CMapZone *)element; QList levels; for (unsigned int idx = 0; idx < zone->levelCount(); ++idx) levels.append(zone->getLevel(idx)); foreach (CMapLevel *level, levels) deleteLevel(level); } deleteElementWithoutGroup(element,delOpsite); closeCommandGroup(); } bool CMapManager::isClean() const { return commandHistory->isClean(); } /** Used to load a map */ void CMapManager::importMap(const QString& file,CMapFileFilterBase *filter) { QFile f(file); setUndoActive(false); commandHistory->clear(); historyGroup = NULL; eraseMap(); if (!f.exists()) createNewMap(); else { // Load the map using the correct filter filter->loadData(file); } if (!getLoginRoom()) { CMapRoom *firstRoom = findFirstRoom(NULL); setLoginRoom(firstRoom); } setCurrentRoomWithoutUndo(loginRoom); if (loginRoom && activeView) { if (activeView->getCurrentlyViewedLevel()==NULL) activeView->showPosition(loginRoom,true); setCurrentRoom(loginRoom); } setUndoActive(true); } /** Used to save a map */ void CMapManager::exportMap(const QString& url,CMapFileFilterBase *filter) { filter->saveData(url); commandHistory->setClean(); } /** Used to inform to change the state of the navigation tools */ void CMapManager::activeViewChanged(void) { if (!activeView) return; CMapLevel *level = activeView->getCurrentlyViewedLevel(); if (!level) return; // nothing here at this time } void CMapManager::levelChanged(CMapLevel *level) { if (level==NULL) return; activeView->changedLevel(level); } /** Used to inform the various parts of the mapper that a element has changed */ void CMapManager::changedElement(CMapElement *element) { if (element==NULL) return; if (!activeView) return; for (CMapPluginBase *plugin = getPluginList()->first();plugin!=0; plugin= getPluginList()->next()) { plugin->elementChanged(element); } activeView->changedElement(element); } /** Used to inform the various parts of the mapper that a element has added */ void CMapManager::addedElement(CMapElement *element) { if (!activeView) return; if (activeView->getCurrentlyViewedLevel()) activeView->addedElement(element); } /** Used to alter the path properties */ bool CMapManager::propertiesPath(CMapPath *path) { DlgMapPathProperties d(this,path); return d.exec(); } /** Used to alter the room properties */ bool CMapManager::propertiesRoom(CMapRoom *room) { openCommandGroup("Change room properties"); DlgMapRoomProperties d(this,room); bool b = d.exec(); closeCommandGroup(); return b; } /** Used to alter the text properties */ bool CMapManager::propertiesText(CMapText *text) { DlgMapTextProperties d(this,text); if (d.exec()) { text->updateLinkElements(); return true; } return false; } void CMapManager::setDefaultOptions() { cGlobalSettings *gs = cGlobalSettings::self(); // directions gs->setDefaultString ("mapper-direction-north", "north"); gs->setDefaultString ("mapper-direction-northeast", "northeast"); gs->setDefaultString ("mapper-direction-east", "east"); gs->setDefaultString ("mapper-direction-southeast", "southeast"); gs->setDefaultString ("mapper-direction-south", "south"); gs->setDefaultString ("mapper-direction-southwest", "southwest"); gs->setDefaultString ("mapper-direction-west", "west"); gs->setDefaultString ("mapper-direction-northwest", "northwest"); gs->setDefaultString ("mapper-direction-up", "up"); gs->setDefaultString ("mapper-direction-down", "down"); gs->setDefaultString ("mapper-direction-n", "n"); gs->setDefaultString ("mapper-direction-ne", "ne"); gs->setDefaultString ("mapper-direction-e", "e"); gs->setDefaultString ("mapper-direction-se", "se"); gs->setDefaultString ("mapper-direction-s", "s"); gs->setDefaultString ("mapper-direction-sw", "sw"); gs->setDefaultString ("mapper-direction-w", "w"); gs->setDefaultString ("mapper-direction-nw", "nw"); gs->setDefaultString ("mapper-direction-u", "u"); gs->setDefaultString ("mapper-direction-d", "d"); // move check gs->setDefaultBool ("mapper-movement-validcheck", false); gs->setDefaultColor ("mapper-color-Background", QColor(12*16,12*16,12*16)); gs->setDefaultColor ("mapper-color-Grid",QColor(160,160,160)); gs->setDefaultColor ("mapper-color-LowerRoom", Qt::darkGray); gs->setDefaultColor ("mapper-color-LowerZone", Qt::darkGray); gs->setDefaultColor ("mapper-color-LowerText", Qt::darkGray); gs->setDefaultColor ("mapper-color-DefaultRoom", QColor(32,255,0)); gs->setDefaultColor ("mapper-color-DefaultZone", QColor(32,255,0)); gs->setDefaultColor ("mapper-color-HigherRoom", Qt::white); gs->setDefaultColor ("mapper-color-HigherZone", Qt::white); gs->setDefaultColor ("mapper-color-HigherText", Qt::white); gs->setDefaultColor ("mapper-color-LowerPath", Qt::darkGray); gs->setDefaultColor ("mapper-color-DefaultPath", Qt::black); gs->setDefaultColor ("mapper-color-HigherPath", Qt::white); gs->setDefaultColor ("mapper-color-DefaultText", Qt::black); gs->setDefaultColor ("mapper-color-Selected", Qt::blue); gs->setDefaultColor ("mapper-color-Special", Qt::yellow); gs->setDefaultColor ("mapper-color-Login", Qt::blue); gs->setDefaultColor ("mapper-color-Edit", Qt::red); gs->setDefaultColor ("mapper-color-Current", Qt::red); // read speedwalk options gs->setDefaultBool ("mapper-speedwalk-abort-active", true); gs->setDefaultInt ("mapper-speedwalk-abort-limit", 100); gs->setDefaultInt ("mapper-speedwalk-delay", 0); } /** Used to read the map options */ void CMapManager::readOptions() { cGlobalSettings *gs = cGlobalSettings::self(); // Read directions getMapData()->directions[NORTH] = gs->getString ("mapper-direction-north"); getMapData()->directions[NORTHEAST] = gs->getString ("mapper-direction-northeast"); getMapData()->directions[EAST] = gs->getString ("mapper-direction-east"); getMapData()->directions[SOUTHEAST] = gs->getString ("mapper-direction-southeast"); getMapData()->directions[SOUTH] = gs->getString ("mapper-direction-south"); getMapData()->directions[SOUTHWEST] = gs->getString ("mapper-direction-southwest"); getMapData()->directions[WEST] = gs->getString ("mapper-direction-west"); getMapData()->directions[NORTHWEST] = gs->getString ("mapper-direction-northwest"); getMapData()->directions[UP] = gs->getString ("mapper-direction-up"); getMapData()->directions[DOWN] = gs->getString ("mapper-direction-down"); int half = NUM_DIRECTIONS/2; getMapData()->directions[NORTH+half] = gs->getString ("mapper-direction-n"); getMapData()->directions[NORTHEAST+half] = gs->getString ("mapper-direction-ne"); getMapData()->directions[EAST+half] = gs->getString ("mapper-direction-e"); getMapData()->directions[SOUTHEAST+half] = gs->getString ("mapper-direction-se"); getMapData()->directions[SOUTH+half] = gs->getString ("mapper-direction-s"); getMapData()->directions[SOUTHWEST+half] = gs->getString ("mapper-direction-sw"); getMapData()->directions[WEST+half] = gs->getString ("mapper-direction-w"); getMapData()->directions[NORTHWEST+half] = gs->getString ("mapper-direction-nw"); getMapData()->directions[UP+half] = gs->getString ("mapper-direction-u"); getMapData()->directions[DOWN+half] = gs->getString ("mapper-direction-d"); // Read movecheck config getMapData()->validRoomCheck = gs->getBool ("mapper-movement-validcheck"); int count = gs->getInt ("mapper-movement-check-count"); getMapData()->failedMoveMsg.clear(); for (int i = 1; i <= count; ++i) getMapData()->failedMoveMsg << gs->getString ("mapper-movement-check-" + QString::number (i)); // Read map colors mapData->backgroundColor=gs->getColor ("mapper-color-Background"); mapData->gridColor=gs->getColor ("mapper-color-Grid"); mapData->lowerRoomColor=gs->getColor ("mapper-color-LowerRoom"); mapData->lowerZoneColor=gs->getColor ("mapper-color-LowerZone"); mapData->lowerTextColor=gs->getColor ("mapper-color-LowerText"); mapData->defaultRoomColor=gs->getColor ("mapper-color-DefaultRoom"); mapData->defaultZoneColor=gs->getColor ("mapper-color-DefaultZone"); mapData->higherRoomColor=gs->getColor ("mapper-color-HigherRoom"); mapData->higherZoneColor=gs->getColor ("mapper-color-HigherZone"); mapData->higherTextColor=gs->getColor ("mapper-color-HigherText"); mapData->lowerPathColor=gs->getColor ("mapper-color-LowerPath"); mapData->defaultPathColor=gs->getColor ("mapper-color-DefaultPath"); mapData->higherPathColor=gs->getColor ("mapper-color-HigherPath"); mapData->defaultTextColor=gs->getColor ("mapper-color-DefaultText"); mapData->selectedColor=gs->getColor ("mapper-color-Selected"); mapData->specialColor = gs->getColor ("mapper-color-Special"); mapData->loginColor=gs->getColor ("mapper-color-Login"); mapData->editColor=gs->getColor ("mapper-color-Edit"); mapData->currentColor=gs->getColor ("mapper-color-Current"); // read speedwalk options mapData->speedwalkAbortActive = gs->getBool ("mapper-speedwalk-abort-active"); mapData->speedwalkAbortLimit = gs->getInt ("mapper-speedwalk-abort-limit"); mapData->speedwalkDelay = gs->getInt ("mapper-speedwalk-delay"); activeView->readOptions(); for (CMapPluginBase *plugin = getPluginList()->first(); plugin!=0; plugin = getPluginList()->next()) { plugin->loadConfigOptions(); } } /** Used to write the map options */ void CMapManager::saveGlobalConfig() { cGlobalSettings *gs = cGlobalSettings::self(); // directions gs->setString ("mapper-direction-north", getMapData()->directions[NORTH]); gs->setString ("mapper-direction-northeast", getMapData()->directions[NORTHEAST]); gs->setString ("mapper-direction-east", getMapData()->directions[EAST]); gs->setString ("mapper-direction-southeast", getMapData()->directions[SOUTHEAST]); gs->setString ("mapper-direction-south", getMapData()->directions[SOUTH]); gs->setString ("mapper-direction-southeast", getMapData()->directions[SOUTHWEST]); gs->setString ("mapper-direction-west", getMapData()->directions[WEST]); gs->setString ("mapper-direction-northwest", getMapData()->directions[NORTHWEST]); gs->setString ("mapper-direction-up", getMapData()->directions[UP]); gs->setString ("mapper-direction-down", getMapData()->directions[DOWN]); int half = NUM_DIRECTIONS/2; gs->setString ("mapper-direction-n", getMapData()->directions[NORTH+half]); gs->setString ("mapper-direction-ne", getMapData()->directions[NORTHEAST+half]); gs->setString ("mapper-direction-e", getMapData()->directions[EAST+half]); gs->setString ("mapper-direction-se", getMapData()->directions[SOUTHEAST+half]); gs->setString ("mapper-direction-s", getMapData()->directions[SOUTH+half]); gs->setString ("mapper-direction-sw", getMapData()->directions[SOUTHWEST+half]); gs->setString ("mapper-direction-w", getMapData()->directions[WEST+half]); gs->setString ("mapper-direction-nw", getMapData()->directions[NORTHWEST+half]); gs->setString ("mapper-direction-u", getMapData()->directions[UP+half]); gs->setString ("mapper-direction-d", getMapData()->directions[DOWN+half]); // movement gs->setBool ("mapper-movement-validcheck", getMapData()->validRoomCheck); gs->setInt ("mapper-movement-check-count", getMapData()->failedMoveMsg.size()); int idx = 0; QStringList::iterator it; for (it = getMapData()->failedMoveMsg.begin(); it != getMapData()->failedMoveMsg.end(); ++it) gs->setString ("mapper-movement-check-" + QString::number (++idx), *it); gs->setColor ("mapper-color-Background", mapData->backgroundColor); gs->setColor ("mapper-color-Grid", mapData->gridColor); gs->setColor ("mapper-color-LowerRoom", mapData->lowerRoomColor); gs->setColor ("mapper-color-LowerZone", mapData->lowerZoneColor); gs->setColor ("mapper-color-LowerText", mapData->lowerTextColor); gs->setColor ("mapper-color-HigherZone", mapData->higherZoneColor); gs->setColor ("mapper-color-DefaultRoom", mapData->defaultRoomColor); gs->setColor ("mapper-color-DefaultZone", mapData->defaultZoneColor); gs->setColor ("mapper-color-DefaultText", mapData->defaultTextColor); gs->setColor ("mapper-color-HigherRoom", mapData->higherRoomColor); gs->setColor ("mapper-color-HigherText", mapData->higherTextColor); gs->setColor ("mapper-color-LowerPath", mapData->lowerPathColor); gs->setColor ("mapper-color-DefaultPath",mapData->defaultPathColor); gs->setColor ("mapper-color-HigherPath", mapData->higherPathColor); gs->setColor ("mapper-color-Selected", mapData->selectedColor); gs->setColor ("mapper-color-Special", mapData->specialColor); gs->setColor ("mapper-color-Login", mapData->loginColor); gs->setColor ("mapper-color-Edit", mapData->editColor); gs->setColor ("mapper-color-Current", mapData->currentColor); for (CMapPluginBase *plugin = getPluginList()->first(); plugin!=0; plugin = getPluginList()->next()) { plugin->saveConfigOptions(); } gs->setBool ("mapper-speedwalk-abort-active", mapData->speedwalkAbortActive); gs->setInt ("mapper-speedwalk-abort-limit", mapData->speedwalkAbortLimit); gs->setInt ("mapper-speedwalk-delay", mapData->speedwalkDelay); redrawAllViews(); } void CMapManager::getCounts(int *levels,int *rooms,int *paths,int *labels) { *rooms = 0; *labels = 0; *paths = 0; CMapZone *zone = getZone(); *levels = zone->levelCount(); for (unsigned int idx = 0; idx < zone->levelCount(); ++idx) { CMapLevel *level = zone->getLevel(idx); foreach (CMapRoom *room, *level->getRoomList()) *paths += room->getPathList()->count(); *rooms += level->getRoomList()->count(); *labels += level->getTextList()->count(); } } directionTyp CMapManager::getOpsiteDirection(directionTyp dir) { directionTyp result = SOUTH; switch (dir) { case NORTH : result = SOUTH; break; case SOUTH : result = NORTH; break; case EAST : result = WEST; break; case WEST : result = EAST; break; case NORTHWEST : result = SOUTHEAST; break; case NORTHEAST : result = SOUTHWEST; break; case SOUTHWEST : result = NORTHEAST; break; case SOUTHEAST : result = NORTHWEST; break; case UP : result = DOWN; break; case DOWN : result = UP; break; case SPECIAL : result = SPECIAL; break; } return result; } /** Used to set the current tool */ void CMapManager::setCurrentTool(CMapToolBase *tool) { if (currentTool) currentTool->toolUnselected(); currentTool=tool; if (currentTool) currentTool->toolSelected(); activeView->changed(); } /** Usd to get the current tool */ CMapToolBase *CMapManager::getCurrentTool(void) { return currentTool; } /** This method puts a element into edit state */ void CMapManager::setEditElement(CMapElement *element) { if (elementEdit) { elementEdit->setEditMode(false); changedElement(elementEdit); } element->setEditMode(true); elementEdit = element; changedElement(elementEdit); } /** This is used to remove edit state from element being edited */ void CMapManager::unsetEditElement(void) { if (elementEdit) { elementEdit->setEditMode(false); changedElement(elementEdit); } } /** This gets the element that is being edited */ CMapElement *CMapManager::getEditElement(void) { return elementEdit; } /** This cancels any editing */ void CMapManager::stopEditing(void) { if (elementEdit) { elementEdit->setEditMode(false); } elementEdit = NULL; } int CMapManager::getUndoActive(void) { return m_commandsActive; } /** This is used to tell the mapper if commands should be added to the history list */ void CMapManager::setUndoActive(bool active) { m_commandsActive = active; } /** Used to add a command to the command history */ void CMapManager::addCommand(CMapCommand *command) { if (getUndoActive()) { if (historyGroup) { // If there is a history group, it will -not- execute anything. That will happen once the group gets closed. historyGroup->addCommand(command); } else { commandHistory->push(command); } } else { command->redo(); } } void CMapManager::openCommandGroup(QString name) { CMapCmdGroup *group = new CMapCmdGroup(this,name); group->setPreviousGroup(historyGroup); historyGroup = group; } void CMapManager::closeCommandGroup() { CMapCmdGroup *currentGroup = historyGroup; CMapCmdGroup *oldGroup =historyGroup->getPreviousGroup(); historyGroup = oldGroup; addCommand(currentGroup); } /** move the player relative to the current position of the player * @param cmd The move command used to move the player */ void CMapManager::movePlayerBy(QString cmd) { QString specialCmd = ""; directionTyp dir = textToDirection(cmd); if (dir == SPECIAL) specialCmd = cmd; movePlayerBy(dir, getActiveView()->getCreateMode(), specialCmd); } /** move the player relative to the current position of the player * This command has support for special paths, but can only move * anlong exsiting special paths. In other words, it is unable to * create special paths. */ void CMapManager::movePlayerBy(directionTyp dir,bool create,QString specialCmd) { // Make sure that the room we are currently in is visible if (!currentRoom) return; CMapCmdMovePlayer *cmd = new CMapCmdMovePlayer(this, dir, specialCmd, create); addCommand(cmd); } /** Used to walk the player in the mud to a given room */ void CMapManager::walkPlayerTo(CMapRoom *toRoom) { QQueue roomsToVisit; CMapRoom *destRoom; CMapRoom *srcRoom; CMapPath *path; CMapRoom *foundRoom; signed int time = 0; bool bFound = false; CMapPath *foundPath = NULL; int speedWalkAbortCount = 0; if ((!currentRoom) || (currentRoom == toRoom)) return; if (speedwalkActive) { KMessageBox::information (NULL,i18n("Speedwalking is already in progress"),i18n("KMuddy Mapper")); return; } speedwalkActive = true; pathToWalk.clear(); // Reset the seach count for all the rooms for (unsigned int idx = 0; idx < getZone()->levelCount(); ++idx) { CMapLevel *level = getZone()->getLevel(idx); foreach (CMapRoom *room, *level->getRoomList()) room->setMoveTime(-1); } // Init things for the start room srcRoom = currentRoom; destRoom = (CMapRoom *)toRoom; srcRoom->setMoveTime(time++); // enqueue starting room roomsToVisit.enqueue(srcRoom); CMapRoom* room; // this is the Breadth First Search Algorithm while (!(roomsToVisit.isEmpty() || bFound)) { foundRoom = roomsToVisit.dequeue(); // for all neighbours of foundRoom foreach (path, *foundRoom->getPathList()) { room = path->getDestRoom(); if (room == destRoom) { bFound = true; break; } // neighbour has not been visited yet, enqueue it if (room->getMoveTime() == -1) { room->setMoveTime(time++); roomsToVisit.enqueue(room); } } } // Check to see if we were unable to find any paths if (!bFound) { speedwalkActive = false; KMessageBox::information (NULL,i18n("The automapper was unable to find a path to requested room"),i18n("KMuddy Mapper")); return; } speedWalkAbortCount=0; // Trace steps that need to be taken backwards from the dest to the src room while(destRoom != srcRoom) { time = destRoom->getConnectingPathList()->first()->getSrcRoom()->getMoveTime(); foundRoom = destRoom->getConnectingPathList()->first()->getSrcRoom(); // Find the room with the shortest time as this is the room we // should be moving to. foreach (path, *destRoom->getConnectingPathList()) { if (time == -1 || (path->getSrcRoom()->getMoveTime()<=time && path->getSrcRoom()->getMoveTime()!=-1)) { time = path->getSrcRoom()->getMoveTime(); foundRoom = path->getSrcRoom(); foundPath = path; } } pathToWalk.push(new QString(directionToText(foundPath->getSrcDir(),foundPath->getSpecialCmd()))); destRoom=foundRoom; // Check to make sure that tings are not stuck in a loop and abort // if the move limit is reached speedWalkAbortCount++; if (mapData->speedwalkAbortActive && (speedWalkAbortCount == mapData->speedwalkAbortLimit)) { speedwalkActive = false; KMessageBox::information (NULL,i18n("Speedwalk abort because move limit was reached"),i18n("KMuddy Mapper")); return; } } speedwalkProgressDlg->setTotalSteps(pathToWalk.count()); speedwalkProgressDlg->setProgress(0); cActionManager *am = cActionManager::self(); cStatus *status = dynamic_cast(am->object ("status", am->activeSession())); if (status) status->statusBar()->addPermanentWidget(speedwalkProgressDlg,0); speedwalkProgressDlg->show(); speedwalkProgress = 0; // Start walking path slotWalkPlayerAlongPath(); } void CMapManager::slotAbortSpeedwalk(void) { pathToWalk.clear(); speedwalkActive = false; speedwalkProgressDlg->setProgress(speedwalkProgressDlg->getTotalSteps()); speedwalkProgressDlg->hide(); cActionManager *am = cActionManager::self(); cStatus *status = dynamic_cast(am->object ("status", am->activeSession())); if (status) status->statusBar()->removeWidget(speedwalkProgressDlg); } /** Used to recersivly move the play along a speedwalk path */ void CMapManager::slotWalkPlayerAlongPath(void) { if (speedwalkActive) { QString *dir = pathToWalk.pop(); // TODO: using active session isn't a very good idea; progress bar should be shown on the mapper window, not in KMuddy's status bar; furthermore, the mapper should distinguish sessions and switch maps when session changes or something - until all this gets done, we cannot implement this any better mapperPlugin->sendCommand (mapperPlugin->activeSession(), *dir); speedwalkProgressDlg->setProgress(++speedwalkProgress); // Walk the path if (!pathToWalk.isEmpty()) { QTimer::singleShot( mapData->speedwalkDelay * 100, this, SLOT(slotWalkPlayerAlongPath()) ); } else { slotAbortSpeedwalk(); } } } /** This method is used to convert a direction into a offset */ void CMapManager::directionToCord(directionTyp dir, QSize distance,QPoint *pos) { int x = pos->x(); int y = pos->y(); switch (dir) { case NORTH : x = 0; y = -distance.height(); break; case EAST : x = distance.width(); y = 0; break; case SOUTH : x = 0; y = distance.height(); break; case WEST : x = -distance.width(); y = 0; break; case NORTHEAST : x = distance.width(); y = -distance.height(); break; case NORTHWEST : x = -distance.width(); y = -distance.height(); break; case SOUTHEAST : x = distance.width(); y = distance.height(); break; case SOUTHWEST : x = -distance.width(); y = distance.height(); break; case UP : break; case DOWN : break; case SPECIAL : break; } pos->setX(x); pos->setY(y); } /** This method is used to move the elements in a zone by the given vector */ void CMapManager::moveMap(QPoint inc,CMapZone *) { CMapCmdMoveMap *cmd = new CMapCmdMoveMap(this,inc,i18n("Move Elements in map")); addCommand(cmd); } /** This method is used to make a path two way */ void CMapManager::makePathTwoWay(CMapPath *path) { if (!path->getOpsitePath()) { CMapCmdTogglePathTwoWay *cmd = new CMapCmdTogglePathTwoWay(this,i18n("Make Path Two-Way"),path); addCommand(cmd); } } /** This method is used to make a path one way */ void CMapManager::makePathOneWay(CMapPath *path) { if (path->getOpsitePath()) { CMapCmdTogglePathTwoWay *cmd = new CMapCmdTogglePathTwoWay(this,i18n("Make Path One-Way"),path); addCommand(cmd); } } /** Get the main window */ CMapView *CMapManager::getActiveView() { return activeView; } /** Used to repaint all the views */ void CMapManager::redrawAllViews(void) { activeView->changed(); } CMapFileFilterBase *CMapManager::nativeFilter(bool isLoad) { for (CMapFileFilterBase *filter = m_fileFilter.first();filter!=0;filter=m_fileFilter.next()) { if (isLoad && (!filter->supportLoad())) continue; if ((!isLoad) && (!filter->supportSave())) continue; if (filter->isNative()) return filter; } return 0; } QString CMapManager::defaultSavePath () const { return KStandardDirs::locateLocal ("appdata", "maps/"); } /** This is a debug function and not for genreal use */ void CMapManager::changeProperties(CMapElement *element,QString key,QString oldData,QString newData) { CMapCmdElementProperties *cmd = new CMapCmdElementProperties(this,i18n("Change Element Property"),element); cmd->getOrgProperties().writeEntry(key,oldData); cmd->getNewProperties().writeEntry(key,newData); addCommand(cmd); } /** This is a debug function and not for genreal use */ void CMapManager::changeProperties(CMapElement *element,QString key,int oldData,int newData) { CMapCmdElementProperties *cmd = new CMapCmdElementProperties(this,i18n("Change Element Property"),element); cmd->getOrgProperties().writeEntry(key,oldData); cmd->getNewProperties().writeEntry(key,newData); addCommand(cmd); } /** This is a debug function and not for genreal use */ void CMapManager::generateTestMap() { kDebug() << "creating test map"; bool smallMap = false; ///////////////////////////////////////////////////////////////////// // Create a new empty map setUndoActive(false); commandHistory->clear(); historyGroup = NULL; eraseMap(); createNewMap(); setUndoActive(true); ///////////////////////////////////////////////////////////////////// // Create a test map // Test rooms and paths openCommandGroup("Create Test Map"); if (!smallMap) { movePlayerBy(SOUTH,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(WEST,true,""); movePlayerBy(NORTH,true,""); movePlayerBy(EAST,true,""); movePlayerBy(EAST,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(EAST,true,""); movePlayerBy(EAST,true,""); movePlayerBy(EAST,true,""); movePlayerBy(EAST,true,""); movePlayerBy(UP,true,""); movePlayerBy(EAST,true,""); movePlayerBy(EAST,true,""); movePlayerBy(EAST,true,""); movePlayerBy(EAST,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(EAST,true,""); movePlayerBy(EAST,true,""); movePlayerBy(DOWN,true,""); movePlayerBy(DOWN,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(EAST,true,""); movePlayerBy(EAST,true,""); movePlayerBy(UP,true,""); movePlayerBy(SOUTH,true,""); movePlayerBy(WEST,true,""); // Test text changeProperties(getZone(),"Label","",i18n("Root Zone")); } CMapLevel *level = getZone()->firstLevel(); if (level->getNextLevel()) level = level->getNextLevel(); QFont font = QFont("times"); font.setPointSize(25); createText(QPoint(160,20),level,"Test Map",font,Qt::black); if (!smallMap) { CMapRoom *test1=CMapElementUtil::createRoom(this, QPoint(14*20,14*20),level); changeProperties(test1,"Label","",i18n("Test room 1")); changeProperties(test1,"LabelPos",(int)CMapRoom::HIDE,(int)CMapRoom::WEST); CMapRoom *test2=CMapElementUtil::createRoom(this, QPoint(20*20,20*20),level); changeProperties(test2,"Label","",i18n("Test room 2")); changeProperties(test2,"LabelPos",(int)CMapRoom::HIDE,(int)CMapRoom::EAST); CMapRoom *test3=CMapElementUtil::createRoom(this, QPoint(14*20,20*20),level); changeProperties(test3,"Label","",i18n("Test room 3")); changeProperties(test3,"LabelPos",(int)CMapRoom::HIDE,(int)CMapRoom::WEST); CMapRoom *test4=CMapElementUtil::createRoom(this, QPoint(20*20,14*20),level); changeProperties(test4,"Label","",i18n("Test room 4")); changeProperties(test4,"LabelPos",(int)CMapRoom::HIDE,(int)CMapRoom::NORTH); createPath(QPoint(14*20,14*20),level,SOUTHEAST, QPoint(20*20,20*20),level,NORTHWEST); createPath(QPoint(20*20,20*20),level,NORTHWEST, QPoint(14*20,14*20),level,SOUTHEAST); createPath(QPoint(14*20,20*20),level,NORTHEAST, QPoint(20*20,14*20),level,SOUTHWEST); createPath(QPoint(20*20,14*20),level,SOUTHWEST, QPoint(14*20,20*20),level,NORTHEAST); CMapPath *specialPath = createPath(test1,SPECIAL,test4,SPECIAL); makePathTwoWay(specialPath); CMapCmdElementProperties *cmd = new CMapCmdElementProperties(this,i18n("Set Special Exit"),specialPath); cmd->getOrgProperties().writeEntry("SpecialCmdSrc",""); cmd->getOrgProperties().writeEntry("SpecialCmdDest",""); cmd->getOrgProperties().writeEntry("SpecialExit",false); cmd->getNewProperties().writeEntry("SpecialCmdSrc","enter"); cmd->getNewProperties().writeEntry("SpecialCmdDest","out"); cmd->getNewProperties().writeEntry("SpecialExit",true); addCommand(cmd); } closeCommandGroup(); kDebug() << "test map created"; } diff --git a/plugins/mapper/cmappath.cpp b/plugins/mapper/cmappath.cpp index 29e089a..0262bc7 100644 --- a/plugins/mapper/cmappath.cpp +++ b/plugins/mapper/cmappath.cpp @@ -1,948 +1,938 @@ /*************************************************************************** cmappath.cpp ------------------- begin : Sat Mar 10 2001 copyright : (C) 2001 by Kmud Developer Team email : kmud-devel@kmud.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "cmappath.h" #include "cmapmanager.h" #include #include #include #include //Added by qt3to4: #include #include #include #include "cmaplevel.h" #include "cmapcmdelementproperties.h" CMapPath::CMapPath(CMapManager *manager,CMapRoom *srcRoom,directionTyp srcDir,CMapRoom *destRoom,directionTyp destDir, bool twoWay) : CMapElement(manager,NULL) { setSrcRoom(srcRoom); setDestRoom(destRoom); setSrcDir(srcDir); setDestDir(destDir); setCords(); bSpecialExit = false; specialCmd = ""; setLevel(srcRoom->getLevel()); srcRoom->addPath(this); destRoom->getConnectingPathList()->append(this); // Check to see if there is a a path in the opsite directon, if so make this a two way path bool found = false; foreach (CMapPath *path, *destRoom->getPathList()) { // FIXME_jp : Fix this for multiple special paths between the same rooms with different cmd's if (path->getDestRoom()==srcRoom && path->getSrcDir() == destDir && path->getDestDir() == srcDir && path->getSpecialCmd() == "") { setOpsitePath(path); path->setOpsitePath(this); found = true; } } if (twoWay && (!found)) makeTwoWay(); beforeCommand = ""; afterCommand = ""; done = false; opsitePath = NULL; m_dontPaintBend=0; } CMapPath::CMapPath(CMapManager *manager,CMapRoom *srcRoom,CMapRoom *destRoom) : CMapElement(manager,NULL) { setSrcRoom(srcRoom); setDestRoom(destRoom); setSrcDir(NORTH); setDestDir(SOUTH); beforeCommand = ""; afterCommand = ""; bSpecialExit = false; specialCmd = ""; done = false; opsitePath = NULL; } CMapPath::~CMapPath() { if (opsitePath) { opsitePath->setOpsitePath(NULL); // needed to prevent endless looping delete opsitePath; } if (destRoom) destRoom->getConnectingPathList()->removeAll(this); if (srcRoom) srcRoom->getPathList()->removeAll(this); } void CMapPath::setDontPaintBend(int bend) { m_dontPaintBend = bend; } /** This method is used to set the cords of the path */ void CMapPath::setCords(void) { QPoint pos1,pos2; CMapRoom *srcRoom = getSrcRoom(); CMapRoom *destRoom = getDestRoom(); directionTyp srcDir = getSrcDir(); directionTyp destDir = getDestDir(); QPoint start; QSize halfRoomSize; start.setX(srcRoom->getX() + (srcRoom->getWidth() / 2)); start.setY(srcRoom->getY() + (srcRoom->getHeight() / 2)); halfRoomSize = QSize(srcRoom->getSize().width()/2,srcRoom->getSize().height()/2); getManager()->directionToCord(srcDir,halfRoomSize,&pos1); pos1+=start; QPoint end; end.setX(destRoom->getX() + (destRoom->getWidth() / 2)); end.setY(destRoom->getY() + (destRoom->getHeight() / 2)); halfRoomSize = QSize(destRoom->getSize().width()/2,destRoom->getSize().height()/2); getManager()->directionToCord(destDir,halfRoomSize,&pos2); pos2+=end; QRect rect(pos1,pos2); setRect(rect); setDone(false); } /** Used to draw an arrow head */ void CMapPath::drawArrow(directionTyp dir,QPainter *p,QPoint end) { int x1=0,x2=0,y1=0,y2=0; Q3PointArray cords(3); switch (dir) { case NORTH : x1=end.x()-3; x2=end.x()+3; y1=end.y()-3; y2=end.y()-3; break; case SOUTH : x1=end.x()-3; x2=end.x()+3; y1=end.y()+3; y2=end.y()+3; break; case WEST : x1=end.x()-3; x2=end.x()-3; y1=end.y()-3; y2=end.y()+3; break; case EAST : x1=end.x()+3; x2=end.x()+3; y1=end.y()-3; y2=end.y()+3; break; case NORTHEAST : x1=end.x(); x2=end.x()+4; y1=end.y()-4; y2=end.y(); break; case SOUTHEAST : x1=end.x(); x2=end.x()+4; y1=end.y()+4; y2=end.y(); break; case SOUTHWEST : x1=end.x(); x2=end.x()-4; y1=end.y()+4; y2=end.y(); break; case NORTHWEST : x1=end.x(); x2=end.x()-4; y1=end.y()-4; y2=end.y(); break; case UP : break; case DOWN : break; case SPECIAL : break; } // Draw the arrow head to indicate the direction of the path cords.setPoint(0,end); cords.setPoint(1,x1,y1); cords.setPoint(2,x2,y2); p->drawPolygon(cords.constData(), 3, Qt::OddEvenFill); } QPoint CMapPath::getIndent(directionTyp dir,QPoint pos) { int x=0,y=0; int posx = pos.x(); int posy = pos.y(); switch (dir) { case NORTH : x = posx ; y=posy-5; break; case SOUTH : x = posx ; y=posy+5; break; case WEST : x = posx-5; y=posy ; break; case EAST : x = posx+5; y=posy ; break; case NORTHEAST : x = posx+5; y=posy-5; break; case SOUTHEAST : x = posx+5; y=posy+5; break; case SOUTHWEST : x = posx-5; y=posy+5; break; case NORTHWEST : x = posx-5; y=posy-5; break; case UP : break; case DOWN : break; case SPECIAL : break; } return QPoint(x,y); } /** This method is used to calcualte the distance from a path segment */ int CMapPath::getDistance (int x,int y,int x1,int x2,int y1,int y2) { int a = y1 - y2; int b = -(x1 - x2); int d = (int)(( (x - x2) * a + (y-y2) * b) / sqrt (a*a + b*b)); return abs(d); } /** Set a pointer to the destination room */ void CMapPath::setDestRoom(CMapRoom *DestRoom) { destRoom = DestRoom; } /** Set a pointer to the source room */ void CMapPath::setSrcRoom(CMapRoom *SrcRoom) { srcRoom = SrcRoom; } /** Set the start and finish directrions of the path */ void CMapPath::setSrcDir(directionTyp SrcDir) { srcDir = SrcDir; } void CMapPath::setDestDir(directionTyp DestDir) { destDir = DestDir; } void CMapPath::makeOneWay() { CMapPath *path = getOpsitePath(); if (!path) return; path->setOpsitePath(NULL); // so it doesn't delete us too delete path; } void CMapPath::makeTwoWay() { if (opsitePath) return; CMapPath *newPath = new CMapPath(getManager(), destRoom, destDir, srcRoom, srcDir, false); setOpsitePath(newPath); newPath->setOpsitePath(this); if (bSpecialExit) newPath->setSpecialCmd(specialCmd); } directionTyp CMapPath::generatePath() { tempPathCords.clear(); QPoint start = getLowPos(); QPoint end = getHighPos(); directionTyp destDir = getDestDir(); QPoint indent1 = getIndent(getSrcDir(),start); QPoint indent2 = getIndent(destDir,end); tempPathCords.append(start); tempPathCords.append(indent1); for( PointList::Iterator point = bendList.begin(); point != bendList.end(); ++point ) { tempPathCords.append(*point); } tempPathCords.append(indent2); tempPathCords.append(end); return destDir; } /** Used to draw the path */ void CMapPath::drawPath(QPainter *p,CMapZone *zone,QPoint offset,QColor color,int editBox,QPoint editPos) { directionTyp tempDestDir = generatePath(); p->setPen(color); p->setBrush(color); // If the path has not already been then draw it if (!getDone()) { if (tempPathCords.count()>1) { - QPoint temp = *(tempPathCords.at(1)); + QPoint temp = tempPathCords.at(1); int count = 0; for( PointList::Iterator point = tempPathCords.begin(); point != tempPathCords.end(); ++point ) { if (editBox > 0 && count==editBox + 1) { p->drawLine(temp + offset,editPos + offset); } else if (editBox > 0 && count==editBox + 2) { p->drawLine(editPos + offset,(*point) + offset); } else { if (editBox == 0 && m_dontPaintBend == 0) { p->drawLine(temp + offset,(*point) + offset); } else { if (count != m_dontPaintBend+1 && count != m_dontPaintBend + 2) { p->drawLine(temp + offset,(*point) + offset); } } } temp = *point; count++; } } if (getEditMode()) { int count = 0; p->setPen(getManager()->getMapData()->editColor); p->setBrush(getManager()->getMapData()->editColor); for( PointList::Iterator point = tempPathCords.begin(); point != tempPathCords.end(); ++point ) { if (count>1 && count < (int)tempPathCords.count()-2) { if (editBox > 0 && count==editBox + 2) { p->drawRect(editPos.x()-3,editPos.y()-3,6,6); } else { if (editBox == 0 && m_dontPaintBend == 0) { p->drawRect((*point).x()-3,(*point).y()-3,6,6); } else { if (count != m_dontPaintBend+1) { p->drawRect((*point).x()-3,(*point).y()-3,6,6); } } } } count ++; } } } p->setPen(color); p->setBrush(color); // Draw the arrow head of the path drawArrow(tempDestDir,p,tempPathCords.last() + offset); if (getDestRoom()->getZone()!=zone) { if (getOpsitePath()) drawArrow(getSrcDir(),p,tempPathCords.first() + offset); } // Mark this path and the opsite (two way path) as having been drawn setDone(true); if (getOpsitePath()) { getOpsitePath()->setDone(true); } } /** Used to paint the element at a given location and size * @param p The painter to paint the element to * @param pos The position to paint the elmenet * @param size The size the element should be draw * @param zone The current zone being viewed */ void CMapPath::paintElementResize(QPainter *p,QPoint,QSize,CMapZone *zone) { if (srcDir == UP || srcDir == DOWN || destDir == UP || destDir == DOWN || srcDir==SPECIAL || destDir==SPECIAL) return; // Get start and end points of the path drawPath(p,zone,QPoint(0,0),getManager()->getMapData()->defaultPathColor); if (getSelected()) { p->setPen(getManager()->getMapData()->selectedColor); p->setBrush(getManager()->getMapData()->selectedColor); p->drawRect(tempPathCords.first().x()-3,tempPathCords.first().y()-3,6,6); p->drawRect(tempPathCords.last().x()-3,tempPathCords.last().y()-3,6,6); } } /** Used to find out if the mouse is in the element */ bool CMapPath::mouseInElement(QPoint mousePos) { if (srcDir == UP || srcDir == DOWN || srcDir==SPECIAL) return false; //FIXME_jp: Handle zone paths that have been termintated generatePath(); if (tempPathCords.count()>1) { - QPoint temp = *tempPathCords.at(1); + QPoint temp = tempPathCords.at(1); for( PointList::Iterator point = tempPathCords.begin(); point != tempPathCords.end(); ++point ) { QPoint pos1 = temp; QPoint pos2 = *point; QRect rect = getBoundRectOfSeg(pos1,pos2); QRegion region(rect,QRegion::Rectangle); if (region.contains(mousePos)) { int distance = getDistance(mousePos.x(),mousePos.y(),pos1.x(),pos2.x(),pos1.y(),pos2.y()); return (distance <= 5); } temp = *point; } } return false; } QRect CMapPath::getBoundRectOfSeg(QPoint pos1,QPoint pos2) { QRect rect; if (pos1.x() == pos2.x()) { pos1.setX(pos1.x()-5); pos2.setX(pos2.x()+5); } if (pos1.y() == pos2.y()){ pos1.setY(pos1.y()-5); pos2.setY(pos2.y()+5); } if (pos1.y()>pos2.y()) { rect.setBottom(pos1.y()); rect.setTop(pos2.y()); } else { rect.setTop(pos1.y()); rect.setBottom(pos2.y()); } if (pos1.x()>pos2.x()) { rect.setRight(pos1.x()); rect.setLeft(pos2.x()); } else { rect.setLeft(pos1.x()); rect.setRight(pos2.x()); } return rect; } void CMapPath::paint(QPainter *p,CMapZone *zone) { if (srcDir == UP || srcDir == DOWN || destDir == UP || destDir == DOWN || srcDir==SPECIAL || destDir==SPECIAL) return; CMapElement::paint(p,zone); } void CMapPath::resizePaint(QPoint,QPainter *,CMapZone *,int) { } void CMapPath::editPaint(QPoint pos,QPainter *p,CMapZone *zone,int editBox) { if (srcDir == UP || srcDir == DOWN || destDir == UP || destDir == DOWN || srcDir==SPECIAL || destDir==SPECIAL) return; setDone(false); drawPath(p,zone,QPoint (0,0),getManager()->getMapData()->defaultPathColor,editBox,pos); } void CMapPath::dragPaint(QPoint offset,QPainter *p,CMapZone *zone) { if (srcDir == UP || srcDir == DOWN || destDir == UP || destDir == DOWN || srcDir==SPECIAL || destDir==SPECIAL) return; if (getSrcRoom()->getSelected() && getDestRoom()->getSelected()) { drawPath(p,zone,offset,getManager()->getMapData()->defaultPathColor); } } void CMapPath::lowerPaint(QPainter *p,CMapZone *zone) { if (srcDir == UP || srcDir == DOWN || destDir == UP || destDir == DOWN || srcDir==SPECIAL || destDir==SPECIAL) return; // Get start and end points of the path drawPath(p,zone,QPoint(-5,-5),getManager()->getMapData()->lowerPathColor); } void CMapPath::higherPaint(QPainter *p,CMapZone *zone) { if (srcDir == UP || srcDir == DOWN || destDir == UP || destDir == DOWN || srcDir==SPECIAL || destDir==SPECIAL) return; // Get start and end points of the path drawPath(p,zone,QPoint(5,5),getManager()->getMapData()->higherPathColor); } /** Used to create a deep copy of the path */ CMapElement *CMapPath::copy(void) { CMapPath *path = new CMapPath(getManager(),getSrcRoom(),getSrcDir(),getDestRoom(),getDestDir(),getOpsitePath()); path->setAfterCommand(getAfterCommand()); path->setBeforeCommand(getBeforeCommand()); path->setSpecialCmd(getSpecialCmd()); path->setSpecialExit(getSpecialExit()); for( PointList::Iterator bend = bendList.begin(); bend != bendList.end(); ++bend ) { path->addBend(*bend); } return path; } /** Used to add a bend to the path */ int CMapPath::addBend(QPoint pos) { - if (bendList.contains(pos)>-1) + if (bendList.contains(pos)) return -1; if (bendList.count()==0) { bendList.append(pos); return bendList.count()-1; } else { int x1 = getX(); int y1 = getY(); int x2 = getHighX(); int y2 = getHighY(); QPoint pos1 = getIndent(getSrcDir(),QPoint (x1,y1)); x1=pos1.x(),y1=pos1.y(); int count = 0; for( PointList::Iterator point = bendList.begin(); point != bendList.end(); ++point ) { x2 = (*point).x(); y2 = (*point).y(); if (x1 == x2) { x1-=3; x2+=3; } if (y1 == y2) { y1-=3; y2+=3; } int x1_1 = x1 < x2 ? x1 : x2; int y1_1 = y1 < y2 ? y1 : y2; int x2_1 = x1 >= x2 ? x1 : x2; int y2_1 = y1 >= y2 ? y1 : y2; QRegion r(x1_1,y1_1,x2_1-x1_1,y2_1-y1_1); if (r.contains(pos)) { - bendList.insert(bendList.at(count),pos); + bendList.insert(count, pos); return count; } x1 = (*point).x(); y1 = (*point).y(); count++; } bendList.append(pos); return bendList.count()-1; } } /** Used to add a bend to the path */ void CMapPath::addBendWithUndo(QPoint pos) { - if (bendList.contains(pos)>-1) + if (bendList.contains(pos)) return; CMapCmdElementProperties *cmdAddBend = new CMapCmdElementProperties(getManager(),i18n("Add Bend"),this); cmdAddBend->getNewProperties().writeEntry("AddBend",pos); cmdAddBend->getOrgProperties().writeEntry("DelBend",pos); getManager()->addCommand(cmdAddBend); } /** Used to move a bend to a new position */ void CMapPath::moveBendWithUndo(int bend, QPoint pos) { if (bend>0 && bend-1 < (int)bendList.count()) { - QPoint oldPos = *(bendList.at(bend-1)); + QPoint oldPos = bendList.at(bend-1); CMapCmdElementProperties *cmdMoveBend = new CMapCmdElementProperties(getManager(),i18n("Move Bend"),this); cmdMoveBend->getNewProperties().writeEntry("MoveBendPos",pos); cmdMoveBend->getNewProperties().writeEntry("MoveBendBend",bend); cmdMoveBend->getOrgProperties().writeEntry("MoveBendPos",oldPos); cmdMoveBend->getOrgProperties().writeEntry("MoveBendBend",bend); getManager()->addCommand(cmdMoveBend); } } /** This method is used to delete bends from a path * @param seg The path segment number to delete */ void CMapPath::deletePathSegWithUndo(int seg) { QPoint bend = deletePathSeg(seg); CMapCmdElementProperties *cmdDeleteBend = new CMapCmdElementProperties(getManager(),i18n("Delete Path Segment"),this); cmdDeleteBend->getNewProperties().writeEntry("DelBend",bend); cmdDeleteBend->getOrgProperties().writeEntry("AddBend",bend); getManager()->addCommand(cmdDeleteBend); } void CMapPath::deleteBend(QPoint bend) { bendList.removeAll(bend); } /** Used to load the properties of the element from a list of properties */ void CMapPath::loadProperties(KConfigGroup grp) { CMapElement::loadProperties(grp); setAfterCommand(grp.readEntry("SrcAfterCommand",getAfterCommand())); setBeforeCommand(grp.readEntry("SrcBeforeCommand",getBeforeCommand())); setSpecialCmd(grp.readEntry("SpecialCmdSrc",getSpecialCmd())); setSpecialExit(grp.readEntry("SpecialExit",getSpecialExit())); setSrcDir((directionTyp)grp.readEntry("SrcDir",(int)getSrcDir())); setDestDir((directionTyp)grp.readEntry("DestDir",(int)getDestDir())); setCords(); if (grp.readEntry("PathTwoWay", getOpsitePath() != 0)) makeTwoWay(); else makeOneWay(); CMapPath *opposite = getOpsitePath(); if (opposite) { opposite->setAfterCommand(grp.readEntry("DestAfterCommand",opposite->getAfterCommand())); opposite->setBeforeCommand(grp.readEntry("DestBeforeCommand",opposite->getBeforeCommand())); opposite->setSrcDir((directionTyp)grp.readEntry("DestDir",(int)opposite->getSrcDir())); opposite->setDestDir((directionTyp)grp.readEntry("SrcDir",(int)opposite->getDestDir())); opposite->setSpecialCmd(grp.readEntry("SpecialCmdDest",opposite->getSpecialCmd())); opposite->setSpecialExit(grp.readEntry("SpecialExit",opposite->getSpecialExit())); opposite->setCords(); } if (grp.hasKey("AddBend")) { QPoint bend(0,0); bend = grp.readEntry("AddBend",bend); addBend(bend); } if (grp.hasKey("DelBend")) { QPoint bend(0,0); bend = grp.readEntry("DelBend",bend); deleteBend(bend); } if (grp.hasKey("MoveBendBend")) { QPoint pos(0,0); pos = grp.readEntry("MoveBendPos",pos); int bend = grp.readEntry("MoveBendBend",-1); moveBend(bend,pos); } if (grp.hasKey("DeletePathSeg")) { int seg = grp.readEntry("DeletePathSeg", 0); deletePathSeg(seg); } } /** Used to save the properties of the element to a list of properties */ void CMapPath::saveProperties(KConfigGroup grp) { // FIXME_jp : Make sure twoway paths are handled correctly CMapElement::saveProperties(grp); grp.writeEntry("SrcAfterCommand",getAfterCommand()); grp.writeEntry("SrcBeforeCommand",getBeforeCommand()); grp.writeEntry("SpecialCmdSrc",getSpecialCmd()); grp.writeEntry("SpecialExit",getSpecialExit()); grp.writeEntry("SrcDir",(int)getSrcDir()); grp.writeEntry("DestDir",(int)getDestDir()); grp.writeEntry("SrcRoom",getSrcRoom()->getRoomID()); grp.writeEntry("SrcZone",getSrcRoom()->getZone()->getZoneID()); grp.writeEntry("SrcLevel",getSrcRoom()->getLevel()->getLevelID()); grp.writeEntry("DestRoom",getDestRoom()->getRoomID()); grp.writeEntry("DestZone",getDestRoom()->getZone()->getZoneID()); grp.writeEntry("DestLevel",getDestRoom()->getLevel()->getLevelID()); if (getOpsitePath()) { grp.writeEntry("PathTwoWay",true); grp.writeEntry("DestAfterCommand",getOpsitePath()->getAfterCommand()); grp.writeEntry("DestBeforeCommand",getOpsitePath()->getBeforeCommand()); grp.writeEntry("SpecialCmdDest",getOpsitePath()->getSpecialCmd()); } else { grp.writeEntry("PathTwoWay",false); } } /** Used to save the element as an XML object * @param properties The XML object to save the properties too * @param doc The XML Document */ void CMapPath::saveQDomElement(QDomDocument *doc,QDomElement *properties) { CMapElement::saveQDomElement(doc,properties); properties->setAttribute("AfterCommand",getAfterCommand()); properties->setAttribute("BeforeCommand",getBeforeCommand()); properties->setAttribute("SpecialCmd",getSpecialCmd()); writeBool(properties,"SpecialExit",getSpecialExit()); writeInt(doc,properties,"SrcDir",(int)getSrcDir()); writeInt(doc,properties,"DestDir",(int)getDestDir()); writeInt(doc,properties,"SrcRoom",getSrcRoom()->getRoomID()); writeInt(doc,properties,"SrcZone",getSrcRoom()->getZone()->getZoneID()); writeInt(doc,properties,"SrcLevel",getSrcRoom()->getLevel()->getLevelID()); writeInt(doc,properties,"DestRoom",getDestRoom()->getRoomID()); writeInt(doc,properties,"DestZone",getDestRoom()->getZone()->getZoneID()); writeInt(doc,properties,"DestLevel",getDestRoom()->getLevel()->getLevelID()); QDomElement bendsNode = doc->createElement ("bends"); properties->appendChild(bendsNode); for( PointList::Iterator bend = bendList.begin(); bend != bendList.end(); ++bend ) { QDomElement bendNode = doc->createElement ("bend"); writeInt(doc,&bendNode,"X",(*bend).x()); writeInt(doc,&bendNode,"Y",(*bend).y()); bendsNode.appendChild(bendNode); } } /** Used to load the properties from a XML object * @param properties The XML object to load the properties from */ void CMapPath::loadQDomElement(QDomElement *properties) { CMapElement::loadQDomElement(properties); setAfterCommand(properties->attribute("AfterCommand",getAfterCommand())); setBeforeCommand(properties->attribute("BeforeCommand",getAfterCommand())); setSpecialCmd(properties->attribute("SpecialCmd",getSpecialCmd())); setSpecialExit(readBool(properties,"SpecialExit",getSpecialExit())); QDomNode n = properties->namedItem("bends"); if (!n.isNull()) { QDomElement bendsNode = n.toElement(); if (!bendsNode.isNull() ) { QDomNode n1 = bendsNode.firstChild(); while (!n1.isNull() ) { QDomElement bendNode = n1.toElement(); if (!bendNode.isNull() ) { int x=readInt(&bendNode,"X",-1); int y=readInt(&bendNode,"X",-1); if (x!=-1 && y!=-1) { addBend(QPoint(x,y)); } } n1 = n1.nextSibling(); } } } //TODO_jp : write path bends } void CMapPath::moveBy(QPoint offset) { if (getSrcRoom()->getSelected() && getDestRoom()->getSelected()) { for( PointList::Iterator point = bendList.begin(); point != bendList.end(); ++point ) { (*point)+=offset; } } } /** This method is used to calculate the positions of the resize handles */ void CMapPath::generateResizePositions(void) { resizePos.clear(); resizePos.append(QRect(tempPathCords.first().x()-3,tempPathCords.first().y()-3,7,7)); resizePos.append(QRect(tempPathCords.last().x()-3,tempPathCords.last().y()-3,7,7)); } /** Used to find out if the mouse is in the resize box * @param mousePos The position of the mouse pointer * @param currentZone A pointer to the current zone * @return the ID of the resize box, or 0 if not in any */ int CMapPath::mouseInResize(QPoint ,CMapZone *) { return 0; } /** Used to find out if the mosuse is in the edit box of the path * @param mousePos The position of the mouse pointer * @param currentZone A pointer to the current zone * @return the ID of the edit box, or 0 if not in any */ int CMapPath::mouseInEditBox(QPoint mousePos ,CMapZone *) { if (getEditMode()) { int count = 1; for( PointList::Iterator point = bendList.begin(); point != bendList.end(); ++point ) { QRegion r((*point).x()-3,(*point).y()-3,6,6); if (r.contains(mousePos)) { return count; } count ++; } } return 0; } /** Used to move a bend to a new position */ void CMapPath::moveBend(int bend, QPoint pos) { if (bend>0 && bend-1 < (int)bendList.count()) { - (*bendList.at(bend-1)) = pos; + bendList.replace(bend-1, pos); getManager()->changedElement(this); } } /** This method is used to delete bends from a path * @param seg The path segment number to delete */ QPoint CMapPath::deletePathSeg(int seg) { - QPoint deletedPos; - PointList::Iterator pos; + QPoint deletedPos; - for( PointList::Iterator point = bendList.begin(); point != bendList.end(); ++point ) - { - kDebug() << "Bend : " << (*point).x() << "," << (*point).y(); - } - - if (seg >= (int)bendList.count()) - { - pos =bendList.at(bendList.count()-1); - deletedPos = (*pos); - } - else - { - pos =bendList.at(seg-1); - deletedPos = (*pos); - } + for( PointList::Iterator point = bendList.begin(); point != bendList.end(); ++point ) + { + kDebug() << "Bend : " << (*point).x() << "," << (*point).y(); + } - return deletedPos; + if (seg > (int) bendList.count()) seg = bendList.count(); + deletedPos = bendList.at(seg - 1); + return deletedPos; } /** * This method is used to find out if the mouse pointer is in a path segment. * @param mousePos The position of the mouse * @param currentZone The current zone being viewed * @return 0 if not in any segament, otherwise return the number of the segment */ int CMapPath::mouseInPathSeg(QPoint mousePos,CMapZone *currentZone) { // Is this a inter zone path if (getSrcRoom()->getZone()!=currentZone || getDestRoom()->getZone()!=currentZone) return -1; if (bendList.count()==0) return -1; int count = 0; int x1=tempPathCords.first().x(),y1=tempPathCords.first().y(),x2,y2; for( PointList::Iterator point = tempPathCords.begin(); point != tempPathCords.end(); ++point ) { x2 = (*point).x(); y2 = (*point).y(); if (count > 1 && count < (int)tempPathCords.count()-1) { int startx = x1-5; int endx = x2+5; int starty = y1-5; int endy = y2+5; QRegion r(startx,starty,endx-startx,endy-starty); if (r.contains(mousePos)) { int d = getDistance (mousePos.x(),mousePos.y(),startx,endx,starty,endy); if (d<=5) { return count -1; } } } count++; x1 = x2; y1 = y2; } return -1; } diff --git a/plugins/mapper/cmappath.h b/plugins/mapper/cmappath.h index 9a2f56d..ed90289 100644 --- a/plugins/mapper/cmappath.h +++ b/plugins/mapper/cmappath.h @@ -1,213 +1,213 @@ /*************************************************************************** cmappath.h ------------------- begin : Sat Mar 10 2001 copyright : (C) 2001 by Kmud Developer Team email : kmud-devel@kmud.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CMAPPATH_H #define CMAPPATH_H #include -#include +#include #include "cmapelement.h" #include "kmemconfig.h" #include class CMapRoom; /**The class used to store path data *@author Kmud Developer Team */ class KMUDDY_EXPORT CMapPath : public CMapElement { public: CMapPath(CMapManager *manager,CMapRoom *srcRoom,directionTyp srcDir,CMapRoom *destRoom,directionTyp destDir, bool twoWay); CMapPath(CMapManager *manager,CMapRoom *srcRoom,CMapRoom *destRoom); ~CMapPath(); elementTyp getElementType(void) { return PATH ; } /** This method is used to set the cords of the path */ void setCords(void); bool getDone(void) { return done; } void setDone(bool set) { done = set; } void paint(QPainter *p,CMapZone *zone); /** Used to paint the element while it is bined resized */ void resizePaint(QPoint offset,QPainter *p,CMapZone *currentZone,int resizeId); void dragPaint(QPoint offset,QPainter *p,CMapZone *zone); void lowerPaint(QPainter *p,CMapZone *zone); void higherPaint(QPainter *p,CMapZone *zone); void editPaint(QPoint pos,QPainter *p,CMapZone *,int editBox); /** Used to find out if the mouse is in the element */ bool mouseInElement(QPoint mousePos); /** Used to create a deep copy of the path */ CMapElement *copy(void); /** Get the directions of the start and finish directions of the path */ directionTyp getSrcDir(void) { return srcDir; } directionTyp getDestDir(void) { return destDir; } void setOpsitePath(CMapPath *path) { opsitePath = path; } CMapPath *getOpsitePath(void) { return opsitePath; } /** Get a pointer to the destination room */ CMapRoom *getDestRoom(void) { return destRoom; } CMapRoom *getSrcRoom(void) { return srcRoom; } /** Set the source direction of the path */ void setSrcDir(directionTyp SrcDir); /** Set the destination directions of the path */ void setDestDir(directionTyp DestDir); /** Set a pointer to the destination room */ void setDestRoom(CMapRoom *DestRoom); /** Set a pointer to the source room */ void setSrcRoom(CMapRoom *SrcRoom); void makeOneWay(); void makeTwoWay(); /** Set the special exit command string */ void setSpecialCmd(QString cmd) { specialCmd = cmd; } /** Return the special exit command string */ QString getSpecialCmd(void) { return specialCmd; } /** Tell the mapp if this path is a special exit */ void setSpecialExit(bool special) { bSpecialExit = special; } /** Return if this path is a special exit */ bool getSpecialExit(void) { return bSpecialExit; } /** Get a list of bends in the path */ int getBendCount(void) { return bendList.count(); } /** Used to set the before walking command */ void setBeforeCommand(QString command) { beforeCommand = command; } /** Used to get the before walking commnad */ QString getBeforeCommand(void) { return beforeCommand; } /** Used to set the after walking command */ void setAfterCommand(QString command) { afterCommand = command; } /** Used to get the before walking commnad */ QString getAfterCommand(void) { return afterCommand; } /** Used to load the properties of the element from a list of properties */ virtual void loadProperties(KConfigGroup grp); /** Used to save the properties of the element to a list of properties */ virtual void saveProperties(KConfigGroup grp); /** Used to save the element as an XML object * @param properties The XML object to save the properties too * @param doc The XML Document */ virtual void saveQDomElement(QDomDocument *doc,QDomElement *properties); /** Used to load the properties from a XML object * @param properties The XML object to load the properties from */ virtual void loadQDomElement(QDomElement *properties); /** Used to move the element relative to it's current position */ virtual void moveBy(QPoint offset); /** This is overriddent to stop a path be resized */ virtual void resize(QPoint,int) { } /** Used to find out if the mouse is in the resize box * @param mousePos The position of the mouse pointer * @param currentZone A pointer to the current zone * @return the ID of the resize box, or 0 if not in any */ virtual int mouseInResize(QPoint mousePos,CMapZone *currentZone); /** * This method is used to find out if the mouse pointer is in a path segment. * @param mousePos The position of the mouse * @param currentZone The current zone being viewed * @return 0 if not in any segament, otherwise return the number of the segment */ int mouseInPathSeg(QPoint mousePos,CMapZone *currentZone); /** Used to find out if the mosuse is in the edit box of the path * @param mousePos The position of the mouse pointer * @param currentZone A pointer to the current zone * @return the ID of the edit box, or 0 if not in any */ int mouseInEditBox(QPoint mousePos ,CMapZone *); void setDontPaintBend(int bend); /** Used to add a bend to the path */ void addBendWithUndo(QPoint pos); /** Used to move a bend to a new position */ void moveBendWithUndo(int bend, QPoint pos); /** This method is used to delete bends from a path * @param seg The path segment number to delete */ void deletePathSegWithUndo(int seg); protected: void deleteBend(QPoint bend); /** Used to add a bend to the path */ int addBend(QPoint pos); /** Used to move a bend to a new position */ void moveBend(int bend, QPoint pos); /** This method is used to delete bends from a path * @param seg The path segment number to delete */ QPoint deletePathSeg(int seg); /** This method is used to calculate the positions of the resize handles */ void generateResizePositions(void); /** Used to paint the element at a given location and size * @param p The painer to paint the element to * @param pos The position to paint the elmenet * @param size The size the element should be draw * @param zone The current zone being viewed */ virtual void paintElementResize(QPainter *p,QPoint pos,QSize size,CMapZone *zone); private: /** This method is used to calcualte the distance from a path segment */ int getDistance (int x,int y,int x1,int x2,int y1,int y2); directionTyp generatePath(); /** Used to draw an arrow head */ void drawArrow(directionTyp dir,QPainter *p,QPoint end); QPoint getIndent(directionTyp dir,QPoint pos); /** Used to draw the path */ void drawPath(QPainter *p,CMapZone *zone,QPoint offset,QColor color,int editBox=0,QPoint editPos=QPoint(0,0)); QRect getBoundRectOfSeg(QPoint pos1,QPoint pos2); private: - typedef Q3ValueList PointList; + typedef QList PointList; /** If this is greater than 0 then the bend will not be painted */ int m_dontPaintBend; /** This is used to store a tempray list of path cords */ PointList tempPathCords; bool done; /** The commands of the path */ QString afterCommand,beforeCommand; /** A pointer to the path going in the opsite direction. Null if no path */ CMapPath *opsitePath; /** These are used to store the directions the path enters and leaves a room */ directionTyp srcDir,destDir; /** Used to store a pointer to the desination room */ CMapRoom *destRoom,*srcRoom; /** Used to flag if this is a special exit */ bool bSpecialExit; /** Used to store the special command string for a path */ QString specialCmd; /** A list of bends in the path */ PointList bendList; }; #endif diff --git a/plugins/mapper/cmaptext.cpp b/plugins/mapper/cmaptext.cpp index 41ca9eb..570a44e 100644 --- a/plugins/mapper/cmaptext.cpp +++ b/plugins/mapper/cmaptext.cpp @@ -1,732 +1,731 @@ /*************************************************************************** cmaptext.cpp ------------------- begin : Sat Mar 10 2001 copyright : (C) 2001 by Kmud Developer Team email : kmud-devel@kmud.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "cmaptext.h" #include #include #include #include -#include #include #include "cmapmanager.h" #include "cmaplevel.h" #include CMapText::CMapText(QString str,QFont f,QColor col,CMapManager *manager,QPoint pos,CMapLevel *level) : CMapElement(manager,level) { m_font = f; setRect(QRect(pos,pos)); setText(str); setColor(col); m_linkElement = NULL; getZone()->m_text_id_count=getZone()->m_text_id_count+1; m_ID = getZone()->m_text_id_count; setCursor(QPoint(0,1)); if (level) level->getTextList()->append(this); } CMapText::CMapText(QString str,CMapManager *manager,QPoint pos,CMapLevel *level) : CMapElement(manager,level) { m_font = manager->getMapData()->defaultTextFont; setRect(QRect(pos,pos)); setText(str); setColor(Qt::black); m_linkElement = NULL; getZone()->m_text_id_count=getZone()->m_text_id_count+1; m_ID = getZone()->m_text_id_count; setCursor(QPoint(0,1)); if (level) level->getTextList()->append(this); } CMapText::~CMapText() { if (m_linkElement) { if (m_linkElement->getElementType()==ROOM) { ((CMapRoom *)m_linkElement)->textRemove(); } if (m_linkElement->getElementType()==ZONE) { ((CMapZone *)m_linkElement)->textRemove(); } } getLevel()->getTextList()->removeAll(this); } void CMapText::setLevel(CMapLevel *level) { if (getLevel()) getLevel()->getTextList()->removeAll(this); level->getTextList()->append(this); CMapElement::setLevel(level); } /** This is used to return the actual cords in the view of the cursor * @return the cords */ QPoint CMapText::getCursorCords(void) { return m_cursorOffset + getLowPos(); } void CMapText::dragPaint(QPoint offset,QPainter *p,CMapZone *zone) { QPoint pos(getX()+offset.x(),getY()+offset.y()); paintElementResize(p,pos,getSize(),zone); } void CMapText::lowerPaint(QPainter *,CMapZone *) { // Do nothing as the text is not visiable on the lower level } void CMapText::higherPaint(QPainter *,CMapZone *) { // Do nothing as the text is not visiable on the upper level } /** This is used to convert a Actual size to it's closet font size * @param size The actual size of the font * @param font The text font * @return The closet matching font size */ int CMapText::getActualToFontSize(QSize size,QFont font,QStringList *text) { QFont tmpFont = font; int result = 1; tmpFont.setPointSize(result); QSize fontSize = QSize(1,1); //FIXME_jp: Check this does not go into infinate loop because there is // no upper limit check. while (fontSize.width() < size.width() && fontSize.height() < size.height()) { result+=10; tmpFont.setPointSize(result); QFontMetrics fm(tmpFont); int tmpWidth = 0; for (QStringList::iterator it = text->begin(); it != text->end(); ++it) { if (fm.width(*it) > tmpWidth) tmpWidth = fm.width(*it); } fontSize = QSize(tmpWidth,fm.height()); } while ((fontSize.width() > size.width() || fontSize.height() > size.height()) && result > 1) { result--; tmpFont.setPointSize(result); QFontMetrics fm(tmpFont); int tmpWidth = 0; for (QStringList::iterator it = text->begin(); it != text->end(); ++it) { if (fm.width(*it) > tmpWidth) tmpWidth = fm.width(*it); } fontSize = QSize(tmpWidth,fm.height()); } return result; } /** Used to paint the text on the map * @param p The painter used to paint the text * @param zone The zone the text is being painted in */ void CMapText::paint(QPainter *p,CMapZone *zone) { CMapElement::paint(p,zone); if (getEditMode()) { p->save(); p->translate(getX(),getY()); QFontMetrics fm(m_font); p->setPen(getManager()->getMapData()->defaultTextColor); p->setBrush(getManager()->getMapData()->defaultTextColor); int x = m_cursorOffset.x(); int y1 = m_cursorOffset.y(); int y2 = m_cursorOffset.y()-fm.height(); p->drawLine(x ,y1,x ,y2 ); p->restore(); } } /** Used to paint the element at a given location and size * @param p The painer to paint the element to * @param pos The position to paint the elmenet * @param size The size the element should be draw * @param zone The current zone being viewed */ void CMapText::paintElementResize(QPainter *p,QPoint pos,QSize size,CMapZone *) { paintText(p,m_col,pos,m_font,&m_text,size); } /** This is used to paint the text. It is capable of painting multiline * of text. It is static so that it can be called with out creating a instance of CMapText * @param p The painter used to paint the text * @param col The color to paint the text * @param pos The position to paint the text * @param font The Font used to paint the text * @param text A point to the text list * @param size The size of the text */ void CMapText::paintText(QPainter *p,QColor col,QPoint pos,QFont font,QStringList *text,QSize size) { QFont tmpFont = font; int fontSize = getActualToFontSize(size,font,text); tmpFont.setPointSize(fontSize); p->save(); p->translate(pos.x(),pos.y()); paintText(p,col,QPoint(0,0),tmpFont,text); p->restore(); } /** This is used to paint the text. It is capable of painting multiline of text */ void CMapText::paintText(QPainter *p,QColor col,QPoint pos,QFont font,QStringList *text) { QFontMetrics fm(font); pos.setY(pos.y()+fm.height()-fm.descent()); p->setPen(col); p->setBrush(col); p->setFont(font); for (QStringList::iterator it = text->begin(); it != text->end(); ++it) { p->drawText(pos,*it); pos.setY(pos.y()+fm.height()); } } /** This is used to set the cursor position within the text element * @param pos The cursor position */ void CMapText::setCursor(QPoint pos) { if (pos.y() > (int)m_text.count()) { // Set the cursor to the last position m_cursorPos.setX(QString(m_text.last()).length()); m_cursorPos.setY(m_text.count()); } else { m_cursorPos = pos; } setActualCursorPosition(); } /** This is used to conver a offset from the element orgin into a cursor position * @param offset The offset of the curosr */ QPoint CMapText::convertOffsetToCursor(QPoint offset) { QFontMetrics fm(m_font); int y = (int)(offset.y() / fm.height()); int x = 0; QString s = m_text.at(y); if (s.length()>0) { bool found = false; for (int pos = 0 ; pos <=(int)s.length() ; pos ++) { int charWidth =fm.width(s.left(pos)); if (charWidth>offset.x()) { x = pos -1; found = true; break; } } if (!found) { x = (int)fm.width(s); } } return QPoint(x,y+1); } /** This is used to convert mouse cordinates into a cursor position */ QPoint CMapText::convertPosToCursor(QPoint mousePos) { mousePos-=getLowPos(); return convertOffsetToCursor(mousePos); } /** This method is called when the element looses it's edit mode */ void CMapText::editModeUnsetEvent(void) { kDebug() << "CMapText::editModeUnsetEvent"; //FIXME_jp: Make sure elements are deleted if (m_text.count()==0) emit deleteElement((CMapElement *)this,true); else if (QString(m_text.first()).trimmed().length()==0 && m_text.count() == 1) emit deleteElement((CMapElement *)this,true); setTextSize(); // Update any elements linked with this one (zones/rooms with labels) updateLinkElements(); } /** This method is called when the element gains it's edit mode */ void CMapText::editModeSetEvent(void) { m_orgText = getText(); } /** This method is called to insert a string at the cursor position */ void CMapText::insertString(QString s) { QFontMetrics fm(m_font); QString str = m_text.at(m_cursorPos.y()-1); QString newStr; if ((int)str.length()>m_cursorPos.x()) { newStr = str.left(m_cursorPos.x()) + s + str.right(str.length() - (m_cursorPos.x())); } else { newStr = str.left(m_cursorPos.x()) + s; } m_text.removeAt(m_cursorPos.y()-1); m_text.insert(m_cursorPos.y()-1,newStr); m_cursorPos.setX(m_cursorPos.x()+s.length()); setTextSize(); } /** This will delete a character behind the cursor */ void CMapText::deleteChar(void) { QString str = m_text.at(m_cursorPos.y()-1); if ((int)str.length()>m_cursorPos.x()) { str.remove(m_cursorPos.x(),1); m_text.removeAt(m_cursorPos.y()-1); m_text.insert(m_cursorPos.y()-1,str); } else { if (m_cursorPos.y() < (int)m_text.count()) { QString str2 = m_text.at(m_cursorPos.y()); m_text.removeAt(m_cursorPos.y()); m_text.removeAt(m_cursorPos.y()-1); m_text.insert(m_cursorPos.y()-1,str + str2); } } } /** This will delete a character infront of the cursor */ void CMapText::backspace(void) { QFontMetrics fm(m_font); if (m_cursorPos.x()==0) { if (m_cursorPos.y()>1) { QString str = m_text.at(m_cursorPos.y()-1); m_text.removeAt(m_cursorPos.y()-1); QString str2 = m_text.at(m_cursorPos.y()-2); m_text.removeAt(m_cursorPos.y()-2); m_text.insert(m_cursorPos.y()-2,str2 + str); setCursor(QPoint(str2.length(),m_cursorPos.y()-1)); } } else { QString str = m_text.at(m_cursorPos.y()-1); if (str.length()>0) { str.remove(m_cursorPos.x()-1,1); m_text.removeAt(m_cursorPos.y()-1); m_text.insert(m_cursorPos.y()-1,str); m_cursorPos.setX(m_cursorPos.x()-1); setActualCursorPosition(); /* for (char *s = text.frist();s!=0; s= text.next()) { } if (getWidth() == oldWidth()) */ } } } /** this will insert a caridge return at the cursor */ void CMapText::insertCR(void) { QString str = m_text.at(m_cursorPos.y()-1); m_text.removeAt(m_cursorPos.y()-1); m_text.insert(m_cursorPos.y()-1,str.left(m_cursorPos.x())); m_text.insert(m_cursorPos.y(),str.right(str.length() - m_cursorPos.x())); m_cursorPos.setX(0); m_cursorPos.setY(m_cursorPos.y()+1); setActualCursorPosition(); } /** Move the cursor up */ void CMapText::cursorUp(void) { if (m_cursorPos.y()>1) { QFontMetrics fm(m_font); int y = m_cursorOffset.y()-fm.height()-fm.height(); setCursor(convertOffsetToCursor(QPoint(m_cursorOffset.x(),y))); } } /** Move the cursor down */ void CMapText::cursorDown(void) { if (m_cursorPos.y()<(int)m_text.count()) { QFontMetrics fm(m_font); int y = m_cursorOffset.y(); QPoint p = convertOffsetToCursor(QPoint(m_cursorOffset.x(),y)); setCursor(p); } } /** Move the cursor right */ void CMapText::cursorRight(void) { int x = m_cursorPos.x(); QString str = m_text.at(m_cursorPos.y()-1); if (x<(int)str.length()) { m_cursorPos.setX(x+1); setActualCursorPosition(); } } /** Move the cursor left */ void CMapText::cursorLeft(void) { int x = m_cursorPos.x(); if (x>0) { m_cursorPos.setX(x-1); setActualCursorPosition(); } } /** Move the cursor to the end */ void CMapText::cursorEnd(void) { QString str = m_text.at(m_cursorPos.y()-1); m_cursorPos.setX(str.length()); setActualCursorPosition(); } /** This method is called to restore the orginal text of the element. When editing, if * esc is pressed, then this method is called to restore the text to the value it had * before editing */ void CMapText::restoreText(void) { setText(m_orgText); } /** This used internaly to calculate the offset of the cursor */ void CMapText::setActualCursorPosition(void) { QFontMetrics fm(m_font); int y = fm.height() * m_cursorPos.y(); int x = 0; if ((m_text.count() >= m_cursorPos.y()) && (m_cursorPos.y() > 0)) { QString s = m_text.at(m_cursorPos.y()-1); x = fm.width(s.left(m_cursorPos.x())); } m_cursorOffset.setX(x); m_cursorOffset.setY(y); } /** This is used to get the cursor position * @return The cursor position */ QPoint CMapText::getCursor(void) { return m_cursorPos; } /** This method is over ridden from CMapElement::paint. It is used * draw the text on the map. * @param p A pointer to the paint device the text is to be drawn on */ void CMapText::setColor(QColor color) { m_col = color; } /** This is used to return the color of the text * @return The color of the text */ QColor CMapText::getColor(void) { return m_col; } /** Used to set the font of the text. This font is used when drawing the text. * @param f The required font of the text */ void CMapText::setFont(QFont f) { m_font = f; setTextSize(); } /** This menthod will return the font used to display the text * @return The font used to display text */ QFont CMapText::getFont(void) { return m_font; } /** Gets the text of the text element * @return The text */ QString CMapText::getText(void) { return m_text.join ("\n"); } /** Sets the text of the text element * @param str The new string that the text element should be set to */ void CMapText::setText(QString str) { stringToList(str,&m_text); setTextSize(); } /** This method is used to convert a text string into a text list * @param str The string of text * @param textList The list to add the text to */ void CMapText::stringToList(QString str,QStringList *textList) { textList->clear(); if (str.isEmpty()) { textList->append(""); } else { int oldIndex = 0; int index = str.indexOf('\n'); while(index!=-1) { textList->append(str.mid(oldIndex,index-oldIndex )); oldIndex = index + 1; index = str.indexOf('\n', oldIndex); } textList->append(str.right(str.length()-oldIndex)); } } /** This method is used to update the size of the text element */ void CMapText::setTextSize(void) { QFontMetrics fm(m_font); int width = 0; int height = 0; for (QStringList::iterator it = m_text.begin(); it != m_text.end(); ++it) { if (fm.width(*it)>width) width = fm.width(*it); height+=fm.height(); } if (height < 10) height = 10; if (width < 10) width = 10; QRect rect = getRect(); rect.setWidth(width); rect.setHeight(height); setRect(rect); setActualCursorPosition(); } void CMapText::updateLinkElements(void) { if (m_linkElement) { if (m_linkElement->getElementType()==ROOM) { CMapRoom *room = (CMapRoom *)m_linkElement; room->setLabel(QString(m_text.first())); room->setLabelPosition(room->getLabelPosition()); } if (m_linkElement->getElementType()==ZONE) { CMapZone *zone = (CMapZone *)m_linkElement; zone->setLabel(QString(m_text.first())); zone->setLabelPosition(zone->getLabelPosition()); } } } /** This is used to create a new copy of the text element and return * a pointer to the new text element * @return A pointer to the copy of the text element. */ CMapElement *CMapText::copy(void) { CMapText *newText = new CMapText (getText(),getFont(),getColor(),getManager(),getLowPos(),getLevel()); return newText; } /** Used to load the properties of the element from a list of properties */ void CMapText::loadProperties(KConfigGroup properties) { CMapElement::loadProperties(properties); setText(properties.readEntry("Text",getText())); QColor color=getColor(); color=properties.readEntry("Color",color); setColor(color); QFont font = getFont(); font = properties.readEntry("Font",font); setFont(font); if (properties.hasKey("LinkedType")) { CMapLevel *level = getManager()->findLevel(properties.readEntry("LinkedLevel",-1)); if (level) { elementTyp typ = (elementTyp)properties.readEntry("LinkedType",(int)OTHER); if (typ == ROOM) { CMapRoom *room = level->findRoom(properties.readEntry("LinkedID",-1)); room->setLabelPosition((CMapRoom::labelPosTyp)properties.readEntry("LabelPos",(int)CMapRoom::HIDE),this); } } } setTextID(properties.readEntry("TextID",m_ID)); } /** Used to save the properties of the element to a list of properties */ void CMapText::saveProperties(KConfigGroup properties) { CMapElement::saveProperties(properties); properties.writeEntry("Text",getText()); properties.writeEntry("Color",getColor()); properties.writeEntry("Font",getFont()); properties.writeEntry("TextID",getTextID()); if (m_linkElement) { properties.writeEntry("LinkedType",(int)m_linkElement->getElementType()); if (m_linkElement->getElementType()==ROOM) { CMapRoom *room = (CMapRoom *)m_linkElement; properties.writeEntry("LinkedLevel",room->getLevel()->getLevelID()); properties.writeEntry("LinkedID",room->getRoomID()); properties.writeEntry("LabelPos",(int)room->getLabelPosition()); } } } /** Used to save the element as an XML object * @param properties The XML object to save the properties too * @param doc The XML Document */ void CMapText::saveQDomElement(QDomDocument *doc,QDomElement *properties) { writeColor(doc,properties,"Color",getColor()); CMapElement::saveQDomElement(doc,properties); properties->setAttribute("Text",getText()); properties->setAttribute("Font",getFont().toString()); properties->setAttribute("TextID",getTextID()); } /** Used to load the properties from a XML object * @param properties The XML object to load the properties from */ void CMapText::loadQDomElement(QDomElement *properties) { CMapElement::loadQDomElement(properties); setColor(readColor(properties,"Color",getColor())); setText(properties->attribute("Text",getText())); setTextID(readInt(properties,"TextID",getTextID())); QFont font; font.fromString(properties->attribute("Font")); setFont(font); } void CMapText::setTextID(unsigned int id) { if (id > getZone()->m_text_id_count) getZone()->m_text_id_count = id; m_ID = id; } diff --git a/plugins/mapper/cmapwidget.cpp b/plugins/mapper/cmapwidget.cpp index 550734c..83bef69 100644 --- a/plugins/mapper/cmapwidget.cpp +++ b/plugins/mapper/cmapwidget.cpp @@ -1,417 +1,416 @@ /*************************************************************************** cmapwidget.cpp ------------------- begin : Sun Mar 18 2001 copyright : (C) 2001 by Kmud Developer Team email : kmud-devel@kmud.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "cmapwidget.h" #include -#include #include #include #include #include #include "cmapmanager.h" #include "cmapzone.h" #include "cmaplevel.h" #include "cmappath.h" #include "cmapcmdelementproperties.h" #include "cmapview.h" #include "cmaptoolbase.h" #include "cmappluginbase.h" static unsigned char move_bits[] = { 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01, 0x84, 0x21, 0x86, 0x61, 0xff, 0xff, 0xff, 0xff, 0x86, 0x61, 0x84, 0x21, 0x80, 0x01, 0x80, 0x01, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01}; CMapWidget::CMapWidget(CMapView *view,CMapManager *manager,QWidget *parent) : QWidget(parent) { // Setup vars viewWidget = view; bMouseDrag = false; QBitmap mouseDragCursorShape = QBitmap::fromData (QSize(16,16), move_bits); mouseDragCursor = new QCursor( mouseDragCursorShape, mouseDragCursorShape, -1,-1); mapManager = manager; initContexMenus(); // FIXME_jp : set to proper size instead of test size // Setup scrollview setFocusPolicy(Qt::StrongFocus); setMouseTracking(true); setFocus(); } CMapWidget::~CMapWidget() { viewWidget = NULL; } /** Used to create the element context menus */ void CMapWidget::initContexMenus(void) { - room_menu = (Q3PopupMenu *)getView()->guiFactory()->container("room_popup",getView()); - text_menu = (Q3PopupMenu *)getView()->guiFactory()->container("text_popup",getView()); - path_menu = (Q3PopupMenu *)getView()->guiFactory()->container("path_popup",getView()); - empty_menu = (Q3PopupMenu *)getView()->guiFactory()->container("empty_popup",getView()); + room_menu = (QMenu *)getView()->guiFactory()->container("room_popup",getView()); + text_menu = (QMenu *)getView()->guiFactory()->container("text_popup",getView()); + path_menu = (QMenu *)getView()->guiFactory()->container("path_popup",getView()); + empty_menu = (QMenu *)getView()->guiFactory()->container("empty_popup",getView()); } /** Used to get the views */ CMapView *CMapWidget::getView(void) { return viewWidget; } /** draw the map widget */ void CMapWidget::paintEvent(QPaintEvent *ev) { QPainter p(this); CMapZone *zone = viewWidget->getCurrentlyViewedZone(); QColor color = zone->getUseDefaultBackground() ? mapManager->getMapData()->backgroundColor : zone->getBackgroundColor(); p.fillRect(ev->rect(), color); drawGrid(&p); drawElements(&p); mapManager->getCurrentTool()->paint(&p); } bool CMapWidget::event(QEvent *e) { if (e->type() == QEvent::ToolTip) { QHelpEvent *helpEvent = static_cast(e); QPoint point = helpEvent->pos(); CMapView *view = getView(); CMapLevel *level = view->getCurrentlyViewedLevel(); CMapElement *element = level ? level->findElementAt(point) : 0; QString s; if (element) { if (element->getElementType() == ROOM) { s = ((CMapRoom*)element)->getLabel(); } else if (element->getElementType() == ZONE) { s = ((CMapZone*)element)->getLabel(); } if (!s.trimmed().isEmpty()) QToolTip::showText (helpEvent->globalPos(), s, this); else QToolTip::hideText (); } } return QWidget::event(e); } /** Draw the grid if it's visible */ void CMapWidget::drawGrid(QPainter* p) { if (!mapManager->getMapData()->gridVisable) return; p->setPen(mapManager->getMapData()->gridColor); QSize gridSize = mapManager->getMapData()->gridSize; int maxx = width(); int maxy = height(); // Draw the lines going across for (int y = 0; y <= maxy; y += gridSize.width()) p->drawLine(0, y, maxx, y); // Draw the lines going down for (int x = 0; x <= maxx; x += gridSize.height()) p->drawLine(x, 0, x, maxy); } /** Used to draw all the elments */ void CMapWidget::drawElements(QPainter *p) { CMapLevel *level = viewWidget->getCurrentlyViewedLevel(); if (!level) return; CMapLevel *lowerLevel = level->getPrevLevel(); CMapLevel *upperLevel = level->getNextLevel(); // Mark all paths as undrawn foreach (CMapRoom *room, *level->getRoomList()) foreach (CMapPath *path, *room->getPathList()) path->setDone(false); if (lowerLevel && mapManager->getMapData()->showLowerLevel) { foreach (CMapRoom *room, *lowerLevel->getRoomList()) foreach (CMapPath *path, *room->getPathList()) path->setDone(false); } if (upperLevel && mapManager->getMapData()->showUpperLevel) { foreach (CMapRoom *room, *upperLevel->getRoomList()) foreach (CMapPath *path, *room->getPathList()) path->setDone(false); } // Draw the upper map elements if (lowerLevel && mapManager->getMapData()->showLowerLevel) foreach (CMapElement *element, lowerLevel->getAllElements()) element->lowerPaint(p, viewWidget->getCurrentlyViewedZone()); // Paint the map elements of the current map foreach (CMapElement *element, level->getAllElements()) if (element->getDoPaint()) element->paint(p, viewWidget->getCurrentlyViewedZone()); // Draw the upper map elements if (upperLevel && mapManager->getMapData()->showUpperLevel) { foreach (CMapElement *element, upperLevel->getAllElements()) element->higherPaint(p, viewWidget->getCurrentlyViewedZone()); } } /** The mouse release event */ void CMapWidget::mouseReleaseEvent(QMouseEvent *e) { QCursor* oldCursor; switch (e->button()) { case Qt::LeftButton: // Send the mouse event to the current tool mapManager->getCurrentTool()->mouseReleaseEvent(e->pos(),e,viewWidget->getCurrentlyViewedLevel()); break; case Qt::MidButton: bMouseDrag = false; oldCursor= new QCursor(cursor()); setCursor(*mouseDragCursor); delete mouseDragCursor; mouseDragCursor = oldCursor; break; default: break; } } void CMapWidget::showRoomContextMenu(void) { CMapRoom *room = (CMapRoom *) getView()->getSelectedElement(); KActionCollection *acol = getView()->actionCollection(); QAction *roomSetCurrentPos = acol->action("roomCurrentPos"); QAction *roomSetLogin = acol->action("roomLoginPoint"); KSelectAction *labelMenu=(KSelectAction *) acol->action("labelMenu"); roomSetCurrentPos->setEnabled(!room->getCurrentRoom()); roomSetLogin->setEnabled(!room->getLoginRoom()); switch(room->getLabelPosition()) { case CMapRoom::HIDE : labelMenu->setCurrentItem(0); break; case CMapRoom::NORTH : labelMenu->setCurrentItem(1); break; case CMapRoom::NORTHEAST : labelMenu->setCurrentItem(2); break; case CMapRoom::EAST : labelMenu->setCurrentItem(3); break; case CMapRoom::SOUTHEAST : labelMenu->setCurrentItem(4); break; case CMapRoom::SOUTH : labelMenu->setCurrentItem(5); break; case CMapRoom::SOUTHWEST : labelMenu->setCurrentItem(6); break; case CMapRoom::WEST : labelMenu->setCurrentItem(7); break; case CMapRoom::NORTHWEST : labelMenu->setCurrentItem(8); break; case CMapRoom::CUSTOM : labelMenu->setCurrentItem(9); break; } showContextMenu (room_menu); } void CMapWidget::showPathContextMenu(void) { CMapPath *path = (CMapPath *) getView()->getSelectedElement(); bool twoWay = path->getOpsitePath(); KActionCollection *acol = getView()->actionCollection(); KToggleAction *pathTwoWay = (KToggleAction *)acol->action("pathTwoWay"); KToggleAction *pathOneWay = (KToggleAction *)acol->action("pathOneWay"); QAction *pathEditBends = acol->action("pathEditBends"); QAction *pathDelBend = acol->action("pathDelBend"); QAction *pathAddBend = acol->action("pathAddBend"); pathTwoWay->setChecked(twoWay); pathOneWay->setChecked(!twoWay); CMapView *view = (CMapView *) viewWidget; pathDelBend->setEnabled(path->mouseInPathSeg(selectedPos,view->getCurrentlyViewedZone())!=-1); pathEditBends->setEnabled(path->getBendCount() > 0); pathAddBend->setEnabled(path->getSrcRoom()->getZone()==path->getDestRoom()->getZone()); showContextMenu (path_menu); } void CMapWidget::showTextContextMenu(void) { showContextMenu (text_menu); } void CMapWidget::showOtherContextMenu(void) { showContextMenu (empty_menu); } -void CMapWidget::showContextMenu(Q3PopupMenu *menu) +void CMapWidget::showContextMenu(QMenu *menu) { CMapView *view = mapManager->getActiveView(); CMapElement *el = view->getSelectedElement(); popupMenu(el, menu, selectedPos); } void CMapWidget::showContexMenu(QMouseEvent *e) { CMapLevel *level = viewWidget->getCurrentlyViewedLevel(); if (!level) return; CMapView *view = mapManager->getActiveView(); view->setSelectedPos(e->pos()); selectedPos = e->pos(); view->setSelectedElement(0); CMapElement *element = level->findElementAt (e->pos()); if (!element) { showOtherContextMenu(); return; } view->setSelectedElement(element); mapManager->unsetEditElement(); switch(element->getElementType()) { case ROOM : showRoomContextMenu(); break; case PATH : showPathContextMenu(); break; case TEXT : showTextContextMenu(); break; default : showOtherContextMenu(); break; } } /** This method is used to tell the plugins a menu is about to open then open the menu */ -void CMapWidget::popupMenu(CMapElement *element,Q3PopupMenu *menu,QPoint pos) +void CMapWidget::popupMenu(CMapElement *element,QMenu *menu,QPoint pos) { if (element) { for (CMapPluginBase *plugin = mapManager->getPluginList()->first();plugin!=0;plugin = mapManager->getPluginList()->next()) plugin->beforeOpenElementMenu(element); } menu->popup(mapToGlobal(pos)); } /** This is called when the mouse leaves the widget */ void CMapWidget::leaveEvent(QEvent *) { // Send the mouse event to the current tool mapManager->getCurrentTool()->mouseLeaveEvent(); } /** This is called when the mouse enters the widget */ void CMapWidget::enterEvent(QEvent *) { // Send the mouse event to the current tool mapManager->getCurrentTool()->mouseEnterEvent(); } /** The mouse press event */ void CMapWidget::mousePressEvent(QMouseEvent *e) { QCursor* oldCursor; switch (e->button()) { case Qt::RightButton: showContexMenu(e); break; case Qt::MidButton: bMouseDrag = true; nMouseDragPosX = e->globalX(); nMouseDragPosY = e->globalY(); oldCursor = new QCursor(cursor()); setCursor(*mouseDragCursor); delete mouseDragCursor; mouseDragCursor = oldCursor; break; case Qt::LeftButton: // Send the mouse event to the current tool //p.begin(viewport()); //p.translate(-contentsX(),-contentsY()); mapManager->getCurrentTool()->mousePressEvent(e->pos(),e,viewWidget->getCurrentlyViewedLevel()); //p.end(); default: break; } } void CMapWidget::mouseDoubleClickEvent(QMouseEvent *e) { mapManager->getCurrentTool()->mouseDoubleClickEvent(e->pos(), e, viewWidget->getCurrentlyViewedLevel()); } /** Called when the mouse is being moved */ void CMapWidget::mouseMoveEvent(QMouseEvent *e) { if (bMouseDrag) { int dx, dy; dx = e->globalX() - nMouseDragPosX; dy = e->globalY() - nMouseDragPosY; nMouseDragPosX = e->globalX(); nMouseDragPosY = e->globalY(); QScrollArea *parent = (QScrollArea *) parentWidget(); QScrollBar *sx = parent->horizontalScrollBar(); QScrollBar *sy = parent->verticalScrollBar(); sx->setValue(sx->value() + dx*3); sy->setValue(sy->value() + dy*3); } else { // Send the mouse event to the current tool mapManager->getCurrentTool()->mouseMoveEvent(e->pos(),e->button(),viewWidget->getCurrentlyViewedLevel()); } } /** Called when a key is pressed */ void CMapWidget::keyPressEvent(QKeyEvent *e) { mapManager->getCurrentTool()->keyPressEvent(e); } /** Called when a key is released */ void CMapWidget::keyReleaseEvent(QKeyEvent *e) { mapManager->getCurrentTool()->keyReleaseEvent(e); } diff --git a/plugins/mapper/cmapwidget.h b/plugins/mapper/cmapwidget.h index 70eacf8..dd345f8 100644 --- a/plugins/mapper/cmapwidget.h +++ b/plugins/mapper/cmapwidget.h @@ -1,122 +1,116 @@ /*************************************************************************** cmapwidget.h ------------------- begin : Sun Mar 18 2001 copyright : (C) 2001 by Kmud Developer Team email : kmud-devel@kmud.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CMAPWIDGET_H #define CMAPWIDGET_H -#include +#include #include -#include -#include -//Added by qt3to4: -#include -#include -#include -#include -#include +#include +#include #include #include class CMapManager; class CMapElement; class CMapLevel; class CMapView; /**This is that map widget used for displaying a view of the map *@author Kmud Developer Team */ class CMapWidget : public QWidget { Q_OBJECT public: CMapWidget(CMapView *view,CMapManager *manager,QWidget *parent=0); virtual ~CMapWidget(); /** Used to get the views */ CMapView *getView(void); protected: /** This is used to display custop tooltips. */ bool event (QEvent *e); /** This is called when the mouse leaves the widget */ void leaveEvent(QEvent *e); /** This is called when the mouse enters the widget */ void enterEvent(QEvent *e); /** draw the map widget */ void paintEvent(QPaintEvent *); /** The mouse release event */ void mouseReleaseEvent(QMouseEvent *e); /** The mouse press event */ void mousePressEvent(QMouseEvent *e); /** Called when the mouse is being moved */ void mouseMoveEvent(QMouseEvent *e); /** double click event */ void mouseDoubleClickEvent(QMouseEvent *e); /** Called when a key is pressed */ virtual void keyPressEvent(QKeyEvent *e); /** Called when a key is released */ virtual void keyReleaseEvent(QKeyEvent *e); /** Used to display the text context menu */ void showTextContextMenu(void); /** Used to display the path context menu */ void showPathContextMenu(void); /** Used to display the Room context menu */ void showRoomContextMenu(void); /** Used to display the context menu for other / no elements */ void showOtherContextMenu(void); - void showContextMenu(Q3PopupMenu *menu); + void showContextMenu(QMenu *menu); /** Draw the map elements */ virtual void drawElements(QPainter *p); /** Draw the grid if it's visible */ virtual void drawGrid(QPainter* p); private: /** Show the context menus */ void showContexMenu(QMouseEvent *e); /** Used to create the element context menus */ void initContexMenus(void); /** This method is used to tell the plugins a menu is about to open then open the menu */ - void popupMenu(CMapElement *element,Q3PopupMenu *menu,QPoint pos); + void popupMenu(CMapElement *element,QMenu *menu,QPoint pos); friend class CMapView; private: QPoint selectedPos; /** true when the map is being moved by mouse */ bool bMouseDrag; /** y position of last mouse drag event */ int nMouseDragPosY; /** x position of last mouse drag event */ int nMouseDragPosX; /** The Cursor used when move draging the map */ QCursor* mouseDragCursor; // Menus - Q3PopupMenu *room_menu; - Q3PopupMenu *path_menu; - Q3PopupMenu *text_menu; - Q3PopupMenu *empty_menu; + QMenu *room_menu; + QMenu *path_menu; + QMenu *text_menu; + QMenu *empty_menu; /** A pointer to the map manager */ CMapManager *mapManager; /** A pointer to the mapview */ CMapView *viewWidget; }; #endif diff --git a/plugins/mapper/dialogs/dlgmaproomproperties.cpp b/plugins/mapper/dialogs/dlgmaproomproperties.cpp index f522ebb..70d8d0d 100644 --- a/plugins/mapper/dialogs/dlgmaproomproperties.cpp +++ b/plugins/mapper/dialogs/dlgmaproomproperties.cpp @@ -1,299 +1,298 @@ /*************************************************************************** dlgmaproomproperties.cpp - description ------------------- begin : Thu Mar 8 2001 copyright : (C) 2001 by KMud Development Team email : kmud-devel@kmud.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dlgmaproomproperties.h" #include "../cmaproom.h" #include "../cmappath.h" #include "../cmapmanager.h" #include "../cmapcmdelementcreate.h" #include "../cmapcmdelementdelete.h" #include "../cmapcmdelementproperties.h" #include "../cmapcmdgroup.h" #include "../cmappluginbase.h" #include "../cmappropertiespanebase.h" #include -#include #include #include #include #include #include #include #include #include #include DlgMapRoomProperties::DlgMapRoomProperties(CMapManager *manager,CMapRoom *roomElement,QWidget *parent ) : QDialog(parent) { setupUi (this); connect(this, SIGNAL(accepted()), this, SLOT(slotAccept())); room = roomElement; mapManager = manager; // Populate the dialog txtLabel->setText(room->getLabel()); txtDescription->setText(room->getDescription()); cmdRoomColor->setColor(room->getColor()); slotUseDefaultColor(room->getUseDefaultCol()); setLabelPos(room->getLabelPosition()); lstContents->addItems(*room->getContentsList()); regenerateExits(); // Get the extension panels from the plugins QList paneList = mapManager->createPropertyPanes(ROOM,(CMapElement*)roomElement,(QWidget *)RoomsTab); foreach (CMapPropertiesPaneBase *pane, paneList) { RoomsTab->addTab(pane,pane->getTitle()); connect(cmdOk,SIGNAL(clicked()),pane,SLOT(slotOk())); connect(cmdCancel,SIGNAL(clicked()),pane,SLOT(slotCancel())); } } DlgMapRoomProperties::~DlgMapRoomProperties() { } void DlgMapRoomProperties::regenerateExits(void) { lstPaths->clear(); QTreeWidgetItem *item = nullptr; foreach (CMapPath *path, *room->getPathList()) { QString direction = mapManager->directionToText(path->getSrcDir(),path->getSpecialCmd()); kDebug() << "Path : " << path->getSrcDir() << "," << path->getSpecialCmd() << "," << direction; item = new QTreeWidgetItem(); item->setText(0, direction); item->setText(1, path->getBeforeCommand()); item->setText(2, path->getAfterCommand()); lstPaths->addTopLevelItem(item); } if (item) lstPaths->setCurrentItem(item); } void DlgMapRoomProperties::slotAccept() { CMapCmdElementProperties *command = new CMapCmdElementProperties(mapManager,i18n("Changed Room Properties"),room); command->compare("Label",room->getLabel(),txtLabel->text().trimmed()); command->compare("Description",room->getDescription(),txtDescription->text().trimmed()); command->compare("Color",room->getColor(),cmdRoomColor->color()); command->compare("DefaultColor",room->getUseDefaultCol(),chkUseDefaltColor->isChecked()); command->compare("LabelPos",(int)room->getLabelPosition(),(int)getLabelPos()); QStringList newContents; for (int i = 0; i < lstContents->count(); ++i) { QString text = lstContents->item(i)->text().trimmed(); if (text.length()) newContents += text; } command->compare("Contents",*room->getContentsList(),newContents); QList wipe; foreach (CMapPath *path, *room->getPathList()) { QString name = mapManager->directionToText(path->getSrcDir(),path->getSpecialCmd()); bool found = false; for (int i = 0; i < lstPaths->topLevelItemCount(); ++i) if (lstPaths->topLevelItem(i)->text(0) == name) found = true; if (!found) wipe.push_back(path); } foreach (CMapPath *path, wipe) mapManager->deleteElement(path); mapManager->addCommand(command); } void DlgMapRoomProperties::slotUseDefaultColor(bool useDefaultColor) { chkUseDefaltColor->setChecked(useDefaultColor); cmdRoomColor->setEnabled(!useDefaultColor); lblRoomColor->setEnabled(!useDefaultColor); } void DlgMapRoomProperties::setLabelPos(CMapRoom::labelPosTyp position) { cmdN->setChecked(false); cmdNE->setChecked(false); cmdE->setChecked(false); cmdSE->setChecked(false); cmdS->setChecked(false); cmdSW->setChecked(false); cmdW->setChecked(false); cmdNW->setChecked(false); cmdHide->setChecked(false); cmdCustom->setChecked(false); switch (position) { case CMapRoom::NORTH : cmdN->setChecked(true); break; case CMapRoom::NORTHEAST : cmdNE->setChecked(true); break; case CMapRoom::EAST : cmdE->setChecked(true); break; case CMapRoom::SOUTHEAST : cmdSE->setChecked(true); break; case CMapRoom::SOUTH : cmdS->setChecked(true); break; case CMapRoom::SOUTHWEST : cmdSW->setChecked(true); break; case CMapRoom::WEST : cmdW->setChecked(true); break; case CMapRoom::NORTHWEST : cmdNW->setChecked(true); break; case CMapRoom::HIDE : cmdHide->setChecked(true); break; case CMapRoom::CUSTOM : cmdCustom->setChecked(true); break; } } CMapRoom::labelPosTyp DlgMapRoomProperties::getLabelPos(void) { if (cmdN->isChecked()) return CMapRoom::NORTH; if (cmdE->isChecked()) return CMapRoom::EAST; if (cmdS->isChecked()) return CMapRoom::SOUTH; if (cmdW->isChecked()) return CMapRoom::WEST; if (cmdNE->isChecked()) return CMapRoom::NORTHEAST; if (cmdSE->isChecked()) return CMapRoom::SOUTHEAST; if (cmdSW->isChecked()) return CMapRoom::SOUTHWEST; if (cmdNW->isChecked()) return CMapRoom::NORTHWEST; if (cmdHide->isChecked()) return CMapRoom::HIDE; if (cmdCustom->isChecked()) return CMapRoom::CUSTOM; return CMapRoom::HIDE; } void DlgMapRoomProperties::slotE() { setLabelPos(CMapRoom::EAST); } void DlgMapRoomProperties::slotHide() { setLabelPos(CMapRoom::HIDE); } void DlgMapRoomProperties::slotN() { setLabelPos(CMapRoom::NORTH); } void DlgMapRoomProperties::slotNE() { setLabelPos(CMapRoom::NORTHEAST); } void DlgMapRoomProperties::slotNW() { setLabelPos(CMapRoom::NORTHWEST); } void DlgMapRoomProperties::slotS() { setLabelPos(CMapRoom::SOUTH); } void DlgMapRoomProperties::slotSE() { setLabelPos(CMapRoom::SOUTHEAST); } void DlgMapRoomProperties::slotSW() { setLabelPos(CMapRoom::SOUTHWEST); } void DlgMapRoomProperties::slotW() { setLabelPos(CMapRoom::WEST); } void DlgMapRoomProperties::slotCustom() { setLabelPos(CMapRoom::CUSTOM); } void DlgMapRoomProperties::slotRemoveItem() { QListWidgetItem *item = lstContents->takeItem(lstContents->currentRow()); if (item) delete item; } void DlgMapRoomProperties::slotAddItem() { lstContents->addItem(QString()); lstContents->setCurrentRow(lstContents->count() - 1); } void DlgMapRoomProperties::slotNewItemSelected() { QList sel = lstContents->selectedItems(); if (!sel.count()) return; txtItemName->setText(sel.at(0)->text()); } void DlgMapRoomProperties::slotEditItemName(const QString & name) { QListWidgetItem *item = lstContents->currentItem(); if (item) item->setText(name); } void DlgMapRoomProperties::slotPathDelete() { QList sel = lstPaths->selectedItems(); foreach (QTreeWidgetItem *item, sel) delete item; } void DlgMapRoomProperties::slotPathProperties() { QTreeWidgetItem *item = lstPaths->currentItem(); int idx = lstPaths->indexOfTopLevelItem(item); if ((idx < 0) || (idx >= room->getPathList()->count())) return; CMapPath *path = room->getPathList()->at(idx); mapManager->propertiesPath(path); item->setText(0, mapManager->directionToText(path->getSrcDir(),path->getSpecialCmd())); item->setText(1, path->getBeforeCommand()); item->setText(2, path->getAfterCommand()); } diff --git a/plugins/mapper/dialogs/dlgmaptextproperties.cpp b/plugins/mapper/dialogs/dlgmaptextproperties.cpp index a7c09e3..c3a260f 100644 --- a/plugins/mapper/dialogs/dlgmaptextproperties.cpp +++ b/plugins/mapper/dialogs/dlgmaptextproperties.cpp @@ -1,268 +1,253 @@ /*************************************************************************** dlgmaptextproperties.cpp - description ------------------- begin : Thu Mar 8 2001 copyright : (C) 2001 by KMud Development Team email : kmud-devel@kmud.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dlgmaptextproperties.h" #include -#include #include #include #include -#include -#include #include #include #include #include #include +#include #include #include #include #include #include #include "../cmaptext.h" #include "../cmapmanager.h" #include "../cmapview.h" #include "../cmapcmdelementcreate.h" #include "../cmapcmdelementdelete.h" #include "../cmapcmdelementproperties.h" #include "../cmapcmdgroup.h" #include "../cmappluginbase.h" #include "../cmappropertiespanebase.h" #include CMapTextPreview::CMapTextPreview(CMapManager *manager,QWidget *parent) - : Q3ScrollView(parent, 0, Qt::WNorthWestGravity | Qt::WResizeNoErase | Qt::WRepaintNoErase) + : QWidget(parent, Qt::WNorthWestGravity | Qt::WResizeNoErase | Qt::WRepaintNoErase) { buffer = NULL; mapManager = manager; - - setHScrollBarMode(Auto); - setVScrollBarMode(Auto); } CMapTextPreview::~CMapTextPreview() { if (buffer) delete buffer; } void CMapTextPreview::drawContents(QPainter *paint,int , int , int, int ) { - int width,height; - - if (contentsWidth()>viewport()->width()) - width = contentsWidth(); - else - width = viewport()->width(); - - if (contentsHeight()>viewport()->height()) - height = contentsHeight(); - else - height = viewport()->height(); - - QRect drawArea(0,0,width,height); + QRect drawArea(0,0,width(),height()); // delete the buffer only when we need one with a different size if (buffer && (buffer->size() != drawArea.size())) { delete buffer; buffer = NULL; } if (!buffer) { buffer = new QPixmap(drawArea.size()); } QPainter p; p.begin(buffer); if (mapManager->getActiveView()->getCurrentlyViewedZone()->getUseDefaultBackground()) { p.fillRect(drawArea,mapManager->getMapData()->backgroundColor); } else { p.fillRect(drawArea,mapManager->getActiveView()->getCurrentlyViewedZone()->getBackgroundColor()); } QStringList textList; CMapText::stringToList(text,&textList); CMapText::paintText(&p,color,QPoint(0,0),font,&textList,size); paint->drawPixmap(0,0,*buffer); } DlgMapTextProperties::DlgMapTextProperties(CMapManager *manager,CMapText *textElement,QWidget *parent) : QDialog(parent) { setupUi (this); text = textElement; mapManager = manager; QString width; QString height; QVBoxLayout *vbox = new QVBoxLayout((QWidget *)fraPreview); textScrollView = new CMapTextPreview(mapManager,fraPreview); - vbox->addWidget( textScrollView); + QScrollArea *textScrollArea = new QScrollArea (fraPreview); + textScrollArea->setWidget (textScrollView); + vbox->addWidget( textScrollArea); textScrollView->show(); fillFamilyList(); setFont(text->getFont()); width.sprintf("%d",text->getWidth()); height.sprintf("%d",text->getHeight()); txtText->setText(text->getText()); txtWidth->setText(width); txtHeight->setText(height); cmdColor->setColor(text->getColor()); //FIXME_jp: set txtText background to background color of the map // Get the extension panels from the plugins QList paneList = mapManager->createPropertyPanes(TEXT,(CMapElement*)textElement,(QWidget *)TextTabs); foreach (CMapPropertiesPaneBase *pane, paneList) { TextTabs->addTab(pane,pane->getTitle()); connect(cmdOk,SIGNAL(clicked()),pane,SLOT(slotOk())); connect(cmdCancel,SIGNAL(clicked()),pane,SLOT(slotCancel())); } slotUpdatePreview(); } DlgMapTextProperties::~DlgMapTextProperties() { } void DlgMapTextProperties::fillFamilyList(void) { lstFamily->insertItems (0, QFontDatabase().families()); } void DlgMapTextProperties::setFont(QFont font) { textFont = font; QString family = font.family(); family = family.trimmed(); QString size; size.sprintf("%d",font.pointSize()); for (int i = 0 ; icount();i++) { QString s = lstFamily->item(i)->text(); if (s == family) { lstFamily->setCurrentRow(i); break; } } chkBold->setChecked(font.bold()); chkItalic->setChecked(font.italic()); lstFamily->scrollToItem(lstFamily->currentItem()); slotUpdatePreview(); } void DlgMapTextProperties::slotSetSize(void) { kDebug() << "CMapTextPreview::slotSetSize1 "; int fontSize = txtFontSize->text().toInt(); textFont.setPointSize(fontSize); QFontMetrics fm(textFont); QString width; QString height; QStringList textList; CMapText::stringToList(txtText->text(),&textList); int tmpWidth = 0; for (QStringList::iterator it = textList.begin(); it != textList.end(); ++it) { if (fm.width(*it) > tmpWidth) tmpWidth = fm.width(*it); } width.sprintf("%d",tmpWidth); height.sprintf("%d",fm.height() * textList.count()); txtWidth->setText(width); txtHeight->setText(height); txtFontSize->setText(""); slotUpdatePreview(); } void DlgMapTextProperties::slotBoldClicked(void) { textFont.setBold(chkBold->isChecked()); slotUpdatePreview(); } void DlgMapTextProperties::slotItalicClicked(void) { textFont.setItalic(chkItalic->isChecked()); slotUpdatePreview(); } void DlgMapTextProperties::slotFamilySelected() { textFont.setFamily(lstFamily->currentItem()->text()); slotUpdatePreview(); } void DlgMapTextProperties::slotColorChanged(const QColor &color) { textColor = color; slotUpdatePreview(); } void DlgMapTextProperties::slotAccept() { CMapCmdElementProperties *command = new CMapCmdElementProperties(mapManager,i18n("Changed Room Properties"),text); QStringList textList; int width = txtWidth->text().toInt(); int height = txtHeight->text().toInt(); command->compare("Text",text->getText(),txtText->text()); command->compare("Color",text->getColor(),textColor); command->compare("Font",text->getFont(),textFont); command->compare("Size",text->getSize(),QSize(width,height)); mapManager->addCommand(command); } void DlgMapTextProperties::slotUpdatePreview() { int gridWidth = mapManager->getMapData()->gridSize.width(); int gridHeight = mapManager->getMapData()->gridSize.height(); int width =txtWidth->text().toInt(); if (widthtext().toInt(); if (height < gridHeight) height = 20; textScrollView->setFont(textFont); textScrollView->setColor(textColor); textScrollView->setSize(QSize(width,height)); textScrollView->setText(txtText->text()); - textScrollView->resizeContents(txtWidth->text().toInt(),txtHeight->text().toInt()); - textScrollView->viewport()->update(); + textScrollView->resize(txtWidth->text().toInt(),txtHeight->text().toInt()); + textScrollView->update(); } diff --git a/plugins/mapper/dialogs/dlgmaptextproperties.h b/plugins/mapper/dialogs/dlgmaptextproperties.h index 0954472..90e9e32 100644 --- a/plugins/mapper/dialogs/dlgmaptextproperties.h +++ b/plugins/mapper/dialogs/dlgmaptextproperties.h @@ -1,88 +1,87 @@ /*************************************************************************** dlgmaptextproperties.h - description ------------------- begin : Thu Mar 8 2001 copyright : (C) 2001 by KMud Development Team email : kmud-devel@kmud.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DLGMAPTEXTPROPERTIES_H #define DLGMAPTEXTPROPERTIES_H #include #include #include -#include #include #include "ui_dlgmaptextpropertiesbase.h" class CMapText; class CMapManager; -class CMapTextPreview : public Q3ScrollView +class CMapTextPreview : public QWidget { public: CMapTextPreview(CMapManager *manager,QWidget *parent=0); ~CMapTextPreview(); void setColor(QColor textColor) { color = textColor; } void setFont(QFont textFont) { font = textFont; } void setSize(QSize textSize) { size = textSize; } void setText(QString strText) { text = strText; } protected: void drawContents(QPainter *paint,int , int , int, int ); //void paintEvent(QPaintEvent *e); private: QColor color; QFont font; QSize size; QString text; QPixmap *buffer; CMapManager *mapManager; }; /**The map text properties dialog *@author KMud Development Team */ class DlgMapTextProperties : public QDialog, private Ui::DlgMapTextPropertiesBase { Q_OBJECT public: DlgMapTextProperties(CMapManager *manager,CMapText *textElement,QWidget *parent=0); ~DlgMapTextProperties(); private: void fillFamilyList(void); void setFont(QFont font); private slots: void slotSetSize(void); void slotFamilySelected(); void slotItalicClicked(void); void slotBoldClicked(void); void slotColorChanged(const QColor &color); void slotAccept(); void slotUpdatePreview(); private: QColor textColor; QFont textFont; CMapText *text; CMapManager *mapManager; CMapTextPreview *textScrollView; }; #endif diff --git a/plugins/mapper/dialogs/dlgspeedwalkprogress.cpp b/plugins/mapper/dialogs/dlgspeedwalkprogress.cpp index 15efd74..7565864 100644 --- a/plugins/mapper/dialogs/dlgspeedwalkprogress.cpp +++ b/plugins/mapper/dialogs/dlgspeedwalkprogress.cpp @@ -1,50 +1,50 @@ /*************************************************************************** dlgspeedwalkprogress.cpp ------------------- begin : Wed May 30 2001 copyright : (C) 2001 by Kmud Developer Team email : kmud-devel@kmud.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "dlgspeedwalkprogress.h" -#include -#include +#include +#include DlgSpeedwalkProgress::DlgSpeedwalkProgress(QWidget *parent) : QDialog(parent) { setupUi (this); } DlgSpeedwalkProgress::~DlgSpeedwalkProgress() { } void DlgSpeedwalkProgress::setProgress(int progress) { - ProgressBar->setProgress(progress); + ProgressBar->setValue(progress); } int DlgSpeedwalkProgress::getTotalSteps(void) { - return ProgressBar->totalSteps(); + return ProgressBar->maximum(); } void DlgSpeedwalkProgress::setTotalSteps(int steps) { - ProgressBar->setTotalSteps(steps); + ProgressBar->setMaximum(steps); } void DlgSpeedwalkProgress::slotAbort() { emit abortSpeedwalk(); } diff --git a/plugins/mapper/dialogs/dlgspeedwalkprogressbase.ui b/plugins/mapper/dialogs/dlgspeedwalkprogressbase.ui index 919fbc3..b5a3feb 100644 --- a/plugins/mapper/dialogs/dlgspeedwalkprogressbase.ui +++ b/plugins/mapper/dialogs/dlgspeedwalkprogressbase.ui @@ -1,78 +1,72 @@ DlgSpeedwalkProgressBase 0 0 124 15 0 15 32767 15 Speedwalk Progress 0 6 30 15 x - + 32767 15 - - 100 - - - true - qPixmapFromMimeSource cmdAbort clicked() DlgSpeedwalkProgressBase slotAbort() diff --git a/plugins/mapper/filefilters/cmapfilefilterxml.cpp b/plugins/mapper/filefilters/cmapfilefilterxml.cpp index 96dcdaf..bbed6ca 100644 --- a/plugins/mapper/filefilters/cmapfilefilterxml.cpp +++ b/plugins/mapper/filefilters/cmapfilefilterxml.cpp @@ -1,706 +1,705 @@ /*************************************************************************** cmapfilefilterxml.cpp ------------------- begin : Tue Nov 19 2002 copyright : (C) 2002 by Kmud Developer Team email : kmud-devel@kmud.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "cmapfilefilterxml.h" #include #include #include #include #include #include #include -#include #include #include "../cmaproom.h" #include "../cmappath.h" #include "../cmaptext.h" #include "../cmapmanager.h" #include "../cmaplevel.h" #include "../cmapelementutil.h" #include "../cmappluginbase.h" #include CMapFileFilterXML::CMapFileFilterXML(CMapManager *manager) : CMapFileFilterBase(manager) { } CMapFileFilterXML::~CMapFileFilterXML() { } /** This returns name of the import/export filter. This should be kept small * @return The Name of the filter */ QString CMapFileFilterXML::getName(void) { return "KMuddy map xml filles (*.mapxml)"; } /** This returns a discription of the import/export filter * @return The discription */ QString CMapFileFilterXML::getDescription(void) { return "KMuddy save/load filter"; } /** This returns the extension of the filename that will be loaded,created * @return The exstension */ QString CMapFileFilterXML::getExtension(void) { return ".mapxml"; } /** This returns the pattern extension of the filename that will be loaded,created * @return The exstension */ QString CMapFileFilterXML::getPatternExtension(void) { return "*" + getExtension(); } #include /** This method should be reimplemented if this is a to be a export filter. It * is called to save the map data * @param url The url of the file to be saved * @return 0, The file was saved succesfully * @return -1, The file could not be created */ int CMapFileFilterXML::saveData(const QString &filename) { // Create the archive KZip zip(filename); if ( !zip.open( QIODevice::WriteOnly ) ) { return -1; } zip.setCompression(KZip::DeflateCompression); // Create the xml map file QString result = saveXMLFile(); if (!result.isEmpty()) { kDebug() << "Write map.xml : " << result.size(); zip.writeFile("map.xml", QString(), QString(), result.toLocal8Bit(), result.size()); kDebug() << "Done write"; } zip.close(); return result.isEmpty() ? -1 : 0; } QString CMapFileFilterXML::saveXMLFile() { for (CMapPluginBase *plugin = m_mapManager->getPluginList()->first(); plugin!=0; plugin = m_mapManager->getPluginList()->next()) { plugin->saveAboutToStart(); } // Create XML Document and add root node QDomDocument doc ("kmudmap"); QDomElement root = doc.createElement ("kmudmap"); doc.appendChild(root); // Write version QDomElement version = doc.createElement("Version"); version.setAttribute("Major",1); version.setAttribute("Minor",0); root.appendChild(version); // Write main header // Write the zone CMapZone *rootZone = m_mapManager->getZone(); saveZone(&doc,&root,rootZone); // Write Path Header QDomElement paths = doc.createElement("Paths"); root.appendChild(paths); // Write Links Header QDomElement links = doc.createElement("Links"); root.appendChild(links); // Write Paths saveZoneLinks(&doc,&paths,&links,m_mapManager->getZone()); // Write Speedwalk list // return the result return doc.toString(); } /** * This method is used to save the zone and all of it's sub elements * @param doc The document being the elemnts are saved too * @param rootNode The XML node to save the zone to * @param zone The zone to save */ void CMapFileFilterXML::saveZone(QDomDocument *doc,QDomNode *rootNode,CMapZone *zone) { // Save Zone QDomElement zoneProperties = doc->createElement("Zone"); zone->saveQDomElement(doc,&zoneProperties); savePluginPropertiesForElement(zone,doc,&zoneProperties); for (unsigned int idx = 0; idx < zone->levelCount(); ++idx) { CMapLevel *level = zone->getLevel(idx); QDomElement levelProperties = doc->createElement("Level"); levelProperties.setAttribute("ID",level->getLevelID()); levelProperties.setAttribute("Number",level->getNumber()); levelProperties.setAttribute("Name",level->getName()); levelProperties.setAttribute("NumRooms",level->getRoomList()->count()); levelProperties.setAttribute("NumTexts",level->getTextList()->count()); // Save Rooms foreach (CMapRoom* room, *level->getRoomList()) { QDomElement roomProperties = doc->createElement("Room"); room->saveQDomElement(doc,&roomProperties); savePluginPropertiesForElement(room,doc,&roomProperties); levelProperties.appendChild(roomProperties); } // Save Texts foreach (CMapText* text, *level->getTextList()) { QDomElement textProperties = doc->createElement("Text"); text->saveQDomElement(doc,&textProperties); savePluginPropertiesForElement(text,doc,&textProperties); levelProperties.appendChild(textProperties); } zoneProperties.appendChild(levelProperties); } rootNode->appendChild(zoneProperties); } /** * This method is used to save all the paths in a zone * @param doc The document being the paths are saved too * @param rootNode The XML node to save the paths to * @param zone The zone to save */ void CMapFileFilterXML::saveZoneLinks(QDomDocument *doc,QDomElement *pathsNode,QDomElement *linksNode,CMapZone *zone) { if (zone == NULL) return; std::set saved; // this ensures that we don't save bi-dir paths twice for (unsigned int idx = 0; idx < zone->levelCount(); ++idx) { CMapLevel *level = zone->getLevel(idx); foreach (CMapRoom *room, *level->getRoomList()) { foreach (CMapPath *path, *room->getPathList()) { if (saved.count(path)) continue; QDomElement pathElement = doc->createElement("Path"); path->saveQDomElement(doc,&pathElement); savePluginPropertiesForElement(path,doc,&pathElement); pathsNode->appendChild(pathElement); saved.insert(path); } } foreach (CMapText *text, *level->getTextList()) { CMapElement *element = text->getLinkElement(); if (element) { QDomElement linkElement = doc->createElement("Link"); linkElement.setAttribute("SrcType",text->getElementType()); linkElement.setAttribute("SrcLevel",text->getLevel()->getLevelID()); linkElement.setAttribute("SrcID",text->getTextID()); linkElement.setAttribute("DestType",element->getElementType()); linkElement.setAttribute("DestLevel",element->getLevel()->getLevelID()); if (element->getElementType()==ROOM) { linkElement.setAttribute("DestID",((CMapRoom *)element)->getRoomID()); linkElement.setAttribute("LabelPos",(int)((CMapRoom *)element)->getLabelPosition()); } linksNode->appendChild(linkElement); } } } } /** This method should be reimplemeted if this is to be a import filter. It is * called to load the map data * @param url The url of the file to be loaded * @return 0 , The file was loaded without problems * -1 , Could not open the file * -2 , If the file is corrupt * -4 , Wrong version */ int CMapFileFilterXML::loadData(const QString &filename) { KZip zip(filename); if ( !zip.open( QIODevice::ReadOnly ) ) { return -1; } int result = -1; const KArchiveDirectory* dir = zip.directory(); const KArchiveEntry *e = dir->entry("map.xml"); if (e->isFile()) { const KArchiveFile* mapFile = (KArchiveFile*)e; if (mapFile) { QByteArray arr( mapFile->data() ); result = loadXMLData(arr); } } zip.close(); return result; } /** This method should be reimplemeted if this is to be a import filter. It is * called to load the map data * @param url The url of the file to be loaded * @return 0 , The file was loaded without problems * -1 , Could not open the file * -2 , If the file is corrupt * -4 , Wrong version */ //int CMapFileFilterXML::loadXMLData(QString filename) int CMapFileFilterXML::loadXMLData(const QByteArray & buffer) { // TODO_jp : Make sure Zone ID and level ID max value is set corretly QDomDocument doc ("map"); if (!doc.setContent( buffer)) { kDebug() << "Unable to open the map file, not a valid xml document"; // file.close(); return -1; } for (CMapPluginBase *plugin = m_mapManager->getPluginList()->first(); plugin!=0; plugin = m_mapManager->getPluginList()->next()) { plugin->loadAboutToStart(); } QDomElement docElem = doc.documentElement(); // Check that this version of the file can be loaded QDomElement e = readChildElement(&docElem,"Version"); if (!e.isNull()) { QString major = e.attribute("Major",""); QString minor = e.attribute("Minor",""); if (major != "1" || minor != "0") { //TODO_jp : Output error message kDebug() << "This version can't be loaded"; return -4; } } else { //TODO_jp : Output error message kDebug() << "Unable to find version"; return -2; } // Find Root Zone QDomElement rootZoneNode = readChildElement(&docElem,"Zone"); if (rootZoneNode.isNull()) { //TODO_jp : Output error message kDebug() << "Unable to find root zone"; return -2; } // Load Root Zone int errorZone =loadZone(&rootZoneNode); if (errorZone!=0) { return errorZone; } // Find Paths QDomElement pathsNode = readChildElement(&docElem,"Paths"); if (pathsNode.isNull()) { //TODO_jp : Output error message kDebug() << "Unable to find paths"; return -2; } // Load Paths int errorPath = loadPaths(&pathsNode); if (errorPath!=0) { return errorPath; } // Find Links QDomElement linksNode = readChildElement(&docElem,"Links"); if (pathsNode.isNull()) { //TODO_jp : Output error message kDebug() << "Unable to find links"; return -2; } int errorLinks = loadLinks(&linksNode); if (errorLinks!=0) { return errorLinks; } // Return no error return 0; } /** This method is used to load all of the links * @param pathsNode The XML node to load the links from * @return 0 , The file was loaded without problems * -2 , If the file is corrupt */ int CMapFileFilterXML::loadLinks(QDomElement *pathsNode) { QDomNode n = pathsNode->firstChild(); while (!n.isNull() ) { QDomElement e = n.toElement(); if (e.isNull() ) { kDebug() << "Unable to find link element "; return -2; } if (e.tagName()=="Link") { int srcLevelID = e.attribute("SrcLevel","-2").toInt(); int destLevelID = e.attribute("DestLevel","-2").toInt(); if (srcLevelID == -2 || destLevelID == -2) { kDebug() << "Unable to find link end points"; return -2; } CMapLevel *srcLevel = m_mapManager->findLevel(srcLevelID); CMapLevel *destLevel = m_mapManager->findLevel(destLevelID); int textID = e.attribute("SrcID","-2").toInt(); int destID = e.attribute("DestID","-2").toInt(); int labelPos = e.attribute("LabelPos","0").toInt(); int srcTyp = e.attribute("SrcType","-2").toInt(); int destTyp = e.attribute("DestType","-2").toInt(); if (textID == -2 || destID == -2 || destTyp == -2 || srcTyp == -2) { kDebug() << "Unable to find link end points"; return -2; } if (srcTyp == (int)TEXT) { CMapText *text = srcLevel->findText(textID); if (destTyp==(int)ROOM) { CMapRoom *destElement = destLevel->findRoom(destID); destElement->setLabelPosition((CMapRoom::labelPosTyp)labelPos,text); } } } n = n.nextSibling(); } return 0; } /** This method is used to load all of the paths * @param pathsNode The XML node to load the paths from * @return 0 , The file was loaded without problems * -2 , If the file is corrupt */ int CMapFileFilterXML::loadPaths(QDomElement *pathsNode) { bool first = true; QDomNode n; do { n = first ? pathsNode->firstChild() : n.nextSibling(); if (n.isNull()) break; first = false; QDomElement e = n.toElement(); if (e.tagName() != "Path") continue; int srcLevelID = e.attribute("SrcLevel","-2").toInt(); int destLevelID = e.attribute("DestLevel","-2").toInt(); if (srcLevelID == -2 || destLevelID == -2) { kDebug() << "Unable to find path end points"; continue; } CMapLevel *srcLevel = m_mapManager->findLevel(srcLevelID); CMapLevel *destLevel = m_mapManager->findLevel(destLevelID); int srcRoomID = e.attribute("SrcRoom","-2").toInt(); int destRoomID = e.attribute("DestRoom","-2").toInt(); if (destRoomID == -2 || srcRoomID == -2) { kDebug() << "Unable to find path end points"; continue; } CMapRoom *srcRoom = srcLevel->findRoom(srcRoomID); CMapRoom *destRoom = destLevel->findRoom(destRoomID); if (srcRoom==NULL || destRoom==NULL) { kDebug() << "Src or Dest room is NULL while creating path"; continue; } directionTyp srcDir = (directionTyp)e.attribute("SrcDir","0").toInt(); directionTyp destDir = (directionTyp)e.attribute("DestDir","0").toInt(); QString specialCmd = e.attribute("SpecialCmd", QString()); if (srcRoom->getPathTarget(srcDir, specialCmd)) { kDebug() << "Duplicate path, ignoring"; continue; } CMapPath *path = m_mapManager->createPath(srcRoom,srcDir,destRoom,destDir,false,false); path->loadQDomElement(&e); loadPluginPropertiesForElement(path,&e); } while (!n.isNull()); kDebug() << "loadPaths Here 4"; return 0; } /** * This method is used to load the zone and all of it's sub elememnts * @param zoneNode The XML node to load the zone from * @param intoLevel The level to create the zone in * @return 0 , The file was loaded without problems * -2 , If the file is corrupt */ int CMapFileFilterXML::loadZone(QDomElement *zoneNode) { int gridWidth = m_mapManager->getMapData()->gridSize.width(); int gridHeight = m_mapManager->getMapData()->gridSize.height(); // Wipe the default level. while (m_mapManager->getZone()->levelCount()) delete m_mapManager->getZone()->firstLevel(); QDomNode n = zoneNode->firstChild(); while (!n.isNull() ) { QDomElement e = n.toElement(); if (e.isNull() ) { kDebug() << "Unable to find element "; return -2; } if (e.tagName()=="Level") { CMapLevel *level = m_mapManager->createLevel(UP); QString id = e.attribute("ID","-2"); if (id=="-2") { kDebug() << "Unable to find level ID"; return -2; } level->setLevelID(id.toInt()); level->setName(e.attribute("Name", "")); QDomNode n2 = e.firstChild(); while (!n2.isNull() ) { QDomElement e2 = n2.toElement(); if (e2.isNull() ) { kDebug() << "Unable to find element "; return -2; } int x1 = e2.attribute("X",QString::number(-1)).toInt(); int y1 = e2.attribute("Y",QString::number(-1)).toInt(); if (x1==-1 || y1==-1) { kDebug() << "Unable to find pos "; return -2; } if (e2.tagName()=="Room") { CMapRoom *room = CMapElementUtil::createRoom(m_mapManager, QPoint(x1 * gridWidth,y1 * gridHeight),level); room->loadQDomElement(&e2); loadPluginPropertiesForElement(room,&e2); } else if (e2.tagName()=="Text") { CMapText *text = CMapElementUtil::createText(m_mapManager, QPoint (x1,y1),level,""); text->loadQDomElement(&e2); loadPluginPropertiesForElement(text,&e2); } else { kDebug() << "Unknown Type : " << e2.tagName(); } n2 = n2.nextSibling(); } } n = n.nextSibling(); } return 0; } /** * This method is used to read a child XML object of a XML object * @param parent The parent XML object * @param key The name of the child * @return The child node */ QDomElement CMapFileFilterXML::readChildElement(QDomElement *parent,QString key) { QDomElement e; // Find Root Zone QDomNode n = parent->namedItem(key); if (n.isNull()) { e.clear(); return e; } e = n.toElement(); return e; } /** * This method is used to save element properties that are stored in plugins * @param element The element being saved * @param doc The XML document * @param elProperties The xml properties of the element */ void CMapFileFilterXML::savePluginPropertiesForElement(CMapElement *element,QDomDocument *doc,QDomElement *elProperties) { typedef QMap EntryMap; QDomElement pluginsNode = doc->createElement ("plugins"); for (CMapPluginBase *plugin = m_mapManager->getPluginList()->first(); plugin!=0; plugin = m_mapManager->getPluginList()->next()) { QDomElement pNode = doc->createElement(plugin->name()); KMemConfig pluginProperties; plugin->saveElementProperties(element,&pluginProperties); EntryMap entries = pluginProperties.entryMap("Properties"); for (EntryMap::ConstIterator it = entries.begin(); it != entries.end(); ++it) { pNode.setAttribute(it.key(),it.data()); } pluginsNode.appendChild(pNode); } elProperties->appendChild(pluginsNode); } /** * This method is used to load element properties that are stored in plugins * @param element The Element being loaded * @param elProperties the xml properties of the element */ void CMapFileFilterXML::loadPluginPropertiesForElement(CMapElement *element,QDomElement *elProperties) { QDomElement pluginsNode = readChildElement(elProperties,"plugins"); if (!pluginsNode.isNull()) { QDomNode n = pluginsNode.firstChild(); while (!n.isNull() ) { QDomElement e = n.toElement(); if (!e.isNull() ) { for (CMapPluginBase *plugin = m_mapManager->getPluginList()->first(); plugin!=0; plugin = m_mapManager->getPluginList()->next()) { if (plugin->name()==e.tagName()) { KMemConfig pluginProperties; QDomNamedNodeMap attribs = e.attributes(); for (unsigned int i=0; iloadElementProperties(element,&pluginProperties); break; } } } n = n.nextSibling(); } } } diff --git a/plugins/mapper/plugins/standard/cmappluginstandard.h b/plugins/mapper/plugins/standard/cmappluginstandard.h index c57ddb7..b1561af 100644 --- a/plugins/mapper/plugins/standard/cmappluginstandard.h +++ b/plugins/mapper/plugins/standard/cmappluginstandard.h @@ -1,118 +1,117 @@ /*************************************************************************** cmappluginstandard.h ------------------- begin : Mon Aug 6 2001 copyright : (C) 2001 by Kmud Developer Team email : kmud-devel@kmud.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CMAPPLUGINSTANDARD_H #define CMAPPLUGINSTANDARD_H #include -//Added by qt3to4: -#include +#include #include "../../cmappluginbase.h" class CMapManager; /**This plugin provides the standard mapper tools and views *@author Kmud Developer Team */ class CMapPluginStandard : public CMapPluginBase { Q_OBJECT public: CMapPluginStandard(QObject *); ~CMapPluginStandard(); virtual QList createPropertyPanes(elementTyp type,CMapElement *element,QWidget *parent); void profileChanged(void); /** This is called before a element is deleted * @param element The element about to be deleted */ void beforeElementDeleted(CMapElement *element); /** This method is called after undoing a delete action * @param element The elemening being restored */ void afterElementUndeleted(CMapElement *element); /** * This method is used to add a note or change a exsiting note * @param elemenet The element the note is for * @param note The next of the note */ void addNote(CMapElement *element,QString note); /** This method is used to remove a note * @param element The note to remove */ void removeNote(CMapElement *element); /** * This method is used to get a note for the given element * @param element The element to get the note of * @return The note or empty string if there is no note */ QString getNote(CMapElement *element); /** This method is used to get a list of new properties for a element * It will usally be called when saving map data to file * @param element The element being saved * @param properties When method exits this should contain the new properties */ void saveElementProperties(CMapElement *element,KMemConfig *properties); /** This method is used to update an element with the properties load from a file * It will usally be called when loading map data to file * @param element The element being loaded * @param properties The properties being loaded from the file */ void loadElementProperties(CMapElement *element,KMemConfig *properties); /** * This is called when the map is about to be loaded from file */ void loadAboutToStart(); /** * This is called when the map is about to be saved to file */ void saveAboutToStart(void); /** * This is called when a new map is created */ void newMapCreated(void); private: struct DeletedElement { int type; int id; int level; QString note; }; - typedef Q3ValueList DeletedElementList; + typedef QLinkedList DeletedElementList; DeletedElementList::iterator findRoom(int level,int id,bool *found); DeletedElementList::iterator findZone(int id,bool *found); private: QMap m_noteList; DeletedElementList m_deletedElements; }; #endif