wiRedPanda
Logic Circuit Simulator
Loading...
Searching...
No Matches
DolphinExporter.cpp
Go to the documentation of this file.
1// Copyright 2015 - 2026, GIBIS-UNIFESP and the wiRedPanda contributors
2// SPDX-License-Identifier: GPL-3.0-or-later
3
5
6#include <QHeaderView>
7#include <QPainter>
8#include <QPixmap>
9#include <QPrinter>
10#include <QString>
11#include <QTableView>
12#include <QTextStream>
13
16#include "App/Core/Common.h"
17
18namespace {
19constexpr int kExportCellWidth = 50;
20constexpr int kExportCellHeight = 40;
21} // namespace
22
23namespace DolphinExporter {
24
25QPixmap renderToPixmap(const SignalModel *model, const PlotType plotType, const int cellW, const int cellH)
26{
27 // Render through a throwaway table bound to the same model, so the live view
28 // (its zoom, selection, scroll position) is never disturbed by an export.
29 QTableView view;
30 view.setModel(const_cast<SignalModel *>(model));
31 auto *delegate = new SignalDelegate(&view);
32 delegate->setPlotType(plotType);
33 view.setItemDelegate(delegate);
34 view.setShowGrid(false);
35 view.setAlternatingRowColors(true);
36 view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
37 view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
38 view.horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
39 view.verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
40 view.horizontalHeader()->setDefaultSectionSize(cellW);
41 view.verticalHeader()->setDefaultSectionSize(cellH);
42
43 // Size the view to its full content so grab() captures every row/column with
44 // no scrollbars and no blank padding.
45 const int contentW = view.horizontalHeader()->length() + view.verticalHeader()->width();
46 const int contentH = view.verticalHeader()->length() + view.horizontalHeader()->height();
47 view.resize(contentW, contentH);
48
49 return view.grab();
50}
51
52bool exportToPng(const SignalModel *model, const PlotType plotType, const QString &fileName)
53{
54 return renderToPixmap(model, plotType, kExportCellWidth, kExportCellHeight).save(fileName);
55}
56
57void exportToPdf(const SignalModel *model, const PlotType plotType, const QString &fileName)
58{
59 // Landscape A4 fits a reasonably long waveform without excessive scaling.
60 QPrinter printer(QPrinter::HighResolution);
61 printer.setPageSize(QPageSize(QPageSize::A4));
62 printer.setPageOrientation(QPageLayout::Orientation::Landscape);
63 printer.setOutputFormat(QPrinter::PdfFormat);
64 printer.setOutputFileName(fileName);
65
66 QPainter painter;
67
68 if (!painter.begin(&printer)) {
69 throw PANDACEPTION_WITH_CONTEXT("BewavedDolphin", "Could not print this circuit to PDF.");
70 }
71
72 // Render the waveform offscreen, then scale it to fit the page preserving aspect.
73 const QPixmap pixmap = renderToPixmap(model, plotType, kExportCellWidth, kExportCellHeight);
74 const QSize target = pixmap.size().scaled(painter.viewport().size(), Qt::KeepAspectRatio);
75 painter.drawPixmap(QRect(QPoint(0, 0), target), pixmap);
76 painter.end();
77}
78
79void writeTruthTableText(QTextStream &out, const SignalModel *model, const int inputRowCount)
80{
81 // Write input rows first, then output rows, each followed by its signal label.
82 for (int row = 0; row < inputRowCount; ++row) {
83 for (int col = 0; col < model->columnCount(); ++col) {
84 out << model->value(row, col);
85 }
86
87 const auto *header = model->verticalHeaderItem(row);
88 out << " : \"" << (header ? header->text() : QString()) << "\"\n";
89 }
90
91 out << "\n";
92
93 for (int row = inputRowCount; row < model->rowCount(); ++row) {
94 for (int col = 0; col < model->columnCount(); ++col) {
95 out << model->value(row, col);
96 }
97
98 const auto *header = model->verticalHeaderItem(row);
99 out << " : \"" << (header ? header->text() : QString()) << "\"\n";
100 }
101}
102
103QString csvText(const SignalModel *model)
104{
105 // CSV-ish format: "rows,cols," header line, then one comma-separated line per row.
106 QString text;
107 QTextStream out(&text);
108
109 out << model->rowCount() << "," << model->columnCount() << ",\n";
110
111 for (int row = 0; row < model->rowCount(); ++row) {
112 for (int col = 0; col < model->columnCount(); ++col) {
113 out << model->value(row, col) << ",";
114 }
115
116 out << "\n";
117 }
118
119 return text;
120}
121
122} // namespace DolphinExporter
Common logging utilities, the Pandaception error type, and helper macros.
#define PANDACEPTION_WITH_CONTEXT(context, msg,...)
Definition Common.h:102
DolphinExporter: renders/serializes a SignalModel to images and text artifacts.
SignalDelegate: paints digital waveform graphics into table cells.
PlotType
Controls how signal cells are rendered in the waveform table.
SignalModel for the beWavedDolphin waveform table.
Item delegate that draws digital waveform graphics inside table cells.
QStandardItemModel subclass that makes all cells non-editable.
Definition SignalModel.h:21
int value(int row, int col) const
Returns the logic value (0/1) of the cell at (row, col).
Model → artifact conversions for the beWavedDolphin export paths.
void exportToPdf(const SignalModel *model, const PlotType plotType, const QString &fileName)
QPixmap renderToPixmap(const SignalModel *model, const PlotType plotType, const int cellW, const int cellH)
void writeTruthTableText(QTextStream &out, const SignalModel *model, const int inputRowCount)
QString csvText(const SignalModel *model)
bool exportToPng(const SignalModel *model, const PlotType plotType, const QString &fileName)