blob: 49f8c51972b40088dd046bad499407e75cfd74f8 [file] [log] [blame]
/*
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/
#include <QtWidgets>
#include <QLabel>
#include <QDebug>
#include <QHash>
#include "mainwindow.h"
#include "explorerscene.h"
#include "diagramtextitem.h"
#include "wire.h"
#include "container.h"
//length of a standard text
const int InsertTextButton = 12;
MainWindow::MainWindow()
{
createActions();
createToolBox();
createMenus();
scene = new ExplorerScene(itemMenu, this);
//set the dimensions of the whole scene.
//will be changed as soon as a file is opened.
//The container adjusts the dimensions according to circuit size
scene->setSceneRect(QRectF(0, 0, 50000, 50000));
connect(scene, SIGNAL(itemInserted(LogicUnit*)),
this, SLOT(itemInserted(LogicUnit*)));
connect(scene, SIGNAL(textInserted(QGraphicsTextItem*)),
this, SLOT(textInserted(QGraphicsTextItem*)));
connect(scene, SIGNAL(itemSelected(QGraphicsItem*)),
this, SLOT(itemSelected(QGraphicsItem*)));
createToolbars();
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(toolBox);
view = new QGraphicsView(scene);
//Refresh mode. Can be changed if refresh errors occur
view->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
layout->addWidget(view);
QWidget *widget = new QWidget;
widget->setLayout(layout);
setCentralWidget(widget);
setWindowTitle(tr("Circuit Explorer"));
setWindowIcon(QIcon(":/images/icon.png"));
setUnifiedTitleAndToolBarOnMac(true);
myContainer = new Container(scene);
actSimStep = 0;
activityBase = 5000;
fileopen = false;
}
/*---------------------------------------------------------------------------------------------
* (function: simulationButtonGroupClicked)
*-------------------------------------------------------------------------------------------*/
void MainWindow::simulationButtonGroupClicked(QAbstractButton* button)
{
QList<QAbstractButton *> buttons = simulationButtonGroup->buttons();
foreach (QAbstractButton *myButton, buttons) {
if (myButton != button)
button->setChecked(false);
}
QString text = button->text();
if(text == tr("Previous")){
actSimStep = actSimStep-1;
if(actSimStep<0){
actSimStep =0;
}
myContainer->showSimulationStep(actSimStep);
}else if(text == tr("Next")){
actSimStep = (actSimStep+1);//%myContainer->getMaxSimStep();
if(actSimStep>=myContainer->getMaxSimStep())
{
myContainer->simulateNextWave();
}
myContainer->showSimulationStep(actSimStep);
}else if(text == tr("Start")){
//configure clocks
configureClocks();
//start simulation
myContainer->startSimulator();
}
QString simstat = "";
simstat.append(QString("%1").arg(actSimStep));
simstat.append(" / ");
simstat.append(QString("%1").arg(myContainer->getMaxSimStep()));
fprintf(stderr,"simstep: %d\n", actSimStep);
simstatLabel->setText(simstat);
}
/*---------------------------------------------------------------------------------------------
* (function: buttonGroupClicked)
*-------------------------------------------------------------------------------------------*/
void MainWindow::buttonGroupClicked(int id)
{
QList<QAbstractButton *> buttons = nodeButtonGroup->buttons();
foreach (QAbstractButton *button, buttons) {
if (nodeButtonGroup->button(id) != button)
button->setChecked(false);
}
if (id == InsertTextButton) {
scene->setMode(ExplorerScene::InsertText);
} else {
scene->setUnitType(LogicUnit::UnitType(id));
scene->setMode(ExplorerScene::InsertItem);
}
}
void MainWindow::powerButtonGroupClicked(QAbstractButton *button)
{
QList<QAbstractButton *> buttons = powerButtonGroup->buttons();
foreach (QAbstractButton *myButton, buttons) {
if (myButton != button)
button->setChecked(false);
}
QString text = button->text();
//if(text == tr("Start")){
myContainer->getActivityInformation();
myContainer->showActivity();
//}
}
/*---------------------------------------------------------------------------------------------
* (function: deleteItem)
*-------------------------------------------------------------------------------------------*/
void MainWindow::deleteItem()
{
foreach (QGraphicsItem *item, scene->selectedItems()) {
if (item->type() == Wire::Type) {
scene->removeItem(item);
Wire *wire = qgraphicsitem_cast<Wire *>(item);
wire->startUnit()->removeConnection(wire);
wire->endUnit()->removeConnection(wire);
delete wire;
}
}
foreach (QGraphicsItem *item, scene->selectedItems()) {
if (item->type() == LogicUnit::Type) {
qgraphicsitem_cast<LogicUnit *>(item)->removeConnections();
}
scene->removeItem(item);
delete item;
}
}
/*---------------------------------------------------------------------------------------------
* (function: pointerGroupClicked)
*-------------------------------------------------------------------------------------------*/
void MainWindow::pointerGroupClicked(int)
{
scene->setMode(ExplorerScene::Mode(pointerTypeGroup->checkedId()));
}
/*---------------------------------------------------------------------------------------------
* (function: bringToFront)
*-------------------------------------------------------------------------------------------*/
void MainWindow::bringToFront()
{
if (scene->selectedItems().isEmpty())
return;
QGraphicsItem *selectedItem = scene->selectedItems().first();
QList<QGraphicsItem *> overlapItems = selectedItem->collidingItems();
qreal zValue = 0;
foreach (QGraphicsItem *item, overlapItems) {
if (item->zValue() >= zValue &&
item->type() == LogicUnit::Type)
zValue = item->zValue() + 0.1;
}
selectedItem->setZValue(zValue);
}
/*---------------------------------------------------------------------------------------------
* (function: sendToBack)
*-------------------------------------------------------------------------------------------*/
void MainWindow::sendToBack()
{
if (scene->selectedItems().isEmpty())
return;
QGraphicsItem *selectedItem = scene->selectedItems().first();
QList<QGraphicsItem *> overlapItems = selectedItem->collidingItems();
qreal zValue = 0;
foreach (QGraphicsItem *item, overlapItems) {
if (item->zValue() <= zValue &&
item->type() == LogicUnit::Type)
zValue = item->zValue() - 0.1;
}
selectedItem->setZValue(zValue);
}
/*---------------------------------------------------------------------------------------------
* (function: itemInserted)
*-------------------------------------------------------------------------------------------*/
void MainWindow::itemInserted(LogicUnit *item)
{
pointerTypeGroup->button(int(ExplorerScene::MoveItem))->setChecked(true);
scene->setMode(ExplorerScene::Mode(pointerTypeGroup->checkedId()));
nodeButtonGroup->button(int(item->unitType()))->setChecked(false);
}
/*---------------------------------------------------------------------------------------------
* (function: textInserted)
*-------------------------------------------------------------------------------------------*/
void MainWindow::textInserted(QGraphicsTextItem *)
{
nodeButtonGroup->button(InsertTextButton)->setChecked(false);
scene->setMode(ExplorerScene::Mode(pointerTypeGroup->checkedId()));
}
/*---------------------------------------------------------------------------------------------
* (function: currentFontChanged)
*-------------------------------------------------------------------------------------------*/
void MainWindow::currentFontChanged(const QFont &)
{
handleFontChange();
}
/*---------------------------------------------------------------------------------------------
* (function: fontSizeChanged)
*-------------------------------------------------------------------------------------------*/
void MainWindow::fontSizeChanged(const QString &)
{
handleFontChange();
}
/*---------------------------------------------------------------------------------------------
* (function: sceneScaleChanged)
*-------------------------------------------------------------------------------------------*/
void MainWindow::sceneScaleChanged(int scale)
{
double newScale = scale/100.0;
QMatrix oldMatrix = view->matrix();
view->resetMatrix();
view->translate(oldMatrix.dx(), oldMatrix.dy());
view->scale(newScale, newScale);
}
/*---------------------------------------------------------------------------------------------
* (function: textColorChanged)
*-------------------------------------------------------------------------------------------*/
void MainWindow::textColorChanged()
{
textAction = qobject_cast<QAction *>(sender());
fontColorToolButton->setIcon(createColorToolButtonIcon(
":/images/textpointer.png",
qvariant_cast<QColor>(textAction->data())));
textButtonTriggered();
}
/*---------------------------------------------------------------------------------------------
* (function: itemColorChanged)
*-------------------------------------------------------------------------------------------*/
void MainWindow::itemColorChanged()
{
fillAction = qobject_cast<QAction *>(sender());
fillColorToolButton->setIcon(createColorToolButtonIcon(
":/images/floodfill.png",
qvariant_cast<QColor>(fillAction->data())));
fillButtonTriggered();
}
/*---------------------------------------------------------------------------------------------
* (function: lineColorChanged)
*-------------------------------------------------------------------------------------------*/
void MainWindow::lineColorChanged()
{
lineAction = qobject_cast<QAction *>(sender());
lineColorToolButton->setIcon(createColorToolButtonIcon(
":/images/linecolor.png",
qvariant_cast<QColor>(lineAction->data())));
lineButtonTriggered();
}
/*---------------------------------------------------------------------------------------------
* (function: textButtonTriggered)
*-------------------------------------------------------------------------------------------*/
void MainWindow::textButtonTriggered()
{
scene->setTextColor(qvariant_cast<QColor>(textAction->data()));
}
/*---------------------------------------------------------------------------------------------
* (function: fillButtonTriggered)
*-------------------------------------------------------------------------------------------*/
void MainWindow::fillButtonTriggered()
{
scene->setItemColor(qvariant_cast<QColor>(fillAction->data()));
}
/*---------------------------------------------------------------------------------------------
* (function: lineButtonTriggered)
*-------------------------------------------------------------------------------------------*/
void MainWindow::lineButtonTriggered()
{
scene->setLineColor(qvariant_cast<QColor>(lineAction->data()));
}
/*---------------------------------------------------------------------------------------------
* (function: handleFontChange)
*-------------------------------------------------------------------------------------------*/
void MainWindow::handleFontChange()
{
QFont font = fontCombo->currentFont();
font.setPointSize(fontSizeCombo->currentText().toInt());
font.setWeight(boldAction->isChecked() ? QFont::Bold : QFont::Normal);
font.setItalic(italicAction->isChecked());
font.setUnderline(underlineAction->isChecked());
scene->setFont(font);
}
/*---------------------------------------------------------------------------------------------
* (function: itemSelected)
*-------------------------------------------------------------------------------------------*/
void MainWindow::itemSelected(QGraphicsItem *item)
{
DiagramTextItem *textItem =
qgraphicsitem_cast<DiagramTextItem *>(item);
QFont font = textItem->font();
//QColor color = textItem->defaultTextColor();
fontCombo->setCurrentFont(font);
fontSizeCombo->setEditText(QString().setNum(font.pointSize()));
boldAction->setChecked(font.weight() == QFont::Bold);
italicAction->setChecked(font.italic());
underlineAction->setChecked(font.underline());
}
/*---------------------------------------------------------------------------------------------
* (function: about)
*-------------------------------------------------------------------------------------------*/
void MainWindow::about()
{
QMessageBox::about(this, tr("BLIF explorer"),
tr("BLIF explorer \n"
"v 0.3a/n For more information visit: \n http://code.google.com/p/vtr-verilog-to-routing/"));
}
/*---------------------------------------------------------------------------------------------
* (function: about)
*-------------------------------------------------------------------------------------------*/
void MainWindow::createToolBox()
{
nodeButtonGroup = new QButtonGroup(this);
nodeButtonGroup->setExclusive(false);
connect(nodeButtonGroup, SIGNAL(buttonClicked(int)),
this, SLOT(buttonGroupClicked(int)));
QGridLayout *layout = new QGridLayout;
layout->addWidget(createCellWidget(tr("LogicUnit"),
LogicUnit::LogicGate), 0, 0);
layout->addWidget(createCellWidget(tr("Input"),
LogicUnit::Input), 1, 0);
layout->addWidget(createCellWidget(tr("Latch"),
LogicUnit::Latch), 2, 0);
layout->addWidget(createCellWidget(tr("Clock"),
LogicUnit::Clock), 3, 0);
layout->addWidget(createCellWidget(tr("AND"),
LogicUnit::And), 4, 0);
layout->addWidget(createCellWidget(tr("NAND"),
LogicUnit::Nand), 5, 0);
layout->addWidget(createCellWidget(tr("OR"),
LogicUnit::Or), 6, 0);
layout->addWidget(createCellWidget(tr("NOR"),
LogicUnit::Nor), 7, 0);
layout->addWidget(createCellWidget(tr("XOR"),
LogicUnit::Xor), 8, 0);
layout->addWidget(createCellWidget(tr("XNOR"),
LogicUnit::Xnor), 9, 0);
layout->addWidget(createCellWidget(tr("NOT"),
LogicUnit::Not), 10, 0);
layout->addWidget(createCellWidget(tr("MUX"),
LogicUnit::MUX), 0, 1);
layout->addWidget(createCellWidget(tr("ADDER"),
LogicUnit::ADDER_FUNC), 1, 1);
layout->addWidget(createCellWidget(tr("CARRY"),
LogicUnit::CARRY_FUNC), 2, 1);
layout->addWidget(createCellWidget(tr("Hard ADD"),
LogicUnit::ADD), 3, 1);
layout->addWidget(createCellWidget(tr("Hard Minus"),
LogicUnit::MINUS), 4, 1);
layout->addWidget(createCellWidget(tr("Hard Mult"),
LogicUnit::MULTIPLY), 5, 1);
layout->addWidget(createCellWidget(tr("Hard Memory"),
LogicUnit::MEMORY), 6, 1);
layout->addWidget(createCellWidget(tr("Module"),
LogicUnit::Module), 7, 1);
QToolButton *textButton = new QToolButton;
textButton->setCheckable(true);
nodeButtonGroup->addButton(textButton, InsertTextButton);
textButton->setIcon(QIcon(QPixmap(":/images/textpointer.png")
.scaled(30, 30)));
textButton->setIconSize(QSize(50, 50));
QGridLayout *textLayout = new QGridLayout;
textLayout->addWidget(textButton, 0, 0, Qt::AlignHCenter);
textLayout->addWidget(new QLabel(tr("Text")), 1, 0, Qt::AlignCenter);
QWidget *textWidget = new QWidget;
textWidget->setLayout(textLayout);
layout->addWidget(textWidget, 15, 0);
layout->setRowStretch(3, 10);
layout->setColumnStretch(2, 10);
QWidget *itemWidget = new QWidget;
itemWidget->setLayout(layout);
//create widget for simulation
simulationButtonGroup = new QButtonGroup(this);
connect(simulationButtonGroup, SIGNAL(buttonReleased(QAbstractButton*)),
this, SLOT(simulationButtonGroupClicked(QAbstractButton*)));
QGridLayout* simulationLayout = new QGridLayout;
simulationLayout->addWidget(createSimulationCellWidget(tr("Start"),
":/images/start.png"), 0, 0);
simulationLayout->addWidget(createSimulationCellWidget(tr("Previous"),
":/images/previous.png"), 1, 0);
simulationLayout->addWidget(createSimulationCellWidget(tr("Next"),
":/images/next.png"), 2, 0);
QLabel* legend = new QLabel();
QSize size(100,100);
QPixmap* pixmap = new QPixmap(size);
pixmap->convertFromImage(QImage(":/images/legend.png"));
legend->setPixmap(*pixmap);
simulationLayout->addWidget(legend,4,0);
simStatLayout = new QGridLayout;
simstatLabel = new QLabel();
simStatLayout->addWidget(simstatLabel, 0, 0, Qt::AlignCenter);
QWidget *simwidget = new QWidget;
simwidget->setLayout(simStatLayout);
simulationLayout->addWidget(simwidget,5,0);
simulationLayout->setRowStretch(6,10);
simulationLayout->setColumnStretch(2,10);
QWidget* simulationWidget = new QWidget;
simulationWidget->setLayout(simulationLayout);
powerButtonGroup = new QButtonGroup(this);
connect(powerButtonGroup, SIGNAL(buttonReleased(QAbstractButton*)),
this, SLOT(powerButtonGroupClicked(QAbstractButton*)));
QGridLayout* powerLayout = new QGridLayout;
powerLayout->addWidget(createPowerCellWidget(tr("Static Probability"),
":/images/start.png"), 0, 0);
powerLayout->addWidget(createPowerCellWidget(tr("Switching Probability"),
":/images/start.png"), 1, 0);
powerLayout->addWidget(createPowerCellWidget(tr("Switching Activity"),
":/images/start.png"), 2, 0);
//create cycle input field
QSpinBox *activitySpinBox = new QSpinBox;
activitySpinBox->setRange(100, 1000000);
activitySpinBox->setSingleStep(100);
//activitySpinBox->setSuffix(" cycles");
activitySpinBox->setValue(5000);
connect(activitySpinBox, SIGNAL(valueChanged(int)),
this, SLOT(activityCycleCountChangedChanged(int)));
//add caption
QGridLayout *activityLayout = new QGridLayout;
activityLayout->addWidget(activitySpinBox, 0, 0, Qt::AlignHCenter);
activityLayout->addWidget(new QLabel("Estimation Cycle Base"), 1, 0, Qt::AlignCenter);
QWidget *activityWidget = new QWidget;
activityWidget->setLayout(activityLayout);
//place cycle input field in tab
powerLayout->addWidget(activityWidget,3,0);
powerLayout->setRowStretch(6,10);
powerLayout->setColumnStretch(2,10);
QWidget* powerWidget = new QWidget;
powerWidget->setLayout(powerLayout);
toolBox = new QToolBox;
toolBox->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Ignored));
toolBox->setMinimumWidth(itemWidget->sizeHint().width());
toolBox->addItem(itemWidget, tr("Tools"));
toolBox->addItem(simulationWidget, tr("Simulation"));
toolBox->addItem(powerWidget, tr("Power Estimation"));
}
/*---------------------------------------------------------------------------------------------
* (function: createActions)
*-------------------------------------------------------------------------------------------*/
void MainWindow::createActions()
{
toFrontAction = new QAction(QIcon(":/images/bringtofront.png"),
tr("Bring to F&ront"), this);
toFrontAction->setShortcut(tr("Ctrl+R"));
toFrontAction->setStatusTip(tr("Bring item to front"));
connect(toFrontAction, SIGNAL(triggered()),
this, SLOT(bringToFront()));
sendBackAction = new QAction(QIcon(":/images/sendtoback.png"),
tr("Send to &Back"), this);
sendBackAction->setShortcut(tr("Ctrl+B"));
sendBackAction->setStatusTip(tr("Send item to back"));
connect(sendBackAction, SIGNAL(triggered()),
this, SLOT(sendToBack()));
deleteAction = new QAction(QIcon(":/images/delete.png"),
tr("&Delete"), this);
deleteAction->setShortcut(tr("Delete"));
deleteAction->setStatusTip(tr("Delete item from circuit"));
connect(deleteAction, SIGNAL(triggered()),
this, SLOT(deleteItem()));
exitAction = new QAction(tr("E&xit"), this);
exitAction->setShortcuts(QKeySequence::Quit);
exitAction->setStatusTip(tr("Quit Circuit Explorer"));
connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
boldAction = new QAction(tr("Bold"), this);
boldAction->setCheckable(true);
QPixmap pixmap(":/images/bold.png");
boldAction->setIcon(QIcon(pixmap));
boldAction->setShortcut(tr("Ctrl+B"));
connect(boldAction, SIGNAL(triggered()),
this, SLOT(handleFontChange()));
italicAction = new QAction(QIcon(":/images/italic.png"),
tr("Italic"), this);
italicAction->setCheckable(true);
italicAction->setShortcut(tr("Ctrl+I"));
connect(italicAction, SIGNAL(triggered()),
this, SLOT(handleFontChange()));
underlineAction = new QAction(QIcon(":/images/underline.png"),
tr("Underline"), this);
underlineAction->setCheckable(true);
underlineAction->setShortcut(tr("Ctrl+U"));
connect(underlineAction, SIGNAL(triggered()),
this, SLOT(handleFontChange()));
aboutAction = new QAction(tr("A&bout"), this);
aboutAction->setShortcut(tr("Ctrl+I"));
connect(aboutAction, SIGNAL(triggered()),
this, SLOT(about()));
/*Opens the file in Odin II and creates the visualization based on the netlist*/
openFileOdinAction = new QAction(tr("O&din Open BLIF"), this);
openFileOdinAction->setShortcut(tr("Ctrl+O"));
openFileOdinAction->setToolTip("Opens and visualizes a file in the BLIF format using Odin II");
connect(openFileOdinAction, SIGNAL(triggered()),
this, SLOT(openFileWithOdin()));
/*Changes the name of a node*/
setNameAction = new QAction(tr("&Change Name"), this);
setNameAction->setShortcut(tr("Ctrl+C"));
setNameAction->setStatusTip("Change the name of a node");
connect(setNameAction, SIGNAL(triggered()),this,SLOT(setName()));
selectAllAction = new QAction(tr("Select &All"), this);
selectAllAction->setShortcut(tr("Ctrl+A"));
selectAllAction->setStatusTip("Select all items");
connect(selectAllAction, SIGNAL(triggered()),this,SLOT(selectAll()));
findAction = new QAction(tr("&Find Logic Block"), this);
findAction->setShortcut(tr("Ctrl+f"));
findAction->setStatusTip("Searches for a specific logic block by its name");
connect(findAction, SIGNAL(triggered()),this,SLOT(findBlock()));
showAllConnectionsAction = new QAction(tr("Highlight Connections"), this);
showAllConnectionsAction->setShortcut(tr("Ctrl+H"));
showAllConnectionsAction->setStatusTip("Highlight the logic block and all connections connected to it.");
connect(showAllConnectionsAction, SIGNAL(triggered()),this,SLOT(showAllConnection()));
removeHighlightingAction = new QAction(tr("Reset Highlighting"), this);
removeHighlightingAction->setStatusTip("Highlight the logic block and all connections connected to it.");
connect(removeHighlightingAction, SIGNAL(triggered()),this,SLOT(resetHighlighting()));
showNodeAndNeighboursOnlyAction = new QAction(tr("Show Node and Neighbours Only"), this);
showNodeAndNeighboursOnlyAction->setStatusTip("Hides all nodes except for the selected node and its parents and children.");
connect(showNodeAndNeighboursOnlyAction, SIGNAL(triggered()),this,SLOT(showNodeAndNeighboursOnly()));
addParentsToHighlightingAction = new QAction(tr("Add Parents to Visibility"), this);
addParentsToHighlightingAction->setStatusTip("Adds parents of the selected node to visualization.");
connect(addParentsToHighlightingAction, SIGNAL(triggered()),this,SLOT(addParentsToHighlighting()));
addChildrenToHighlightingAction = new QAction(tr("Add Children to Visibility"), this);
addChildrenToHighlightingAction->setStatusTip("Adds child nodes of the selected node to visualization.");
connect(addChildrenToHighlightingAction, SIGNAL(triggered()),this,SLOT(addChildrenToHighlighting()));
showRelevantGraphAction = new QAction(tr("Show relevant Graph"), this);
showRelevantGraphAction->setStatusTip("Shows the relevant sub graph for the current node.");
connect(showRelevantGraphAction, SIGNAL(triggered()),this,SLOT(showRelevantGraph()));
expandCollapseAction = new QAction(tr("Expand/Collapse Module"), this);
connect(expandCollapseAction, SIGNAL(triggered()),this,SLOT(expandCollapse()));
}
/*---------------------------------------------------------------------------------------------
* (function: createMenus)
*-------------------------------------------------------------------------------------------*/
void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(openFileOdinAction);
fileMenu->addSeparator();
fileMenu->addAction(exitAction);
itemMenu = menuBar()->addMenu(tr("&Item"));
itemMenu->addAction(expandCollapseAction);
itemMenu->addSeparator();
itemMenu->addAction(setNameAction);
itemMenu->addAction(deleteAction);
itemMenu->addAction(selectAllAction);
itemMenu->addSeparator();
itemMenu->addAction(findAction);
itemMenu->addSeparator();
itemMenu->addAction(toFrontAction);
itemMenu->addAction(sendBackAction);
itemMenu->addSeparator();
itemMenu->addAction(showAllConnectionsAction);
itemMenu->addAction(removeHighlightingAction);
itemMenu->addSeparator();
itemMenu->addAction(showNodeAndNeighboursOnlyAction);
itemMenu->addAction(addParentsToHighlightingAction);
itemMenu->addAction(addChildrenToHighlightingAction);
itemMenu->addAction(showRelevantGraphAction);
aboutMenu = menuBar()->addMenu(tr("&Help"));
aboutMenu->addAction(aboutAction);
}
/*---------------------------------------------------------------------------------------------
* (function: createToolbars)
*-------------------------------------------------------------------------------------------*/
void MainWindow::createToolbars()
{
openToolBar = addToolBar("Open");
openToolBar->addAction(openFileOdinAction);
editToolBar = addToolBar(tr("Edit"));
editToolBar->addAction(deleteAction);
editToolBar->addAction(toFrontAction);
editToolBar->addAction(sendBackAction);
fontCombo = new QFontComboBox();
connect(fontCombo, SIGNAL(currentFontChanged(QFont)),
this, SLOT(currentFontChanged(QFont)));
fontSizeCombo = new QComboBox;
fontSizeCombo->setEditable(true);
for (int i = 8; i < 30; i = i + 2)
fontSizeCombo->addItem(QString().setNum(i));
QIntValidator *validator = new QIntValidator(2, 64, this);
fontSizeCombo->setValidator(validator);
connect(fontSizeCombo, SIGNAL(currentIndexChanged(QString)),
this, SLOT(fontSizeChanged(QString)));
fontColorToolButton = new QToolButton;
fontColorToolButton->setPopupMode(QToolButton::MenuButtonPopup);
fontColorToolButton->setMenu(createColorMenu(SLOT(textColorChanged()),
Qt::black));
textAction = fontColorToolButton->menu()->defaultAction();
fontColorToolButton->setIcon(createColorToolButtonIcon(
":/images/textpointer.png", Qt::black));
fontColorToolButton->setAutoFillBackground(true);
connect(fontColorToolButton, SIGNAL(clicked()),
this, SLOT(textButtonTriggered()));
fillColorToolButton = new QToolButton;
fillColorToolButton->setPopupMode(QToolButton::MenuButtonPopup);
fillColorToolButton->setMenu(createColorMenu(SLOT(itemColorChanged()),
Qt::white));
fillAction = fillColorToolButton->menu()->defaultAction();
fillColorToolButton->setIcon(createColorToolButtonIcon(
":/images/floodfill.png", Qt::white));
connect(fillColorToolButton, SIGNAL(clicked()),
this, SLOT(fillButtonTriggered()));
lineColorToolButton = new QToolButton;
lineColorToolButton->setPopupMode(QToolButton::MenuButtonPopup);
lineColorToolButton->setMenu(createColorMenu(SLOT(lineColorChanged()),
Qt::black));
lineAction = lineColorToolButton->menu()->defaultAction();
lineColorToolButton->setIcon(createColorToolButtonIcon(
":/images/linecolor.png", Qt::black));
connect(lineColorToolButton, SIGNAL(clicked()),
this, SLOT(lineButtonTriggered()));
colorToolBar = addToolBar(tr("Color"));
colorToolBar->addWidget(fontColorToolButton);
colorToolBar->addWidget(fillColorToolButton);
colorToolBar->addWidget(lineColorToolButton);
QToolButton *pointerButton = new QToolButton;
pointerButton->setCheckable(true);
pointerButton->setChecked(true);
pointerButton->setIcon(QIcon(":/images/pointer.png"));
QToolButton *linePointerButton = new QToolButton;
linePointerButton->setCheckable(true);
linePointerButton->setIcon(QIcon(":/images/linepointer.png"));
pointerTypeGroup = new QButtonGroup(this);
pointerTypeGroup->addButton(pointerButton, int(ExplorerScene::MoveItem));
pointerTypeGroup->addButton(linePointerButton,
int(ExplorerScene::InsertLine));
connect(pointerTypeGroup, SIGNAL(buttonClicked(int)),
this, SLOT(pointerGroupClicked(int)));
QSpinBox *zoomSpinBox = new QSpinBox;
zoomSpinBox->setRange(5, 150);
zoomSpinBox->setSingleStep(5);
zoomSpinBox->setSuffix("%");
zoomSpinBox->setSpecialValueText(tr("Automatic"));
zoomSpinBox->setValue(100);
connect(zoomSpinBox, SIGNAL(valueChanged(int)),
this, SLOT(sceneScaleChanged(int)));
pointerToolbar = addToolBar(tr("Pointer type"));
pointerToolbar->addWidget(zoomSpinBox);
pointerToolbar->addWidget(pointerButton);
pointerToolbar->addWidget(linePointerButton);
textToolBar = addToolBar(tr("Font"));
textToolBar->addWidget(fontCombo);
textToolBar->addWidget(fontSizeCombo);
textToolBar->addAction(boldAction);
textToolBar->addAction(italicAction);
textToolBar->addAction(underlineAction);
}
/*---------------------------------------------------------------------------------------------
* (function: createBackgroundCellWidget)
*-------------------------------------------------------------------------------------------*/
// not used any more, but can be if background pattern is required
QWidget *MainWindow::createBackgroundCellWidget(const QString &text,
const QString &image)
{
QToolButton *button = new QToolButton;
button->setText(text);
button->setIcon(QIcon(image));
button->setIconSize(QSize(50, 50));
button->setCheckable(true);
backgroundButtonGroup->addButton(button);
QGridLayout *layout = new QGridLayout;
layout->addWidget(button, 0, 0, Qt::AlignHCenter);
layout->addWidget(new QLabel(text), 1, 0, Qt::AlignCenter);
QWidget *widget = new QWidget;
widget->setLayout(layout);
return widget;
}
/*---------------------------------------------------------------------------------------------
* (function: createCellWidget)
*-------------------------------------------------------------------------------------------*/
QWidget *MainWindow::createCellWidget(const QString &text,
LogicUnit::UnitType type)
{
LogicUnit item("Unit",type, itemMenu);
QIcon icon(*item.image());
QToolButton *button = new QToolButton;
button->setIcon(icon);
button->setIconSize(QSize(50, 50));
button->setCheckable(true);
nodeButtonGroup->addButton(button, int(type));
QGridLayout *layout = new QGridLayout;
layout->addWidget(button, 0, 0, Qt::AlignHCenter);
layout->addWidget(new QLabel(text), 1, 0, Qt::AlignCenter);
QWidget *widget = new QWidget;
widget->setLayout(layout);
return widget;
}
/*---------------------------------------------------------------------------------------------
* (function: createColorMenu)
*-------------------------------------------------------------------------------------------*/
QMenu *MainWindow::createColorMenu(const char *slot, QColor defaultColor)
{
QList<QColor> colors;
colors << Qt::black << Qt::white << Qt::red << Qt::blue << Qt::yellow;
QStringList names;
names << tr("black") << tr("white") << tr("red") << tr("blue")
<< tr("yellow");
QMenu *colorMenu = new QMenu(this);
for (int i = 0; i < colors.count(); ++i) {
QAction *action = new QAction(names.at(i), this);
action->setData(colors.at(i));
action->setIcon(createColorIcon(colors.at(i)));
connect(action, SIGNAL(triggered()),
this, slot);
colorMenu->addAction(action);
if (colors.at(i) == defaultColor) {
colorMenu->setDefaultAction(action);
}
}
return colorMenu;
}
/*---------------------------------------------------------------------------------------------
* (function: createColorToolButtonIcon)
*-------------------------------------------------------------------------------------------*/
QIcon MainWindow::createColorToolButtonIcon(const QString &imageFile,
QColor color)
{
QPixmap pixmap(50, 80);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
QPixmap image(imageFile);
QRect target(0, 0, 50, 60);
QRect source(0, 0, 42, 42);
painter.fillRect(QRect(0, 60, 50, 80), color);
painter.drawPixmap(target, image, source);
return QIcon(pixmap);
}
/*---------------------------------------------------------------------------------------------
* (function: createColorIcon)
*-------------------------------------------------------------------------------------------*/
QIcon MainWindow::createColorIcon(QColor color)
{
QPixmap pixmap(20, 20);
QPainter painter(&pixmap);
painter.setPen(Qt::NoPen);
painter.fillRect(QRect(0, 0, 20, 20), color);
return QIcon(pixmap);
}
/*---------------------------------------------------------------------------------------------
* (function: openFileWithOdin)
*-------------------------------------------------------------------------------------------*/
void MainWindow::openFileWithOdin(){
selectAll();
deleteItem();
actBlifFilename = QFileDialog::getOpenFileName(this,
tr("Open BLIF"),
QDir::homePath(),
tr("BLIF files (*.blif);;All files (*.*)"),
0,
QFileDialog::DontUseNativeDialog);
myContainer->setFilename(actBlifFilename);
int ok = myContainer->readInFileOdinOnly();
if(ok == -1){
//An error occured
QMessageBox msgBox(QMessageBox::Warning, tr("No Structure Found in File"),
"The file you tried to explore does not contain any structures or could not be opened. Please select another file."
, 0, this);
msgBox.addButton(tr("Open &Again"), QMessageBox::AcceptRole);
msgBox.addButton(tr("&Continue"), QMessageBox::RejectRole);
if (msgBox.exec() == QMessageBox::AcceptRole)
openFileWithOdin();
}else{
myContainer->arrangeContainer();
QString title = "Circuit Explorer - ";
title.append(actBlifFilename);
setWindowTitle(title);
view->centerOn(0,0);
fileopen = true;
}
}
/*---------------------------------------------------------------------------------------------
* (function: setName)
*-------------------------------------------------------------------------------------------*/
void MainWindow::setName()
{
if (scene->selectedItems().isEmpty())
return;
QGraphicsItem *item = scene->selectedItems().first();
if (item->type() == LogicUnit::Type) {
LogicUnit *unit =
qgraphicsitem_cast<LogicUnit *>(scene->selectedItems().first());
QString Name = unit->getName();
QString newName;
bool ok;
newName = QInputDialog::getText(this, tr("QInputDialog::getText()"),
tr("User name:"), QLineEdit::Normal,
Name, &ok);
if (ok && !newName.isEmpty()){
unit->setName(newName);
unit->update();
}
}
}
/*---------------------------------------------------------------------------------------------
* (function: selectAll)
*-------------------------------------------------------------------------------------------*/
void MainWindow::selectAll()
{
QPainterPath path;
path.moveTo(0,0);
path.addRect(0,0,view->width(),view->height());
scene->setSelectionArea(path);
}
/*---------------------------------------------------------------------------------------------
* (function: findBlock)
*-------------------------------------------------------------------------------------------*/
void MainWindow::findBlock()
{
QHash<QString,LogicUnit *> result;
bool ok;
QString itemName = QInputDialog::getText(this, tr("Find logic block by Name"),
tr("Logic block name:"), QLineEdit::Normal,
"top^b", &ok);
if (ok && !itemName.isEmpty()){
selectAll();
result = myContainer->findByName(itemName);
scene->clearSelection();
fprintf(stderr, "Find process done\n");
if(result.count()!=0){
LogicUnit* match = result.constBegin().value();
view->centerOn(match->x(),match->y());
}
QString message;
message = "Search complete.\n Items found: ";
message.append(QString("%1").arg(result.count()));
QMessageBox::information(this, tr("Search results."), message);
}
}
/*---------------------------------------------------------------------------------------------
* (function: showAllConnection)
*-------------------------------------------------------------------------------------------*/
void MainWindow::showAllConnection()
{
if (scene->selectedItems().isEmpty())
return;
QGraphicsItem *item = scene->selectedItems().first();
if (item->type() == LogicUnit::Type) {
LogicUnit *unit =
qgraphicsitem_cast<LogicUnit *>(scene->selectedItems().first());
QList<Wire *> list = unit->getAllCons();
foreach (Wire *wire, list) {
wire->setColor(QColor(0,0,255,255));
wire->update();
wire->setZValue(905);
}
list = unit->getOutCons();
foreach (Wire *wire, list) {
wire->setColor(QColor(0,200,200,255));
wire->update();
wire->setZValue(905);
}
unit->setBrush(QColor(0,0,255,255));
unit->setZValue(900);
}
}
/*---------------------------------------------------------------------------------------------
* (function: resetHighlighting)
*-------------------------------------------------------------------------------------------*/
void MainWindow::resetHighlighting()
{
if (scene->selectedItems().isEmpty()){
myContainer->resetAllHighlights();
myContainer->setVisibilityForAll(true);
myContainer->arrangeContainer();
return;
}
QGraphicsItem *item = scene->selectedItems().first();
if (item->type() == LogicUnit::Type) {
LogicUnit *unit =
qgraphicsitem_cast<LogicUnit *>(scene->selectedItems().first());
unit->setBrush(QColor(255,255,255,255));
unit->setZValue(0);
QList<Wire *> list = unit->getAllCons();
foreach (Wire *wire, list) {
wire->setColor(QColor(0,0,0,255));
wire->setZValue(-1000);
wire->update();
}
}
}
void MainWindow::showNodeAndNeighboursOnly()
{
//nothing to do if no node is selected
if (scene->selectedItems().isEmpty())
return;
QGraphicsItem *item = scene->selectedItems().first();
if (item->type() == LogicUnit::Type) {
LogicUnit *unit =
qgraphicsitem_cast<LogicUnit *>(scene->selectedItems().first());
//set all nodes to invisible
myContainer->setVisibilityForAll(false);
unit->setShown(true);
//make children visible
QList<LogicUnit*> kidslist = unit->getChildren();
foreach(LogicUnit* kid, kidslist){
kid->setShown(true);
}
//make parents visible
QList<LogicUnit*> parentslist = unit->getParents();
foreach(LogicUnit* parent, parentslist){
parent->setShown(true);
}
QList<Wire *> list = unit->getAllCons();
foreach (Wire *wire, list) {
wire->updatePosition();
}
myContainer->arrangeContainer();
view->centerOn(unit->x(),unit->y());
}
}
void MainWindow::addParentsToHighlighting()
{
//nothing to do if no node is selected
if (scene->selectedItems().isEmpty())
return;
QGraphicsItem *item = scene->selectedItems().first();
if (item->type() == LogicUnit::Type) {
LogicUnit *unit =
qgraphicsitem_cast<LogicUnit *>(scene->selectedItems().first());
//make parents visible
QList<LogicUnit*> parentslist = unit->getParents();
foreach(LogicUnit* parent, parentslist){
parent->setShown(true);
}
QList<Wire *> list = unit->getAllCons();
foreach (Wire *wire, list) {
wire->updatePosition();
}
myContainer->arrangeContainer();
}
}
void MainWindow::addChildrenToHighlighting()
{
//nothing to do if no node is selected
if (scene->selectedItems().isEmpty())
return;
QGraphicsItem *item = scene->selectedItems().first();
if (item->type() == LogicUnit::Type) {
LogicUnit *unit =
qgraphicsitem_cast<LogicUnit *>(scene->selectedItems().first());
//make parents visible
QList<LogicUnit*> kidslist = unit->getChildren();
foreach(LogicUnit* kid, kidslist){
kid->setShown(true);
}
QList<Wire *> list = unit->getAllCons();
foreach (Wire *wire, list) {
wire->updatePosition();
}
myContainer->arrangeContainer();
}
}
void MainWindow::showRelevantGraph()
{
//nothing to do if no node is selected
if (scene->selectedItems().isEmpty())
return;
QQueue<LogicUnit*> queue;
QList<LogicUnit*> donelist;
LogicUnit *node;
QGraphicsItem *item = scene->selectedItems().first();
if (item->type() == LogicUnit::Type) {
node =
qgraphicsitem_cast<LogicUnit *>(scene->selectedItems().first());
} else {
return;
}
//set all nodes to invisible
myContainer->setVisibilityForAll(false);
node->setShown(true);
//go left in the graph until inputs are reached
queue.enqueue(node);
while(!queue.empty()){
LogicUnit *actNode = queue.dequeue();
//make parents visible
QList<LogicUnit*> parentslist = actNode->getParents();
foreach(LogicUnit* parent, parentslist){
if(!queue.contains(parent) && !donelist.contains(parent)){
queue.enqueue(parent);
}
parent->setShown(true);
}
QList<Wire *> list = actNode->getAllCons();
foreach (Wire *wire, list) {
wire->updatePosition();
}
donelist.append(actNode);
}
//go right in the graph until outputs are reached
queue.enqueue(node);
while(!queue.empty()){
LogicUnit *actNode =
queue.dequeue();
//make parents visible
QList<LogicUnit*> kidslist = actNode->getChildren();
foreach(LogicUnit* kid, kidslist){
if(!queue.contains(kid) && !donelist.contains(kid)){
queue.enqueue(kid);
}
kid->setShown(true);
}
QList<Wire *> list = actNode->getAllCons();
foreach (Wire *wire, list) {
wire->updatePosition();
}
donelist.append(actNode);
}
myContainer->arrangeContainer();
view->centerOn(node->x(),node->y());
QString message;
message = "Relevant graph node count: ";
message.append(QString("%1").arg(donelist.count()+1));//the constant 1 re[resents the initiator node
QMessageBox::information(this, tr("Relevant graph"), message);
}
/*---------------------------------------------------------------------------------------------
* (function: createSimulationCellWidget)
*-------------------------------------------------------------------------------------------*/
QWidget * MainWindow::createSimulationCellWidget(const QString &text, const QString &image)
{
QToolButton *button = new QToolButton;
button->setText(text);
button->setIcon(QIcon(image));
button->setIconSize(QSize(50, 50));
button->setCheckable(true);
simulationButtonGroup->addButton(button);
QGridLayout *layout = new QGridLayout;
layout->addWidget(button, 0, 0, Qt::AlignHCenter);
layout->addWidget(new QLabel(text), 1, 0, Qt::AlignCenter);
QWidget *widget = new QWidget;
widget->setLayout(layout);
return widget;
}
QWidget * MainWindow::createPowerCellWidget(const QString &text, const QString &image)
{
QToolButton *button = new QToolButton;
button->setText(text);
button->setIcon(QIcon(image));
button->setIconSize(QSize(50, 50));
button->setCheckable(true);
powerButtonGroup->addButton(button);
QGridLayout *layout = new QGridLayout;
layout->addWidget(button, 0, 0, Qt::AlignHCenter);
layout->addWidget(new QLabel(text), 1, 0, Qt::AlignCenter);
QWidget *widget = new QWidget;
widget->setLayout(layout);
return widget;
}
void MainWindow::activityCycleCountChangedChanged(int number)
{
activityBase = number;
}
void MainWindow::configureClocks()
{
QList<LogicUnit*> clocks = myContainer->getClocks();
//if less than 2 clocks available, end configuration
if(!fileopen || clocks.length() < 2)
return;
clkconfig.passClockList(clocks);
clkconfig.exec();
}
void MainWindow::expandCollapse()
{
//nothing to do if no node is selected
if (scene->selectedItems().isEmpty())
return;
QGraphicsItem *item = scene->selectedItems().first();
if (item->type() == LogicUnit::Type) {
LogicUnit *unit = qgraphicsitem_cast<LogicUnit *>(scene->selectedItems().first());
//if module start right away, otherwise extract module name
if(unit && unit->unitType() == LogicUnit::Module){
myContainer->expandCollapse(unit->getName());
} else if(unit->getName().contains("+")){
QString moduleName = myContainer->extractModuleFromName(
unit->getName());
myContainer->expandCollapse(moduleName);
}
}
}