mirror of
https://github.com/ra3xdh/qucs_s
synced 2025-03-28 21:13:26 +00:00
Note taking feature
A simple code editor example provided by Qt [1] was included in the tool. It is very convenient to have a text pad to include comments on the traces displayed. The notes are saved into the session file and they are restored when a session file is opened. [1] https://doc.qt.io/qt-5/qtwidgets-widgets-codeeditor-example.html
This commit is contained in:
parent
1ce2092ac9
commit
8a7d158067
@ -58,9 +58,9 @@ ADD_DEFINITIONS(${QT_DEFINITIONS})
|
||||
|
||||
#ADD_SUBDIRECTORY( bitmaps ) -> added as resources
|
||||
|
||||
SET( spar_viewer_sources main.cpp qucs-s-spar-viewer.cpp)
|
||||
SET( spar_viewer_sources main.cpp qucs-s-spar-viewer.cpp codeeditor.cpp)
|
||||
|
||||
SET( spar_viewer_moc_headers qucs-s-spar-viewer.h)
|
||||
SET( spar_viewer_moc_headers qucs-s-spar-viewer.h codeeditor.h)
|
||||
|
||||
SET(RESOURCES qucs-s-spar-viewer.qrc)
|
||||
|
||||
@ -93,7 +93,9 @@ ENDIF(APPLE)
|
||||
ADD_EXECUTABLE( ${QUCS_NAME}spar-viewer MACOSX_BUNDLE WIN32
|
||||
${spar_viewer_sources}
|
||||
${spar_viewer_moc_sources}
|
||||
${RESOURCES_SRCS} )
|
||||
${RESOURCES_SRCS}
|
||||
codeeditor.cpp
|
||||
codeeditor.h )
|
||||
|
||||
TARGET_LINK_LIBRARIES( ${QUCS_NAME}spar-viewer Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Charts )
|
||||
SET_TARGET_PROPERTIES(${QUCS_NAME}spar-viewer PROPERTIES POSITION_INDEPENDENT_CODE TRUE)
|
||||
|
187
qucs-s-spar-viewer/codeeditor.cpp
Normal file
187
qucs-s-spar-viewer/codeeditor.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "codeeditor.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QTextBlock>
|
||||
|
||||
//![constructor]
|
||||
|
||||
CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent)
|
||||
{
|
||||
lineNumberArea = new LineNumberArea(this);
|
||||
|
||||
connect(this, &CodeEditor::blockCountChanged, this, &CodeEditor::updateLineNumberAreaWidth);
|
||||
connect(this, &CodeEditor::updateRequest, this, &CodeEditor::updateLineNumberArea);
|
||||
connect(this, &CodeEditor::cursorPositionChanged, this, &CodeEditor::highlightCurrentLine);
|
||||
|
||||
updateLineNumberAreaWidth(0);
|
||||
highlightCurrentLine();
|
||||
}
|
||||
|
||||
//![constructor]
|
||||
|
||||
//![extraAreaWidth]
|
||||
|
||||
int CodeEditor::lineNumberAreaWidth()
|
||||
{
|
||||
int digits = 1;
|
||||
int max = qMax(1, blockCount());
|
||||
while (max >= 10) {
|
||||
max /= 10;
|
||||
++digits;
|
||||
}
|
||||
|
||||
int space = 3 + fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits;
|
||||
|
||||
return space;
|
||||
}
|
||||
|
||||
//![extraAreaWidth]
|
||||
|
||||
//![slotUpdateExtraAreaWidth]
|
||||
|
||||
void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
|
||||
{
|
||||
setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
|
||||
}
|
||||
|
||||
//![slotUpdateExtraAreaWidth]
|
||||
|
||||
//![slotUpdateRequest]
|
||||
|
||||
void CodeEditor::updateLineNumberArea(const QRect &rect, int dy)
|
||||
{
|
||||
if (dy){
|
||||
lineNumberArea->scroll(0, dy);
|
||||
} else
|
||||
lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());
|
||||
|
||||
if (rect.contains(viewport()->rect())){
|
||||
updateLineNumberAreaWidth(0);
|
||||
}
|
||||
}
|
||||
|
||||
//![slotUpdateRequest]
|
||||
|
||||
//![resizeEvent]
|
||||
|
||||
void CodeEditor::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
QPlainTextEdit::resizeEvent(e);
|
||||
|
||||
QRect cr = contentsRect();
|
||||
lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
|
||||
}
|
||||
|
||||
//![resizeEvent]
|
||||
|
||||
//![cursorPositionChanged]
|
||||
|
||||
void CodeEditor::highlightCurrentLine()
|
||||
{
|
||||
QList<QTextEdit::ExtraSelection> extraSelections;
|
||||
|
||||
if (!isReadOnly()) {
|
||||
QTextEdit::ExtraSelection selection;
|
||||
|
||||
QColor lineColor = QColor(Qt::yellow).lighter(160);
|
||||
|
||||
selection.format.setBackground(lineColor);
|
||||
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
|
||||
selection.cursor = textCursor();
|
||||
selection.cursor.clearSelection();
|
||||
extraSelections.append(selection);
|
||||
}
|
||||
|
||||
setExtraSelections(extraSelections);
|
||||
}
|
||||
|
||||
//![cursorPositionChanged]
|
||||
|
||||
//![extraAreaPaintEvent_0]
|
||||
|
||||
void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPainter painter(lineNumberArea);
|
||||
painter.fillRect(event->rect(), Qt::lightGray);
|
||||
|
||||
//![extraAreaPaintEvent_0]
|
||||
|
||||
//![extraAreaPaintEvent_1]
|
||||
QTextBlock block = firstVisibleBlock();
|
||||
int blockNumber = block.blockNumber();
|
||||
int top = qRound(blockBoundingGeometry(block).translated(contentOffset()).top());
|
||||
int bottom = top + qRound(blockBoundingRect(block).height());
|
||||
//![extraAreaPaintEvent_1]
|
||||
|
||||
//![extraAreaPaintEvent_2]
|
||||
while (block.isValid() && top <= event->rect().bottom()) {
|
||||
if (block.isVisible() && bottom >= event->rect().top()) {
|
||||
QString number = QString::number(blockNumber + 1);
|
||||
painter.setPen(Qt::black);
|
||||
painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(),
|
||||
Qt::AlignRight, number);
|
||||
}
|
||||
|
||||
block = block.next();
|
||||
top = bottom;
|
||||
bottom = top + qRound(blockBoundingRect(block).height());
|
||||
++blockNumber;
|
||||
}
|
||||
}
|
||||
|
||||
void CodeEditor::loadText(const QString& text)
|
||||
{
|
||||
setPlainText(text);
|
||||
}
|
||||
//![extraAreaPaintEvent_2]
|
||||
|
119
qucs-s-spar-viewer/codeeditor.h
Normal file
119
qucs-s-spar-viewer/codeeditor.h
Normal file
@ -0,0 +1,119 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CODEEDITOR_H
|
||||
#define CODEEDITOR_H
|
||||
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QPaintEvent;
|
||||
class QResizeEvent;
|
||||
class QSize;
|
||||
class QWidget;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class LineNumberArea;
|
||||
|
||||
//![codeeditordefinition]
|
||||
|
||||
class CodeEditor : public QPlainTextEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CodeEditor(QWidget *parent = nullptr);
|
||||
|
||||
void lineNumberAreaPaintEvent(QPaintEvent *event);
|
||||
int lineNumberAreaWidth();
|
||||
QString getText() const { return toPlainText(); }
|
||||
void loadText(const QString& text);
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void updateLineNumberAreaWidth(int newBlockCount);
|
||||
void highlightCurrentLine();
|
||||
void updateLineNumberArea(const QRect &rect, int dy);
|
||||
|
||||
private:
|
||||
QWidget *lineNumberArea;
|
||||
};
|
||||
|
||||
//![codeeditordefinition]
|
||||
//![extraarea]
|
||||
|
||||
class LineNumberArea : public QWidget
|
||||
{
|
||||
public:
|
||||
LineNumberArea(CodeEditor *editor) : QWidget(editor), codeEditor(editor)
|
||||
{}
|
||||
|
||||
QSize sizeHint() const override
|
||||
{
|
||||
return QSize(codeEditor->lineNumberAreaWidth(), 0);
|
||||
}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override
|
||||
{
|
||||
codeEditor->lineNumberAreaPaintEvent(event);
|
||||
}
|
||||
|
||||
private:
|
||||
CodeEditor *codeEditor;
|
||||
};
|
||||
|
||||
//![extraarea]
|
||||
|
||||
#endif
|
@ -27,7 +27,6 @@
|
||||
|
||||
#include "qucs-s-spar-viewer.h"
|
||||
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
@ -495,6 +494,9 @@ Qucs_S_SPAR_Viewer::Qucs_S_SPAR_Viewer()
|
||||
Limits_VBox->addWidget(LimitSettings);
|
||||
Limits_VBox->addWidget(scrollArea_Limits);
|
||||
|
||||
// Notes
|
||||
Notes_Widget = new CodeEditor();
|
||||
|
||||
|
||||
|
||||
dockFiles = new QDockWidget("S-parameter files", this);
|
||||
@ -502,6 +504,7 @@ Qucs_S_SPAR_Viewer::Qucs_S_SPAR_Viewer()
|
||||
dockTracesList = new QDockWidget("Traces List", this);
|
||||
dockMarkers = new QDockWidget("Markers", this);
|
||||
dockLimits = new QDockWidget("Limits", this);
|
||||
dockNotes = new QDockWidget("Notes", this);
|
||||
|
||||
// Disable dock closing
|
||||
dockChart->setFeatures(dockChart->features() & ~QDockWidget::DockWidgetClosable);
|
||||
@ -510,23 +513,27 @@ Qucs_S_SPAR_Viewer::Qucs_S_SPAR_Viewer()
|
||||
dockTracesList->setFeatures(dockTracesList->features() & ~QDockWidget::DockWidgetClosable);
|
||||
dockMarkers->setFeatures(dockMarkers->features() & ~QDockWidget::DockWidgetClosable);
|
||||
dockLimits->setFeatures(dockLimits->features() & ~QDockWidget::DockWidgetClosable);
|
||||
dockNotes->setFeatures(dockLimits->features() & ~QDockWidget::DockWidgetClosable);
|
||||
|
||||
dockAxisSettings->setWidget(SettingsGroup);
|
||||
dockTracesList->setWidget(TracesGroup);
|
||||
dockFiles->setWidget(FilesGroup);
|
||||
dockMarkers->setWidget(MarkersGroup);
|
||||
dockLimits->setWidget(LimitsGroup);
|
||||
dockNotes->setWidget(Notes_Widget);
|
||||
|
||||
addDockWidget(Qt::RightDockWidgetArea, dockAxisSettings);
|
||||
addDockWidget(Qt::RightDockWidgetArea, dockTracesList);
|
||||
addDockWidget(Qt::RightDockWidgetArea, dockFiles);
|
||||
addDockWidget(Qt::RightDockWidgetArea, dockMarkers);
|
||||
addDockWidget(Qt::RightDockWidgetArea, dockLimits);
|
||||
addDockWidget(Qt::RightDockWidgetArea, dockNotes);
|
||||
|
||||
splitDockWidget(dockTracesList, dockAxisSettings, Qt::Vertical);
|
||||
tabifyDockWidget(dockFiles, dockTracesList);
|
||||
tabifyDockWidget(dockTracesList, dockMarkers);
|
||||
tabifyDockWidget(dockMarkers, dockLimits);
|
||||
tabifyDockWidget(dockMarkers, dockNotes);
|
||||
dockFiles->raise();
|
||||
setDockNestingEnabled(true);
|
||||
|
||||
@ -2903,6 +2910,13 @@ bool Qucs_S_SPAR_Viewer::save()
|
||||
xmlWriter.writeTextElement("lock_status", QString::number(lock_axis));
|
||||
|
||||
xmlWriter.writeEndElement(); // Axes
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Save notes
|
||||
xmlWriter.writeStartElement("NOTES");
|
||||
xmlWriter.writeTextElement("note", Notes_Widget->getText());
|
||||
xmlWriter.writeEndElement();
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Save the datasets
|
||||
xmlWriter.writeStartElement("DATASETS");
|
||||
@ -2932,7 +2946,6 @@ bool Qucs_S_SPAR_Viewer::save()
|
||||
xmlWriter.writeEndElement(); // Datasets
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
|
||||
xmlWriter.writeEndElement(); // Top level
|
||||
xmlWriter.writeEndDocument();
|
||||
|
||||
@ -2990,7 +3003,7 @@ void Qucs_S_SPAR_Viewer::loadSession(QString session_file)
|
||||
// Read next element
|
||||
QXmlStreamReader::TokenType token = xml.readNext();
|
||||
|
||||
// If token is StartElement, check element name
|
||||
//qDebug() << xml.name().toString();
|
||||
if (token == QXmlStreamReader::StartElement) {
|
||||
if (xml.name() == QStringLiteral("trace")) {
|
||||
while (!(xml.tokenType() == QXmlStreamReader::EndElement && xml.name() == QStringLiteral("trace"))) {
|
||||
@ -3083,6 +3096,9 @@ void Qucs_S_SPAR_Viewer::loadSession(QString session_file)
|
||||
}
|
||||
xml.readNext();
|
||||
}
|
||||
} else if (xml.name().toString().contains("note")){
|
||||
QString note = xml.readElementText();
|
||||
Notes_Widget->loadText(note);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef QUCSSPARVIEWER_H
|
||||
#define QUCSSPARVIEWER_H
|
||||
|
||||
#include "codeeditor.h"
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QLabel>
|
||||
#include <QCheckBox>
|
||||
@ -206,6 +208,10 @@ protected:
|
||||
bool save();
|
||||
void loadSession(QString);
|
||||
|
||||
// Notes
|
||||
QDockWidget *dockNotes;
|
||||
CodeEditor *Notes_Widget;
|
||||
|
||||
// Utilities
|
||||
void convert_MA_RI_to_dB(double *, double *, double *, double *, QString);
|
||||
double getFreqScale();
|
||||
|
Loading…
x
Reference in New Issue
Block a user