File indexing completed on 2024-12-01 08:18:29

0001 /***************************************************************************
0002  *   Copyright (C) 2004-2005 by David Saxton                               *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "mechanicsdocument.h"
0012 #include "canvasmanipulator.h"
0013 #include "documentiface.h"
0014 #include "drawpart.h"
0015 #include "itemlibrary.h"
0016 #include "mechanicsgroup.h"
0017 #include "mechanicsitem.h"
0018 #include "mechanicssimulation.h"
0019 #include "mechanicsview.h"
0020 
0021 #include <KLocalizedString>
0022 
0023 MechanicsDocument::MechanicsDocument(const QString &caption)
0024     : ItemDocument(caption)
0025 {
0026     m_type = Document::dt_mechanics;
0027     m_pDocumentIface = new MechanicsDocumentIface(this);
0028     m_fileExtensionInfo = QString("*.mechanics|%1 (*.mechanics)\n*|%2").arg(i18n("Mechanics")).arg(i18n("All Files"));
0029     m_fileExtensionValue = QString(".mechanics");
0030     m_canvas->retune(128);
0031 
0032     m_selectList = new MechanicsGroup(this);
0033 
0034     m_cmManager->addManipulatorInfo(CMSelect::manipulatorInfo());
0035     m_cmManager->addManipulatorInfo(CMDraw::manipulatorInfo());
0036     m_cmManager->addManipulatorInfo(CMRightClick::manipulatorInfo());
0037     m_cmManager->addManipulatorInfo(CMRepeatedItemAdd::manipulatorInfo());
0038     m_cmManager->addManipulatorInfo(CMItemResize::manipulatorInfo());
0039     m_cmManager->addManipulatorInfo(CMMechItemMove::manipulatorInfo());
0040     m_mechanicsSimulation = new MechanicsSimulation(this);
0041     requestStateSave();
0042 }
0043 
0044 MechanicsDocument::~MechanicsDocument()
0045 {
0046     m_bDeleted = true;
0047 
0048     // Remove all items from the canvas
0049     selectAll();
0050     deleteSelection();
0051     delete m_mechanicsSimulation;
0052 }
0053 
0054 View *MechanicsDocument::createView(ViewContainer *viewContainer, uint viewAreaId)
0055 {
0056     ItemView *itemView = new MechanicsView(this, viewContainer, viewAreaId);
0057     handleNewView(itemView);
0058     return itemView;
0059 }
0060 
0061 ItemGroup *MechanicsDocument::selectList() const
0062 {
0063     return m_selectList;
0064 }
0065 
0066 bool MechanicsDocument::isValidItem(const QString &itemId)
0067 {
0068     return itemId.startsWith("mech/") || itemId.startsWith("dp/");
0069 }
0070 
0071 bool MechanicsDocument::isValidItem(Item *item)
0072 {
0073     return item && ((dynamic_cast<MechanicsItem *>(item)) || (dynamic_cast<DrawPart *>(item)));
0074 }
0075 
0076 Item *MechanicsDocument::addItem(const QString &id, const QPoint &p, bool newItem)
0077 {
0078     if (!isValidItem(id))
0079         return nullptr;
0080 
0081     Item *item = itemLibrary()->createItem(id, this, newItem);
0082     if (!item)
0083         return nullptr;
0084 
0085     QRect rect = item->boundingRect();
0086 
0087     int dx = int(p.x()) - rect.width() / 2;
0088     int dy = int(p.y()) - rect.height() / 2;
0089 
0090     if (dx < 16 || dx > (m_canvas->width()))
0091         dx = 16;
0092     if (dy < 16 || dy > (m_canvas->height()))
0093         dy = 16;
0094 
0095     item->move(dx, dy);
0096     item->show();
0097 
0098     registerItem(item);
0099     //  setModified(true);
0100     requestStateSave();
0101     return item;
0102 }
0103 
0104 void MechanicsDocument::deleteSelection()
0105 {
0106     // End whatever editing mode we are in, as we don't want to start editing
0107     // something that is about to no longer exist...
0108     m_cmManager->cancelCurrentManipulation();
0109 
0110     if (m_selectList->isEmpty())
0111         return;
0112 
0113     // We nee to tell the selete items to remove themselves, and then
0114     // pass the items that have add themselves to the delete list to the
0115     // CommandAddItems command
0116 
0117     m_selectList->deleteAllItems();
0118     flushDeleteList();
0119     setModified(true);
0120 
0121     // We need to emit this so that property widgets etc...
0122     // can clear themselves.
0123     emit selectionChanged();
0124     requestStateSave();
0125 }
0126 
0127 bool MechanicsDocument::registerItem(KtlQCanvasItem *qcanvasItem)
0128 {
0129     return ItemDocument::registerItem(qcanvasItem);
0130 }
0131 
0132 void MechanicsDocument::appendDeleteList(KtlQCanvasItem *qcanvasItem)
0133 {
0134     MechanicsItem *mechItem = dynamic_cast<MechanicsItem *>(qcanvasItem);
0135     if (!mechItem || m_itemDeleteList.contains(mechItem)) {
0136         return;
0137     }
0138 
0139     m_itemDeleteList.append(mechItem);
0140     m_itemList.remove(mechItem->id());
0141 
0142     disconnect(mechItem, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
0143 
0144     mechItem->removeItem();
0145 }
0146 
0147 void MechanicsDocument::flushDeleteList()
0148 {
0149     // Remove duplicate items in the delete list
0150     ItemList::iterator end = m_itemDeleteList.end();
0151     for (ItemList::iterator it = m_itemDeleteList.begin(); it != end; ++it) {
0152         if (*it && m_itemDeleteList.count(*it) > 1)
0153             *it = nullptr;
0154     }
0155     m_itemDeleteList.removeAll(QPointer<Item>(nullptr));
0156 
0157     end = m_itemDeleteList.end();
0158     for (ItemList::iterator it = m_itemDeleteList.begin(); it != end; ++it) {
0159         m_itemList.remove((*it)->id());
0160         (*it)->setCanvas(nullptr);
0161         delete *it;
0162     }
0163 }
0164 
0165 MechanicsItem *MechanicsDocument::mechanicsItemWithID(const QString &id)
0166 {
0167     return dynamic_cast<MechanicsItem *>(itemWithID(id));
0168 }
0169 
0170 void MechanicsDocument::selectAll()
0171 {
0172     const ItemMap::iterator end = m_itemList.end();
0173     for (ItemMap::iterator it = m_itemList.begin(); it != end; ++it) {
0174         select(*it);
0175     }
0176 }
0177 
0178 void MechanicsDocument::copy()
0179 {
0180 }
0181 
0182 #include "moc_mechanicsdocument.cpp"