File indexing completed on 2024-04-14 05:36:58

0001 /***************************************************************************
0002  *   Copyright (C) 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 "circuitview.h"
0012 #include "circuitdocument.h"
0013 #include "ktechlab.h"
0014 #include "simulator.h"
0015 #include "viewiface.h"
0016 
0017 #include <KActionCollection>
0018 #include <KLocalizedString>
0019 
0020 #include <QAction>
0021 #include <QActionGroup>
0022 #include <QDragEnterEvent>
0023 #include <QMimeData>
0024 
0025 #include <ktechlab_debug.h>
0026 
0027 CircuitView::CircuitView(CircuitDocument *circuitDocument, ViewContainer *viewContainer, uint viewAreaId)
0028     : ICNView(circuitDocument, viewContainer, viewAreaId)
0029     , p_circuitDocument(circuitDocument)
0030 {
0031     KActionCollection *ac = actionCollection();
0032 
0033     {
0034         // new QAction( "Dump linear equations", Qt::CTRL|Qt::Key_D, circuitDocument, SLOT(displayEquations()), ac, "dump_les" );
0035         QAction *a = new QAction(i18n("Dump linear equations"), ac);
0036         a->setObjectName("dump_les");
0037         ac->setDefaultShortcut(a, Qt::CTRL | Qt::Key_D);
0038         connect(a, &QAction::triggered, circuitDocument, &CircuitDocument::displayEquations);
0039         ac->addAction(a->objectName(), a);
0040     }
0041 
0042     // BEGIN Item Control Actions
0043     // QAction * ra; // 2017.10.01 - commented unused variable
0044     {
0045         // ra = new QAction( i18n("0 Degrees"), "", 0, circuitDocument, SLOT(setOrientation0()), ac, "edit_orientation_0" );
0046         // ra->setExclusiveGroup("orientation"); // TODO test
0047         QAction *ra = new QAction(i18n("0 Degrees"), ac);
0048         ra->setObjectName("edit_orientation_0");
0049         connect(ra, &QAction::triggered, circuitDocument, &CircuitDocument::setOrientation0);
0050         ac->addAction(ra->objectName(), ra);
0051         ra->setChecked(true);
0052     }
0053     {
0054         // ra = new QAction( i18n("90 Degrees"), "", 0, circuitDocument, SLOT(setOrientation90()), ac, "edit_orientation_90" );
0055         // ra->setExclusiveGroup("orientation"); // TODO test
0056         QAction *ra = new QAction(i18n("90 Degrees"), ac);
0057         ra->setObjectName("edit_orientation_90");
0058         connect(ra, &QAction::triggered, circuitDocument, &CircuitDocument::setOrientation90);
0059         ac->addAction(ra->objectName(), ra);
0060     }
0061     {
0062         // ra = new QAction( i18n("180 Degrees"), "", 0, circuitDocument, SLOT(setOrientation180()), ac, "edit_orientation_180" );
0063         // ra->setExclusiveGroup("orientation"); // TODO test
0064         QAction *ra = new QAction(i18n("180 Degrees"), ac);
0065         ra->setObjectName("edit_orientation_180");
0066         connect(ra, &QAction::triggered, circuitDocument, &CircuitDocument::setOrientation180);
0067         ac->addAction(ra->objectName(), ra);
0068     }
0069     {
0070         // ra =new QAction( i18n("270 Degrees"), "", 0, circuitDocument, SLOT(setOrientation270()), ac, "edit_orientation_270" );
0071         // ra->setExclusiveGroup("orientation"); // TODO test
0072         QAction *ra = new QAction(i18n("270 Degrees"), ac);
0073         ra->setObjectName("edit_orientation_270");
0074         connect(ra, &QAction::triggered, circuitDocument, &CircuitDocument::setOrientation270);
0075         ac->addAction(ra->objectName(), ra);
0076     }
0077 
0078     {
0079         // new QAction( i18n("Create Subcircuit"), "", 0, circuitDocument, SLOT(createSubcircuit()), ac, "circuit_create_subcircuit" );
0080         QAction *ra = new QAction(i18n("Create Subcircuit"), ac);
0081         ra->setObjectName("circuit_create_subcircuit");
0082         connect(ra, &QAction::triggered, circuitDocument, &CircuitDocument::createSubcircuit);
0083         ac->addAction(ra->objectName(), ra);
0084     }
0085     {
0086         // new QAction( i18n("Rotate Clockwise"), "object-rotate-right", "]", circuitDocument, SLOT(rotateClockwise()), ac, "edit_rotate_cw" );
0087         QAction *ra = new QAction(QIcon::fromTheme("object-rotate-right"), i18n("Rotate Clockwise"), ac);
0088         ra->setObjectName("edit_rotate_cw");
0089         connect(ra, &QAction::triggered, circuitDocument, &CircuitDocument::rotateClockwise);
0090         ac->addAction(ra->objectName(), ra);
0091     }
0092     {
0093         // new QAction( i18n("Rotate Counter-Clockwise"), "object-rotate-left", "[", circuitDocument, SLOT(rotateCounterClockwise()), ac, "edit_rotate_ccw" );
0094         QAction *ra = new QAction(QIcon::fromTheme("object-rotate-left"), i18n("Rotate Counter-Clockwise"), ac);
0095         ra->setObjectName("edit_rotate_ccw");
0096         connect(ra, &QAction::triggered, circuitDocument, &CircuitDocument::rotateCounterClockwise);
0097         ac->addAction(ra->objectName(), ra);
0098     }
0099     {
0100         // new QAction( i18n("Flip Horizontally"), "", 0, circuitDocument, SLOT(flipHorizontally()), ac, "edit_flip_horizontally" );
0101         QAction *ra = new QAction(QIcon::fromTheme("object-flip-horizontal"), i18n("Flip Horizontally"), ac);
0102         ra->setObjectName("edit_flip_horizontally");
0103         connect(ra, &QAction::triggered, circuitDocument, &CircuitDocument::flipHorizontally);
0104         ac->addAction(ra->objectName(), ra);
0105     }
0106     {
0107         // new QAction( i18n("Flip Vertically"), "", 0, circuitDocument, SLOT(flipVertically()), ac, "edit_flip_vertically" );
0108         QAction *ra = new QAction(QIcon::fromTheme("object-flip-vertical"), i18n("Flip Vertically"), ac);
0109         ra->setObjectName("edit_flip_vertically");
0110         connect(ra, &QAction::triggered, circuitDocument, &CircuitDocument::flipVertically);
0111         ac->addAction(ra->objectName(), ra);
0112     }
0113     // END Item Control Actions
0114 
0115     setXMLFile("ktechlabcircuitui.rc", true);
0116 
0117     setWhatsThis(
0118         i18n("Construct a circuit by dragging components from the Component selector from the left. Create the connections by dragging a wire from the component connectors.<br><br>"
0119 
0120              "The simulation is running by default, but can be paused and resumed from the Tools menu.<br><br>"
0121 
0122              "To delete a wire, select it with a select box, and hit delete.<br><br>"
0123 
0124              "To edit the attributes of a component, select it (making sure that no components of another type are also selected), and edit in the toolbar. More advanced properties can be edited using the item editor on the right.<br><br>"
0125 
0126              "Subcircuits can be created by connecting the components with an External Connection, selecting the desired components and clicking on \"Create Subcircuit\" in the right-click menu."));
0127 
0128     m_pViewIface = new CircuitViewIface(this);
0129 
0130     // note: the text below normally should not be visible; it is needed to get the "real" status displayed;
0131     // see slotUpdateRunningStatus
0132     m_statusBar->setStatusText(i18n("Simulation Initializing"));
0133     connect(Simulator::self(), &Simulator::simulatingStateChanged, this, &CircuitView::slotUpdateRunningStatus);
0134     slotUpdateRunningStatus(Simulator::self()->isSimulating());
0135 }
0136 
0137 CircuitView::~CircuitView()
0138 {
0139     delete m_pViewIface;
0140 }
0141 
0142 void CircuitView::slotUpdateRunningStatus(bool isRunning)
0143 {
0144     m_statusBar->setStatusText(isRunning ? i18n("Simulation Running") : i18n("Simulation Paused"));
0145 }
0146 
0147 void CircuitView::dragEnterEvent(QDragEnterEvent *e)
0148 {
0149     const QMimeData *mimeData = e->mimeData();
0150     qCDebug(KTL_LOG) << mimeData->formats();
0151 
0152     ICNView::dragEnterEvent(e);
0153     if (e->isAccepted())
0154         return;
0155 
0156     // bool acceptable = e->provides("ktechlab/component") || e->provides("ktechlab/subcircuit");
0157     bool acceptable = e->mimeData()->hasFormat("ktechlab/component") || e->mimeData()->hasFormat("ktechlab/subcircuit");
0158     if (!acceptable)
0159         return;
0160 
0161     e->setAccepted(true);
0162     createDragItem(e);
0163 }
0164 
0165 #include "moc_circuitview.cpp"