moved to shstk
This commit is contained in:
1
libs/CMakeLists.txt
Normal file
1
libs/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
add_directories_with_include("qad_")
|
||||
1
libs/application/CMakeLists.txt
Normal file
1
libs/application/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
qad_library(application "Gui;Widgets" "qad_widgets")
|
||||
217
libs/application/aboutwindow.cpp
Normal file
217
libs/application/aboutwindow.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
#include "aboutwindow.h"
|
||||
#include "ui_aboutwindow.h"
|
||||
#include "qad_types.h"
|
||||
#include "qpiconfig.h"
|
||||
#include <QApplication>
|
||||
#include <QFile>
|
||||
#if QT_VERSION < 0x050000
|
||||
# include <QDesktopWidget>
|
||||
#else
|
||||
# include <QScreen>
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||
# define MOBILE_VIEW
|
||||
#endif
|
||||
|
||||
QImage AboutWindow::logo;
|
||||
QVector<AboutWindow::SSPair> AboutWindow::versions, AboutWindow::builds;
|
||||
QString AboutWindow::comment, AboutWindow::stylesheet;
|
||||
|
||||
|
||||
AboutWindow::AboutWindow(QWidget * parent): QDialog(parent), ui(new Ui::AboutWindow) {
|
||||
#ifdef ANDROID
|
||||
QDialog::setStyleSheet("font: 12pt \"DejaVu Sans\";");
|
||||
#endif
|
||||
if (!stylesheet.isEmpty())
|
||||
QDialog::setStyleSheet(stylesheet);
|
||||
ui->setupUi(this);
|
||||
ui->labelAuthors->setOpenExternalLinks(true);
|
||||
QImage logo_im = logo;
|
||||
if (logo_im.isNull())
|
||||
logo_im.load(":/icons/splash.png");
|
||||
setWindowTitle(QApplication::applicationName() + " - " + tr("About"));
|
||||
QIcon ic = QApplication::windowIcon();
|
||||
if (ic.isNull()) {
|
||||
QWidgetList tlw = QApplication::topLevelWidgets();
|
||||
foreach (QWidget * w, tlw)
|
||||
if (!w->windowIcon().isNull()) {
|
||||
ic = w->windowIcon();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ic.isNull())
|
||||
ic = QIcon(QPixmap::fromImage(logo_im));
|
||||
setWindowIcon(ic);
|
||||
QFormLayout * lay = (QFormLayout*)(ui->groupVersions->layout());
|
||||
foreach (SSPair p, versions) {
|
||||
lay->addRow(p.first, new QLabel(p.second));
|
||||
}
|
||||
lay = (QFormLayout*)(ui->groupBuild->layout());
|
||||
foreach (SSPair p, builds) {
|
||||
lay->addRow(p.first, new QLabel(p.second));
|
||||
}
|
||||
ui->imageView->setPixmap(QPixmap::fromImage(logo_im));
|
||||
ui->labelComment->setText(comment);
|
||||
ui->labelComment->setOpenExternalLinks(true);
|
||||
ui->labelComment->setHidden(comment.isEmpty());
|
||||
//ui->labelArch->setText(QSysInfo::currentCpuArchitecture());
|
||||
ui->labelAuthors->setText(authors());
|
||||
connect(ui->buttonQt, SIGNAL(clicked()), qApp, SLOT(aboutQt()));
|
||||
#ifdef MOBILE_VIEW
|
||||
ui->layoutMain->insertWidget(0, ui->imageView);
|
||||
//ui->verticalSpacer->changeSize(1, 1, QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
#endif
|
||||
#ifdef MOBILE_VIEW
|
||||
ui->layoutMain->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Preferred, QSizePolicy::Expanding));
|
||||
#else
|
||||
QRect r;
|
||||
# if QT_VERSION < 0x050000
|
||||
r = QApplication::desktop()->geometry();
|
||||
# else
|
||||
QScreen * scr =
|
||||
# if QT_VERSION >= 0x050A00
|
||||
QApplication::screenAt(QCursor::pos());
|
||||
# else
|
||||
QApplication::screens()[0];
|
||||
# endif
|
||||
if (scr) {
|
||||
r.setSize(scr->availableSize() / 2);
|
||||
r.moveCenter(scr->availableGeometry().center());
|
||||
}
|
||||
# endif
|
||||
if (r.isValid())
|
||||
setGeometry(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
AboutWindow::~AboutWindow() {
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
void AboutWindow::setLogo(QImage im) {
|
||||
logo = im;
|
||||
}
|
||||
|
||||
|
||||
void AboutWindow::setLogo(QString path) {
|
||||
logo = QImage(path);
|
||||
}
|
||||
|
||||
|
||||
void AboutWindow::addVersion(QString name, QString version) {
|
||||
if (!name.endsWith(":")) name.append(":");
|
||||
foreach (const SSPair & p, versions) {
|
||||
if (p.first == name) return;
|
||||
}
|
||||
version.prepend("<b>");
|
||||
if (version.contains("("))
|
||||
version.insert(version.indexOf("("), "</b>");
|
||||
else
|
||||
version.append("</b>");
|
||||
versions << SSPair(name, version);
|
||||
}
|
||||
|
||||
|
||||
void AboutWindow::addBuildInfo(QString name, QString value) {
|
||||
if (!name.endsWith(":")) name.append(":");
|
||||
foreach (const SSPair & p, builds) {
|
||||
if (p.first == name) return;
|
||||
}
|
||||
builds << SSPair(name, value);
|
||||
}
|
||||
|
||||
|
||||
void AboutWindow::setComment(QString text) {
|
||||
comment = text;
|
||||
}
|
||||
|
||||
|
||||
void AboutWindow::setStyleSheet(QString ss) {
|
||||
stylesheet = ss;
|
||||
}
|
||||
|
||||
|
||||
void AboutWindow::show() {
|
||||
AboutWindow w;
|
||||
w.exec();
|
||||
}
|
||||
|
||||
|
||||
int AboutWindow::exec() {
|
||||
#ifdef MOBILE_VIEW
|
||||
showFullScreen();
|
||||
//setWindowState(Qt::WindowFullScreen);
|
||||
#endif
|
||||
return QDialog::exec();
|
||||
}
|
||||
|
||||
|
||||
void AboutWindow::changeEvent(QEvent *e) {
|
||||
QDialog::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
ui->retranslateUi(this);
|
||||
setWindowTitle(QApplication::applicationName() + " - " + tr("About"));
|
||||
break;
|
||||
case QEvent::FontChange:
|
||||
case QEvent::Polish:
|
||||
ui->buttonOK->setIconSize(preferredIconSize(2., this));
|
||||
ui->buttonQt->setIconSize(preferredIconSize(2., this));
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void addAuthor(QString & ret, const QString & name, const QString & mail) {
|
||||
ret += QString("<p>%1 (<a href=\"mailto:%2?subject=%3\">%2</a>)</p>").arg(name, mail, QApplication::applicationName());
|
||||
}
|
||||
QString AboutWindow::authors() {
|
||||
QString ret, fc;
|
||||
if (QFile::exists(":/authors.txt")) {
|
||||
QFile f(":/authors.txt");
|
||||
f.open(QIODevice::ReadOnly);
|
||||
fc = QString::fromUtf8(f.readAll());
|
||||
} else {
|
||||
if (QFile::exists(":/AUTHORS.txt")) {
|
||||
QFile f(":/AUTHORS.txt");
|
||||
f.open(QIODevice::ReadOnly);
|
||||
fc = QString::fromUtf8(f.readAll());
|
||||
}
|
||||
}
|
||||
QTextStream ts(&fc, QIODevice::ReadOnly);
|
||||
QString l = ts.readLine();
|
||||
if (l.contains(";")) {
|
||||
QStringList sl;
|
||||
while (!ts.atEnd()) {
|
||||
l = ts.readLine();
|
||||
if (l.isEmpty()) continue;
|
||||
QString name, mail;
|
||||
sl = l.split(";");
|
||||
if (sl.size() > 0) name = sl[0].trimmed();
|
||||
if (sl.size() > 1) mail = sl[1].trimmed();
|
||||
addAuthor(ret, name, mail);
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
QPIConfig conf(&fc);
|
||||
QPIConfig::Branch br = conf.allLeaves();
|
||||
foreach (QPIConfig::Entry * e, br) {
|
||||
l = e->toString().trimmed();
|
||||
if (!l.contains("<")) continue;
|
||||
QString name, mail;
|
||||
name = l.left(l.indexOf("<"));
|
||||
mail = l.mid(name.size() + 1);
|
||||
if (mail.endsWith(">"))
|
||||
mail.chop(1);
|
||||
name = name.trimmed();
|
||||
mail = mail.trimmed();
|
||||
addAuthor(ret, name, mail);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
83
libs/application/aboutwindow.h
Normal file
83
libs/application/aboutwindow.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ABOUTWINDOW_H
|
||||
#define ABOUTWINDOW_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "qad_application_export.h"
|
||||
|
||||
|
||||
#define ADD_ABOUT_VERSION(lib) \
|
||||
{ \
|
||||
if (lib##_VERSION_BUILD > 0) \
|
||||
AboutWindow::addVersion(#lib, lib##_VERSION_NAME " (build " + QString::number(lib##_VERSION_BUILD) + ")"); \
|
||||
else \
|
||||
AboutWindow::addVersion(#lib, lib##_VERSION_NAME); \
|
||||
}
|
||||
#define ADD_ABOUT_VERSION_NAMED(lib, label) \
|
||||
{ \
|
||||
if (lib##_VERSION_BUILD > 0) \
|
||||
AboutWindow::addVersion(label, lib##_VERSION_NAME " (build " + QString::number(lib##_VERSION_BUILD) + ")"); \
|
||||
else \
|
||||
AboutWindow::addVersion(label, lib##_VERSION_NAME); \
|
||||
}
|
||||
#define ADD_ABOUT_BUILD_INFO(lib) \
|
||||
AboutWindow::addBuildInfo("Arch", lib##_ARCH); \
|
||||
AboutWindow::addBuildInfo("Compiler", lib##_CXX_COMPILER); \
|
||||
AboutWindow::addBuildInfo("CMake", lib##_CMAKE_VERSION); \
|
||||
AboutWindow::addBuildInfo("Date", lib##_BUILD_DATE);
|
||||
|
||||
namespace Ui {
|
||||
class AboutWindow;
|
||||
}
|
||||
|
||||
class QAD_APPLICATION_EXPORT AboutWindow: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
typedef QPair<QString, QString> SSPair;
|
||||
explicit AboutWindow(QWidget * parent = 0);
|
||||
~AboutWindow();
|
||||
public:
|
||||
|
||||
static void setLogo(QImage im);
|
||||
static void setLogo(QString path);
|
||||
static void addVersion(QString name, QString version);
|
||||
static void addBuildInfo(QString name, QString value);
|
||||
static void setComment(QString text);
|
||||
static void setStyleSheet(QString ss);
|
||||
|
||||
static void show();
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent * e);
|
||||
virtual int exec();
|
||||
|
||||
QString authors();
|
||||
|
||||
private:
|
||||
Ui::AboutWindow * ui;
|
||||
|
||||
static QImage logo;
|
||||
static QVector<SSPair> versions, builds;
|
||||
static QString stylesheet, comment;
|
||||
|
||||
};
|
||||
|
||||
#endif // ABOUTWINDOW_H
|
||||
155
libs/application/aboutwindow.ui
Normal file
155
libs/application/aboutwindow.ui
Normal file
@@ -0,0 +1,155 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AboutWindow</class>
|
||||
<widget class="QWidget" name="AboutWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>724</width>
|
||||
<height>502</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string> - About</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="ImageView" name="imageView">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="backgroundBrush">
|
||||
<brush brushstyle="NoBrush">
|
||||
<color alpha="255">
|
||||
<red>0</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
</color>
|
||||
</brush>
|
||||
</property>
|
||||
<property name="renderHints">
|
||||
<set>QPainter::SmoothPixmapTransform|QPainter::TextAntialiasing</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="layoutMain">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelComment"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupVersions">
|
||||
<property name="title">
|
||||
<string>Versions</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="labelAlignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBuild">
|
||||
<property name="title">
|
||||
<string>Build</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="labelAlignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupAuthors">
|
||||
<property name="title">
|
||||
<string>Authors</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelAuthors">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonQt">
|
||||
<property name="text">
|
||||
<string>About Qt...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_application.qrc">
|
||||
<normaloff>:/icons/qt.png</normaloff>:/icons/qt.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonOK">
|
||||
<property name="text">
|
||||
<string>OK</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../widgets/qad_widgets.qrc">
|
||||
<normaloff>:/icons/dialog-ok-apply.png</normaloff>:/icons/dialog-ok-apply.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ImageView</class>
|
||||
<extends>QGraphicsView</extends>
|
||||
<header>image_view.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../widgets/qad_widgets.qrc"/>
|
||||
<include location="qad_application.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonOK</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>AboutWindow</receiver>
|
||||
<slot>close()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>712</x>
|
||||
<y>490</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>320</x>
|
||||
<y>385</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
96
libs/application/edockwidget.cpp
Normal file
96
libs/application/edockwidget.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "edockwidget.h"
|
||||
#include "qad_types.h"
|
||||
#include <QEvent>
|
||||
#include <QStyle>
|
||||
|
||||
|
||||
void EDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features) {
|
||||
btn_dock->setVisible(features.testFlag(DockWidgetFloatable));
|
||||
btn_hide->setVisible(features.testFlag(DockWidgetClosable));
|
||||
QDockWidget::setFeatures(features);
|
||||
}
|
||||
|
||||
|
||||
void EDockWidget::setWindowTitle(const QString & title) {
|
||||
lbl_title->setText(title);
|
||||
QDockWidget::setWindowTitle(title);
|
||||
}
|
||||
|
||||
|
||||
void EDockWidget::setWindowIcon(const QIcon & icon) {
|
||||
//#ifndef Q_OS_MACOS
|
||||
lbl_icon->setPixmap(icon.pixmap(QSize(256, 256)));
|
||||
QDockWidget::setWindowIcon(icon);
|
||||
if (!icon.isNull()) {
|
||||
lbl_icon->setScaledContents(true);
|
||||
lbl_icon->setFixedSize(preferredIconSize(1.5, this));
|
||||
}
|
||||
//#endif
|
||||
}
|
||||
|
||||
|
||||
bool EDockWidget::event(QEvent * e) {
|
||||
if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish) {
|
||||
updateStyle();
|
||||
}
|
||||
return QDockWidget::event(e);
|
||||
}
|
||||
|
||||
|
||||
void EDockWidget::init() {
|
||||
header = new QFrame();
|
||||
header->setFrameShape(QFrame::StyledPanel);
|
||||
QBoxLayout * lay = new QBoxLayout(features().testFlag(QDockWidget::DockWidgetVerticalTitleBar) ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight);
|
||||
lay->setContentsMargins(2, 2, 2, 2);
|
||||
lay->setSpacing(2);
|
||||
lbl_icon = new QLabel();
|
||||
//#ifndef Q_OS_MACOS
|
||||
QIcon wi = windowIcon();
|
||||
if (!wi.isNull()) {
|
||||
lbl_icon->setPixmap(wi.pixmap(QSize(256,256)));
|
||||
/*#if QT_VERSION >= 0x500000
|
||||
if (lbl_icon->pixmap())
|
||||
const_cast<QPixmap*>(lbl_icon->pixmap())->setDevicePixelRatio(1.);
|
||||
#endif*/
|
||||
//qDebug() << windowTitle() << wi.pixmap(QSize(256,256)).size();
|
||||
lbl_icon->setScaledContents(true);
|
||||
}
|
||||
lbl_icon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
//#endif
|
||||
lbl_title = new QLabel(windowTitle());
|
||||
lbl_title->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
btn_dock = new QToolButton();
|
||||
//btn_dock->setIconSize(QSize(16, 16));
|
||||
btn_dock->setAutoRaise(true);
|
||||
btn_dock->setFocusPolicy(Qt::NoFocus);
|
||||
btn_dock->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
btn_hide = new QToolButton();
|
||||
//btn_hide->setIconSize(QSize(16, 16));
|
||||
btn_hide->setAutoRaise(true);
|
||||
btn_hide->setFocusPolicy(Qt::NoFocus);
|
||||
btn_hide->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
connect(btn_dock, SIGNAL(clicked(bool)), this, SLOT(dockClicked()));
|
||||
connect(btn_hide, SIGNAL(clicked(bool)), this, SLOT(hide()));
|
||||
lay->addWidget(lbl_icon);
|
||||
lay->addWidget(lbl_title);
|
||||
lay->addWidget(btn_dock);
|
||||
lay->addWidget(btn_hide);
|
||||
header->setLayout(lay);
|
||||
updateStyle();
|
||||
setTitleBarWidget(header);
|
||||
}
|
||||
|
||||
|
||||
void EDockWidget::updateStyle() {
|
||||
QSize icon_size = preferredIconSize(0.75, this);
|
||||
int bm = 2 * style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, 0, this);
|
||||
QSize btn_size = icon_size;
|
||||
btn_size += QSize(bm, bm);
|
||||
btn_dock->setIcon(style()->standardIcon(QStyle::SP_TitleBarNormalButton));
|
||||
btn_dock->setIconSize(icon_size);
|
||||
btn_dock->setFixedSize(btn_size);
|
||||
btn_hide->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
|
||||
btn_hide->setIconSize(icon_size);
|
||||
btn_hide->setFixedSize(btn_size);
|
||||
lbl_icon->setFixedSize(preferredIconSize(1.5, this));
|
||||
}
|
||||
59
libs/application/edockwidget.h
Normal file
59
libs/application/edockwidget.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef EDOCKWIDGET_H
|
||||
#define EDOCKWIDGET_H
|
||||
|
||||
#include <QDockWidget>
|
||||
#include <QLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QIcon>
|
||||
#include <QToolButton>
|
||||
#include <QDebug>
|
||||
#include "qad_application_export.h"
|
||||
|
||||
|
||||
class QAD_APPLICATION_EXPORT EDockWidget: public QDockWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EDockWidget(const QString & title, QWidget * parent = 0, Qt::WindowFlags flags = Qt::WindowFlags()): QDockWidget(title, parent, flags) {init();}
|
||||
explicit EDockWidget(QWidget * parent = 0, Qt::WindowFlags flags = Qt::WindowFlags()): QDockWidget(parent, flags) {init();}
|
||||
~EDockWidget() {delete btn_hide; delete btn_dock; delete lbl_title; delete lbl_icon; delete header;}
|
||||
|
||||
void setFeatures(QDockWidget::DockWidgetFeatures features);
|
||||
void setWindowTitle(const QString & title);
|
||||
void setWindowIcon(const QIcon & icon);
|
||||
|
||||
private:
|
||||
bool event(QEvent * e);
|
||||
void init();
|
||||
void updateStyle();
|
||||
|
||||
QFrame * header;
|
||||
QLabel * lbl_title, * lbl_icon;
|
||||
QToolButton * btn_hide, * btn_dock;
|
||||
|
||||
private slots:
|
||||
void dockClicked() {setFloating(!isFloating());}
|
||||
|
||||
};
|
||||
|
||||
#endif // EDOCKWIDGET_H
|
||||
439
libs/application/emainwindow.cpp
Normal file
439
libs/application/emainwindow.cpp
Normal file
@@ -0,0 +1,439 @@
|
||||
#include "emainwindow.h"
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QMenu>
|
||||
#include <QLabel>
|
||||
|
||||
|
||||
EMainWindow::EMainWindow(QWidget * parent): QMainWindow(parent), action_show_all_tools(this), action_hide_all_tools(this),
|
||||
action_show_all_docks(this), action_hide_all_docks(this), first_show(true) {
|
||||
tid = 0;
|
||||
menu_recent = 0;
|
||||
action_clear_recent = new QAction(QIcon(":/icons/edit-clear.png"), tr("Clear recent list"), this);
|
||||
connect(action_clear_recent, SIGNAL(triggered()), this, SLOT(clearRecent()));
|
||||
qRegisterMetaType<Qt::DockWidgetArea>("Qt::DockWidgetArea");
|
||||
action_show_all_tools.setText(tr("Show all"));
|
||||
action_show_all_docks.setText(tr("Show all"));
|
||||
action_hide_all_tools.setText(tr("Hide all"));
|
||||
action_hide_all_docks.setText(tr("Hide all"));
|
||||
action_show_all_tools.setIcon(QIcon(":/icons/layer-visible-on.png"));
|
||||
action_show_all_docks.setIcon(QIcon(":/icons/layer-visible-on.png"));
|
||||
action_hide_all_tools.setIcon(QIcon(":/icons/layer-visible-off.png"));
|
||||
action_hide_all_docks.setIcon(QIcon(":/icons/layer-visible-off.png"));
|
||||
max_recent = 8;
|
||||
setChanged(false);
|
||||
initMenus();
|
||||
initSession();
|
||||
tid = startTimer(200); // bad timer, too much overload
|
||||
}
|
||||
|
||||
|
||||
EMainWindow::~EMainWindow() {
|
||||
if (tid > 0) killTimer(tid);
|
||||
tid = 0;
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::setRecentFiles(const QStringList & rl) {
|
||||
clearRecent();
|
||||
for (int i = rl.size() - 1; i >= 0; --i)
|
||||
addToRecent(rl[i]);
|
||||
}
|
||||
|
||||
|
||||
QStringList EMainWindow::recentFiles() const {
|
||||
QStringList ret;
|
||||
foreach (QAction * a, actions_recent)
|
||||
ret << a->data().toString();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::setRecentMenu(QMenu * m) {
|
||||
menu_recent = m;
|
||||
prepareRecent();
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::showEvent(QShowEvent * e) {
|
||||
QWidget::showEvent(e);
|
||||
initMenus();
|
||||
if (!first_show) return;
|
||||
first_show = false;
|
||||
QList<QDockWidget * > docks(findChildren<QDockWidget * >());
|
||||
foreach (QDockWidget * d, docks) {
|
||||
connect(d, SIGNAL(dockLocationChanged(Qt::DockWidgetArea)), this, SLOT(changedDock()));
|
||||
connect(d, SIGNAL(topLevelChanged(bool)), this, SLOT(changedDock()));
|
||||
}
|
||||
changedDock();
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::closeEvent(QCloseEvent * e) {
|
||||
if (!checkSave()) e->ignore();
|
||||
else saveSession();
|
||||
}
|
||||
|
||||
|
||||
bool EMainWindow::eventFilter(QObject * o, QEvent * e) {
|
||||
//qDebug() << o << e;
|
||||
if (tbars.contains((QTabBar*)o) && e->type() == QEvent::MouseButtonDblClick) {
|
||||
int tab = ((QTabBar*)o)->tabAt(((QMouseEvent * )e)->pos());
|
||||
if (tab >= 0) {
|
||||
QDockWidget * dock = (QDockWidget * )(((QTabBar*)o)->tabData(tab).toULongLong());
|
||||
if (dock != 0) {
|
||||
dock->setFloating(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e->type() == QEvent::Show || e->type() == QEvent::Hide || e->type() == QEvent::ChildAdded || e->type() == QEvent::ChildRemoved || e->type() == QEvent::MouseButtonPress) {
|
||||
if (tbars.contains((QTabBar*)o) || tdocks.contains((QDockWidget*)o)) {
|
||||
if (e->type() == QEvent::MouseButtonPress) {
|
||||
if (((QMouseEvent*)e)->button() == Qt::RightButton) {
|
||||
bool popup = tbars.contains((QTabBar*)o);
|
||||
if (tdocks.contains((QDockWidget*)o))
|
||||
popup = popup || ((QDockWidget*)o)->titleBarWidget()->geometry().contains(((QMouseEvent*)e)->pos());
|
||||
if (popup) {
|
||||
createPopupMenu()->popup(((QMouseEvent*)e)->globalPos());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e->type() == QEvent::Show || e->type() == QEvent::Hide /*|| e->type() == QEvent::ChildAdded || e->type() == QEvent::ChildRemoved*/) {
|
||||
//qDebug() << "filter";
|
||||
//QMetaObject::invokeMethod(this, "changedDock", Qt::QueuedConnection);
|
||||
changedDock();
|
||||
}
|
||||
}
|
||||
}
|
||||
return QMainWindow::eventFilter(o, e);
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::timerEvent(QTimerEvent * e) {
|
||||
if (e->timerId() == tid) {
|
||||
changedDock();
|
||||
return;
|
||||
}
|
||||
QMainWindow::timerEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::changeEvent(QEvent * e) {
|
||||
QMainWindow::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
action_show_all_tools.setText(tr("Show all"));
|
||||
action_show_all_docks.setText(tr("Show all"));
|
||||
action_hide_all_tools.setText(tr("Hide all"));
|
||||
action_hide_all_docks.setText(tr("Hide all"));
|
||||
action_clear_recent->setText(tr("Clear recent list"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QMenu * EMainWindow::createPopupMenu() {
|
||||
QMenu * menuPopup = new QMenu;
|
||||
QWidgetAction * wa;
|
||||
QLabel * lbl;
|
||||
QAction * a;
|
||||
QFont f;
|
||||
f.setBold(true);
|
||||
// Toolbars
|
||||
QList<QToolBar * > tools = findChildren<QToolBar * >();
|
||||
if (!tools.isEmpty()) {
|
||||
wa = new QWidgetAction(menuPopup);
|
||||
lbl = new QLabel();
|
||||
lbl->setFrameShape(QFrame::StyledPanel);
|
||||
lbl->setFrameShadow(QFrame::Sunken);
|
||||
lbl->setText(tr("Toolbars"));
|
||||
lbl->setFont(f);
|
||||
lbl->setAlignment(Qt::AlignCenter);
|
||||
wa->setDefaultWidget(lbl);
|
||||
menuPopup->addAction(wa);
|
||||
foreach (QToolBar * i, tools) {
|
||||
if (i->property("ribbon").toBool()) continue;
|
||||
a = new QAction(i->windowTitle(), menuPopup);
|
||||
a->setCheckable(true);
|
||||
a->setChecked(!i->isHidden());
|
||||
a->setIcon(i->windowIcon());
|
||||
connect(a, SIGNAL(toggled(bool)), i, SLOT(setVisible(bool)));
|
||||
menuPopup->addAction(a);
|
||||
}
|
||||
menuPopup->addSeparator();
|
||||
menuPopup->addAction(&action_show_all_tools);
|
||||
menuPopup->addAction(&action_hide_all_tools);
|
||||
}
|
||||
// Docks
|
||||
QList<QDockWidget * > docks = findChildren<QDockWidget * >();
|
||||
if (!docks.isEmpty()) {
|
||||
wa = new QWidgetAction(menuPopup);
|
||||
lbl = new QLabel();
|
||||
lbl->setFrameShape(QFrame::StyledPanel);
|
||||
lbl->setFrameShadow(QFrame::Sunken);
|
||||
lbl->setText(tr("Docks"));
|
||||
lbl->setFont(f);
|
||||
lbl->setAlignment(Qt::AlignCenter);
|
||||
wa->setDefaultWidget(lbl);
|
||||
menuPopup->addAction(wa);
|
||||
foreach (QDockWidget * i, docks) {
|
||||
if (i->property("ribbon").toBool()) continue;
|
||||
a = new QAction(i->windowTitle(), menuPopup);
|
||||
a->setCheckable(true);
|
||||
a->setChecked(!i->isHidden());
|
||||
a->setIcon(i->windowIcon());
|
||||
connect(a, SIGNAL(toggled(bool)), i, SLOT(setVisible(bool)));
|
||||
menuPopup->addAction(a);
|
||||
}
|
||||
menuPopup->addSeparator();
|
||||
menuPopup->addAction(&action_show_all_docks);
|
||||
menuPopup->addAction(&action_hide_all_docks);
|
||||
}
|
||||
return menuPopup;
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::addToRecent(const QString & path) {
|
||||
if (path.isEmpty()) return;
|
||||
QFileInfo fi(path);
|
||||
QString fp = fi.absoluteFilePath();
|
||||
bool insert = true;
|
||||
for (int i = 0; i < actions_recent.size(); ++i)
|
||||
if (actions_recent[i]->data().toString() == fp) {
|
||||
actions_recent.push_front(actions_recent.takeAt(i));
|
||||
insert = false;
|
||||
prepareRecent();
|
||||
break;
|
||||
}
|
||||
if (!insert) return;
|
||||
QAction * a = new QAction(this);
|
||||
a->setData(fp);
|
||||
connect(a, SIGNAL(triggered()), this, SLOT(recentTriggered()));
|
||||
actions_recent.push_front(a);
|
||||
while (actions_recent.size() > max_recent)
|
||||
delete actions_recent.takeLast();
|
||||
prepareRecent();
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::prepareRecent() {
|
||||
for (int i = 0; i < actions_recent.size(); ++i) {
|
||||
QAction * a = actions_recent[i];
|
||||
a->setText(QString("&%1 - %2").arg(i + 1).arg(a->data().toString()));
|
||||
}
|
||||
if (!menu_recent) return;
|
||||
menu_recent->clear();
|
||||
menu_recent->addActions(actions_recent);
|
||||
menu_recent->addSeparator();
|
||||
menu_recent->addAction(action_clear_recent);
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::initMenus() {
|
||||
action_show_all_tools.disconnect();
|
||||
action_hide_all_tools.disconnect();
|
||||
action_show_all_docks.disconnect();
|
||||
action_hide_all_docks.disconnect();
|
||||
|
||||
QList<QToolBar * > tools = findChildren<QToolBar * >();
|
||||
foreach (QToolBar * i, tools) {
|
||||
if (i->property("ribbon").toBool()) continue;
|
||||
i->toggleViewAction()->setIcon(i->windowIcon());
|
||||
connect(&action_show_all_tools, SIGNAL(triggered(bool)), i, SLOT(show()));
|
||||
connect(&action_hide_all_tools, SIGNAL(triggered(bool)), i, SLOT(hide()));
|
||||
}
|
||||
|
||||
QList<QDockWidget * > docks = findChildren<QDockWidget * >();
|
||||
foreach (QDockWidget * i, docks) {
|
||||
if (i->property("ribbon").toBool()) continue;
|
||||
i->toggleViewAction()->setIcon(i->windowIcon());
|
||||
connect(&action_show_all_docks, SIGNAL(triggered(bool)), i, SLOT(show()));
|
||||
connect(&action_hide_all_docks, SIGNAL(triggered(bool)), i, SLOT(hide()));
|
||||
}
|
||||
|
||||
QList<QAction * > actions = findChildren<QAction * >();
|
||||
foreach (QAction * i, actions)
|
||||
i->setIconVisibleInMenu(true);
|
||||
addActions(actions);
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::initSession() {
|
||||
connect(&session, SIGNAL(loading(QPIConfig & )), this, SLOT(sessionLoading(QPIConfig & )));
|
||||
connect(&session, SIGNAL(saving(QPIConfig & )), this, SLOT(sessionSaving(QPIConfig & )));
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::saveSession() {
|
||||
session.save();
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::loadSession() {
|
||||
session.load();
|
||||
}
|
||||
|
||||
|
||||
bool EMainWindow::checkSave() {
|
||||
if (!isWindowModified()) return true;
|
||||
return saveFile(true);
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::changedDock() {
|
||||
if (isHidden()) return;
|
||||
QList<QTabBar * > tabs(findChildren<QTabBar * >());
|
||||
QList<QDockWidget * > docks = findChildren<QDockWidget * >();
|
||||
// QSet<QDockWidget * > docks_tabs;
|
||||
QDockWidget * dock;
|
||||
// qDebug() << "### change";
|
||||
foreach (QTabBar * t, tabs) {
|
||||
if (!t->objectName().isEmpty() || t->isHidden()) continue;
|
||||
if (!tbars.contains(t)) {
|
||||
tbars << t;
|
||||
connect(t, SIGNAL(tabCloseRequested(int)), this, SLOT(closeDock(int)));
|
||||
t->installEventFilter(this);
|
||||
#ifndef Q_OS_MACOS
|
||||
t->setIconSize(dockTabsIconSize());
|
||||
#endif
|
||||
t->setTabsClosable(true);
|
||||
}
|
||||
// qDebug() << "tab" << t << t->count();
|
||||
for (int i = 0; i < t->count(); ++i) {
|
||||
dock = (QDockWidget * )t->tabData(i).toULongLong();
|
||||
//qDebug() << i << t->tabData(i);
|
||||
if (!docks.contains(dock)) continue;
|
||||
#ifndef Q_OS_MACOS
|
||||
t->setIconSize(dockTabsIconSize());
|
||||
#endif
|
||||
t->setTabIcon(i, dock->windowIcon());
|
||||
// docks_tabs << dock;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (QDockWidget * d, docks) {
|
||||
if (d->titleBarWidget() == 0) continue;
|
||||
QWidget * ctb = d->titleBarWidget();
|
||||
if (!d->property("__titleWidget").isValid()) {
|
||||
d->setProperty("__titleWidget", qulonglong(ctb));
|
||||
QWidget * ntb = new QWidget();
|
||||
int m = style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin);
|
||||
ntb->setLayout(new QBoxLayout(QBoxLayout::BottomToTop));
|
||||
ntb->layout()->setContentsMargins(m, m, 0, 0);
|
||||
d->setProperty("__titleEmptyWidget", qulonglong(ntb));
|
||||
}
|
||||
if (!tdocks.contains(d)) {
|
||||
tdocks << d;
|
||||
// qDebug() << "connect" << d;
|
||||
// connect(d, SIGNAL(destroyed(QObject*)), this, SLOT(changedDockClose(QObject*)), Qt::UniqueConnection);
|
||||
d->installEventFilter(this);
|
||||
}
|
||||
//d->titleBarWidget()->setHidden(docks_tabs.contains(d));
|
||||
if (tabifiedDockWidgets(d).isEmpty()) {
|
||||
if (d->titleBarWidget() != (QWidget * )(d->property("__titleWidget").toULongLong()))
|
||||
d->setTitleBarWidget((QWidget * )(d->property("__titleWidget").toULongLong()));
|
||||
} else {
|
||||
if (d->titleBarWidget() != (QWidget * )(d->property("__titleEmptyWidget").toULongLong())) {
|
||||
d->setTitleBarWidget((QWidget * )(d->property("__titleEmptyWidget").toULongLong()));
|
||||
d->layout()->setContentsMargins(0, 20, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//void EMainWindow::changedDockClose(QObject * dock) {
|
||||
// qDebug() << "changedDockClose" << dock;
|
||||
// if (!dock) return;
|
||||
// foreach (QTabBar * t, tbars) {
|
||||
// for (int i = 0; i < t->count(); ++i)
|
||||
// if (t->tabData(i).toULongLong() == (qulonglong)dock) {
|
||||
// t->removeTab(i);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
void EMainWindow::closeDock(int index) {
|
||||
QDockWidget * dock = (QDockWidget * )((QTabBar*)sender())->tabData(index).toULongLong();
|
||||
if (dock == 0) return;
|
||||
dock->close();
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::recentTriggered() {
|
||||
QAction * a = qobject_cast<QAction * >(sender());
|
||||
if (!a) return;
|
||||
QString path = a->data().toString();
|
||||
if (path.isEmpty()) return;
|
||||
if (!checkSave()) return;
|
||||
if (load(path))
|
||||
addToRecent(path);
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::setMaxRecentItems(int mr) {
|
||||
max_recent = qMax(0, mr);
|
||||
for (int i = actions_recent.size() - 1; i >= mr; --i)
|
||||
delete actions_recent.takeLast();
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::newFile() {
|
||||
if (!checkSave()) return;
|
||||
reset(true);
|
||||
setWindowModified(false);
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::openFile() {
|
||||
if (!checkSave()) return;
|
||||
QString ret = QFileDialog::getOpenFileName(this, tr("Select file to open"), file_name, loadFilter());
|
||||
if (ret.isEmpty()) return;
|
||||
if (load(ret))
|
||||
addToRecent(ret);
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::openFiles() {
|
||||
if (!checkSave()) return;
|
||||
QStringList ret = QFileDialog::getOpenFileNames(this, tr("Select files to open"), file_name, loadFilter());
|
||||
foreach (QString s, ret) {
|
||||
if (load(s))
|
||||
addToRecent(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool EMainWindow::saveFile(bool ask) {
|
||||
if (ask) {
|
||||
int ret = QMessageBox::question(this, windowTitle(), tr("Save changes%1?").arg(!file_name.isEmpty() ? (tr(" in") + " \"" + file_name + "\"") : ""), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, QMessageBox::Save);
|
||||
if (ret == QMessageBox::Cancel) return false;
|
||||
if (ret == QMessageBox::Save) return saveFile();
|
||||
return true;
|
||||
}
|
||||
if (file_name.isEmpty()) return saveAsFile();
|
||||
if (save(file_name))
|
||||
addToRecent(file_name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool EMainWindow::saveAsFile() {
|
||||
QString ret = QFileDialog::getSaveFileName(this, tr("Select file to save"), file_name, saveFilter());
|
||||
if (ret.isEmpty()) return false;
|
||||
if (save(ret))
|
||||
addToRecent(ret);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void EMainWindow::clearRecent() {
|
||||
qDeleteAll(actions_recent);
|
||||
actions_recent.clear();
|
||||
prepareRecent();
|
||||
}
|
||||
149
libs/application/emainwindow.h
Normal file
149
libs/application/emainwindow.h
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef EMAINWINDOW_H
|
||||
#define EMAINWINDOW_H
|
||||
|
||||
#include <QTranslator>
|
||||
#include <QUrl>
|
||||
#include <QDesktopWidget>
|
||||
#include <QInputDialog>
|
||||
#include <QClipboard>
|
||||
#include <QRadioButton>
|
||||
#include <QThread>
|
||||
#include <QColorDialog>
|
||||
#include <QTime>
|
||||
#include <QSplitter>
|
||||
#include "session_manager.h"
|
||||
#include "ribbon.h"
|
||||
#include "qad_application_export.h"
|
||||
|
||||
|
||||
class QAD_APPLICATION_EXPORT UAction: public QAction {
|
||||
Q_OBJECT
|
||||
public:
|
||||
UAction(int ind,const QString & text, QObject * parent): QAction(text, parent) {
|
||||
index = ind;
|
||||
connect(this, SIGNAL(triggered()), this, SLOT(triggered()));
|
||||
connect(this, SIGNAL(toggled(bool)), this, SLOT(toggled(bool)));
|
||||
connect(this, SIGNAL(hovered()), this, SLOT(hovered()));
|
||||
}
|
||||
UAction(int ind, const QIcon & icon, const QString & text, QObject * parent): QAction(icon, text, parent) {
|
||||
index = ind;
|
||||
connect(this, SIGNAL(triggered()), this, SLOT(triggered()));
|
||||
connect(this, SIGNAL(toggled(bool)), this, SLOT(toggled(bool)));
|
||||
connect(this, SIGNAL(hovered()), this, SLOT(hovered()));
|
||||
}
|
||||
public slots:
|
||||
void show() {setVisible(true);}
|
||||
void hide() {setVisible(false);}
|
||||
void setCheckedTrue() {setChecked(true);}
|
||||
void setCheckedFalse() {setChecked(false);}
|
||||
private:
|
||||
int index;
|
||||
private slots:
|
||||
void triggered() {emit itriggered(this, index);}
|
||||
void toggled(bool t) {emit itoggled(t, this, index);}
|
||||
void hovered() {emit ihovered(this);}
|
||||
signals:
|
||||
void itriggered(QAction *, int);
|
||||
void itoggled(bool, QAction *, int);
|
||||
void ihovered(QAction * action);
|
||||
};
|
||||
|
||||
|
||||
class QAD_APPLICATION_EXPORT EMainWindow: public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int maxRecentItems READ maxRecentItems WRITE setMaxRecentItems)
|
||||
public:
|
||||
EMainWindow(QWidget * parent = 0);
|
||||
~EMainWindow();
|
||||
|
||||
virtual void reset(bool full = false) {}
|
||||
virtual bool load(const QString & path) {return true;}
|
||||
virtual bool save(const QString & path) {return true;}
|
||||
|
||||
void addSeparator() {}
|
||||
void setRecentFiles(const QStringList & rl);
|
||||
QStringList recentFiles() const;
|
||||
void setRecentMenu(QMenu * m);
|
||||
|
||||
int maxRecentItems() const {return max_recent;}
|
||||
|
||||
protected:
|
||||
// Qt`s overloaded
|
||||
void showEvent(QShowEvent * );
|
||||
void closeEvent(QCloseEvent * );
|
||||
bool eventFilter(QObject * o, QEvent * e);
|
||||
void timerEvent(QTimerEvent * e);
|
||||
void changeEvent(QEvent * e);
|
||||
QMenu * createPopupMenu();
|
||||
void addToRecent(const QString & path);
|
||||
void prepareRecent();
|
||||
|
||||
void init(const QString & config) {session.setFile(config); initMenus(); initSession(); loadSession();} // unusable
|
||||
void saveSession();
|
||||
void loadSession();
|
||||
virtual void savingSession(QPIConfig & conf) {}
|
||||
virtual void loadingSession(QPIConfig & conf) {}
|
||||
virtual QSize dockTabsIconSize() const {return iconSize();}
|
||||
virtual QString loadFilter() {return "All files(*)";}
|
||||
virtual QString saveFilter() {return "All files(*)";}
|
||||
|
||||
bool checkSave();
|
||||
void setChanged(bool yes = true) {isChanged = yes; setWindowModified(yes);}
|
||||
|
||||
void initMenus();
|
||||
void initSession();
|
||||
|
||||
QAction action_show_all_tools, action_hide_all_tools, action_show_all_docks, action_hide_all_docks;
|
||||
QString file_name;
|
||||
QList<QTabBar * > tbars;
|
||||
QList<QDockWidget * > tdocks;
|
||||
QList<QAction * > actions_recent;
|
||||
QAction * action_clear_recent;
|
||||
QMenu * menu_recent;
|
||||
SessionManager session;
|
||||
bool isChanged, first_show;
|
||||
int tid, max_recent;
|
||||
|
||||
private slots:
|
||||
void changedDock();
|
||||
void sessionLoading(QPIConfig & conf) {loadingSession(conf);}
|
||||
void sessionSaving(QPIConfig & conf) {savingSession(conf);}
|
||||
// void changedDockClose(QObject * dock);
|
||||
void closeDock(int index);
|
||||
void recentTriggered();
|
||||
|
||||
public slots:
|
||||
void setMaxRecentItems(int mr);
|
||||
void changed() {setChanged(true);}
|
||||
void newFile();
|
||||
void openFile();
|
||||
void openFiles();
|
||||
bool saveFile(bool ask = false);
|
||||
bool saveAsFile();
|
||||
void clearRecent();
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
116
libs/application/etabwidget.cpp
Normal file
116
libs/application/etabwidget.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "etabwidget.h"
|
||||
|
||||
|
||||
ETabWidget::ETabWidget(QWidget* parent): QTabWidget(parent) {
|
||||
tabBar()->setMouseTracking(true);
|
||||
tabBar()->installEventFilter(this);
|
||||
}
|
||||
|
||||
|
||||
void ETabWidget::retranslate() {
|
||||
for (int i = 0; i < buttons.size(); ++i)
|
||||
buttons[i].toolTip = QApplication::translate("MainWindow", buttons[i].srcToolTip.toUtf8(), 0/*, QCoreApplication::UnicodeUTF8*/);
|
||||
QList<QToolButton * > bl = findChildren<QToolButton * >();
|
||||
foreach (QToolButton * i, bl)
|
||||
i->setToolTip(QApplication::translate("MainWindow", i->property("sourceToolTip").toString().toUtf8(), 0/*, QCoreApplication::UnicodeUTF8*/));
|
||||
}
|
||||
|
||||
|
||||
int ETabWidget::addTab(QWidget * page, const QIcon & icon, const QString & label) {
|
||||
int ret = QTabWidget::addTab(page, icon, label);
|
||||
QWidget * w = new QWidget();
|
||||
w->setLayout(new QBoxLayout(QBoxLayout::RightToLeft));
|
||||
w->layout()->setContentsMargins(0, 0, 0, 0);
|
||||
w->layout()->setSpacing(2);
|
||||
QToolButton * b;
|
||||
foreach (const TabButton & i, buttons) {
|
||||
b = new QToolButton();
|
||||
b->setToolTip(i.toolTip);
|
||||
b->setIconSize(QSize(16, 16));
|
||||
b->setIcon(i.icon);
|
||||
//b->setFlat(true);
|
||||
b->setProperty("sourceToolTip", i.toolTip);
|
||||
b->setProperty("buttonRole", i.role);
|
||||
connect(b, SIGNAL(clicked(bool)), this, SLOT(buttonClicked()));
|
||||
w->layout()->addWidget(b);
|
||||
b->setVisible(i.visible);
|
||||
}
|
||||
tabBar()->setTabButton(ret, QTabBar::RightSide, w);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void ETabWidget::setButtonVisible(int role, bool yes) {
|
||||
QList<QToolButton * > bl = findChildren<QToolButton * >();
|
||||
foreach (QToolButton * i, bl)
|
||||
if (i->property("buttonRole").toInt() == role)
|
||||
i->setVisible(yes);
|
||||
QWidget * w;
|
||||
for (int i = 0; i < buttons.size(); ++i) {
|
||||
if (buttons[i].role == role)
|
||||
buttons[i].visible = yes;
|
||||
w = tabBar()->tabButton(i, QTabBar::RightSide);
|
||||
if (w != 0) w->adjustSize();
|
||||
}
|
||||
tabBar()->adjustSize();
|
||||
}
|
||||
|
||||
/*
|
||||
void ETabWidget::removeTab(int index) {
|
||||
tbs.removeAll(qobject_cast<QToolButton * >(tabBar()->tabButton(index, QTabBar::RightSide)->layout()->itemAt(1)->widget()));
|
||||
tbs.removeAll(qobject_cast<QToolButton * >(tabBar()->tabButton(index, QTabBar::RightSide)->layout()->itemAt(0)->widget()));
|
||||
QTabWidget::removeTab(index);
|
||||
}
|
||||
*/
|
||||
|
||||
bool ETabWidget::eventFilter(QObject * o, QEvent * e) {
|
||||
static int prev = -1;
|
||||
if (e->type() == QEvent::MouseMove) {
|
||||
QTabBar * t = qobject_cast<QTabBar * >(o);
|
||||
if (t == 0) return QTabWidget::eventFilter(o, e);
|
||||
for (int i = 0; i < count(); ++i)
|
||||
if (t->tabRect(i).contains(((QMouseEvent * )e)->pos())) {
|
||||
if (i != prev) {
|
||||
prev = i;
|
||||
emit tabHovered(i);
|
||||
}
|
||||
return QTabWidget::eventFilter(o, e);
|
||||
}
|
||||
if (-1 != prev) {
|
||||
prev = -1;
|
||||
emit tabHovered(-1);
|
||||
}
|
||||
}
|
||||
if (e->type() == QEvent::Leave) {
|
||||
if (-1 != prev) {
|
||||
prev = -1;
|
||||
emit tabHovered(-1);
|
||||
}
|
||||
}
|
||||
return QTabWidget::eventFilter(o, e);
|
||||
}
|
||||
|
||||
|
||||
void ETabWidget::changeEvent(QEvent * e) {
|
||||
QTabWidget::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
retranslate();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ETabWidget::buttonClicked() {
|
||||
QToolButton * s = qobject_cast<QToolButton * >(sender());
|
||||
if (s == 0) return;
|
||||
QWidget * pw = s->parentWidget();
|
||||
if (pw == 0) return;
|
||||
for (int i = 0; i < count(); ++i)
|
||||
if (tabBar()->tabButton(i, QTabBar::RightSide) == pw) {
|
||||
emit tabButtonClicked(i, s->property("buttonRole").toInt());
|
||||
return;
|
||||
}
|
||||
}
|
||||
75
libs/application/etabwidget.h
Normal file
75
libs/application/etabwidget.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ETABWIDGET_H
|
||||
#define ETABWIDGET_H
|
||||
|
||||
#include <QTabWidget>
|
||||
#include <QDebug>
|
||||
#include <QTabBar>
|
||||
#include <QMouseEvent>
|
||||
#include <QEvent>
|
||||
#include <QToolButton>
|
||||
#include <QPushButton>
|
||||
#include <QLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QApplication>
|
||||
#include "qad_application_export.h"
|
||||
|
||||
|
||||
class QAD_APPLICATION_EXPORT ETabWidget: public QTabWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ETabWidget(QWidget * parent = 0);
|
||||
|
||||
void retranslate();
|
||||
void addTabButton(int role, const QIcon & icon, const QString & toolTip = QString()) {buttons << TabButton(role, icon, toolTip);}
|
||||
int addTab(QWidget * page, const QIcon & icon, const QString & label);
|
||||
int addTab(QWidget * page, const QString & label) {return addTab(page, QIcon(), label);}
|
||||
void setButtonVisible(int role, bool yes);
|
||||
|
||||
private:
|
||||
bool eventFilter(QObject * o, QEvent * e);
|
||||
void tabInserted(int) {emit countChanged();}
|
||||
void tabRemoved(int) {emit countChanged();}
|
||||
void changeEvent(QEvent * e);
|
||||
|
||||
struct QAD_APPLICATION_EXPORT TabButton {
|
||||
TabButton(int r, const QIcon & i, const QString & t) {role = r; icon = i; visible = true; srcToolTip = t; toolTip = QApplication::translate("MainWindow", t.toUtf8(), 0/*, QCoreApplication::UnicodeUTF8*/);}
|
||||
int role;
|
||||
bool visible;
|
||||
QIcon icon;
|
||||
QString srcToolTip;
|
||||
QString toolTip;
|
||||
};
|
||||
|
||||
QList<TabButton> buttons;
|
||||
|
||||
private slots:
|
||||
void buttonClicked();
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
void tabHovered(int tab);
|
||||
void tabButtonClicked(int tab, int role);
|
||||
|
||||
};
|
||||
|
||||
#endif // ETABWIDGET_H
|
||||
174
libs/application/historyview.cpp
Normal file
174
libs/application/historyview.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
#include "historyview.h"
|
||||
#include <QEvent>
|
||||
|
||||
|
||||
HistoryView::HistoryView(QWidget* parent): QListWidget(parent) {
|
||||
setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||
setSelectionMode(QAbstractItemView::MultiSelection);
|
||||
setEditTriggers(NoEditTriggers);
|
||||
active_ = true;
|
||||
duplicates_ = false;
|
||||
index = 0;
|
||||
setLimit(32);
|
||||
setHistoryColor(palette().color(QPalette::Highlight));
|
||||
connect(this, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(itemClicked(QListWidgetItem*)));
|
||||
connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged()));
|
||||
registerAction(-1, tr("History cleared"), QImage(":/icons/clear-history.png"));
|
||||
}
|
||||
|
||||
|
||||
HistoryView::~HistoryView() {
|
||||
}
|
||||
|
||||
|
||||
QByteArray HistoryView::current() const {
|
||||
QListWidgetItem * ci = currentItem();
|
||||
if (!ci) return QByteArray();
|
||||
int i = row(ci);
|
||||
if (i < 0 || i >= history_.size()) return QByteArray();
|
||||
return history_[i].command;
|
||||
}
|
||||
|
||||
|
||||
void HistoryView::addEntry(int action, int count_, const QString & suffix) {
|
||||
if (!active_) return;
|
||||
QByteArray ba;
|
||||
emit commandRequest(ba);
|
||||
if (!duplicates_)
|
||||
if (current() == ba)
|
||||
return;
|
||||
int cnt = count();
|
||||
for (int i = index; i < cnt; ++i)
|
||||
if (i >= 0) delete takeItem(index);
|
||||
QListWidgetItem * li = new QListWidgetItem(actions_.value(action).icon, actionText(action, count_) + suffix);
|
||||
blockSignals(true);
|
||||
addItem(li);
|
||||
setCurrentItem(li);
|
||||
index = count();
|
||||
history_.resize(index);
|
||||
history_.back() = Entry(action, ba);
|
||||
checkLimit();
|
||||
scrollToItem(item(index - 1));
|
||||
for (int i = 0; i < index; ++i)
|
||||
item(i)->setSelected(true);
|
||||
blockSignals(false);
|
||||
emit changed();
|
||||
emit redoAvailable(false);
|
||||
emit undoAvailable((index > 1));
|
||||
emit clearAvailable(history_.count() > 1);
|
||||
}
|
||||
|
||||
|
||||
void HistoryView::registerAction(int action, const QString & text, const QImage & icon) {
|
||||
actions_[action] = HistoryView::Action(action, text, icon);
|
||||
}
|
||||
|
||||
|
||||
QString HistoryView::actionText(int action, int count_) {
|
||||
return QString(actions_.value(action).text).replace("%count", QString::number(count_));
|
||||
}
|
||||
|
||||
|
||||
void HistoryView::checkLimit() {
|
||||
if (count() < limit_ + 1) return;
|
||||
int c = count() - limit_;
|
||||
for (int i = 0; i < c; ++i) {
|
||||
if (i >= index - 1) {
|
||||
if (count() < 2) break;
|
||||
delete takeItem(1);
|
||||
history_.remove(1);
|
||||
} else {
|
||||
if (count() < 1) break;
|
||||
delete takeItem(0);
|
||||
history_.pop_front();
|
||||
index--;
|
||||
}
|
||||
}
|
||||
if (index < 1) index = 1;
|
||||
if (index > count()) index = count();
|
||||
}
|
||||
|
||||
|
||||
void HistoryView::changeEvent(QEvent * e) {
|
||||
QListWidget::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
actions_[-1].text = tr("History cleared");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HistoryView::itemClicked(QListWidgetItem * item) {
|
||||
if (!active_) return;
|
||||
if (index == row(item) + 1) return;
|
||||
index = row(item) + 1;
|
||||
//qDebug() << actions[index - 1].command;
|
||||
emit commandExecute(history_[index - 1].command);
|
||||
emit changed();
|
||||
itemSelectionChanged();
|
||||
}
|
||||
|
||||
|
||||
void HistoryView::itemSelectionChanged() {
|
||||
if (!active_) return;
|
||||
if (index < 1) index = 1;
|
||||
//qDebug() << "changed" << count();
|
||||
blockSignals(true);
|
||||
setCurrentItem(item(index - 1));
|
||||
for (int i = 0; i < index; ++i)
|
||||
item(i)->setSelected(true);
|
||||
for (int i = index; i < count(); ++i)
|
||||
item(i)->setSelected(false);
|
||||
blockSignals(false);
|
||||
emit redoAvailable(index < count());
|
||||
emit undoAvailable((index > 1));
|
||||
}
|
||||
|
||||
|
||||
void HistoryView::setLimit(int l) {
|
||||
limit_ = l;
|
||||
checkLimit();
|
||||
emit redoAvailable(index < count());
|
||||
emit undoAvailable((index > 1));
|
||||
}
|
||||
|
||||
|
||||
void HistoryView::setHistoryColor(const QColor & c) {
|
||||
color_ = c;
|
||||
QPalette pal(palette());
|
||||
pal.setColor(QPalette::Highlight, color_);
|
||||
pal.setColor(QPalette::HighlightedText, pal.color(QPalette::Text));
|
||||
setPalette(pal);
|
||||
}
|
||||
|
||||
|
||||
void HistoryView::clear(bool silent) {
|
||||
history_.clear();
|
||||
QListWidget::clear();
|
||||
if (!silent) addEntry(-1);
|
||||
emit clearAvailable(false);
|
||||
emit redoAvailable(index < count());
|
||||
emit undoAvailable((index > 1));
|
||||
}
|
||||
|
||||
|
||||
void HistoryView::undo() {
|
||||
if (index <= 1) return;
|
||||
index--;
|
||||
emit commandExecute(history_[index - 1].command);
|
||||
emit changed();
|
||||
itemSelectionChanged();
|
||||
}
|
||||
|
||||
|
||||
void HistoryView::redo() {
|
||||
if (index >= count()) return;
|
||||
index++;
|
||||
emit commandExecute(history_[index - 1].command);
|
||||
emit changed();
|
||||
itemSelectionChanged();
|
||||
}
|
||||
100
libs/application/historyview.h
Normal file
100
libs/application/historyview.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef HISTORYVIEW_H
|
||||
#define HISTORYVIEW_H
|
||||
|
||||
#include <QListWidget>
|
||||
#include <QDebug>
|
||||
#include "qad_application_export.h"
|
||||
|
||||
|
||||
class QAD_APPLICATION_EXPORT HistoryView: public QListWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool active READ isActive WRITE setActive)
|
||||
Q_PROPERTY(bool duplicatesEnabled READ isDuplicatesEnabled WRITE setDuplicatesEnabled)
|
||||
Q_PROPERTY(int limit READ limit WRITE setLimit)
|
||||
Q_PROPERTY(QColor historyColor READ historyColor WRITE setHistoryColor)
|
||||
public:
|
||||
explicit HistoryView(QWidget * parent = 0);
|
||||
~HistoryView();
|
||||
|
||||
bool isActive() const {return active_;}
|
||||
bool isDuplicatesEnabled() const {return duplicates_;}
|
||||
int limit() const {return limit_;}
|
||||
QColor historyColor() const {return color_;}
|
||||
QByteArray current() const;
|
||||
|
||||
void addEntry(int action, int count = 0, const QString & suffix = QString());
|
||||
void registerAction(int action, const QString & text, const QImage & icon = QImage());
|
||||
|
||||
private:
|
||||
struct QAD_APPLICATION_EXPORT Action {
|
||||
Action(int i = -1, const QString & t = QString(), const QImage & c = QImage()): id(i), text(t) {
|
||||
QPixmap px = QPixmap::fromImage(c);
|
||||
icon.addPixmap(px, QIcon::Active);
|
||||
icon.addPixmap(px, QIcon::Disabled);
|
||||
icon.addPixmap(px, QIcon::Normal);
|
||||
icon.addPixmap(px, QIcon::Selected);
|
||||
}
|
||||
int id;
|
||||
QString text;
|
||||
QIcon icon;
|
||||
};
|
||||
struct QAD_APPLICATION_EXPORT Entry {
|
||||
Entry(int a = -1, const QByteArray & c = QByteArray()): action(a), command(c) {}
|
||||
int action;
|
||||
QByteArray command;
|
||||
};
|
||||
|
||||
void checkLimit();
|
||||
void changeEvent(QEvent * e);
|
||||
QString actionText(int action, int count_);
|
||||
|
||||
QMap<int, Action> actions_;
|
||||
QVector<Entry> history_;
|
||||
QColor color_;
|
||||
bool active_, duplicates_;
|
||||
int index, limit_;
|
||||
|
||||
public slots:
|
||||
void setActive(bool yes) {active_ = yes;}
|
||||
void setDuplicatesEnabled(bool yes) {duplicates_ = yes;}
|
||||
void setLimit(int l);
|
||||
void setHistoryColor(const QColor & c);
|
||||
void clear(bool silent = false);
|
||||
void undo();
|
||||
void redo();
|
||||
|
||||
private slots:
|
||||
void itemClicked(QListWidgetItem * item);
|
||||
void itemSelectionChanged();
|
||||
|
||||
signals:
|
||||
void undoAvailable(bool);
|
||||
void redoAvailable(bool);
|
||||
void clearAvailable(bool);
|
||||
void commandRequest(QByteArray & s);
|
||||
void commandExecute(const QByteArray & s);
|
||||
void changed();
|
||||
|
||||
};
|
||||
|
||||
#endif // HISTORYVIEW_H
|
||||
144
libs/application/lang/qad_application_en.ts
Normal file
144
libs/application/lang/qad_application_en.ts
Normal file
@@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="en_US">
|
||||
<context>
|
||||
<name>AboutWindow</name>
|
||||
<message>
|
||||
<location filename="../aboutwindow.ui" line="14"/>
|
||||
<source> - About</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../aboutwindow.ui" line="41"/>
|
||||
<source>Versions</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../aboutwindow.ui" line="56"/>
|
||||
<source>Build</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../aboutwindow.ui" line="71"/>
|
||||
<source>Authors</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../aboutwindow.ui" line="100"/>
|
||||
<source>About Qt...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../aboutwindow.ui" line="111"/>
|
||||
<source>OK</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../aboutwindow.cpp" line="33"/>
|
||||
<location filename="../aboutwindow.cpp" line="157"/>
|
||||
<source>About</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EMainWindow</name>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="12"/>
|
||||
<location filename="../emainwindow.cpp" line="130"/>
|
||||
<source>Clear recent list</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="15"/>
|
||||
<location filename="../emainwindow.cpp" line="16"/>
|
||||
<location filename="../emainwindow.cpp" line="126"/>
|
||||
<location filename="../emainwindow.cpp" line="127"/>
|
||||
<source>Show all</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="17"/>
|
||||
<location filename="../emainwindow.cpp" line="18"/>
|
||||
<location filename="../emainwindow.cpp" line="128"/>
|
||||
<location filename="../emainwindow.cpp" line="129"/>
|
||||
<source>Hide all</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="152"/>
|
||||
<source>Toolbars</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="177"/>
|
||||
<source>Docks</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="395"/>
|
||||
<source>Select file to open</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="404"/>
|
||||
<source>Select files to open</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="414"/>
|
||||
<source>Save changes%1?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="414"/>
|
||||
<source> in</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="427"/>
|
||||
<source>Select file to save</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>HistoryView</name>
|
||||
<message>
|
||||
<location filename="../historyview.cpp" line="17"/>
|
||||
<location filename="../historyview.cpp" line="97"/>
|
||||
<source>History cleared</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LogView</name>
|
||||
<message>
|
||||
<location filename="../logview.ui" line="92"/>
|
||||
<source>Category:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../logview.ui" line="119"/>
|
||||
<location filename="../logview.cpp" line="37"/>
|
||||
<location filename="../logview.cpp" line="133"/>
|
||||
<source>Clear</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../logview.cpp" line="35"/>
|
||||
<location filename="../logview.cpp" line="131"/>
|
||||
<source>Select All</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../logview.cpp" line="36"/>
|
||||
<location filename="../logview.cpp" line="132"/>
|
||||
<source>Copy</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../logview.cpp" line="46"/>
|
||||
<source>All</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
144
libs/application/lang/qad_application_ru.ts
Normal file
144
libs/application/lang/qad_application_ru.ts
Normal file
@@ -0,0 +1,144 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="ru_RU">
|
||||
<context>
|
||||
<name>AboutWindow</name>
|
||||
<message>
|
||||
<location filename="../aboutwindow.ui" line="14"/>
|
||||
<source> - About</source>
|
||||
<translation> - О программе</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../aboutwindow.ui" line="41"/>
|
||||
<source>Versions</source>
|
||||
<translation>Версии</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../aboutwindow.ui" line="56"/>
|
||||
<source>Build</source>
|
||||
<translation>Сборка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../aboutwindow.ui" line="71"/>
|
||||
<source>Authors</source>
|
||||
<translation>Авторы</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../aboutwindow.ui" line="100"/>
|
||||
<source>About Qt...</source>
|
||||
<translation>О Qt ...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../aboutwindow.ui" line="111"/>
|
||||
<source>OK</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../aboutwindow.cpp" line="33"/>
|
||||
<location filename="../aboutwindow.cpp" line="157"/>
|
||||
<source>About</source>
|
||||
<translation>О программе</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>EMainWindow</name>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="12"/>
|
||||
<location filename="../emainwindow.cpp" line="130"/>
|
||||
<source>Clear recent list</source>
|
||||
<translation>Очистить список недавних</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="15"/>
|
||||
<location filename="../emainwindow.cpp" line="16"/>
|
||||
<location filename="../emainwindow.cpp" line="126"/>
|
||||
<location filename="../emainwindow.cpp" line="127"/>
|
||||
<source>Show all</source>
|
||||
<translation>Показать все</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="17"/>
|
||||
<location filename="../emainwindow.cpp" line="18"/>
|
||||
<location filename="../emainwindow.cpp" line="128"/>
|
||||
<location filename="../emainwindow.cpp" line="129"/>
|
||||
<source>Hide all</source>
|
||||
<translation>Скрыть все</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="152"/>
|
||||
<source>Toolbars</source>
|
||||
<translation>Панели инструментов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="177"/>
|
||||
<source>Docks</source>
|
||||
<translation>Окна</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="395"/>
|
||||
<source>Select file to open</source>
|
||||
<translation>Выбрать файл для открытия</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="404"/>
|
||||
<source>Select files to open</source>
|
||||
<translation>Выберите файлы для открытия</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="414"/>
|
||||
<source>Save changes%1?</source>
|
||||
<translation>Сохранить изменения%1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="414"/>
|
||||
<source> in</source>
|
||||
<translation> в</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../emainwindow.cpp" line="427"/>
|
||||
<source>Select file to save</source>
|
||||
<translation>Выберите файл для сохранения</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>HistoryView</name>
|
||||
<message>
|
||||
<location filename="../historyview.cpp" line="17"/>
|
||||
<location filename="../historyview.cpp" line="97"/>
|
||||
<source>History cleared</source>
|
||||
<translation>История очищена</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LogView</name>
|
||||
<message>
|
||||
<location filename="../logview.ui" line="92"/>
|
||||
<source>Category:</source>
|
||||
<translation>Категория:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../logview.ui" line="119"/>
|
||||
<location filename="../logview.cpp" line="37"/>
|
||||
<location filename="../logview.cpp" line="133"/>
|
||||
<source>Clear</source>
|
||||
<translation>Очистить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../logview.cpp" line="35"/>
|
||||
<location filename="../logview.cpp" line="131"/>
|
||||
<source>Select All</source>
|
||||
<translation>Выделить всё</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../logview.cpp" line="36"/>
|
||||
<location filename="../logview.cpp" line="132"/>
|
||||
<source>Copy</source>
|
||||
<translation>Копировать</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../logview.cpp" line="46"/>
|
||||
<source>All</source>
|
||||
<translation>Все</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
2
libs/application/lang/update.bat
Normal file
2
libs/application/lang/update.bat
Normal file
@@ -0,0 +1,2 @@
|
||||
lupdate ../ -ts qad_application_ru.ts
|
||||
lupdate ../ -ts qad_application_en.ts
|
||||
294
libs/application/logview.cpp
Normal file
294
libs/application/logview.cpp
Normal file
@@ -0,0 +1,294 @@
|
||||
#include "logview.h"
|
||||
#include "ui_logview.h"
|
||||
#include "qad_types.h"
|
||||
#include "ecombobox.h"
|
||||
#include <QTextDocument>
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QTextEdit>
|
||||
#include <QTextBlock>
|
||||
#include <QScrollBar>
|
||||
#include <QPixmap>
|
||||
#include <QEvent>
|
||||
|
||||
|
||||
LogView::Category::Category() {
|
||||
bold = false;
|
||||
}
|
||||
|
||||
|
||||
void LogView::Category::makeIcon(QSize size, QSize size_icon) {
|
||||
icon_image = QImage();
|
||||
if (!image.isNull())
|
||||
icon_image = image.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||
QPixmap px = QPixmap::fromImage(image.scaled(size_icon, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||
icon.addPixmap(px, QIcon::Active);
|
||||
icon.addPixmap(px, QIcon::Disabled);
|
||||
icon.addPixmap(px, QIcon::Normal);
|
||||
icon.addPixmap(px, QIcon::Selected);
|
||||
}
|
||||
|
||||
|
||||
LogView::LogView(QWidget * parent): QWidget(parent) {
|
||||
ui = new Ui::LogView();
|
||||
ui->setupUi(this);
|
||||
ui->textEdit->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
actionLogSelectAll = new QAction(QIcon(":/icons/select-all.png"), tr("Select All"), this);
|
||||
actionLogCopy = new QAction(QIcon(":/icons/edit-copy.png"), tr("Copy"), this);
|
||||
actionLogClear = new QAction(QIcon(":/icons/edit-clear.png"), tr("Clear"), this);
|
||||
connect(actionLogSelectAll, SIGNAL(triggered(bool)), ui->textEdit, SLOT(selectAll()));
|
||||
connect(actionLogCopy, SIGNAL(triggered(bool)), ui->textEdit, SLOT(copy()));
|
||||
connect(actionLogClear, SIGNAL(triggered(bool)), ui->textEdit, SLOT(clear()));
|
||||
ui->textEdit->addAction(actionLogSelectAll);
|
||||
ui->textEdit->addAction(actionLogCopy);
|
||||
ui->textEdit->addAction(actionLogClear);
|
||||
ui->buttonClear->setDefaultAction(ui->actionClear);
|
||||
ui->labelIconSearch->setFixedSize(preferredIconSize(1.2, this));
|
||||
ui->comboCategory->addItem(tr("All"));
|
||||
ui->textEdit->document()->setUndoRedoEnabled(false);
|
||||
setLinesLimit(10000);
|
||||
QTextCursor tc(ui->textEdit->document());
|
||||
def_cf = tc.charFormat();
|
||||
}
|
||||
|
||||
|
||||
LogView::~LogView() {
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
const QTextEdit * LogView::textEdit() const {
|
||||
return ui->textEdit;
|
||||
}
|
||||
|
||||
|
||||
void LogView::setLogFont(QFont f) {
|
||||
ui->textEdit->document()->setDefaultFont(f);
|
||||
QTextCursor tc(ui->textEdit->document());
|
||||
def_cf = tc.charFormat();
|
||||
}
|
||||
|
||||
|
||||
QFont LogView::logFont() const {
|
||||
return ui->textEdit->document()->defaultFont();
|
||||
}
|
||||
|
||||
|
||||
bool LogView::isFilterVisible() const {
|
||||
return ui->widgetToolbar->isVisible();
|
||||
}
|
||||
|
||||
|
||||
int LogView::linesLimit() const {
|
||||
int ret = ui->textEdit->document()->maximumBlockCount();
|
||||
if (ret > 0) --ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void LogView::registerCategory(const QString & label, QString keyword, const QImage & icon, QColor color, bool bold) {
|
||||
QRegularExpression regexp(keyword,
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption)
|
||||
#else
|
||||
Qt::CaseInsensitive
|
||||
#endif
|
||||
);
|
||||
registerCategory(label, regexp, icon, color, bold);
|
||||
}
|
||||
|
||||
|
||||
void LogView::registerCategory(const QString & label, QRegularExpression regexp, const QImage & icon, QColor color, bool bold) {
|
||||
if (!regexp.isValid() || regexp.pattern().isEmpty()) return;
|
||||
removeCategory(regexp);
|
||||
Category c;
|
||||
c.regexp = regexp;
|
||||
c.label = label;
|
||||
c.image = icon;
|
||||
c.color = color;
|
||||
c.bold = bold;
|
||||
c.makeIcon(iconImageSize(), preferredIconSize(1., this));
|
||||
categories.append(c);
|
||||
ui->comboCategory->addItem(c.icon, label, QVariant(regexp));
|
||||
}
|
||||
|
||||
|
||||
void LogView::removeCategory(QString keyword) {
|
||||
QRegularExpression regexp(keyword,
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
QRegularExpression::PatternOptions(QRegularExpression::CaseInsensitiveOption)
|
||||
#else
|
||||
Qt::CaseInsensitive
|
||||
#endif
|
||||
);
|
||||
removeCategory(regexp);
|
||||
}
|
||||
|
||||
|
||||
void LogView::removeCategory(QRegularExpression regexp) {
|
||||
Category c;
|
||||
c.regexp = regexp;
|
||||
categories.removeAll(c);
|
||||
for (int i = 1; i < ui->comboCategory->count(); ++i) {
|
||||
if (ui->comboCategory->itemData(i).
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
toRegularExpression()
|
||||
#else
|
||||
toRegExp()
|
||||
#endif
|
||||
.pattern() == regexp.pattern()) {
|
||||
ui->comboCategory->removeItem(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LogView::clearCategories() {
|
||||
ui->comboCategory->blockSignals(true);
|
||||
while (ui->comboCategory->count() > 1)
|
||||
ui->comboCategory->removeItem(ui->comboCategory->count() - 1);
|
||||
categories.clear();
|
||||
ui->comboCategory->blockSignals(false);
|
||||
filter();
|
||||
}
|
||||
|
||||
|
||||
void LogView::addText(const QString & text, bool insert_newline) {
|
||||
if (text.isEmpty()) return;
|
||||
QTextCursor tc(ui->textEdit->document());
|
||||
QStringList sl = text.split("\n");
|
||||
tc.movePosition(QTextCursor::End);
|
||||
QScrollBar * bar = ui->textEdit->verticalScrollBar();
|
||||
bool at_end = (bar->value() == bar->maximum()) || bar->isHidden();
|
||||
for (int i = 0; i < sl.size(); ++i) {
|
||||
tc.insertText(sl[i]);
|
||||
if ((i < sl.size() - 1) || insert_newline)
|
||||
newLine();
|
||||
}
|
||||
if (at_end)
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
|
||||
void LogView::changeEvent(QEvent * e) {
|
||||
QWidget::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
ui->retranslateUi(this);
|
||||
ui->comboCategory->setItemText(0, tr("All"));
|
||||
actionLogSelectAll->setText(tr("Select All"));
|
||||
actionLogCopy->setText(tr("Copy"));
|
||||
actionLogClear->setText(tr("Clear"));
|
||||
break;
|
||||
case QEvent::Polish: {
|
||||
ui->labelIconSearch->setFixedSize(preferredIconSize(1.2, this));
|
||||
QSize is = iconImageSize(), is_i = preferredIconSize(1., this);
|
||||
for (int i = 0; i < categories.size(); ++i)
|
||||
categories[i].makeIcon(is, is_i);
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LogView::newLine() {
|
||||
QTextCursor tc(ui->textEdit->document());
|
||||
tc.movePosition(QTextCursor::End);
|
||||
tc.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor);
|
||||
QString line = tc.selectedText();
|
||||
QImage icon;
|
||||
foreach (const Category & c, categories) {
|
||||
if (line.contains(c.regexp)) {
|
||||
QTextCharFormat cf = def_cf;
|
||||
cf.setForeground(c.color);
|
||||
if (c.bold)
|
||||
cf.setFontWeight(QFont::Bold);
|
||||
tc.setCharFormat(cf);
|
||||
icon = c.icon_image;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!icon.isNull()) {
|
||||
tc.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
|
||||
tc.insertImage(icon);
|
||||
}
|
||||
QRegularExpression regexp =
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
ui->comboCategory->currentData().toRegularExpression();
|
||||
#else
|
||||
ui->comboCategory->itemData(ui->comboCategory->currentIndex()).toRegExp();
|
||||
#endif
|
||||
QString fs = ui->lineEdit->text();
|
||||
if (isFilterVisible())
|
||||
filterBlock(tc.block(), fs, regexp);
|
||||
tc.movePosition(QTextCursor::End);
|
||||
tc.setCharFormat(def_cf);
|
||||
tc.insertBlock();
|
||||
}
|
||||
|
||||
|
||||
QSize LogView::iconImageSize() {
|
||||
int hei = QFontMetrics(ui->textEdit->document()->defaultFont()).height() / 1.25;
|
||||
return QSize(hei, hei);
|
||||
}
|
||||
|
||||
|
||||
void LogView::filterBlock(QTextBlock block, const QString & fs, const QRegularExpression & regexp) {
|
||||
bool vis = true;//, pvis = block.isVisible();
|
||||
QString line = block.text();
|
||||
if (!line.isEmpty()) {
|
||||
if (line[0] == QChar::ObjectReplacementCharacter)
|
||||
line.remove(0, 1);
|
||||
}
|
||||
if (regexp.isValid()) vis = vis && line.contains(regexp);
|
||||
if (!fs.isEmpty()) vis = vis && line.contains(fs, Qt::CaseInsensitive);
|
||||
block.setVisible(vis);
|
||||
//qDebug() << "filterBlock" << line << vis;
|
||||
//if (vis != pvis)
|
||||
// ;//ui->textEdit->document()->mar
|
||||
}
|
||||
|
||||
|
||||
void LogView::setFilterVisible(bool yes) {
|
||||
ui->widgetToolbar->setHidden(!yes);
|
||||
filter();
|
||||
}
|
||||
|
||||
|
||||
void LogView::setLinesLimit(int l) {
|
||||
ui->textEdit->document()->setMaximumBlockCount(l <= 0 ? 0 : l + 1);
|
||||
}
|
||||
|
||||
|
||||
void LogView::clear() {
|
||||
ui->textEdit->clear();
|
||||
}
|
||||
|
||||
|
||||
void LogView::scrollToBottom() {
|
||||
QScrollBar * bar = ui->textEdit->verticalScrollBar();
|
||||
bar->setValue(bar->maximum());
|
||||
}
|
||||
|
||||
|
||||
void LogView::filter() {
|
||||
QTextDocument * doc = ui->textEdit->document();
|
||||
int bc = doc->blockCount();
|
||||
QRegularExpression regexp;
|
||||
QString fs;
|
||||
if (isFilterVisible()) {
|
||||
regexp =
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
ui->comboCategory->currentData().toRegularExpression();
|
||||
#else
|
||||
ui->comboCategory->itemData(ui->comboCategory->currentIndex()).toRegExp();
|
||||
#endif
|
||||
fs = ui->lineEdit->text();
|
||||
}
|
||||
QTextBlock bl;
|
||||
for (int i = 0; i < bc; ++i) {
|
||||
bl = doc->findBlockByNumber(i);
|
||||
filterBlock(bl, fs, regexp);
|
||||
}
|
||||
doc->markContentsDirty(0, bl.position() + bl.length());
|
||||
}
|
||||
114
libs/application/logview.h
Normal file
114
libs/application/logview.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOGVIEW_H
|
||||
#define LOGVIEW_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QIcon>
|
||||
#include <QImage>
|
||||
#include <QTextBlockFormat>
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
|
||||
# include <QRegularExpression>
|
||||
#else
|
||||
# include <QRegExp>
|
||||
typedef QRegExp QRegularExpression;
|
||||
#endif
|
||||
#include "qad_application_export.h"
|
||||
|
||||
class QTextEdit;
|
||||
class QTextBlock;
|
||||
class QAction;
|
||||
|
||||
namespace Ui {
|
||||
class LogView;
|
||||
}
|
||||
|
||||
class QAD_APPLICATION_EXPORT LogView: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool filterVisible READ isFilterVisible WRITE setFilterVisible)
|
||||
Q_PROPERTY(int linesLimit READ linesLimit WRITE setLinesLimit)
|
||||
Q_PROPERTY(QFont logFont READ logFont WRITE setLogFont)
|
||||
public:
|
||||
explicit LogView(QWidget * parent = 0);
|
||||
~LogView();
|
||||
|
||||
const QTextEdit * textEdit() const;
|
||||
void setLogFont(QFont f);
|
||||
QFont logFont() const;
|
||||
|
||||
bool isFilterVisible() const;
|
||||
int linesLimit() const;
|
||||
|
||||
void registerCategory(const QString & label,
|
||||
QString keyword = QString(),
|
||||
const QImage & icon = QImage(),
|
||||
QColor color = QColor(),
|
||||
bool bold = false);
|
||||
|
||||
void registerCategory(const QString & label,
|
||||
QRegularExpression regexp,
|
||||
const QImage & icon = QImage(),
|
||||
QColor color = QColor(),
|
||||
bool bold = false);
|
||||
void removeCategory(QString keyword);
|
||||
void removeCategory(QRegularExpression regexp);
|
||||
void clearCategories();
|
||||
|
||||
void addText(const QString & text, bool insert_newline = true);
|
||||
|
||||
private:
|
||||
struct QAD_APPLICATION_EXPORT Category {
|
||||
Category();
|
||||
void makeIcon(QSize size, QSize size_icon);
|
||||
QString label;
|
||||
QRegularExpression regexp;
|
||||
QImage image, icon_image;
|
||||
QIcon icon;
|
||||
QColor color;
|
||||
bool bold;
|
||||
inline bool operator ==(const Category & it) const {return (regexp.pattern() == it.regexp.pattern());}
|
||||
};
|
||||
|
||||
void changeEvent(QEvent * e);
|
||||
void newLine();
|
||||
QSize iconImageSize();
|
||||
void filterBlock(QTextBlock block, const QString & fs, const QRegularExpression & regexp);
|
||||
|
||||
Ui::LogView * ui;
|
||||
QList<Category> categories;
|
||||
QTextCharFormat def_cf;
|
||||
QAction * actionLogSelectAll, * actionLogCopy, * actionLogClear;
|
||||
|
||||
public slots:
|
||||
void setFilterVisible(bool yes);
|
||||
void setLinesLimit(int l);
|
||||
void clear();
|
||||
|
||||
private slots:
|
||||
void scrollToBottom();
|
||||
void filter();
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // LOGVIEW_H
|
||||
198
libs/application/logview.ui
Normal file
198
libs/application/logview.ui
Normal file
@@ -0,0 +1,198 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>LogView</class>
|
||||
<widget class="QWidget" name="LogView">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>724</width>
|
||||
<height>502</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetToolbar" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonClear"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelIconSearch">
|
||||
<property name="pixmap">
|
||||
<pixmap resource="qad_application.qrc">:/icons/edit-find.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="CLineEdit" name="lineEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Category:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="EComboBox" name="comboCategory"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="undoRedoEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="acceptRichText">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionClear">
|
||||
<property name="icon">
|
||||
<iconset resource="qad_application.qrc">
|
||||
<normaloff>:/icons/edit-clear.png</normaloff>:/icons/edit-clear.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>CLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>clineedit.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>EComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>ecombobox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="qad_application.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>actionClear</sender>
|
||||
<signal>triggered()</signal>
|
||||
<receiver>LogView</receiver>
|
||||
<slot>clear()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>-1</x>
|
||||
<y>-1</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>361</x>
|
||||
<y>250</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>lineEdit</sender>
|
||||
<signal>textChanged(QString)</signal>
|
||||
<receiver>LogView</receiver>
|
||||
<slot>filter()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>544</x>
|
||||
<y>138</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>728</x>
|
||||
<y>90</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>comboCategory</sender>
|
||||
<signal>currentIndexChanged(int)</signal>
|
||||
<receiver>LogView</receiver>
|
||||
<slot>filter()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>675</x>
|
||||
<y>134</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>728</x>
|
||||
<y>76</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>clear()</slot>
|
||||
<slot>filter()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
1
libs/application/plugin/CMakeLists.txt
Normal file
1
libs/application/plugin/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
qad_plugin(application "Gui;Widgets" "")
|
||||
69
libs/application/plugin/edockwidgetplugin.cpp
Normal file
69
libs/application/plugin/edockwidgetplugin.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "edockwidget.h"
|
||||
#include "edockwidgetplugin.h"
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
|
||||
EDockWidgetPlugin::EDockWidgetPlugin(QObject * parent): QObject(parent) {
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
|
||||
void EDockWidgetPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
|
||||
if (m_initialized)
|
||||
return;
|
||||
|
||||
// Add extension registrations, etc. here
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
|
||||
bool EDockWidgetPlugin::isInitialized() const {
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
|
||||
QWidget * EDockWidgetPlugin::createWidget(QWidget * parent) {
|
||||
return new EDockWidget(parent);
|
||||
}
|
||||
|
||||
|
||||
QString EDockWidgetPlugin::name() const {
|
||||
return QLatin1String("EDockWidget");
|
||||
}
|
||||
|
||||
|
||||
QString EDockWidgetPlugin::group() const {
|
||||
return QLatin1String("Containers");
|
||||
}
|
||||
|
||||
|
||||
QIcon EDockWidgetPlugin::icon() const {
|
||||
return QIcon(":/icons/edockwidget.png");
|
||||
}
|
||||
|
||||
|
||||
QString EDockWidgetPlugin::toolTip() const {
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
|
||||
QString EDockWidgetPlugin::whatsThis() const {
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
|
||||
bool EDockWidgetPlugin::isContainer() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QString EDockWidgetPlugin::domXml() const {
|
||||
return QLatin1String("<widget class=\"EDockWidget\" name=\"dockWidget\">\n</widget>\n");
|
||||
}
|
||||
|
||||
|
||||
QString EDockWidgetPlugin::includeFile() const {
|
||||
return QLatin1String("edockwidget.h");
|
||||
}
|
||||
|
||||
36
libs/application/plugin/edockwidgetplugin.h
Normal file
36
libs/application/plugin/edockwidgetplugin.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef EDOCKWIDGETPLUGIN_H
|
||||
#define EDOCKWIDGETPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#if QT_VERSION >= 0x050000
|
||||
# include <QtUiPlugin/QDesignerCustomWidgetInterface>
|
||||
#else
|
||||
# include <QDesignerCustomWidgetInterface>
|
||||
#endif
|
||||
|
||||
class EDockWidgetPlugin: public QObject, public QDesignerCustomWidgetInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||
|
||||
public:
|
||||
EDockWidgetPlugin(QObject * parent = 0);
|
||||
|
||||
bool isContainer() const;
|
||||
bool isInitialized() const;
|
||||
QIcon icon() const;
|
||||
QString domXml() const;
|
||||
QString group() const;
|
||||
QString includeFile() const;
|
||||
QString name() const;
|
||||
QString toolTip() const;
|
||||
QString whatsThis() const;
|
||||
QWidget * createWidget(QWidget * parent);
|
||||
void initialize(QDesignerFormEditorInterface * core);
|
||||
|
||||
private:
|
||||
bool m_initialized;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
69
libs/application/plugin/emainwindowplugin.cpp
Normal file
69
libs/application/plugin/emainwindowplugin.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "emainwindow.h"
|
||||
#include "emainwindowplugin.h"
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
|
||||
EMainWindowPlugin::EMainWindowPlugin(QObject * parent): QObject(parent) {
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
|
||||
void EMainWindowPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
|
||||
if (m_initialized)
|
||||
return;
|
||||
|
||||
// Add extension registrations, etc. here
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
|
||||
bool EMainWindowPlugin::isInitialized() const {
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
|
||||
QWidget * EMainWindowPlugin::createWidget(QWidget * parent) {
|
||||
return new EMainWindow(parent);
|
||||
}
|
||||
|
||||
|
||||
QString EMainWindowPlugin::name() const {
|
||||
return QLatin1String("EMainWindow");
|
||||
}
|
||||
|
||||
|
||||
QString EMainWindowPlugin::group() const {
|
||||
return QLatin1String("Containers");
|
||||
}
|
||||
|
||||
|
||||
QIcon EMainWindowPlugin::icon() const {
|
||||
return QIcon();
|
||||
}
|
||||
|
||||
|
||||
QString EMainWindowPlugin::toolTip() const {
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
|
||||
QString EMainWindowPlugin::whatsThis() const {
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
|
||||
bool EMainWindowPlugin::isContainer() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QString EMainWindowPlugin::domXml() const {
|
||||
return QLatin1String("<widget class=\"EMainWindow\" name=\"mainWindow\">\n</widget>\n");
|
||||
}
|
||||
|
||||
|
||||
QString EMainWindowPlugin::includeFile() const {
|
||||
return QLatin1String("emainwindow.h");
|
||||
}
|
||||
|
||||
36
libs/application/plugin/emainwindowplugin.h
Normal file
36
libs/application/plugin/emainwindowplugin.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef EMAINWINDOWPLUGIN_H
|
||||
#define EMAINWINDOWPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#if QT_VERSION >= 0x050000
|
||||
# include <QtUiPlugin/QDesignerCustomWidgetInterface>
|
||||
#else
|
||||
# include <QDesignerCustomWidgetInterface>
|
||||
#endif
|
||||
|
||||
class EMainWindowPlugin: public QObject, public QDesignerCustomWidgetInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||
|
||||
public:
|
||||
EMainWindowPlugin(QObject * parent = 0);
|
||||
|
||||
bool isContainer() const;
|
||||
bool isInitialized() const;
|
||||
QIcon icon() const;
|
||||
QString domXml() const;
|
||||
QString group() const;
|
||||
QString includeFile() const;
|
||||
QString name() const;
|
||||
QString toolTip() const;
|
||||
QString whatsThis() const;
|
||||
QWidget * createWidget(QWidget * parent);
|
||||
void initialize(QDesignerFormEditorInterface * core);
|
||||
|
||||
private:
|
||||
bool m_initialized;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
69
libs/application/plugin/historyviewplugin.cpp
Normal file
69
libs/application/plugin/historyviewplugin.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "historyview.h"
|
||||
#include "historyviewplugin.h"
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
|
||||
HistoryViewPlugin::HistoryViewPlugin(QObject * parent): QObject(parent) {
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
|
||||
void HistoryViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
|
||||
if (m_initialized)
|
||||
return;
|
||||
|
||||
// Add extension registrations, etc. here
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
|
||||
bool HistoryViewPlugin::isInitialized() const {
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
|
||||
QWidget * HistoryViewPlugin::createWidget(QWidget * parent) {
|
||||
return new HistoryView(parent);
|
||||
}
|
||||
|
||||
|
||||
QString HistoryViewPlugin::name() const {
|
||||
return QLatin1String("HistoryView");
|
||||
}
|
||||
|
||||
|
||||
QString HistoryViewPlugin::group() const {
|
||||
return QLatin1String("Display Widgets");
|
||||
}
|
||||
|
||||
|
||||
QIcon HistoryViewPlugin::icon() const {
|
||||
return QIcon(":/icons/historyview.png");
|
||||
}
|
||||
|
||||
|
||||
QString HistoryViewPlugin::toolTip() const {
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
|
||||
QString HistoryViewPlugin::whatsThis() const {
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
|
||||
bool HistoryViewPlugin::isContainer() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QString HistoryViewPlugin::domXml() const {
|
||||
return QLatin1String("<widget class=\"HistoryView\" name=\"historyView\">\n</widget>\n");
|
||||
}
|
||||
|
||||
|
||||
QString HistoryViewPlugin::includeFile() const {
|
||||
return QLatin1String("historyview.h");
|
||||
}
|
||||
|
||||
36
libs/application/plugin/historyviewplugin.h
Normal file
36
libs/application/plugin/historyviewplugin.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef HISTORYVIEWPLUGIN_H
|
||||
#define HISTORYVIEWPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#if QT_VERSION >= 0x050000
|
||||
# include <QtUiPlugin/QDesignerCustomWidgetInterface>
|
||||
#else
|
||||
# include <QDesignerCustomWidgetInterface>
|
||||
#endif
|
||||
|
||||
class HistoryViewPlugin: public QObject, public QDesignerCustomWidgetInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||
|
||||
public:
|
||||
HistoryViewPlugin(QObject * parent = 0);
|
||||
|
||||
bool isContainer() const;
|
||||
bool isInitialized() const;
|
||||
QIcon icon() const;
|
||||
QString domXml() const;
|
||||
QString group() const;
|
||||
QString includeFile() const;
|
||||
QString name() const;
|
||||
QString toolTip() const;
|
||||
QString whatsThis() const;
|
||||
QWidget * createWidget(QWidget * parent);
|
||||
void initialize(QDesignerFormEditorInterface * core);
|
||||
|
||||
private:
|
||||
bool m_initialized;
|
||||
|
||||
};
|
||||
|
||||
#endif // HISTORYVIEWPLUGIN_H
|
||||
69
libs/application/plugin/logviewplugin.cpp
Normal file
69
libs/application/plugin/logviewplugin.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "logview.h"
|
||||
#include "logviewplugin.h"
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
|
||||
LogViewPlugin::LogViewPlugin(QObject * parent): QObject(parent) {
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
|
||||
void LogViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
|
||||
if (m_initialized)
|
||||
return;
|
||||
|
||||
// Add extension registrations, etc. here
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
|
||||
bool LogViewPlugin::isInitialized() const {
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
|
||||
QWidget * LogViewPlugin::createWidget(QWidget * parent) {
|
||||
return new LogView(parent);
|
||||
}
|
||||
|
||||
|
||||
QString LogViewPlugin::name() const {
|
||||
return QLatin1String("LogView");
|
||||
}
|
||||
|
||||
|
||||
QString LogViewPlugin::group() const {
|
||||
return QLatin1String("Display Widgets");
|
||||
}
|
||||
|
||||
|
||||
QIcon LogViewPlugin::icon() const {
|
||||
return QIcon(":/icons/logview.png");
|
||||
}
|
||||
|
||||
|
||||
QString LogViewPlugin::toolTip() const {
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
|
||||
QString LogViewPlugin::whatsThis() const {
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
|
||||
bool LogViewPlugin::isContainer() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QString LogViewPlugin::domXml() const {
|
||||
return QLatin1String("<widget class=\"LogView\" name=\"logView\">\n</widget>\n");
|
||||
}
|
||||
|
||||
|
||||
QString LogViewPlugin::includeFile() const {
|
||||
return QLatin1String("logview.h");
|
||||
}
|
||||
|
||||
36
libs/application/plugin/logviewplugin.h
Normal file
36
libs/application/plugin/logviewplugin.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef LOGVIEWPLUGIN_H
|
||||
#define LOGVIEWPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#if QT_VERSION >= 0x050000
|
||||
# include <QtUiPlugin/QDesignerCustomWidgetInterface>
|
||||
#else
|
||||
# include <QDesignerCustomWidgetInterface>
|
||||
#endif
|
||||
|
||||
class LogViewPlugin: public QObject, public QDesignerCustomWidgetInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||
|
||||
public:
|
||||
LogViewPlugin(QObject * parent = 0);
|
||||
|
||||
bool isContainer() const;
|
||||
bool isInitialized() const;
|
||||
QIcon icon() const;
|
||||
QString domXml() const;
|
||||
QString group() const;
|
||||
QString includeFile() const;
|
||||
QString name() const;
|
||||
QString toolTip() const;
|
||||
QString whatsThis() const;
|
||||
QWidget * createWidget(QWidget * parent);
|
||||
void initialize(QDesignerFormEditorInterface * core);
|
||||
|
||||
private:
|
||||
bool m_initialized;
|
||||
|
||||
};
|
||||
|
||||
#endif // LOGVIEWPLUGIN_H
|
||||
23
libs/application/plugin/qad_application.cpp
Normal file
23
libs/application/plugin/qad_application.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "qad_application.h"
|
||||
#include "edockwidgetplugin.h"
|
||||
#include "emainwindowplugin.h"
|
||||
#include "historyviewplugin.h"
|
||||
#include "logviewplugin.h"
|
||||
|
||||
|
||||
QADApplication::QADApplication(QObject * parent): QObject(parent) {
|
||||
//m_widgets.append(new EDockWidgetPlugin(this));
|
||||
m_widgets.append(new EMainWindowPlugin(this));
|
||||
m_widgets.append(new HistoryViewPlugin(this));
|
||||
m_widgets.append(new LogViewPlugin(this));
|
||||
}
|
||||
|
||||
|
||||
QList<QDesignerCustomWidgetInterface * > QADApplication::customWidgets() const {
|
||||
return m_widgets;
|
||||
}
|
||||
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
Q_EXPORT_PLUGIN2(qad_application_plugin, QADApplication)
|
||||
#endif
|
||||
23
libs/application/plugin/qad_application.h
Normal file
23
libs/application/plugin/qad_application.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef QAD_APPLICATION_H
|
||||
#define QAD_APPLICATION_H
|
||||
|
||||
#include <QtDesigner/QtDesigner>
|
||||
#include <QtCore/qplugin.h>
|
||||
|
||||
class QADApplication: public QObject, public QDesignerCustomWidgetCollectionInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
|
||||
#if QT_VERSION >= 0x050000
|
||||
Q_PLUGIN_METADATA(IID "qad.application")
|
||||
#endif
|
||||
public:
|
||||
explicit QADApplication(QObject * parent = 0);
|
||||
virtual QList<QDesignerCustomWidgetInterface * > customWidgets() const;
|
||||
|
||||
private:
|
||||
QList<QDesignerCustomWidgetInterface * > m_widgets;
|
||||
|
||||
};
|
||||
|
||||
#endif // QAD_APPLICATION_H
|
||||
34
libs/application/qad_application.qrc
Normal file
34
libs/application/qad_application.qrc
Normal file
@@ -0,0 +1,34 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>../../icons/application-exit.png</file>
|
||||
<file>../../icons/dialog-close.png</file>
|
||||
<file>../../icons/configure.png</file>
|
||||
<file>../../icons/document-edit.png</file>
|
||||
<file>../../icons/document-new.png</file>
|
||||
<file>../../icons/document-save.png</file>
|
||||
<file>../../icons/document-save-all.png</file>
|
||||
<file>../../icons/document-save-as.png</file>
|
||||
<file>../../icons/document-open.png</file>
|
||||
<file>../../icons/document-open-recent.png</file>
|
||||
<file>../../icons/document-close.png</file>
|
||||
<file>../../icons/edit-clear.png</file>
|
||||
<file>../../icons/edit-clear-locationbar-rtl.png</file>
|
||||
<file>../../icons/edit-find.png</file>
|
||||
<file>../../icons/list-add.png</file>
|
||||
<file>../../icons/edit-delete.png</file>
|
||||
<file>../../icons/edit-copy.png</file>
|
||||
<file>../../icons/edit-paste.png</file>
|
||||
<file>../../icons/edit-undo.png</file>
|
||||
<file>../../icons/edit-redo.png</file>
|
||||
<file>../../icons/border-line.png</file>
|
||||
<file>../../icons/edockwidget.png</file>
|
||||
<file>../../icons/historyview.png</file>
|
||||
<file>../../icons/clear-history.png</file>
|
||||
<file>../../icons/layer-visible-off.png</file>
|
||||
<file>../../icons/layer-visible-on.png</file>
|
||||
<file>../../icons/logview.png</file>
|
||||
<file>../../icons/qt.png</file>
|
||||
<file>../../icons/select-all.png</file>
|
||||
<file>../../icons/select-none.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
87
libs/application/qsingleapplication.cpp
Normal file
87
libs/application/qsingleapplication.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include <QDebug>
|
||||
#include "qsingleapplication.h"
|
||||
|
||||
|
||||
#define QSA_SHMSIZE 4096
|
||||
#define QSA_MSGSIZE (QSA_SHMSIZE - sizeof(quint32) - sizeof(quint32))
|
||||
|
||||
|
||||
QSingleApplication::QSingleApplication(const QString & app_name): QThread() {
|
||||
shm.setKey(app_name);
|
||||
exiting = false;
|
||||
first = !shm.attach();
|
||||
if (!first) {
|
||||
shm.detach();
|
||||
first = !shm.attach();
|
||||
if (!first)
|
||||
return;
|
||||
}
|
||||
shm.create(QSA_SHMSIZE);
|
||||
shm.attach();
|
||||
shm.lock();
|
||||
void * d = shm.data();
|
||||
if (d) memset(d, 0, sizeof(quint32));
|
||||
shm.unlock();
|
||||
start();
|
||||
//qDebug() << "start listen";
|
||||
}
|
||||
|
||||
|
||||
QSingleApplication::~QSingleApplication() {
|
||||
if (first) {
|
||||
exiting = true;
|
||||
quit();
|
||||
if (!wait(100))
|
||||
terminate();
|
||||
}
|
||||
if (shm.isAttached()) shm.detach();
|
||||
}
|
||||
|
||||
|
||||
void QSingleApplication::sendMessage(const QByteArray & m) {
|
||||
//qDebug() << "send message" << first << shm.isAttached();
|
||||
if (first || !shm.isAttached()) return;
|
||||
if (m.size() > int(QSA_MSGSIZE)) {
|
||||
qDebug() << "[QSingleApplication] Too large message:" << m.size() << ">" << QSA_MSGSIZE;
|
||||
return;
|
||||
}
|
||||
shm.lock();
|
||||
quint32 num(0), size = m.size();
|
||||
void * d = shm.data();
|
||||
if (d) {
|
||||
memcpy(&num, d, sizeof(quint32));
|
||||
num++;
|
||||
memcpy(d, &num, sizeof(quint32));
|
||||
memcpy((((char*)d) + sizeof(quint32)), &size, sizeof(quint32));
|
||||
memcpy((((char*)d) + sizeof(quint32) + sizeof(quint32)), m.constData(), size);
|
||||
}
|
||||
shm.unlock();
|
||||
}
|
||||
|
||||
|
||||
void QSingleApplication::run() {
|
||||
quint32 num(0), pnum(0), size(0);
|
||||
while (!exiting) {
|
||||
shm.lock();
|
||||
const void * d = shm.constData();
|
||||
if (d) {
|
||||
memcpy(&num, d, sizeof(quint32));
|
||||
if (pnum != num) {
|
||||
pnum = num;
|
||||
//qDebug() << "new message" << num;
|
||||
memcpy(&size, (((const char*)d) + sizeof(quint32)), sizeof(quint32));
|
||||
if (size <= int(QSA_MSGSIZE)) {
|
||||
QByteArray msg;
|
||||
msg.resize(size);
|
||||
memcpy(msg.data(), (((const char*)d) + sizeof(quint32) + sizeof(quint32)), size);
|
||||
emit messageReceived(msg);
|
||||
} else {
|
||||
qDebug() << "[QSingleApplication] Invalid message size:" << size;
|
||||
}
|
||||
}
|
||||
}
|
||||
shm.unlock();
|
||||
if (exiting) break;
|
||||
msleep(10);
|
||||
}
|
||||
}
|
||||
51
libs/application/qsingleapplication.h
Normal file
51
libs/application/qsingleapplication.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QSINGLEAPPLICATION_H
|
||||
#define QSINGLEAPPLICATION_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QSharedMemory>
|
||||
#include "qad_application_export.h"
|
||||
|
||||
|
||||
class QAD_APPLICATION_EXPORT QSingleApplication: public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QSingleApplication(const QString & app_name = QString("qapp"));
|
||||
~QSingleApplication();
|
||||
|
||||
bool isFirst() const {return first;}
|
||||
|
||||
private:
|
||||
void run();
|
||||
|
||||
QSharedMemory shm;
|
||||
bool first, exiting;
|
||||
|
||||
public slots:
|
||||
void sendMessage(const QByteArray & m);
|
||||
|
||||
signals:
|
||||
void messageReceived(QByteArray);
|
||||
|
||||
};
|
||||
|
||||
#endif // QSINGLEAPPLICATION_H
|
||||
243
libs/application/ribbon.cpp
Normal file
243
libs/application/ribbon.cpp
Normal file
@@ -0,0 +1,243 @@
|
||||
#include "ribbon.h"
|
||||
#include "qad_types.h"
|
||||
#include <QScrollBar>
|
||||
|
||||
|
||||
Ribbon::Ribbon(QMainWindow * parent_): QToolBar() {
|
||||
tab = 0;
|
||||
scroll_area = 0;
|
||||
delay_e = true;
|
||||
delay = 1000;
|
||||
hovered = -1;
|
||||
setObjectName("ribbon");
|
||||
setProperty("ribbon", true);
|
||||
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
parent = parent_;
|
||||
if (parent_)
|
||||
parent_->installEventFilter(this);
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
Ribbon::~Ribbon() {
|
||||
}
|
||||
|
||||
|
||||
bool Ribbon::eventFilter(QObject * o, QEvent * e) {
|
||||
//qDebug() << e;
|
||||
if (o == parent) {
|
||||
if (e->type() == QEvent::Resize || e->type() == QEvent::WindowActivate)
|
||||
_resize();
|
||||
if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish)
|
||||
_setIconsSize();
|
||||
return QToolBar::eventFilter(o, e);
|
||||
}
|
||||
if (e->type() == QEvent::ActionChanged) {
|
||||
QToolButton * b = qobject_cast<QToolButton * >((QObject * )o->property("ribbonButton").toLongLong());
|
||||
if (b != 0)
|
||||
b->setEnabled(qobject_cast<QAction * >(o)->isEnabled());
|
||||
}
|
||||
return QToolBar::eventFilter(o, e);
|
||||
}
|
||||
|
||||
|
||||
void Ribbon::timerEvent(QTimerEvent * e) {
|
||||
if (hovers.value(e->timerId(), -1) == hovered)
|
||||
tab->setCurrentIndex(hovered);
|
||||
hovers.remove(e->timerId());
|
||||
killTimer(e->timerId());
|
||||
}
|
||||
|
||||
|
||||
void Ribbon::changeEvent(QEvent * e) {
|
||||
QToolBar::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
retranslate();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Ribbon::_resize() {
|
||||
return; // WARNING
|
||||
for (int i = 0; i < tab->count(); ++i) {
|
||||
int h = ((QScrollArea*)(tab->widget(i)))->sizeHint().height();
|
||||
if (((QScrollArea*)(tab->widget(i)))->horizontalScrollBar()->isVisible())
|
||||
h += ((QScrollArea*)(tab->widget(i)))->horizontalScrollBar()->height();
|
||||
((QScrollArea*)(tab->widget(i)))->setMinimumHeight(h);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Ribbon::_setIconsSize() {
|
||||
//qDebug() << "resize" << preferredIconSize() << QApplication::font();
|
||||
setTabIconSize(preferredIconSize(2, this));
|
||||
setIconSize(preferredIconSize(3, this));
|
||||
}
|
||||
|
||||
|
||||
void Ribbon::setVisible(bool yes) {
|
||||
QToolBar::setVisible(yes);
|
||||
if (parent == 0) return;
|
||||
if (parent->menuBar() == 0) return;
|
||||
parent->menuBar()->setVisible(!yes);
|
||||
}
|
||||
|
||||
|
||||
void Ribbon::init() {
|
||||
if (parent == 0) return;
|
||||
if (parent->menuBar() == 0) return;
|
||||
QList<QAction * > lm = parent->menuBar()->actions(), la;
|
||||
clear();
|
||||
if (scroll_area) delete scroll_area;
|
||||
buttons.clear();
|
||||
tab = new ETabWidget();
|
||||
tab->setObjectName("ribbon_tab_widget");
|
||||
connect(tab, SIGNAL(tabHovered(int)), this, SLOT(tabHovered(int)));
|
||||
connect(tab, SIGNAL(currentChanged(int)), this, SIGNAL(currentTabChanged(int)));
|
||||
tab->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
QFrame * g;
|
||||
QBoxLayout * l, * tl;
|
||||
QToolButton * b;
|
||||
//tab->setIconSize(QSize(32, 32));
|
||||
foreach (QAction * i, lm) {
|
||||
if (!i->menu()) continue;
|
||||
//if (!i->menu()->isVisible()) continue;
|
||||
la = i->menu()->actions();
|
||||
QIcon tic = i->icon();
|
||||
if (!tic.isNull())
|
||||
i->setProperty("__icon", QVariant::fromValue<QIcon>(tic));
|
||||
else
|
||||
tic = i->property("__icon").value<QIcon>();
|
||||
//#ifdef Q_OS_MACOS
|
||||
// tic = QIcon();
|
||||
//#endif
|
||||
tab->addTab(new QWidget(), tic, i->text());
|
||||
//qDebug() << this << i->icon() << i->text();
|
||||
//continue;
|
||||
/*QScrollArea * sa = new QScrollArea();
|
||||
sa->setWidget(new QWidget());
|
||||
sa->setWidgetResizable(true);
|
||||
sa->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
sa->setFrameShape(QFrame::NoFrame);
|
||||
tab->addTab(sa, i->icon(), i->text());*/
|
||||
tab->widget(tab->count() - 1)->setProperty("ribbonAction", qlonglong((void * )i));
|
||||
i->setIcon(QIcon());
|
||||
tl = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
tl->setSpacing(2);
|
||||
#ifndef Q_OS_MACOS
|
||||
tl->setContentsMargins(2, 2, 2, 2);
|
||||
#else
|
||||
tl->setContentsMargins(2, 0, 2, 2);
|
||||
#endif
|
||||
g = new QFrame(); g->setFrameShape(QFrame::StyledPanel);
|
||||
l = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
g->setLayout(l);
|
||||
l->setSpacing(2);
|
||||
l->setContentsMargins(2, 2, 2, 2);
|
||||
foreach (QAction * j, la) {
|
||||
if (j->isSeparator()) {
|
||||
if (l->isEmpty()) continue;
|
||||
tl->addWidget(g);
|
||||
g = new QFrame(); g->setFrameShape(QFrame::StyledPanel);
|
||||
l = new QBoxLayout(QBoxLayout::LeftToRight);
|
||||
l->setSpacing(2);
|
||||
l->setContentsMargins(2, 2, 2, 2);
|
||||
g->setLayout(l);
|
||||
continue;
|
||||
}
|
||||
if (qobject_cast<QWidgetAction*>(j)) {
|
||||
QWidget * _w = qobject_cast<QWidgetAction*>(j)->defaultWidget();
|
||||
l->addWidget(_w);
|
||||
_w->show();
|
||||
continue;
|
||||
}
|
||||
b = new QToolButton();
|
||||
//b->setVisible(j->isVisible());
|
||||
b->setEnabled(j->isEnabled());
|
||||
b->setProperty("ribbonAction", qlonglong((void * )j));
|
||||
j->setProperty("ribbonButton", qlonglong((void * )b));
|
||||
j->installEventFilter(this);
|
||||
if (j->menu() != 0) {
|
||||
b->setPopupMode(QToolButton::InstantPopup);
|
||||
b->setMenu(j->menu());
|
||||
} else {
|
||||
b->setCheckable(j->isCheckable());
|
||||
if (b->isCheckable()) {
|
||||
b->setChecked(j->isChecked());
|
||||
connect(b, SIGNAL(toggled(bool)), j, SLOT(setChecked(bool)));
|
||||
connect(b, SIGNAL(clicked(bool)), j, SIGNAL(triggered(bool)));
|
||||
connect(j, SIGNAL(toggled(bool)), b, SLOT(setChecked(bool)));
|
||||
} else
|
||||
connect(b, SIGNAL(clicked()), j, SLOT(trigger()));
|
||||
}
|
||||
//b->setIconSize(QSize(16, 16));
|
||||
b->setIcon(j->icon());
|
||||
b->setText(j->text());
|
||||
b->setToolTip(j->text());
|
||||
//b->addAction(j);
|
||||
//b->setShortcut(j->shortcut());
|
||||
b->setAutoRaise(true);
|
||||
b->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
|
||||
b->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
|
||||
buttons << b;
|
||||
l->addWidget(b);
|
||||
}
|
||||
tl->addWidget(g);
|
||||
tl->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed));
|
||||
//sa->widget()->setLayout(tl);
|
||||
tab->widget(tab->count() - 1)->setLayout(tl);
|
||||
}
|
||||
setFloatable(false);
|
||||
setMovable(false);
|
||||
/*scroll_area = new QScrollArea();
|
||||
scroll_area->setFrameShape(QFrame::NoFrame);
|
||||
scroll_area->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
scroll_area->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
scroll_area->setWidget(tab);*/
|
||||
_resize();
|
||||
//addWidget(scroll_area);
|
||||
addWidget(tab);
|
||||
parent->addToolBar(Qt::TopToolBarArea, this);
|
||||
parent->menuBar()->hide();
|
||||
tab->setAutoFillBackground(false);
|
||||
_setIconsSize();
|
||||
}
|
||||
|
||||
|
||||
void Ribbon::retranslate() {
|
||||
QAction * a;
|
||||
foreach (QToolButton * i, buttons) {
|
||||
a = (QAction * )(i->property("ribbonAction").toLongLong());
|
||||
if (a == 0) continue;
|
||||
i->setText(a->text());
|
||||
i->setToolTip(a->toolTip());
|
||||
//i->setShortcut(a->shortcut());
|
||||
}
|
||||
for (int i = 0; i < tab->count(); ++i) {
|
||||
a = (QAction * )(tab->widget(i)->property("ribbonAction").toLongLong());
|
||||
if (a == 0) continue;
|
||||
tab->setTabText(i, a->text());
|
||||
}
|
||||
_resize();
|
||||
}
|
||||
|
||||
|
||||
void Ribbon::setIconSize(const QSize & size) {
|
||||
foreach (QToolButton * i, buttons)
|
||||
i->setIconSize(size);
|
||||
_resize();
|
||||
}
|
||||
|
||||
|
||||
void Ribbon::setTabIconSize(const QSize & size) {
|
||||
#ifndef Q_OS_MACOS
|
||||
tab->setIconSize(size);
|
||||
#endif
|
||||
_resize();
|
||||
}
|
||||
84
libs/application/ribbon.h
Normal file
84
libs/application/ribbon.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef RIBBON_H
|
||||
#define RIBBON_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QActionGroup>
|
||||
#include <QWidgetAction>
|
||||
#include <QMenuBar>
|
||||
#include <QTabWidget>
|
||||
#include <QGroupBox>
|
||||
#include <QDockWidget>
|
||||
#include <QToolBar>
|
||||
#include <QToolButton>
|
||||
#include <QScrollArea>
|
||||
#include "etabwidget.h"
|
||||
#include "qad_application_export.h"
|
||||
|
||||
|
||||
class QAD_APPLICATION_EXPORT Ribbon: public QToolBar
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Ribbon(QMainWindow * parent = 0);
|
||||
~Ribbon();
|
||||
|
||||
void init();
|
||||
void retranslate();
|
||||
void setIconSize(const QSize & size);
|
||||
void setTabIconSize(const QSize & size);
|
||||
void setButtonStyle(const Qt::ToolButtonStyle & style) {foreach (QToolButton * i, buttons) i->setToolButtonStyle(style);}
|
||||
void setAutoSwitchEnabled(bool yes) {delay_e = yes;}
|
||||
void setAutoSwitchDelay(float delay_s) {delay = delay_s * 1000;}
|
||||
void setCurrentTab(int tab_) {if (tab_ < 0 || tab_ >= tab->count()) return; tab->setCurrentIndex(tab_);}
|
||||
int currentTab() const {return tab->currentIndex();}
|
||||
QTabWidget * tabWidget() const {return tab;}
|
||||
|
||||
private:
|
||||
bool eventFilter(QObject * o, QEvent * e);
|
||||
void timerEvent(QTimerEvent * e);
|
||||
void changeEvent(QEvent *e);
|
||||
void _resize();
|
||||
void _setIconsSize();
|
||||
|
||||
int hovered, delay;
|
||||
bool delay_e;
|
||||
QList<QToolButton * > buttons;
|
||||
QMap<int, int> hovers;
|
||||
ETabWidget * tab;
|
||||
QScrollArea * scroll_area;
|
||||
QMainWindow * parent;
|
||||
|
||||
private slots:
|
||||
void tabHovered(int tab) {if (!delay_e) return; hovers.clear(); hovered = tab; hovers.insert(startTimer(delay), tab);}
|
||||
|
||||
public slots:
|
||||
void setVisible(bool yes);
|
||||
void setHidden(bool yes) {setVisible(!yes);}
|
||||
void show() {setVisible(true);}
|
||||
void hide() {setVisible(false);}
|
||||
|
||||
signals:
|
||||
void currentTabChanged(int);
|
||||
|
||||
};
|
||||
|
||||
#endif // RIBBON_H
|
||||
1
libs/blockview/CMakeLists.txt
Normal file
1
libs/blockview/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
qad_library(blockview "Gui;Widgets" "qad_utils;qad_widgets")
|
||||
62
libs/blockview/alignedtextitem.cpp
Normal file
62
libs/blockview/alignedtextitem.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include "alignedtextitem.h"
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
AlignedTextItem::AlignedTextItem(QGraphicsItem * parent): QGraphicsItem(parent), text_(this) {
|
||||
align_ = Qt::AlignTop | Qt::AlignHCenter;
|
||||
text_.setData(1003, true);
|
||||
setFont(font());
|
||||
_move();
|
||||
}
|
||||
|
||||
|
||||
AlignedTextItem::AlignedTextItem(const QString & text, QGraphicsItem * parent): QGraphicsItem(parent), text_(this) {
|
||||
align_ = Qt::AlignTop | Qt::AlignHCenter;
|
||||
text_.setData(1003, true);
|
||||
setFont(font());
|
||||
setText(text);
|
||||
}
|
||||
|
||||
void AlignedTextItem::setFont(const QFont & f) {
|
||||
font_ = f;
|
||||
text_.setFont(sceneFont(f));
|
||||
_move();
|
||||
}
|
||||
|
||||
|
||||
QFont AlignedTextItem::sceneFont(const QFont & f) {
|
||||
QFont ret = f;
|
||||
double scl = 16. / QApplication::fontMetrics().size(0, "0").height();
|
||||
ret.setPointSizeF(ret.pointSizeF() * scl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QPointF AlignedTextItem::_point(Qt::Alignment a) const {
|
||||
QRectF br = text_.boundingRect();
|
||||
QPointF ret;
|
||||
switch (Qt::AlignmentFlag(int(align_ & Qt::AlignHorizontal_Mask))) {
|
||||
case Qt::AlignRight: ret.rx() = br.left(); break;
|
||||
case Qt::AlignHCenter: ret.rx() = br.center().x(); break;
|
||||
case Qt::AlignLeft: ret.rx() = br.right(); break;
|
||||
default: break;
|
||||
}
|
||||
switch (Qt::AlignmentFlag(int(align_ & Qt::AlignVertical_Mask))) {
|
||||
case Qt::AlignBottom: ret.ry() = br.top(); break;
|
||||
case Qt::AlignVCenter: ret.ry() = br.center().y(); break;
|
||||
case Qt::AlignTop: ret.ry() = br.bottom(); break;
|
||||
default: break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void AlignedTextItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) {
|
||||
if (isSelected()) {
|
||||
painter->setPen(QPen(Qt::DashLine));
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawRect(boundingRect());
|
||||
}
|
||||
}
|
||||
68
libs/blockview/alignedtextitem.h
Normal file
68
libs/blockview/alignedtextitem.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ALIGNEDTEXTITEM_H
|
||||
#define ALIGNEDTEXTITEM_H
|
||||
|
||||
#include <QGraphicsSimpleTextItem>
|
||||
#include <QPen>
|
||||
#include <QBrush>
|
||||
#include <QFont>
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT AlignedTextItem: public QGraphicsItem {
|
||||
public:
|
||||
AlignedTextItem(QGraphicsItem * parent = 0);
|
||||
AlignedTextItem(const QString & text, QGraphicsItem * parent = 0);
|
||||
|
||||
void setText(const QString & t) {text_.setText(t); _move();}
|
||||
void setFont(const QFont & f);
|
||||
void setPen(const QPen & p) {text_.setPen(p); _move();}
|
||||
void setBrush(const QBrush & b) {text_.setBrush(b); _move();}
|
||||
void setAlignment(Qt::Alignment align) {align_ = align; _move();}
|
||||
|
||||
QString text() const {return text_.text();}
|
||||
QFont font() const {return /*text_.font()*/font_;}
|
||||
QPen pen() const {return text_.pen();}
|
||||
QBrush brush() const {return text_.brush();}
|
||||
Qt::Alignment alignment() const {return align_;}
|
||||
|
||||
void clear() {setText(QString());}
|
||||
|
||||
enum {Type = UserType + 0x100};
|
||||
|
||||
static QFont sceneFont(const QFont & f);
|
||||
|
||||
protected:
|
||||
virtual QRectF boundingRect() const {return text_.boundingRect().translated(text_.pos());}
|
||||
virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0);
|
||||
virtual int type() const {return Type;}
|
||||
|
||||
void _move() {text_.setPos(-_point(align_));}
|
||||
QPointF _point(Qt::Alignment a) const;
|
||||
|
||||
QGraphicsSimpleTextItem text_;
|
||||
Qt::Alignment align_;
|
||||
QFont font_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // ALIGNEDTEXTITEM_H
|
||||
109
libs/blockview/blockbase.cpp
Normal file
109
libs/blockview/blockbase.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#include "blockbase.h"
|
||||
#include "alignedtextitem.h"
|
||||
#include "qvariantedit.h"
|
||||
|
||||
|
||||
QDataStream & operator <<(QDataStream & s, const QGraphicsItem * item) {
|
||||
if (!item) {
|
||||
s << int(-1);
|
||||
return s;
|
||||
}
|
||||
const QGraphicsRectItem * irect = qgraphicsitem_cast<const QGraphicsRectItem*>(item);
|
||||
const QGraphicsEllipseItem * iell = qgraphicsitem_cast<const QGraphicsEllipseItem*>(item);
|
||||
const QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<const QGraphicsSimpleTextItem*>(item);
|
||||
const AlignedTextItem * iatext = qgraphicsitem_cast<const AlignedTextItem*>(item);
|
||||
const QGraphicsLineItem * iline = qgraphicsitem_cast<const QGraphicsLineItem*>(item);
|
||||
const QGraphicsPathItem * ipath = qgraphicsitem_cast<const QGraphicsPathItem*>(item);
|
||||
const QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<const QGraphicsPixmapItem*>(item);
|
||||
if (irect) {
|
||||
s << int(0) << (irect->pen()) << (irect->brush()) << (irect->rect());
|
||||
} else if (iell) {
|
||||
s << int(1) << (iell->pen()) << (iell->brush()) << (iell->rect());
|
||||
} else if (itext) {
|
||||
s << int(2) << (itext->pen()) << (itext->brush()) << (itext->font()) << (itext->text());
|
||||
} else if (iatext) {
|
||||
s << int(6) << (iatext->pen()) << (iatext->brush()) << (iatext->font()) << (iatext->text()) << int(iatext->alignment());
|
||||
} else if (iline) {
|
||||
s << int(3) << (iline->pen()) << (iline->line());
|
||||
} else if (ipath) {
|
||||
s << int(4) << (ipath->pen()) << (ipath->path());
|
||||
} else if (ipixmap) {
|
||||
s << int(7) << (ipixmap->pixmap()) << (ipixmap->transform());
|
||||
} else {
|
||||
s << int(-1);
|
||||
return s;
|
||||
}
|
||||
s << (item->pos()) << (item->rotation()) << int(item->flags());
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
QDataStream & operator >>(QDataStream & s, QGraphicsItem *& item) {
|
||||
int type_; s >> type_;
|
||||
if (type_ < 0) {
|
||||
item = 0;
|
||||
return s;
|
||||
}
|
||||
QGraphicsRectItem * nrect = 0;
|
||||
QGraphicsEllipseItem * nell = 0;
|
||||
QGraphicsSimpleTextItem * ntext = 0;
|
||||
AlignedTextItem * natext = 0;
|
||||
QGraphicsLineItem * nline = 0;
|
||||
QGraphicsPathItem * npath = 0;
|
||||
QGraphicsPixmapItem * npixmap = 0;
|
||||
item = 0;
|
||||
switch (type_) {
|
||||
case 0:
|
||||
nrect = new QGraphicsRectItem(); item = nrect;
|
||||
{QPen _v; s >> _v; nrect->setPen(_v);}
|
||||
{QBrush _v; s >> _v; nrect->setBrush(_v);}
|
||||
{QRectF _v; s >> _v; nrect->setRect(_v);}
|
||||
break;
|
||||
case 1:
|
||||
nell = new QGraphicsEllipseItem(); item = nell;
|
||||
{QPen _v; s >> _v; nell->setPen(_v);}
|
||||
{QBrush _v; s >> _v; nell->setBrush(_v);}
|
||||
{QRectF _v; s >> _v; nell->setRect(_v);}
|
||||
break;
|
||||
case 2:
|
||||
ntext = new QGraphicsSimpleTextItem(); item = ntext;
|
||||
{QPen _v; s >> _v; ntext->setPen(_v);}
|
||||
{QBrush _v; s >> _v; ntext->setBrush(_v);}
|
||||
{QFont _v; s >> _v; ntext->setFont(_v);}
|
||||
{QString _v; s >> _v; ntext->setText(_v);}
|
||||
break;
|
||||
case 6:
|
||||
natext = new AlignedTextItem(); item = natext;
|
||||
{QPen _v; s >> _v; natext->setPen(_v);}
|
||||
{QBrush _v; s >> _v; natext->setBrush(_v);}
|
||||
{QFont _v; s >> _v; natext->setFont(_v);}
|
||||
{QString _v; s >> _v; natext->setText(_v);}
|
||||
{int _v; s >> _v; natext->setAlignment((Qt::AlignmentFlag)_v);}
|
||||
break;
|
||||
case 3:
|
||||
nline = new QGraphicsLineItem(); item = nline;
|
||||
{QPen _v; s >> _v; nline->setPen(_v);}
|
||||
{QLineF _v; s >> _v; nline->setLine(_v);}
|
||||
break;
|
||||
case 4:
|
||||
npath = new QGraphicsPathItem(); item = npath;
|
||||
{QPen _v; s >> _v; npath->setPen(_v);}
|
||||
{QPainterPath _v; s >> _v; npath->setPath(_v);}
|
||||
break;
|
||||
case 5:
|
||||
npixmap = new QGraphicsPixmapItem(); item = npixmap;
|
||||
{QPixmap _v; s >> _v; npixmap->setPixmap(_v);}
|
||||
break;
|
||||
case 7:
|
||||
npixmap = new QGraphicsPixmapItem(); item = npixmap;
|
||||
{QPixmap _v; s >> _v; npixmap->setPixmap(_v);}
|
||||
{QTransform _t; s >> _t; npixmap->setTransform(_t);}
|
||||
break;
|
||||
}
|
||||
if (item) {
|
||||
{QPointF _v; s >> _v; item->setPos(_v);}
|
||||
{qreal _v; s >> _v; item->setRotation(_v);}
|
||||
{int _v; s >> _v; item->setFlags((QGraphicsItem::GraphicsItemFlags)_v);}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
101
libs/blockview/blockbase.h
Normal file
101
libs/blockview/blockbase.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLOCKBASE_H
|
||||
#define BLOCKBASE_H
|
||||
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsItem>
|
||||
#include <QGraphicsObject>
|
||||
#include <QGraphicsEllipseItem>
|
||||
#include <QGraphicsSceneHoverEvent>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QStack>
|
||||
#include "qad_types.h"
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
|
||||
/// data:
|
||||
/// 1002 - flag for move parent (true)
|
||||
/// 1003 - flag for visualize selection (true)
|
||||
/// 1004 - BlockItemPin ("pin")
|
||||
/// 1005 - BlockBusItem ("connection")
|
||||
/// 1006 - BlockItem ("item")
|
||||
/// 1007 - BlockItem selection (true)
|
||||
/// 1008 - item is NOT decor, ignore for function decors() (true)
|
||||
/// 1009 - item is scene decor ("decor")
|
||||
/// 1010 - BlockItem decor (src text for QGraphicsSimpleTextItem)
|
||||
/// 1011 - item is BlockItem decor (true)
|
||||
/// 1100 - flag for correct move (true)
|
||||
|
||||
static const int _blockitem_current_version_ = 1;
|
||||
|
||||
|
||||
enum BlockviewItemData {
|
||||
bvidSelected = 1000, // bool
|
||||
bvidItemPos = 1001, // QpointF
|
||||
bvidMoveParent = 1002, // bool
|
||||
bvidVisualizeSelection = 1003, // bool
|
||||
bvidType = 1005, // BlockviewItemType
|
||||
bvidInvalidItem = 1008, // bool
|
||||
bvidDecorText = 1010, // QString
|
||||
bvidBlockDecor = 1011, // bool
|
||||
bvidDTHandle = 1012, // bool
|
||||
bvidCorrectMove = 1100, // bool
|
||||
};
|
||||
|
||||
enum BlockviewItemType {
|
||||
bvitPin,
|
||||
bvitBus,
|
||||
bvitBlock,
|
||||
bvitSelection,
|
||||
bvitDecor,
|
||||
bvitItemText,
|
||||
};
|
||||
|
||||
QAD_BLOCKVIEW_EXPORT QDataStream & operator <<(QDataStream & s, const QGraphicsItem * item);
|
||||
QAD_BLOCKVIEW_EXPORT QDataStream & operator >>(QDataStream & s, QGraphicsItem *& item);
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT BlockItemBase: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS(Action)
|
||||
public:
|
||||
|
||||
enum Action {
|
||||
BlockAdd = 1,
|
||||
BlockMove,
|
||||
BlockRemove,
|
||||
BlockCopy,
|
||||
BusAdd,
|
||||
BusRemove,
|
||||
BusPointAdd,
|
||||
BusPointMove,
|
||||
BusPointRemove,
|
||||
BusSegmentAdd,
|
||||
BusSegmentMove,
|
||||
BusSegmentRemove,
|
||||
Paste
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // BLOCKBASE_H
|
||||
834
libs/blockview/blockbusitem.cpp
Normal file
834
libs/blockview/blockbusitem.cpp
Normal file
@@ -0,0 +1,834 @@
|
||||
#include "blockview.h"
|
||||
|
||||
|
||||
BlockBusItem::BlockBusItem(bool temp): QGraphicsObject(), PropertyStorage() {
|
||||
temp_ = temp;
|
||||
_init();
|
||||
if (!temp) setData(1005, "connection");
|
||||
else hide();
|
||||
}
|
||||
|
||||
|
||||
BlockBusItem::BlockBusItem(const BlockBusItem & other): QGraphicsObject(), PropertyStorage() {
|
||||
temp_ = false;
|
||||
_init();
|
||||
setData(1005, "connection");
|
||||
setPen(other.pen());
|
||||
setBrush(other.brush());
|
||||
setBusType(other.busType());
|
||||
square_node = other.square_node;
|
||||
max_ep = other.max_ep;
|
||||
pol = other.pol;
|
||||
segments = other.segments;
|
||||
im_bus = other.im_bus;
|
||||
im_end = other.im_end;
|
||||
im_bus_scale = other.im_bus_scale;
|
||||
im_end_scale = other.im_end_scale;
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::_init() {
|
||||
setZValue(1.);
|
||||
setBusType(-1);
|
||||
setAcceptHoverEvents(true);
|
||||
ph.setColor(Qt::blue); ph.setJoinStyle(Qt::MiterJoin);
|
||||
bh.setColor(Qt::blue); bh.setStyle(Qt::SolidPattern);
|
||||
pu = pa = pr = ph; bu = ba = br = bh;
|
||||
grid_step = 10.;
|
||||
pu.setWidth(1);
|
||||
pu.setColor(Qt::black); bu.setColor(Qt::black);
|
||||
pa.setColor(Qt::darkGreen); ba.setColor(Qt::darkGreen);
|
||||
pr.setColor(Qt::darkRed); br.setColor(Qt::darkRed);
|
||||
pn.setColor(Qt::gray); pn.setStyle(Qt::DashLine);
|
||||
if (temp_) {
|
||||
pu.setStyle(Qt::DashLine);
|
||||
pu.setColor(Qt::darkGray);
|
||||
bu.setColor(Qt::darkGray);
|
||||
}
|
||||
setPen(pu); setBrush(bu);
|
||||
square_node = false;
|
||||
max_ep = 0;
|
||||
selPoint = selSegment = state_ = -1;
|
||||
pen_width = 2.;
|
||||
point_size = 3.;
|
||||
im_bus_scale = im_end_scale = 1.;
|
||||
moved = deleted = mark_in = mark_out = new_segment = mm_cancel = lm_point = false;
|
||||
anim_point_size.setTargetObject(this);
|
||||
anim_point_size.setPropertyName("pointSize");
|
||||
anim_point_size.setStartValue(0);
|
||||
anim_point_size.setEasingCurve(QEasingCurve::OutQuad);
|
||||
anim_point_size.setEndValue(point_size);
|
||||
anim_point_size.setDuration(200);
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::reconnect() {
|
||||
if (temp_) return;
|
||||
if (!scene()) return;
|
||||
if (scene()->views().isEmpty()) return;
|
||||
QMetaObject::invokeMethod(scene()->views().back(), "reconnectAll");
|
||||
}
|
||||
|
||||
|
||||
bool BlockBusItem::sceneEvent(QEvent * e) {
|
||||
if (temp_) return QGraphicsObject::sceneEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::GraphicsSceneHoverEnter: hoverEnterEvent((QGraphicsSceneHoverEvent * )e); break;
|
||||
case QEvent::GraphicsSceneHoverMove: hoverMoveEvent((QGraphicsSceneHoverEvent * )e); break;
|
||||
case QEvent::GraphicsSceneHoverLeave: hoverLeaveEvent((QGraphicsSceneHoverEvent * )e); break;
|
||||
case QEvent::GraphicsSceneMousePress: mousePressEvent((QGraphicsSceneMouseEvent * )e); break;
|
||||
case QEvent::GraphicsSceneMouseMove: mouseMoveEvent((QGraphicsSceneMouseEvent * )e); break;
|
||||
case QEvent::GraphicsSceneMouseRelease: mouseReleaseEvent((QGraphicsSceneMouseEvent * )e); break;
|
||||
default: break;
|
||||
}
|
||||
return QGraphicsObject::sceneEvent(e);
|
||||
}
|
||||
|
||||
|
||||
int BlockBusItem::addPoint(const QPointF & point, bool update) {
|
||||
int ei = pol.indexOf(point);
|
||||
if (ei >= 0) return ei;
|
||||
if (selSegment < 0 || selSegment >= pol.size() - 1) return -1;
|
||||
pol << quantize(nearestPointOnLine(pol[segments[selSegment].first], pol[segments[selSegment].second], point), grid_step);
|
||||
selPoint = pol.size() - 1;
|
||||
segments << QPair<int, int>(selPoint, segments[selSegment].second);
|
||||
segments[selSegment].second = selPoint;
|
||||
selSegment = -1;
|
||||
updateGeometry();
|
||||
if (scene() != 0 && update) scene()->update();
|
||||
return pol.size() - 1;
|
||||
}
|
||||
|
||||
|
||||
int BlockBusItem::segmentPointPair(int point, int * seg) const {
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
if (segments[i].first == point) {
|
||||
if (seg) *seg = i;
|
||||
return segments[i].second;
|
||||
}
|
||||
if (segments[i].second == point) {
|
||||
if (seg) *seg = i;
|
||||
return segments[i].first;
|
||||
}
|
||||
}
|
||||
if (seg) *seg = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::removePoint(int index) {
|
||||
if (index < 0 || index > pol.size() - 1) return;
|
||||
int sc = 0, fs = -1, ss = -1;
|
||||
for (int i = 0; i < segments.size(); ++i)
|
||||
if (segments[i].first == index ||
|
||||
segments[i].second == index) {
|
||||
sc++;
|
||||
if (fs < 0) fs = i;
|
||||
else ss = i;
|
||||
}
|
||||
int ei(0);
|
||||
switch (sc) {
|
||||
case 1:
|
||||
segments.removeAt(fs);
|
||||
break;
|
||||
case 2:
|
||||
if (segments[ss].first == index) ei = segments[ss].second;
|
||||
else ei = segments[ss].first;
|
||||
if (segments[fs].first == index) segments[fs].first = ei;
|
||||
else segments[fs].second = ei;
|
||||
segments.removeAt(ss);
|
||||
break;
|
||||
default: return;
|
||||
}
|
||||
pol.remove(index);
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
if (segments[i].first >= index)
|
||||
segments[i].first--;
|
||||
if (segments[i].second >= index)
|
||||
segments[i].second--;
|
||||
}
|
||||
selPoint = -1;
|
||||
checkDelete();
|
||||
updateGeometry();
|
||||
if (scene() != 0) scene()->update();
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::removeSegment(int index) {
|
||||
if (index < 0 || index > segments.size() - 1) return;
|
||||
int pif = segments[index].first, pis = segments[index].second;
|
||||
if (pif > pis) qSwap<int>(pif, pis);
|
||||
int scf = 0, scs = 0;
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
if (segments[i].first == pif ||
|
||||
segments[i].second == pif)
|
||||
scf++;
|
||||
if (segments[i].first == pis ||
|
||||
segments[i].second == pis)
|
||||
scs++;
|
||||
}
|
||||
if (scs <= 2) removePoint(pis);
|
||||
if (scf <= 2) removePoint(pif);
|
||||
if (scs <= 2 || scf <= 2) selSegment = -1;
|
||||
if (scene() != 0) scene()->update();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::appendPoint(const QPointF & p) {
|
||||
pol << p;
|
||||
if (pol.size() > 1)
|
||||
segments << QPair<int, int>(pol.size() - 2, pol.size() - 1);
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::appendPoint(qreal x, qreal y) {
|
||||
appendPoint(QPointF(x, y));
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::clear() {
|
||||
pol.clear();
|
||||
segments.clear();
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::movePolyline(const QPointF & dp) {
|
||||
pol.translate(dp);
|
||||
prepareGeometryChange();
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::movePoint(int index, const QPointF & dp) {
|
||||
pol[index] += dp;
|
||||
prepareGeometryChange();
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::setWidth(const double & w) {
|
||||
pen_width = w;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::setColor(const QColor & c) {
|
||||
pu.setColor(c);
|
||||
bu.setColor(c);
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::setSquareNodes(bool yes) {
|
||||
square_node = yes;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::markAsInput() {
|
||||
mark_in = true;
|
||||
mark_out = false;
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::markAsOutput() {
|
||||
mark_in = false;
|
||||
mark_out = true;
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::unmark() {
|
||||
mark_in = mark_out = false;
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::simplify(bool full) {
|
||||
int pcnt = pol.size();
|
||||
for (int s = 0; s < segments.size(); ++s) {
|
||||
if (pol[segments[s].first] != pol[segments[s].second]) continue;
|
||||
int ti = segments[s].first, fi = segments[s].second;
|
||||
segments.removeAt(s);
|
||||
pol.remove(fi);
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
if (segments[i].first == fi) segments[i].first = ti;
|
||||
if (segments[i].second == fi) segments[i].second = ti;
|
||||
if (segments[i].first > fi) segments[i].first--;
|
||||
if (segments[i].second > fi) segments[i].second--;
|
||||
}
|
||||
}
|
||||
if (full) {
|
||||
QList<int> segs;
|
||||
for (int p = 0; p < pol.size(); ++p) {
|
||||
if (pointSegmentsCount(p, &segs) != 2) continue;
|
||||
int s0 = segs[0], s1 = segs[1];
|
||||
QPointF cp = pol[p], sp[2];
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (segments[segs[i]].first == p) sp[i] = pol[segments[segs[i]].second];
|
||||
else sp[i] = pol[segments[segs[i]].first];
|
||||
}
|
||||
QLineF l0(sp[0], cp), l1(cp, sp[1]);
|
||||
if (qAbs(l0.angle() - l1.angle()) > 0.1) continue;
|
||||
if (segments[s0].first == p) {
|
||||
if (segments[s1].first == p) segments[s0].first = segments[s1].second;
|
||||
else segments[s0].first = segments[s1].first;
|
||||
} else {
|
||||
if (segments[s1].first == p) segments[s0].second = segments[s1].second;
|
||||
else segments[s0].second = segments[s1].first;
|
||||
}
|
||||
segments.removeAt(s1);
|
||||
pol.remove(p);
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
if (segments[i].first >= p) segments[i].first--;
|
||||
if (segments[i].second >= p) segments[i].second--;
|
||||
}
|
||||
p = -1;
|
||||
}
|
||||
}
|
||||
if (pcnt == pol.size()) return;
|
||||
updateGeometry();
|
||||
//if (scene()) scene()->update();
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::adjustLine() {
|
||||
}
|
||||
|
||||
|
||||
int BlockBusItem::endpointCount() const {
|
||||
return endpoints().size();
|
||||
}
|
||||
|
||||
|
||||
|
||||
QList<BlockItem * > BlockBusItem::connectedBlocks() const {
|
||||
QList<BlockItemPin * > pins = connections_.values();
|
||||
QSet<BlockItem * > ret;
|
||||
foreach (BlockItemPin * p, pins)
|
||||
ret << p->parent();
|
||||
return ret.values();
|
||||
}
|
||||
|
||||
|
||||
QList<BlockItemPin * > BlockBusItem::connectedPins() const {
|
||||
return connections_.values();
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::setBusState(bool state) {
|
||||
int s = state ? 1 : 0;
|
||||
if (state_ == s) return;
|
||||
state_ = s;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::clearBusState() {
|
||||
if (state_ == -1) return;
|
||||
state_ = -1;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
QByteArray BlockBusItem::save() const {
|
||||
ChunkStream cs;
|
||||
cs << cs.chunk(1, busType()) << cs.chunk(2, busName()) << cs.chunk(3, width()) << cs.chunk(4, pen())
|
||||
<< cs.chunk(5, brush()) << cs.chunk(6, pol) << cs.chunk(7, segments) << cs.chunk(8, props)
|
||||
<< cs.chunk(9, im_bus_scale) << cs.chunk(10, im_end_scale);
|
||||
return cs.data();
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::load(const QByteArray & data) {
|
||||
clear();
|
||||
if (data.isEmpty()) return;
|
||||
ChunkStream cs(data);
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
case 1: setBusType(cs.getData<int>()); break;
|
||||
case 2: setBusName(cs.getData<QString>()); break;
|
||||
case 3: setWidth(cs.getData<double>()); break;
|
||||
case 4: setPen(cs.getData<QPen>()); break;
|
||||
case 5: setBrush(cs.getData<QBrush>()); break;
|
||||
case 6: pol = cs.getData<QPolygonF>(); break;
|
||||
case 7: segments = cs.getData<QList<QPair<int, int> > >(); break;
|
||||
case 8: props = cs.getData<QList<BlockItem::Property> >(); break;
|
||||
case 9: im_bus_scale = cs.getData<double>(); break;
|
||||
case 10: im_end_scale = cs.getData<double>(); break;
|
||||
}
|
||||
}
|
||||
updateGeometry();
|
||||
}
|
||||
|
||||
|
||||
BlockBusItem * BlockBusItem::copy() const {
|
||||
return new BlockBusItem(*this);
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::saveState() {
|
||||
segments_s = segments;
|
||||
ends_ind_s = ends_ind;
|
||||
ends_s = ends;
|
||||
pol_s = pol;
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::restoreState() {
|
||||
segments = segments_s;
|
||||
ends_ind = ends_ind_s;
|
||||
ends = ends_s;
|
||||
pol = pol_s;
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::updateGeometry() {
|
||||
ends = endpoints();
|
||||
ends_ind.clear();
|
||||
for (int e = 0; e < ends.size(); ++e) {
|
||||
int ce = ends[e];
|
||||
for (int s = 0; s < segments.size(); ++s) {
|
||||
if (segments[s].first == ce) {
|
||||
ends_ind << QPair<int, int>(segments[s].first, segments[s].second);
|
||||
break;
|
||||
}
|
||||
if (segments[s].second == ce) {
|
||||
ends_ind << QPair<int, int>(segments[s].second, segments[s].first);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
reconnect();
|
||||
prepareGeometryChange();
|
||||
}
|
||||
|
||||
|
||||
bool BlockBusItem::checkDelete() {
|
||||
if (pol.size() >= 2 && segments.size() >= 1) return false;
|
||||
deleteLater();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::emitAction(BlockItemBase::Action a) {
|
||||
QMetaObject::invokeMethod(scene()->views().back(), "schemeAction", Q_ARG(BlockItemBase::Action, a), Q_ARG(QList<QGraphicsItem*>, QList<QGraphicsItem*>() << this));
|
||||
QMetaObject::invokeMethod(scene()->views().back(), "connectionsChanged");
|
||||
}
|
||||
|
||||
|
||||
QVector<int> BlockBusItem::endpoints() const {
|
||||
QVector<int> counts(pol.size(), 0), ret;
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
counts[segments[i].first]++;
|
||||
counts[segments[i].second]++;
|
||||
}
|
||||
for (int i = 0; i < counts.size(); ++i) {
|
||||
if (counts[i] == 1)
|
||||
ret << i;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QVector<int> BlockBusItem::endpointLine(int ep, double angle) const {
|
||||
QVector<int> ret;
|
||||
int seg = -1;
|
||||
int np = segmentPointPair(ep, &seg), pp = np;
|
||||
if (ep < 0 || np < 0) return ret;
|
||||
if (pol[np] == pol[ep]) return ret;
|
||||
//QPointF sp = pol[np] - pol[ep];
|
||||
QLineF l(pol[ep], pol[np]);
|
||||
//qDebug() << "first" << l.angle() << angle << (l.angle() != angle);
|
||||
if (qAbs(l.angle() - angle) > 0.1) return ret;
|
||||
//qDebug() << "check next" << segments.size();
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
//qDebug() << i << np << pointSegmentsCount(np);
|
||||
if (np < 0) break;
|
||||
if (pointSegmentsCount(np) != 2) break;
|
||||
if (i > 0) {
|
||||
QLineF l(pol[pp], pol[np]);
|
||||
//qDebug() << i << l.angle() << angle;
|
||||
if (qAbs(l.angle() - angle) > 0.1) break;
|
||||
}
|
||||
ret << np;
|
||||
pp = np;
|
||||
np = neighborSegmentPoint(np, &seg);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int BlockBusItem::pointSegmentsCount(int point, QList<int> * segs) const {
|
||||
int ret = 0;
|
||||
if (segs) segs->clear();
|
||||
for (int i = 0; i < segments.size(); ++i)
|
||||
if (segments[i].first == point || segments[i].second == point) {
|
||||
ret++;
|
||||
if (segs) segs->append(i);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int BlockBusItem::neighborSegmentPoint(int point, int * seg) const {
|
||||
if (point < 0 || !seg) return -1;
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
if (i == *seg) continue;
|
||||
if (segments[i].first == point) {*seg = i; return segments[i].second;}
|
||||
if (segments[i].second == point) {*seg = i; return segments[i].first ;}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::testPoint(QPointF pos, int * sel_point, int * sel_segment, bool for_trace) {
|
||||
for (int i = 0; i < pol.size(); ++i) {
|
||||
if ((pol[i] - pos).manhattanLength() <= (for_trace ? 5. : 10.)) { // Point
|
||||
*sel_point = i;
|
||||
*sel_segment = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
if (distPointToLine(pol[segments[i].first], pol[segments[i].second], pos) <= (for_trace ? 5. : 7.)) { // Segment
|
||||
*sel_point = -1;
|
||||
*sel_segment = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
*sel_point = -1;
|
||||
*sel_segment = -1;
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::hoverEnterEvent(QGraphicsSceneHoverEvent * e) {
|
||||
tt = bus_name + (bus_name.isEmpty() ? "" : "\n\n")
|
||||
+ tr("Add point: Ctrl + LeftClick\n"
|
||||
"Remove point\\segment: Ctrl + RightClick\n"
|
||||
"Remove connection: Shift + RightClick\n"
|
||||
"Move point\\segment: Shift + LeftPress\n"
|
||||
"Change trace mode: press Shift, when mouse move");
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::hoverMoveEvent(QGraphicsSceneHoverEvent * e) {
|
||||
if (temp_) return;
|
||||
QPointF sp = e->scenePos();
|
||||
int pp = selPoint;
|
||||
int ps = selSegment;
|
||||
bool empt = !(selPoint >= 0 || selSegment >= 0);
|
||||
testPoint(sp, &selPoint, &selSegment);
|
||||
if ((selPoint >= 0 && pp != selPoint) || (selSegment >= 0 && ps != selSegment)) {
|
||||
if (((BlockView *)scene()->views().back())->isBlockAnimationEnabled()) {
|
||||
setPointSize(0);
|
||||
anim_point_size.start();
|
||||
} else setPointSize(anim_point_size.endValue().toDouble());
|
||||
}
|
||||
|
||||
if (selPoint >= 0 || selSegment >= 0) {
|
||||
if (empt) {
|
||||
QList<BlockItemPin * > pins = connectedPins();
|
||||
foreach (BlockItemPin * p, pins) {
|
||||
p->animAccept();
|
||||
}
|
||||
}
|
||||
setToolTip(tt);
|
||||
update();
|
||||
return;
|
||||
}
|
||||
setToolTip(QString());
|
||||
QList<QGraphicsItem * > il = scene()->items(sp, Qt::ContainsItemBoundingRect, Qt::DescendingOrder), bil;
|
||||
bil << this;
|
||||
for (int i = 0; i < il.size(); ++i) {
|
||||
QGraphicsItem * b = il[i];
|
||||
if (b->data(1005) == "connection" && b != this) {
|
||||
int tp = -1, ts = -1;
|
||||
((BlockBusItem*)b)->testPoint(sp, &tp, &ts);
|
||||
if (tp >= 0 || ts >= 0) {
|
||||
foreach (QGraphicsItem * b2, bil)
|
||||
b2->stackBefore(b);
|
||||
break;
|
||||
}
|
||||
bil << b;
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
|
||||
if (temp_) return;
|
||||
selPoint = selSegment = -1;
|
||||
setPen(pu); setBrush(bu);
|
||||
setToolTip(QString());
|
||||
anim_point_size.stop();
|
||||
update();
|
||||
QGraphicsObject::hoverLeaveEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::mousePressEvent(QGraphicsSceneMouseEvent * e) {
|
||||
if (temp_) return;
|
||||
lp = quantize(e->scenePos(), grid_step);
|
||||
if (new_segment) {
|
||||
QMetaObject::invokeMethod(scene()->views().back(), "newBranchCancel");
|
||||
}
|
||||
new_segment = false;
|
||||
if ((selPoint < 0 || selPoint > pol.size() - 1) && (selSegment < 0) && e->modifiers().testFlag(Qt::ShiftModifier)) {
|
||||
QGraphicsObject::mousePressEvent(e);
|
||||
return;
|
||||
}
|
||||
int btncnt = 0;
|
||||
if (endpoints().contains(selPoint) && (e->button() == Qt::LeftButton) && e->modifiers().testFlag(Qt::ShiftModifier))
|
||||
QMetaObject::invokeMethod(scene()->views().back(), "startBusPointMove", Q_ARG(int, busType()));
|
||||
if (e->buttons().testFlag(Qt::LeftButton)) btncnt++;
|
||||
if (e->buttons().testFlag(Qt::RightButton)) btncnt++;
|
||||
if (e->buttons().testFlag(Qt::MidButton)) btncnt++;
|
||||
if (btncnt > 0) mm_mods = e->modifiers();
|
||||
//qDebug() << "press" << e;
|
||||
if (btncnt >= 2 && e->button() == Qt::RightButton) {
|
||||
mm_cancel = true;
|
||||
moved = false;
|
||||
QPointF lp = qp - press_pos;
|
||||
//qDebug() << lp;
|
||||
if (selPoint >= 0 && selPoint <= pol.size() - 1) {
|
||||
pol[selPoint] += lp;
|
||||
}
|
||||
if (selSegment >= 0 && selSegment <= segments.size() - 1) {
|
||||
pol[segments[selSegment].first] += lp;
|
||||
pol[segments[selSegment].second] += lp;
|
||||
}
|
||||
moved = true;
|
||||
prepareGeometryChange();
|
||||
return;
|
||||
}
|
||||
if (e->buttons().testFlag(Qt::LeftButton) && e->modifiers().testFlag(Qt::NoModifier)) {
|
||||
if (selSegment >= 0)
|
||||
press_pos = quantize(nearestPointOnLine(pol[segments[selSegment].first], pol[segments[selSegment].second], e->scenePos()), grid_step);
|
||||
else {
|
||||
if (selPoint >= 0)
|
||||
press_pos = pol[selPoint];
|
||||
else
|
||||
return;
|
||||
}
|
||||
if (max_ep >= 2) {
|
||||
if (endpointCount() >= max_ep)
|
||||
if (pointSegmentsCount(selPoint) >= 2 || selSegment >= 0)
|
||||
return;
|
||||
}
|
||||
QMetaObject::invokeMethod(scene()->views().back(), "newBranch", Q_ARG(BlockBusItem * , this));
|
||||
new_segment = true;
|
||||
return;
|
||||
}
|
||||
if (e->buttons().testFlag(Qt::RightButton) && e->modifiers().testFlag(Qt::ShiftModifier)) {
|
||||
deleteLater();
|
||||
}
|
||||
if (e->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
if (e->buttons().testFlag(Qt::RightButton)) {
|
||||
if (selPoint >= 0 && selPoint <= pol.size() - 1) {
|
||||
removePoint(selPoint);
|
||||
simplify();
|
||||
if (!checkDelete()) emitAction(BlockItemBase::BusPointRemove);
|
||||
return;
|
||||
}
|
||||
if (selSegment >= 0 && selSegment <= segments.size() - 1) {
|
||||
removeSegment(selSegment);
|
||||
simplify();
|
||||
if (!checkDelete()) emitAction(BlockItemBase::BusSegmentRemove);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (e->buttons().testFlag(Qt::LeftButton) && selSegment >= 0) {
|
||||
if (addPoint(e->scenePos()) >= 0)
|
||||
emitAction(BlockItemBase::BusPointAdd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (e->buttons().testFlag(Qt::RightButton)) {
|
||||
if (deleted) return;
|
||||
deleted = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::mouseMoveEvent(QGraphicsSceneMouseEvent * e) {
|
||||
if (temp_ || mm_cancel) return;
|
||||
if (((selPoint < 0 || selPoint > pol.size() - 1) && (selSegment < 0)) && !new_segment && mm_mods.testFlag(Qt::ShiftModifier)) {
|
||||
QGraphicsObject::mouseMoveEvent(e);
|
||||
return;
|
||||
}
|
||||
qp = quantize(e->scenePos(), grid_step);
|
||||
lp = qp - lp;
|
||||
if (e->buttons().testFlag(Qt::LeftButton) && mm_mods.testFlag(Qt::NoModifier) && new_segment) {
|
||||
QMetaObject::invokeMethod(scene()->views().back(), "newBranchTrace", Q_ARG(BlockBusItem * , this), Q_ARG(QPointF, e->scenePos()));
|
||||
return;
|
||||
}
|
||||
if (new_segment) {
|
||||
new_end = qp;
|
||||
prepareGeometryChange();
|
||||
} else {
|
||||
if (e->buttons().testFlag(Qt::LeftButton)) {
|
||||
lm_point = selPoint >= 0;
|
||||
if (selPoint >= 0 && selPoint <= pol.size() - 1)
|
||||
pol[selPoint] += lp;
|
||||
if (selSegment >= 0 && selSegment <= segments.size() - 1) {
|
||||
pol[segments[selSegment].first] += lp;
|
||||
pol[segments[selSegment].second] += lp;
|
||||
}
|
||||
moved = true;
|
||||
prepareGeometryChange();
|
||||
}
|
||||
}
|
||||
lp = qp;
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * e) {
|
||||
mm_mods = Qt::KeyboardModifiers();
|
||||
int btncnt = 0;
|
||||
if (e->buttons().testFlag(Qt::LeftButton)) btncnt++;
|
||||
if (e->buttons().testFlag(Qt::RightButton)) btncnt++;
|
||||
if (e->buttons().testFlag(Qt::MidButton)) btncnt++;
|
||||
if (btncnt == 0) mm_cancel = false;
|
||||
if (new_segment) {
|
||||
QMetaObject::invokeMethod(scene()->views().back(), "newBranchAccept", Q_ARG(BlockBusItem * , this));
|
||||
updateGeometry();
|
||||
selPoint = selSegment = -1;
|
||||
}
|
||||
if (moved) {
|
||||
simplify(false);
|
||||
if (lm_point) {
|
||||
emitAction(BlockItemBase::BusPointMove);
|
||||
} else {
|
||||
reconnect();
|
||||
emitAction( BlockItemBase::BusSegmentMove);
|
||||
}
|
||||
}
|
||||
QMetaObject::invokeMethod(scene()->views().back(), "endBusPointMove");
|
||||
moved = new_segment = false;
|
||||
QGraphicsObject::mouseReleaseEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::paint(QPainter * p, const QStyleOptionGraphicsItem * o, QWidget * w) {
|
||||
ph.setWidthF(pen_width + point_size / 2.);
|
||||
pu.setWidthF(pen_width);
|
||||
pa.setWidthF(pen_width);
|
||||
pr.setWidthF(pen_width);
|
||||
pn.setWidthF(pen_width);
|
||||
if (pol.size() < 2) return;
|
||||
if (selPoint >= 0 || selSegment >= 0) {
|
||||
p->setPen(pa);
|
||||
p->setBrush(ba);
|
||||
} else {
|
||||
p->setPen(pu);
|
||||
p->setBrush(bu);
|
||||
}
|
||||
//if (mark_in) {p->setPen(pa); p->setBrush(ba);}
|
||||
//if (mark_out) {p->setPen(pr); p->setBrush(br);}
|
||||
if (im_bus.isNull()) {
|
||||
QPen _pen(p->pen());
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
_pen.setWidthF(pen_width);
|
||||
_pen.setCapStyle(Qt::SquareCap);
|
||||
p->setPen(_pen);
|
||||
p->drawLine(pol[segments[i].first], pol[segments[i].second]);
|
||||
if (pointSegmentsCount(segments[i].first) > 2) {
|
||||
_pen.setWidthF(pen_width * 1.8 + 2.);
|
||||
_pen.setCapStyle(square_node ? Qt::SquareCap : Qt::RoundCap);
|
||||
p->setPen(_pen);
|
||||
p->drawPoint(pol[segments[i].first]);
|
||||
}
|
||||
}
|
||||
p->setPen(_pen);
|
||||
} else {
|
||||
QBrush br;
|
||||
br.setTextureImage(im_bus);
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
QPointF sp(pol[segments[i].first]), ep(pol[segments[i].second]);
|
||||
QTransform tf;
|
||||
tf.translate(sp.x(), sp.y());
|
||||
tf.rotate(-QLineF(sp, ep).angle());
|
||||
tf.translate(0., -im_bus.height() / 2. * im_bus_scale);
|
||||
tf.scale(im_bus_scale, im_bus_scale);
|
||||
/*
|
||||
br.setTransform(tf);
|
||||
p->setPen(QPen(br, im_bus.height(), Qt::SolidLine, Qt::FlatCap, Qt::BevelJoin));
|
||||
p->drawLine(sp, ep);
|
||||
*/
|
||||
p->save();
|
||||
p->setTransform(tf, true);
|
||||
p->setPen(Qt::NoPen);
|
||||
p->setBrush(br);
|
||||
//p->drawLine(QPointF(0., 0.), QPointF(QLineF(sp, ep).length(), 0.));
|
||||
p->drawRect(QRectF(0., 0., QLineF(sp, ep).length() / qMax<double>(im_bus_scale, 1E-3), im_bus.height()));
|
||||
p->restore();
|
||||
}
|
||||
}
|
||||
if (!im_end.isNull()) {
|
||||
for (int i = 0; i < ends_ind.size(); ++i) {
|
||||
QPointF sp = pol[ends_ind[i].first], ep = pol[ends_ind[i].second];
|
||||
QTransform tf;
|
||||
tf.translate(sp.x(), sp.y());
|
||||
tf.rotate(-QLineF(sp, ep).angle());
|
||||
tf.translate(-pen_width, -im_end.height() / 2. * im_end_scale);
|
||||
tf.scale(im_end_scale, im_end_scale);
|
||||
p->save();
|
||||
p->setTransform(tf, true);
|
||||
p->drawImage(0, 0, im_end);
|
||||
p->restore();
|
||||
}
|
||||
}
|
||||
if (state_ >= 0) {
|
||||
if (state_ == 0) {
|
||||
pr.setWidthF(pen_width + 1.);
|
||||
p->setPen(pr);
|
||||
} else if (state_ == 1) {
|
||||
pa.setWidthF(pen_width + 1.);
|
||||
p->setPen(pa);
|
||||
}
|
||||
p->setOpacity(0.5);
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
p->drawLine(pol[segments[i].first], pol[segments[i].second]);
|
||||
}
|
||||
p->setOpacity(1.);
|
||||
}
|
||||
if (!im_bus.isNull() && (selPoint >= 0 || selSegment >= 0)) {
|
||||
p->setPen(pa);
|
||||
p->setBrush(ba);
|
||||
for (int i = 0; i < segments.size(); ++i) {
|
||||
p->drawLine(pol[segments[i].first], pol[segments[i].second]);
|
||||
}
|
||||
}
|
||||
//if (mark_in) {p->setPen(pa); p->setBrush(ba);}
|
||||
//if (mark_out) {p->setPen(pr); p->setBrush(br);}
|
||||
if (selPoint >= 0) {
|
||||
p->save();
|
||||
p->setPen(ph);
|
||||
p->setBrush(bh);
|
||||
p->translate(pol[selPoint]);
|
||||
p->drawEllipse(QPointF(0, 0), point_size, point_size);
|
||||
p->restore();
|
||||
}
|
||||
if (selSegment >= 0) {
|
||||
p->save();
|
||||
p->setPen(ph);
|
||||
p->drawLine(pol[segments[selSegment].first], pol[segments[selSegment].second]);
|
||||
p->restore();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockBusItem::setPointSize(double s) {
|
||||
point_size = s;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
QRectF BlockBusItem::boundingRect() const {
|
||||
QPolygonF p(pol);
|
||||
if (new_segment) p << new_end;
|
||||
return enlargedRect(p.boundingRect(), 0, 0, 10.f);
|
||||
}
|
||||
150
libs/blockview/blockbusitem.h
Normal file
150
libs/blockview/blockbusitem.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLOCKBUSITEM_H
|
||||
#define BLOCKBUSITEM_H
|
||||
|
||||
#include "blockitem.h"
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT BlockBusItem: public QGraphicsObject, public PropertyStorage {
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QGraphicsItem)
|
||||
Q_PROPERTY(double pointSize READ pointSize WRITE setPointSize DESIGNABLE false SCRIPTABLE false)
|
||||
friend class BlockView;
|
||||
public:
|
||||
BlockBusItem(bool temp = false);
|
||||
BlockBusItem(const BlockBusItem & other);
|
||||
~BlockBusItem() {;}
|
||||
|
||||
void setGridStep(double gs) {grid_step = gs;}
|
||||
void setEndpointsNumber(int num) {max_ep = num;}
|
||||
void setImages(const QImage & bus, const QImage & end = QImage()) {im_bus = bus; im_end = end; update();}
|
||||
void setBusImageScale(double s) {im_bus_scale = s; update();}
|
||||
void setEndpointImageScale(double s) {im_end_scale = s; update();}
|
||||
void setBusType(int type_) {bus_type = type_;}
|
||||
void setBusName(const QString & name) {bus_name = name;}
|
||||
int busType() const {return bus_type;}
|
||||
QString busName() const {return bus_name;}
|
||||
double busImageScale() const {return im_bus_scale;}
|
||||
double endpointImageScale() const {return im_end_scale;}
|
||||
void appendPoint(const QPointF & p);
|
||||
void appendPoint(qreal x, qreal y);
|
||||
void testPoint(QPointF pos, int * sel_point, int * sel_segment, bool for_trace = false);
|
||||
void clear();
|
||||
/*void setStart(const QPointF & p) {pol[0] = p; scene()->update();}
|
||||
void setStart(qreal x, qreal y) {setStart(QPointF(x, y));}
|
||||
void setFinish(const QPointF & p) {pol[pol.size() - 1] = p; scene()->update();}
|
||||
void setFinish(qreal x, qreal y) {setFinish(QPointF(x, y));}
|
||||
void setPoint(int index, const QPointF & p) {pol[index] = p; scene()->update();}
|
||||
void setPoint(int index, qreal x, qreal y) {setPoint(index, QPointF(x, y));}*/
|
||||
void setPen(const QPen & p) {p_ = p; update();}
|
||||
QPen pen() const {return p_;}
|
||||
void setBrush(const QBrush & b) {b_ = b; update();}
|
||||
QBrush brush() const {return b_;}
|
||||
//void disconnectBrick() {BrickBase::disconnect(brickFrom, portFrom, brickTo, portTo);}
|
||||
void movePolyline(const QPointF & dp);
|
||||
void movePoint(int index, const QPointF & dp);
|
||||
double width() const {return pen_width;}
|
||||
void setWidth(const double & w);
|
||||
void setColor(const QColor & c);
|
||||
void setSquareNodes(bool yes);
|
||||
int addPoint(const QPointF & point, bool update = true);
|
||||
int segmentPointPair(int point, int * seg = 0) const;
|
||||
void removePoint(int index);
|
||||
void removeSegment(int index);
|
||||
void markAsInput();
|
||||
void markAsOutput();
|
||||
void unmark();
|
||||
void simplify(bool full = true);
|
||||
void adjustLine();
|
||||
int endpointCount() const;
|
||||
bool isBusSelected() const {return selSegment >= 0 || selPoint >= 0;}
|
||||
QList<BlockItem * > connectedBlocks() const;
|
||||
QList<BlockItemPin * > connectedPins() const;
|
||||
|
||||
void setBusState(bool state);
|
||||
bool busState() const {return state_ > 0;}
|
||||
void clearBusState();
|
||||
|
||||
QByteArray save() const;
|
||||
void load(const QByteArray & data);
|
||||
BlockBusItem * copy() const;
|
||||
|
||||
void saveState();
|
||||
void restoreState();
|
||||
|
||||
enum {Type = UserType + 2};
|
||||
|
||||
protected:
|
||||
void _init();
|
||||
void reconnect();
|
||||
void updateGeometry();
|
||||
bool checkDelete();
|
||||
void emitAction(BlockItemBase::Action a);
|
||||
QVector<int> endpoints() const;
|
||||
QVector<int> endpointLine(int ep, double angle) const;
|
||||
int pointSegmentsCount(int point, QList<int> * segs = 0) const;
|
||||
int neighborSegmentPoint(int point, int * seg) const;
|
||||
int type() const {return Type;}
|
||||
QRectF boundingRect() const;
|
||||
bool sceneEvent(QEvent * e);
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent * e);
|
||||
void hoverMoveEvent(QGraphicsSceneHoverEvent * e);
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent * e);
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent * e);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent * e);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent * e);
|
||||
void paint(QPainter * p, const QStyleOptionGraphicsItem * o, QWidget * w = 0);
|
||||
|
||||
QPointF lp, new_start, new_end, press_pos, qp;
|
||||
QPen p_, ph, pu, pa, pr, pn;
|
||||
QBrush b_, bh, bu, ba, br;
|
||||
QString tt, bus_name;
|
||||
QList<QPair<int, int> > segments, ends_ind, segments_s, ends_ind_s;
|
||||
QMap<int, BlockItemPin * > connections_;
|
||||
QVector<int> ends, ends_s;
|
||||
QImage im_bus, im_end;
|
||||
QPolygonF pol, bpol, pol_s;
|
||||
Qt::KeyboardModifiers mm_mods;
|
||||
bool temp_, square_node;
|
||||
double pen_width, grid_step, im_bus_scale, im_end_scale;
|
||||
int selPoint, selSegment, max_ep, bus_type, state_;
|
||||
bool moved, deleted, mark_in, mark_out, new_segment, mm_cancel, lm_point;
|
||||
|
||||
private:
|
||||
double pointSize() const {return point_size;}
|
||||
void setPointSize(double s);
|
||||
|
||||
double point_size;
|
||||
QPropertyAnimation anim_point_size;
|
||||
};
|
||||
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const BlockBusItem * b) {s << b->save(); return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, BlockBusItem *& b) {
|
||||
QByteArray ba; s >> ba;
|
||||
b = new BlockBusItem();
|
||||
b->load(ba);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
#endif // BLOCKBUSITEM_H
|
||||
400
libs/blockview/blockeditor.cpp
Normal file
400
libs/blockview/blockeditor.cpp
Normal file
@@ -0,0 +1,400 @@
|
||||
#include "blockeditor.h"
|
||||
#include "ui_blockeditor.h"
|
||||
#include "drawtools.h"
|
||||
#include "blockview.h"
|
||||
#include <QToolBar>
|
||||
#include <QComboBox>
|
||||
#include <QFileDialog>
|
||||
#include <QFile>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
BlockEditor::BlockEditor(QWidget *parent) : QWidget(parent), ui(new Ui::BlockEditor) {
|
||||
init = false;
|
||||
m_editorMode = false;
|
||||
m_pinsEditable = true;
|
||||
ui->setupUi(this);
|
||||
src_title = windowTitle();
|
||||
connect(ui->blockView->scene(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
|
||||
block.setFlags(0);
|
||||
ui->blockView->addItem(&block);
|
||||
ui->blockView->viewport()->installEventFilter(this);
|
||||
DrawTools * drawtools = new DrawTools(ui->blockView);
|
||||
connect(drawtools, SIGNAL(itemCreated(QGraphicsItem*)), this, SLOT(addItem(QGraphicsItem*)));
|
||||
drawtools->textEditCombo()->addItems(QStringList() << "%name" << "%value" << "%id");
|
||||
ui->layoutProperties->addWidget(drawtools->propertyWidget());
|
||||
ui->actionRemove_items->setEnabled(false);
|
||||
ui->button_color->setColor(Qt::lightGray);
|
||||
ui->treePins->setItemDelegateForColumn(1, new PinBusDelegate());
|
||||
connect(ui->treePins, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(updateBlock()));
|
||||
ui->treePins->viewport()->installEventFilter(this);
|
||||
|
||||
QToolBar * bar;
|
||||
bar = new QToolBar(ui->widgetBar);
|
||||
bar->setOrientation(Qt::Vertical);
|
||||
bar->addActions(drawtools->actionsForAdd());
|
||||
ui->widgetBar->setMinimumSize(bar->sizeHint());
|
||||
|
||||
bar = new QToolBar(ui->widgetBarZ);
|
||||
bar->setOrientation(Qt::Vertical);
|
||||
bar->addActions(drawtools->actionsForZ());
|
||||
bar->addSeparator();
|
||||
bar->addActions(QList<QAction*>() << ui->actionRemove_items);
|
||||
ui->widgetBarZ->setMinimumSize(bar->sizeHint());
|
||||
init = true;
|
||||
on_buttonClear_clicked();
|
||||
}
|
||||
|
||||
|
||||
BlockEditor::~BlockEditor() {
|
||||
init = false;
|
||||
delete ui;
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::loadFile(QString path) {
|
||||
if (path.isEmpty()) return;
|
||||
QFile f(path);
|
||||
if (f.open(QIODevice::ReadOnly)) {
|
||||
cur_file = path;
|
||||
loadModel(f.readAll());
|
||||
QDir::setCurrent(QFileInfo(path).dir().path());
|
||||
}
|
||||
setWindowTitle(src_title + QString(" - %1").arg(QFileInfo(path).baseName()));
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::loadModel(const QByteArray &model) {
|
||||
BlockItem b;
|
||||
b.loadModel(model);
|
||||
ui->spin_w->setValue(b.width());
|
||||
ui->spin_h->setValue(b.height());
|
||||
ui->spin_margin->setValue(b.pinsMargin());
|
||||
ui->button_color->setColor(b.color());
|
||||
block.loadModel(model);
|
||||
treePinsClear();
|
||||
ui->treePins->blockSignals(true);
|
||||
QVector<BlockItemPin * > pins = block.pins();
|
||||
foreach (BlockItemPin * p, pins) {
|
||||
QTreeWidgetItem * ti = new QTreeWidgetItem(QStringList() << p->text() << QString::number(p->busType()));
|
||||
ti->setData(0, Qt::UserRole, qulonglong(p));
|
||||
ti->setData(0, Qt::UserRole + 1, (int)p->alignment());
|
||||
ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled);
|
||||
pin_tli[p->alignment()]->addChild(ti);
|
||||
}
|
||||
foreach (QGraphicsItem * i, block.decors()) {
|
||||
i->setData(1002, false);
|
||||
i->setData(1100, true);
|
||||
}
|
||||
ui->treePins->blockSignals(false);
|
||||
}
|
||||
|
||||
|
||||
QByteArray BlockEditor::saveModel() {
|
||||
return block.saveModel();
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::setEditorMode(bool editorMode) {
|
||||
m_editorMode = editorMode;
|
||||
ui->buttonClear->setVisible(!editorMode);
|
||||
ui->buttonSave->setVisible(!editorMode);
|
||||
ui->buttonSaveAs->setVisible(!editorMode);
|
||||
ui->buttonLoad->setVisible(!editorMode);
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::setPinsEditable(bool pinsEditable) {
|
||||
m_pinsEditable = pinsEditable;
|
||||
ui->treePins->setVisible(pinsEditable);
|
||||
ui->buttonPinAdd->setVisible(pinsEditable);
|
||||
ui->buttonPinClear->setVisible(pinsEditable);
|
||||
ui->buttonPinDelete->setVisible(pinsEditable);
|
||||
ui->buttonPinDup->setVisible(pinsEditable);
|
||||
ui->groupPins->setVisible(pinsEditable);
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::selectionChanged() {
|
||||
if (!init) return;
|
||||
ui->actionRemove_items->setEnabled(!ui->blockView->scene()->selectedItems().isEmpty());
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::addItem(QGraphicsItem *item) {
|
||||
block.addDecor(item);
|
||||
item->setData(1002, false);
|
||||
item->setData(1100, true);
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::updateBlock() {
|
||||
block.setSize(ui->spin_w->value(), ui->spin_h->value());
|
||||
block.setColor(ui->button_color->color());
|
||||
block.setPinsMargin(ui->spin_margin->value());
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::treePinsClear() {
|
||||
ui->treePins->blockSignals(true);
|
||||
ui->treePins->clear();
|
||||
QFont bf(font()); bf.setBold(true);
|
||||
QList<int> al = QList<int>() << Qt::AlignLeft << Qt::AlignRight << Qt::AlignTop << Qt::AlignBottom;
|
||||
QStringList an = QStringList() << "Left" << "Right" << "Top" << "Bottom";
|
||||
pin_tli.clear();
|
||||
for (int i = 0; i < al.size(); ++i) {
|
||||
QTreeWidgetItem * ti = new QTreeWidgetItem();
|
||||
ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsDropEnabled);
|
||||
ti->setData(0, Qt::UserRole, al[i]);
|
||||
ti->setText(0, an[i]);
|
||||
ti->setFont(0, bf);
|
||||
ui->treePins->addTopLevelItem(ti);
|
||||
ti->setFirstColumnSpanned(true);
|
||||
ti->setExpanded(true);
|
||||
pin_tli[al[i]] = ti;
|
||||
}
|
||||
ui->treePins->blockSignals(false);
|
||||
}
|
||||
|
||||
|
||||
bool BlockEditor::eventFilter(QObject *o, QEvent *e) {
|
||||
if (!init) QWidget::eventFilter(o, e);
|
||||
if (o == ui->treePins->viewport()) {
|
||||
if (e->type() == QEvent::Drop) {
|
||||
QTimer::singleShot(0, this, SLOT(arrangePins()));
|
||||
}
|
||||
}
|
||||
if (o == ui->blockView->viewport()) {
|
||||
if (e->type() == QEvent::Resize) {
|
||||
ui->blockView->centerOn(&block);
|
||||
}
|
||||
}
|
||||
return QWidget::eventFilter(o, e);
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::changeEvent(QEvent * e) {
|
||||
QWidget::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
ui->retranslateUi(this);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::on_actionRemove_items_triggered() {
|
||||
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
|
||||
foreach (QGraphicsItem * i, si)
|
||||
block.removeDecor(i);
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::on_buttonSave_clicked() {
|
||||
if (cur_file.isEmpty()) {
|
||||
on_buttonSaveAs_clicked();
|
||||
return;
|
||||
}
|
||||
QFile f(cur_file);
|
||||
if (f.open(QIODevice::WriteOnly)) {
|
||||
f.write(saveModel());
|
||||
//setWindowTitle(src_title + QString(" - %1").arg(QFileInfo(c).baseName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::on_buttonSaveAs_clicked() {
|
||||
QString c = QFileDialog::getSaveFileName(this, "Save block model to file", cur_file, "*.blockmodel");
|
||||
if (!c.isEmpty()) {
|
||||
QFile f(c);
|
||||
if (f.open(QIODevice::WriteOnly)) {
|
||||
cur_file = c;
|
||||
f.write(saveModel());
|
||||
setWindowTitle(src_title + QString(" - %1").arg(QFileInfo(c).baseName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::on_buttonLoad_clicked() {
|
||||
QString c = QFileDialog::getOpenFileName(this, "Save block model to file", cur_file, "*.blockmodel");
|
||||
loadFile(c);
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::on_buttonClear_clicked() {
|
||||
BlockItem b;
|
||||
ui->spin_w->setValue(b.width());
|
||||
ui->spin_h->setValue(b.height());
|
||||
ui->spin_margin->setValue(b.pinsMargin());
|
||||
ui->button_color->setColor(b.color());
|
||||
block.loadModel(QByteArray());
|
||||
treePinsClear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BlockEditor::on_buttonPinAdd_clicked() {
|
||||
ui->treePins->blockSignals(true);
|
||||
QTreeWidgetItem * ti = new QTreeWidgetItem(QStringList() << "" << "0");
|
||||
ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled);
|
||||
ti->setData(0, Qt::UserRole, qulonglong(block.addPin(Qt::AlignLeft, ti->text(1).toInt(), ti->text(0))));
|
||||
ti->setData(0, Qt::UserRole + 1, (int)Qt::AlignLeft);
|
||||
pin_tli[Qt::AlignLeft]->addChild(ti);
|
||||
ui->treePins->setCurrentItem(ti);
|
||||
ui->treePins->blockSignals(false);
|
||||
updateBlock();
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::on_buttonPinDup_clicked() {
|
||||
QTreeWidgetItem * ci = ui->treePins->currentItem();
|
||||
if (ci == 0) return;
|
||||
ui->treePins->blockSignals(true);
|
||||
QTreeWidgetItem * ti = ci->clone();
|
||||
ti->setText(0, ti->text(0));
|
||||
ti->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled);
|
||||
Qt::Alignment al = (Qt::Alignment)ci->data(0, Qt::UserRole + 1).toInt();
|
||||
ti->setData(0, Qt::UserRole, qulonglong(block.addPin(al, ci->text(1).toInt(), ci->text(0))));
|
||||
ti->setData(0, Qt::UserRole + 1, (int)al);
|
||||
pin_tli[al]->addChild(ti);
|
||||
ui->treePins->setCurrentItem(ti);
|
||||
ui->treePins->blockSignals(false);
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::on_buttonPinDelete_clicked() {
|
||||
ui->treePins->blockSignals(true);
|
||||
QList<QTreeWidgetItem*> si = ui->treePins->selectedItems();
|
||||
foreach (QTreeWidgetItem * i, si) {
|
||||
if (!i->parent()) continue;
|
||||
block.removePin((BlockItemPin*)(i->data(0, Qt::UserRole).toLongLong()));
|
||||
delete i;
|
||||
}
|
||||
ui->treePins->blockSignals(false);
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::on_buttonPinClear_clicked() {
|
||||
treePinsClear();
|
||||
block.clearPins();
|
||||
}
|
||||
|
||||
|
||||
void BlockEditor::on_treePins_itemChanged(QTreeWidgetItem * item, int column) {
|
||||
if (!item) return;
|
||||
BlockItemPin * pin = (BlockItemPin*)item->data(0, Qt::UserRole).toULongLong();
|
||||
if (!pin) return;
|
||||
switch (column) {
|
||||
case 0:
|
||||
ui->treePins->blockSignals(true);
|
||||
item->setText(0, item->text(0));
|
||||
pin->setText(item->text(0));
|
||||
ui->treePins->blockSignals(false);
|
||||
break;
|
||||
case 1: pin->setBusType(item->text(1).toInt()); break;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BlockEditor::arrangePins() {
|
||||
QVector<BlockItemPin * > pins = block.pins();
|
||||
// block.clearPins();
|
||||
QList<QTreeWidgetItem*> tli = pin_tli.values();
|
||||
foreach (QTreeWidgetItem * ti, tli) {
|
||||
for (int i = 0; i < ti->childCount(); ++i) {
|
||||
foreach (BlockItemPin * p, pins)
|
||||
if (p == (BlockItemPin*)(ti->child(i)->data(0, Qt::UserRole).toULongLong())) {
|
||||
p->setAlignment((Qt::Alignment)ti->data(0, Qt::UserRole).toInt());
|
||||
BlockItemPin * np = block.addPin(p, false);
|
||||
ti->child(i)->setData(0, Qt::UserRole, qulonglong(np));
|
||||
ti->child(i)->setData(0, Qt::UserRole + 1, ti->data(0, Qt::UserRole).toInt());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for (int i = 0; i < ui->treePins->topLevelItemCount(); ++i) {
|
||||
// QTreeWidgetItem * ti = ui->treePins->topLevelItem(i);
|
||||
// if (tli.contains(ti)) continue;
|
||||
// ti = ui->treePins->takeTopLevelItem(i);
|
||||
// pin_tli[ti->data(0, Qt::UserRole + 1).toInt()]->addChild(ti);
|
||||
// foreach (BlockItemPin * p, pins)
|
||||
// if (p->text() == ti->text(0)) {
|
||||
// p->setAlignment((Qt::Alignment)ti->data(0, Qt::UserRole + 1).toInt());
|
||||
// block.addPin(p, false);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
block.arrangePins();
|
||||
}
|
||||
|
||||
|
||||
/// ***********************************************************
|
||||
/// ***********************************************************
|
||||
/// ***********************************************************
|
||||
/// ***********************************************************
|
||||
|
||||
|
||||
QWidget * PinAlignDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {
|
||||
QComboBox * combo = new QComboBox(parent);
|
||||
int cv = index.data().toInt();
|
||||
combo->addItem("Left", int(Qt::AlignLeft)); if (cv == Qt::AlignLeft) combo->setCurrentIndex(0);
|
||||
combo->addItem("Right", int(Qt::AlignRight)); if (cv == Qt::AlignRight) combo->setCurrentIndex(1);
|
||||
combo->addItem("Top", int(Qt::AlignTop)); if (cv == Qt::AlignTop) combo->setCurrentIndex(2);
|
||||
combo->addItem("Bottom", int(Qt::AlignBottom)); if (cv == Qt::AlignBottom) combo->setCurrentIndex(3);
|
||||
combo->setGeometry(option.rect);
|
||||
return combo;
|
||||
}
|
||||
|
||||
|
||||
QString PinAlignDelegate::displayText(const QVariant & value, const QLocale & locale) const {
|
||||
int cv = value.toInt();
|
||||
switch (cv) {
|
||||
case Qt::AlignLeft: return tr("Left"); break;
|
||||
case Qt::AlignRight: return tr("Right"); break;
|
||||
case Qt::AlignTop: return tr("Top"); break;
|
||||
case Qt::AlignBottom: return tr("Bottom"); break;
|
||||
}
|
||||
return tr("unknown");
|
||||
}
|
||||
|
||||
|
||||
void PinAlignDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const {
|
||||
model->setData(index, ((QComboBox*)editor)->itemData(((QComboBox*)editor)->currentIndex()).toInt());
|
||||
}
|
||||
|
||||
|
||||
/// ***********************************************************
|
||||
/// ***********************************************************
|
||||
/// ***********************************************************
|
||||
/// ***********************************************************
|
||||
|
||||
|
||||
QWidget * PinBusDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const {
|
||||
QSpinBox * spin = new QSpinBox(parent);
|
||||
spin->setMinimum(-2147483648);
|
||||
spin->setMaximum(2147483647);
|
||||
spin->setValue(index.data().toInt());
|
||||
return spin;
|
||||
}
|
||||
|
||||
|
||||
QString PinBusDelegate::displayText(const QVariant & value, const QLocale & locale) const {
|
||||
int cv = value.toInt();
|
||||
return QString::number(cv);
|
||||
}
|
||||
|
||||
|
||||
void PinBusDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const {
|
||||
model->setData(index, ((QSpinBox*)editor)->value());
|
||||
}
|
||||
|
||||
|
||||
|
||||
//void BlockEditor::on_treePins_itemSelectionChanged() {
|
||||
// arrangePins();
|
||||
// qDebug() << "111111111111111";
|
||||
//}
|
||||
112
libs/blockview/blockeditor.h
Normal file
112
libs/blockview/blockeditor.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLOCKEDITOR_H
|
||||
#define BLOCKEDITOR_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QStyledItemDelegate>
|
||||
#include "blockitem.h"
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class BlockEditor;
|
||||
}
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT BlockEditor : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool editorMode READ editorMode WRITE setEditorMode)
|
||||
Q_PROPERTY(bool pinsEditable READ pinsEditable WRITE setPinsEditable)
|
||||
public:
|
||||
explicit BlockEditor(QWidget *parent = 0);
|
||||
~BlockEditor();
|
||||
|
||||
|
||||
bool editorMode() const {return m_editorMode;}
|
||||
bool pinsEditable() const {return m_pinsEditable;}
|
||||
|
||||
public slots:
|
||||
void loadFile(QString path);
|
||||
void loadModel(const QByteArray & model);
|
||||
QByteArray saveModel();
|
||||
void setEditorMode(bool editorMode);
|
||||
void setPinsEditable(bool pinsEditable);
|
||||
|
||||
private slots:
|
||||
void selectionChanged();
|
||||
void addItem(QGraphicsItem * item);
|
||||
void updateBlock();
|
||||
void treePinsClear();
|
||||
void arrangePins();
|
||||
void on_actionRemove_items_triggered();
|
||||
void on_buttonSave_clicked();
|
||||
void on_buttonSaveAs_clicked();
|
||||
void on_buttonLoad_clicked();
|
||||
void on_buttonClear_clicked();
|
||||
void on_buttonPinAdd_clicked();
|
||||
void on_buttonPinDup_clicked();
|
||||
void on_buttonPinDelete_clicked();
|
||||
void on_buttonPinClear_clicked();
|
||||
void on_treePins_itemChanged(QTreeWidgetItem *item, int column);
|
||||
// void on_treePins_itemSelectionChanged();
|
||||
|
||||
private:
|
||||
bool eventFilter(QObject * o, QEvent * e);
|
||||
void changeEvent(QEvent * e);
|
||||
|
||||
Ui::BlockEditor *ui;
|
||||
QMap<int, QTreeWidgetItem*> pin_tli;
|
||||
BlockItem block;
|
||||
QString src_title, cur_file;
|
||||
bool init;
|
||||
bool m_editorMode;
|
||||
bool m_pinsEditable;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT PinAlignDelegate: public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PinAlignDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {}
|
||||
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const;
|
||||
QString displayText(const QVariant & value, const QLocale & locale) const;
|
||||
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
|
||||
QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const {return QSize(60, 26);}
|
||||
};
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT PinBusDelegate: public QStyledItemDelegate {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PinBusDelegate(QObject * parent = 0): QStyledItemDelegate(parent) {}
|
||||
QWidget * createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const;
|
||||
QString displayText(const QVariant & value, const QLocale & locale) const;
|
||||
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
|
||||
QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const {return QSize(60, 26);}
|
||||
private:
|
||||
typedef QPair<int, QString> ISPair;
|
||||
QVector<ISPair> buses;
|
||||
};
|
||||
|
||||
#endif // BLOCKEDITOR_H
|
||||
543
libs/blockview/blockeditor.ui
Normal file
543
libs/blockview/blockeditor.ui
Normal file
@@ -0,0 +1,543 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BlockEditor</class>
|
||||
<widget class="QWidget" name="BlockEditor">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>847</width>
|
||||
<height>810</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Block editor</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="qad_blockview.qrc">
|
||||
<normaloff>:/icons/blockview.png</normaloff>:/icons/blockview.png</iconset>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="groupParameters">
|
||||
<property name="title">
|
||||
<string>Block parameters</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="labelAlignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Width:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="spin_w">
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Heigth:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="spin_h">
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>60</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Pins margin:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="spin_margin">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="ColorButton" name="button_color"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="groupPins">
|
||||
<property name="title">
|
||||
<string>Pins</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="treePins">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::InternalMove</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::MoveAction</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="itemsExpandable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="headerDefaultSectionSize">
|
||||
<number>200</number>
|
||||
</attribute>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Bus</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonPinAdd">
|
||||
<property name="toolTip">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../utils/qad_utils.qrc">
|
||||
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonPinDup">
|
||||
<property name="toolTip">
|
||||
<string>Clone</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../utils/qad_utils.qrc">
|
||||
<normaloff>:/icons/edit-copy.png</normaloff>:/icons/edit-copy.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonPinDelete">
|
||||
<property name="toolTip">
|
||||
<string>Remove selected</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../utils/qad_utils.qrc">
|
||||
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonPinClear">
|
||||
<property name="toolTip">
|
||||
<string>Remove all</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../utils/qad_utils.qrc">
|
||||
<normaloff>:/icons/edit-clear.png</normaloff>:/icons/edit-clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frameProperties">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="layoutProperties">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetBar" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetBarZ" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="BlockView" name="blockView">
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="navigateAnimationEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="miniMap" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="zoomWheelOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonSave">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../utils/qad_utils.qrc">
|
||||
<normaloff>:/icons/document-save.png</normaloff>:/icons/document-save.png</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+S</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonSaveAs">
|
||||
<property name="text">
|
||||
<string>Save as ...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../utils/qad_utils.qrc">
|
||||
<normaloff>:/icons/document-save.png</normaloff>:/icons/document-save.png</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+S</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonLoad">
|
||||
<property name="text">
|
||||
<string>Load ...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../application/qad_application.qrc">
|
||||
<normaloff>:/icons/document-open.png</normaloff>:/icons/document-open.png</iconset>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+O</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonClear">
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../utils/qad_utils.qrc">
|
||||
<normaloff>:/icons/edit-clear.png</normaloff>:/icons/edit-clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionRemove_items">
|
||||
<property name="icon">
|
||||
<iconset resource="../utils/qad_utils.qrc">
|
||||
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove items</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Del</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>BlockView</class>
|
||||
<extends>QGraphicsView</extends>
|
||||
<header>blockview.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ColorButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>colorbutton.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../utils/qad_utils.qrc"/>
|
||||
<include location="../application/qad_application.qrc"/>
|
||||
<include location="qad_blockview.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>spin_w</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>BlockEditor</receiver>
|
||||
<slot>updateBlock()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>170</x>
|
||||
<y>21</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>254</x>
|
||||
<y>1</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spin_h</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>BlockEditor</receiver>
|
||||
<slot>updateBlock()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>250</x>
|
||||
<y>49</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>373</x>
|
||||
<y>5</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spin_margin</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>BlockEditor</receiver>
|
||||
<slot>updateBlock()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>350</x>
|
||||
<y>90</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>492</x>
|
||||
<y>8</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>button_color</sender>
|
||||
<signal>colorChanged(QColor)</signal>
|
||||
<receiver>BlockEditor</receiver>
|
||||
<slot>updateBlock()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>561</x>
|
||||
<y>115</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>613</x>
|
||||
<y>6</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>updateBlock()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
548
libs/blockview/blockitem.cpp
Normal file
548
libs/blockview/blockitem.cpp
Normal file
@@ -0,0 +1,548 @@
|
||||
#include "blockview.h"
|
||||
#include <QApplication>
|
||||
|
||||
|
||||
#define BLOCKITEM_DEFAULT_PIN_MARGIN 20
|
||||
|
||||
BlockItem::BlockItem(QGraphicsItem * parent): QGraphicsObject(parent), PropertyStorage(),
|
||||
g_main(this), g_selection(this) {
|
||||
setData(1006, "item");
|
||||
setZValue(2.);
|
||||
setAcceptHoverEvents(true);
|
||||
setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);
|
||||
g_main.setData(1002, true);
|
||||
g_selection.setData(1007, true);
|
||||
g_selection.setAcceptedMouseButtons(0);
|
||||
g_selection.setZValue(10.);
|
||||
g_selection.hide();
|
||||
g_selection.setData(1003, true);
|
||||
col = Qt::lightGray;
|
||||
_resize(QSizeF(100., 60.));
|
||||
QPen p(QColor(128, 128, 255), lineThickness(), Qt::DotLine);
|
||||
p.setCosmetic(true);
|
||||
g_selection.setPen(p);
|
||||
g_selection.setBrush(QColor(128, 128, 255, 32));
|
||||
pins_margin = BLOCKITEM_DEFAULT_PIN_MARGIN;
|
||||
anim_thick.setTargetObject(this);
|
||||
anim_thick.setPropertyName("_thickness");
|
||||
anim_thick.setEasingCurve(QEasingCurve::OutQuad);
|
||||
anim_thick.setDuration(300);
|
||||
anim_sel.setTargetObject(this);
|
||||
anim_sel.setPropertyName("_selRect");
|
||||
anim_sel.setEasingCurve(QEasingCurve::OutCubic);
|
||||
anim_sel.setDuration(400);
|
||||
t_sel.start();
|
||||
//g_main.setBrush(QColor(128, 128, 128, 64));
|
||||
/*
|
||||
BlockItemPin * pin = new BlockItemPin(Qt::AlignRight, 0, this);
|
||||
pin->setText("text");
|
||||
pin->setBusType(0);
|
||||
addPin(pin);
|
||||
pin = new BlockItemPin(Qt::AlignTop, this);
|
||||
pin->setBusType(0); addPin(pin);
|
||||
pin = new BlockItemPin(Qt::AlignLeft, this);
|
||||
pin->setBusType(1); addPin(pin);
|
||||
pin = new BlockItemPin(Qt::AlignRight, this);
|
||||
pin->setBusType(1); addPin(pin);*/
|
||||
}
|
||||
|
||||
|
||||
BlockItem::~BlockItem() {
|
||||
clearDecors();
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::_resize(QSizeF s) {
|
||||
g_main.setRect(QRectF(QPointF(), s));
|
||||
g_main.setPos(QPointF(-g_main.rect().center().x(), -10.));
|
||||
g_selection.setRect(enlargedRect(g_main.rect(), 0, 0, 8));
|
||||
g_selection.setPos(g_main.pos());
|
||||
QRadialGradient g(g_main.rect().width() / 2., 0, qMax<qreal>(g_main.rect().width() / 2., g_main.rect().height()));
|
||||
g.setSpread(QGradient::PadSpread);
|
||||
g.setCoordinateMode(QGradient::LogicalMode);
|
||||
g.setColorAt(0., col.darker(120.));
|
||||
g.setColorAt(1., col.lighter(120.));
|
||||
g_main.setBrush(QBrush(g));
|
||||
prepareGeometryChange();
|
||||
arrangePins();
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::_moveToTop(bool only_decors) {
|
||||
qreal dy = -g_main.rect().center().y() + 10;
|
||||
if (!only_decors)
|
||||
moveBy(0., dy);
|
||||
foreach (QGraphicsItem * d, decors_)
|
||||
d->moveBy(0., -dy);
|
||||
|
||||
}
|
||||
|
||||
|
||||
BlockItemPin * BlockItem::addPin(BlockItemPin * pin, bool update_) {
|
||||
pin->setParentItem(this);
|
||||
if (!pins_[pin->alignment()].contains(pin)) pins_[pin->alignment()] << pin;
|
||||
pin->parent_ = this;
|
||||
if (update_)
|
||||
arrangePins();
|
||||
return pin;
|
||||
}
|
||||
|
||||
|
||||
BlockItemPin * BlockItem::addPin(Qt::Alignment align, int bus_type, const QString & text, bool update_) {
|
||||
BlockItemPin * pin = new BlockItemPin(align, bus_type, text, this);
|
||||
pin->parent_ = this;
|
||||
pins_[pin->alignment()] << pin;
|
||||
if (update_)
|
||||
arrangePins();
|
||||
return pin;
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::removePin(BlockItemPin * pin) {
|
||||
if (!pin) return;
|
||||
QMutableMapIterator<Qt::Alignment, QVector<BlockItemPin * > > it(pins_);
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
QVector<BlockItemPin * > & pv(it.value());
|
||||
if (pv.contains(pin))
|
||||
pv.remove(it.value().indexOf(pin));
|
||||
}
|
||||
delete pin;
|
||||
arrangePins();
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::addDecor(QGraphicsItem * item) {
|
||||
if (decors_.contains(item)) return;
|
||||
if (qgraphicsitem_cast<QGraphicsPixmapItem*>(item))
|
||||
qgraphicsitem_cast<QGraphicsPixmapItem*>(item)->setTransformationMode(Qt::SmoothTransformation);
|
||||
if (qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item))
|
||||
qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item)->setData(1010, qgraphicsitem_cast<QGraphicsSimpleTextItem*>(item)->text());
|
||||
if (qgraphicsitem_cast<AlignedTextItem*>(item))
|
||||
qgraphicsitem_cast<AlignedTextItem*>(item)->setData(1010, qgraphicsitem_cast<AlignedTextItem*>(item)->text());
|
||||
item->setData(1002, true);
|
||||
item->setData(1011, true);
|
||||
decors_ << item;
|
||||
item->setParentItem(this);
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::addDecor(QGraphicsItem & item) {
|
||||
if (decors_.contains(&item)) return;
|
||||
if (qgraphicsitem_cast<QGraphicsPixmapItem*>(&item))
|
||||
qgraphicsitem_cast<QGraphicsPixmapItem*>(&item)->setTransformationMode(Qt::SmoothTransformation);
|
||||
if (qgraphicsitem_cast<QGraphicsSimpleTextItem*>(&item))
|
||||
qgraphicsitem_cast<QGraphicsSimpleTextItem*>(&item)->setData(1010, qgraphicsitem_cast<QGraphicsSimpleTextItem*>(&item)->text());
|
||||
if (qgraphicsitem_cast<AlignedTextItem*>(&item))
|
||||
qgraphicsitem_cast<AlignedTextItem*>(&item)->setData(1010, qgraphicsitem_cast<AlignedTextItem*>(&item)->text());
|
||||
item.setData(1002, true);
|
||||
item.setData(1011, true);
|
||||
//decors_ << &item;
|
||||
item.setParentItem(this);
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::removeDecor(QGraphicsItem * item) {
|
||||
if (scene() && item)
|
||||
scene()->sendEvent(item, new QGraphicsSceneEvent(QEvent::Close));
|
||||
decors_.removeAll(item);
|
||||
delete item;
|
||||
}
|
||||
|
||||
|
||||
QVector<BlockItemPin * > BlockItem::takePins() {
|
||||
QVector<BlockItemPin * > ret = pins();
|
||||
pins_.clear();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::clearPins() {
|
||||
QList<QVector<BlockItemPin * > > mp = pins_.values();
|
||||
for (int i = 0; i < mp.size(); ++i)
|
||||
qDeleteAll(mp[i]);
|
||||
pins_.clear();
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::clearDecors() {
|
||||
bool pbs = false;
|
||||
if (scene()) pbs = scene()->blockSignals(true);
|
||||
if (scene())
|
||||
foreach (QGraphicsItem * i, decors_)
|
||||
scene()->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close));
|
||||
qDeleteAll(decors_);
|
||||
decors_.clear();
|
||||
if (scene()) {
|
||||
scene()->blockSignals(pbs);
|
||||
QMetaObject::invokeMethod(scene(), "selectionChanged");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QVector<BlockItemPin * > BlockItem::pins() const {
|
||||
QList<QVector<BlockItemPin * > > mp = pins_.values();
|
||||
QVector<BlockItemPin * > ret;
|
||||
for (int i = 0; i < mp.size(); ++i)
|
||||
ret << mp[i];
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QByteArray BlockItem::saveModel() {
|
||||
/*QDataStream s(&ret, QIODevice::ReadWrite);
|
||||
QVector<BlockItemPin * > ps = pins();
|
||||
s << pos() << rotation() << size() << color() << ps.size();
|
||||
foreach (BlockItemPin * p, ps)
|
||||
s << int(p->alignment()) << p->busType() << p->text() << p->devices();
|
||||
s << decors_.size();
|
||||
foreach (QGraphicsItem * i, decors_)
|
||||
s << i;*/
|
||||
ChunkStream cs;
|
||||
cs << cs.chunk(1, pos()) << cs.chunk(2, rotation()) << cs.chunk(3, size()) << cs.chunk(4, color()) << cs.chunk(5, pins())
|
||||
<< cs.chunk(6, decors_) << cs.chunk(7, pins_margin) << cs.chunk(0xFF, _blockitem_current_version_);
|
||||
return cs.data();
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::loadModel(const QByteArray & data) {
|
||||
//qDebug() << "load from" << data.size() << "bytes";
|
||||
clearPins();
|
||||
clearDecors();
|
||||
col = Qt::lightGray;
|
||||
_resize(QSizeF(100., 60.));
|
||||
if (data.isEmpty()) return;
|
||||
/*QDataStream s(data);
|
||||
{QPointF _v; s >> _v;}
|
||||
{qreal _v; s >> _v;}
|
||||
{QSizeF _v; s >> _v; setSize(_v);}
|
||||
{QColor _v; s >> _v; setColor(_v);}
|
||||
int _s; s >> _s;
|
||||
for (int i = 0; i < _s; ++i) {
|
||||
BlockItemPin * pin = new BlockItemPin();
|
||||
{int _v; s >> _v; pin->setAlignment((Qt::Alignment)_v);}
|
||||
{int _v; s >> _v; pin->setBusType(_v);}
|
||||
{QString _v; s >> _v; pin->setText(_v);}
|
||||
{QMap<QString, BlockItemPin::Device> _v; s >> _v; pin->setDevices(_v);}
|
||||
addPin(pin);
|
||||
}
|
||||
s >> _s;
|
||||
for (int i = 0; i < _s; ++i) {
|
||||
if (s.atEnd()) break;
|
||||
QGraphicsItem * ni = 0;
|
||||
s >> ni;
|
||||
if (ni) {
|
||||
addDecor(ni);
|
||||
}
|
||||
}*/
|
||||
ChunkStream cs(data);
|
||||
QVector<BlockItemPin * > tp;
|
||||
QList<QGraphicsItem * > dl;
|
||||
int version = -1;
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
case 1: /*setPos(cs.getData<QPointF>());*/ break;
|
||||
case 2: /*setRotation(cs.getData<qreal>());*/ break;
|
||||
case 3: setSize(cs.getData<QSizeF>()); break;
|
||||
case 4: setColor(cs.getData<QColor>()); break;
|
||||
case 5:
|
||||
cs.get(tp);
|
||||
foreach (BlockItemPin * p, tp) addPin(p);
|
||||
break;
|
||||
case 6:
|
||||
cs.get(dl);
|
||||
foreach (QGraphicsItem * d, dl) addDecor(d);
|
||||
break;
|
||||
case 7: setPinsMargin(cs.getData<int>()); break;
|
||||
case 0xFF: cs.get(version); break;
|
||||
}
|
||||
}
|
||||
if (version <= 0)
|
||||
_moveToTop(true);
|
||||
}
|
||||
|
||||
|
||||
QByteArray BlockItem::save() const {
|
||||
ChunkStream cs;
|
||||
QMap<QString, QList<BlockItem::Property> > pp;
|
||||
foreach (BlockItemPin * p, pins()) {
|
||||
//qDebug() << "save pin" << p->text() << "->" << p->properties().size();
|
||||
pp[p->text()] = p->properties();
|
||||
}
|
||||
cs << cs.chunk(1, pos()) << cs.chunk(2, rotation()) << cs.chunk(3, props) << cs.chunk(5, pp) << cs.chunk(6, size());
|
||||
cs << cs.chunk(10, data(2000)) << cs.chunk(11, data(2001)) << cs.chunk(12, prop_bindings) << cs.chunk(0xFF, _blockitem_current_version_);
|
||||
return cs.data();
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::load(const QByteArray & data) {
|
||||
if (data.isEmpty()) return;
|
||||
ChunkStream cs(data);
|
||||
QMap<QString, QList<BlockItem::Property> > _p;
|
||||
int version = -1;
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
case 1: setPos(cs.getData<QPointF>()); break;
|
||||
case 2: setRotation(cs.getData<qreal>()); break;
|
||||
case 3: cs.get(props); break;
|
||||
case 5:
|
||||
cs.get(_p);
|
||||
//qDebug() << "load pins" << _p.size();
|
||||
foreach (BlockItemPin * p, pins()) {
|
||||
//qDebug() << "load pin" << p->text() << "->" << _p.contains(p->text());
|
||||
if (_p.contains(p->text()))
|
||||
p->properties() = _p[p->text()];
|
||||
}
|
||||
break;
|
||||
case 6: setSize(cs.getData<QSizeF>()); break;
|
||||
case 10: setData(2000, cs.getData<QVariant>()); break;
|
||||
case 11: setData(2001, cs.getData<QVariant>()); break;
|
||||
case 12: prop_bindings = cs.getData<QList<QPair<QString, QString> > >(); break;
|
||||
case 0xFF: cs.get(version); break;
|
||||
}
|
||||
}
|
||||
if (version <= 0) {
|
||||
_moveToTop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BlockItem * BlockItem::copy() const {
|
||||
BlockItem * ret = new BlockItem();
|
||||
ret->setPos(pos());
|
||||
ret->setSize(size());
|
||||
ret->setColor(color());
|
||||
ret->setSelected(false);
|
||||
ret->props = props;
|
||||
ret->setPinsMargin(pinsMargin());
|
||||
QVector<BlockItemPin * > mp = pins();
|
||||
foreach (BlockItemPin * p, mp) {
|
||||
BlockItemPin * np = new BlockItemPin();
|
||||
np->setBusType(p->busType());
|
||||
np->setAlignment(p->alignment());
|
||||
np->setText(p->text());
|
||||
np->setToolTip(p->toolTip());
|
||||
np->properties() = p->properties();
|
||||
ret->addPin(np);
|
||||
}
|
||||
QByteArray ba;
|
||||
foreach (QGraphicsItem * i, decors_) {
|
||||
ba.clear();
|
||||
QGraphicsItem * ni = 0;
|
||||
QDataStream s(&ba, QIODevice::ReadWrite); s << i;
|
||||
QDataStream s2(ba); s2 >> ni;
|
||||
if (ni)
|
||||
ret->addDecor(ni);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<BlockBusItem * > BlockItem::connectedBuses() const {
|
||||
QList<BlockBusItem * > ret;
|
||||
foreach (BlockItemPin * p, pins())
|
||||
ret << p->connectedBuses();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BlockItemPin * BlockItem::pinByText(const QString & t) const {
|
||||
foreach (BlockItemPin * p, pins())
|
||||
if (p->text() == t)
|
||||
return p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BlockItemPin * BlockItem::pinAtBus(BlockBusItem * bus) const {
|
||||
if (bus == 0) return 0;
|
||||
foreach (BlockItemPin * p, pins())
|
||||
if (p->connectedBuses().contains(bus))
|
||||
return p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
QRectF BlockItem::sceneRect() const {
|
||||
return g_main.mapRectToScene(g_main.boundingRect());
|
||||
}
|
||||
|
||||
|
||||
QRectF BlockItem::boundingRect() const {
|
||||
return g_main.mapRectToParent(g_main.boundingRect());
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event) {
|
||||
//QGraphicsItem::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::hoverEnterEvent(QGraphicsSceneHoverEvent * e) {
|
||||
bool anim = ((BlockView *)scene()->views().back())->isBlockAnimationEnabled();
|
||||
if (anim) {
|
||||
anim_thick.stop();
|
||||
anim_thick.setStartValue(thickness());
|
||||
anim_thick.setEndValue(2.5);
|
||||
anim_thick.start();
|
||||
} else setThickness(2.5);
|
||||
emit blockHoverEnter(this);
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
|
||||
bool anim = ((BlockView *)scene()->views().back())->isBlockAnimationEnabled();
|
||||
if (anim) {
|
||||
anim_thick.stop();
|
||||
anim_thick.setStartValue(thickness());
|
||||
anim_thick.setEndValue(1);
|
||||
anim_thick.start();
|
||||
} else setThickness(1);
|
||||
emit blockHoverLeave(this);
|
||||
}
|
||||
|
||||
|
||||
#define _POS(m) (i - ((cp.size() - 1) / 2)) * m
|
||||
|
||||
void BlockItem::arrangePins() {
|
||||
//double w = g_main.rect().width(), h = g_main.rect().height();
|
||||
QVector<BlockItemPin * > pl = pins();
|
||||
// pl = pl.fromList(pins().toList());
|
||||
pins_.clear();
|
||||
foreach (BlockItemPin * p, pl)
|
||||
pins_[p->alignment()] << p;
|
||||
QVector<BlockItemPin * > cp = pins_.value(Qt::AlignBottom);
|
||||
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(_POS(pins_margin), bottom());
|
||||
cp = pins_.value(Qt::AlignTop);
|
||||
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(_POS(pins_margin), top());
|
||||
cp = pins_.value(Qt::AlignLeft);
|
||||
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(left(), i * pins_margin);
|
||||
cp = pins_.value(Qt::AlignRight);
|
||||
for (int i = 0; i < cp.size(); ++i) cp[i]->setPos(right(), i * pins_margin);
|
||||
}
|
||||
|
||||
#undef _POS
|
||||
|
||||
|
||||
void BlockItem::removeBindings(const QString & bind_name) {
|
||||
for(int i=0; i<prop_bindings.size(); ++i) {
|
||||
if (prop_bindings[i].second == bind_name) {
|
||||
prop_bindings.removeAt(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::removeBindingByProperty(const QString & prop_name) {
|
||||
for(int i=0; i<prop_bindings.size(); ++i) {
|
||||
if (prop_bindings[i].first == prop_name) {
|
||||
prop_bindings.removeAt(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::addBinding(const QString & prop_name, const QString & bind_name) {
|
||||
QPair<QString, QString> pb(prop_name, bind_name);
|
||||
prop_bindings.removeAll(pb);
|
||||
prop_bindings << pb;
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::applyBinding(const QString & bind_name, const QVariant & bind_value) {
|
||||
for(int i=0; i<prop_bindings.size(); ++i) {
|
||||
if (prop_bindings[i].second == bind_name) {
|
||||
setPropertyValue(prop_bindings[i].first, bind_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::applyBindings(const PropertyStorage & bindings) {
|
||||
for(int i=0; i<prop_bindings.size(); ++i) {
|
||||
if (bindings.isPropertyExists(prop_bindings[i].second)) {
|
||||
setPropertyValue(prop_bindings[i].first, bindings.propertyValueByName(prop_bindings[i].second));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::setBindings(const QList<QPair<QString, QString> > & bindings) {
|
||||
prop_bindings = bindings;
|
||||
}
|
||||
|
||||
|
||||
QList<QPair<QString, QString> > BlockItem::getBindings() {
|
||||
return prop_bindings;
|
||||
}
|
||||
|
||||
|
||||
QString BlockItem::getBindName(const QString & prop_name) const {
|
||||
for(int i=0; i<prop_bindings.size(); ++i) {
|
||||
if (prop_bindings[i].first == prop_name) {
|
||||
return prop_bindings[i].second;
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
QStringList BlockItem::getBindNames() const {
|
||||
QStringList ret;
|
||||
for(int i=0; i<prop_bindings.size(); ++i)
|
||||
if (!ret.contains(prop_bindings[i].second)) ret << prop_bindings[i].second;
|
||||
return ret;
|
||||
}
|
||||
|
||||
QStringList BlockItem::getBindProps() const {
|
||||
QStringList ret;
|
||||
for(int i=0; i<prop_bindings.size(); ++i)
|
||||
ret << prop_bindings[i].first;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) {
|
||||
//if ()
|
||||
}
|
||||
|
||||
|
||||
QVariant BlockItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant & value) {
|
||||
if (change == QGraphicsItem::ItemSelectedChange) {
|
||||
// qDebug() << "select" << value.toBool();
|
||||
if (value.toBool() && !isSelected() && ((BlockView *)scene()->views().back())->isBlockAnimationEnabled() && t_sel.elapsed() > 50) {
|
||||
g_selection.setRect(enlargedRect(g_main.rect(), 0, 0, 16));
|
||||
anim_sel.setStartValue(selectionRect());
|
||||
anim_sel.setEndValue(enlargedRect(g_main.rect(), 0, 0, 8));
|
||||
anim_sel.start();
|
||||
}
|
||||
t_sel.restart();
|
||||
g_selection.setVisible(value.toBool());
|
||||
}
|
||||
return QGraphicsItem::itemChange(change, value);
|
||||
}
|
||||
|
||||
|
||||
double BlockItem::thickness() const {
|
||||
return g_main.pen().widthF();
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::setThickness(double w) {
|
||||
QPen p = g_main.pen();
|
||||
p.setWidthF(w);
|
||||
g_main.setPen(p);
|
||||
}
|
||||
|
||||
|
||||
QRectF BlockItem::selectionRect() const {
|
||||
return g_selection.rect();
|
||||
}
|
||||
|
||||
|
||||
void BlockItem::setSelectionRect(const QRectF & r) {
|
||||
g_selection.setRect(r);
|
||||
}
|
||||
|
||||
152
libs/blockview/blockitem.h
Normal file
152
libs/blockview/blockitem.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLOCKITEM_H
|
||||
#define BLOCKITEM_H
|
||||
|
||||
#include <QTime>
|
||||
#include "blockitempin.h"
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT BlockItem: public QGraphicsObject, public PropertyStorage
|
||||
{
|
||||
friend class BlockView;
|
||||
friend class BlockItemPin;
|
||||
friend class DrawTools;
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(double _thickness READ thickness WRITE setThickness DESIGNABLE false SCRIPTABLE false)
|
||||
Q_PROPERTY(QRectF _selRect READ selectionRect WRITE setSelectionRect DESIGNABLE false SCRIPTABLE false)
|
||||
public:
|
||||
BlockItem(QGraphicsItem * parent = 0);
|
||||
~BlockItem();
|
||||
|
||||
BlockItem * copy() const;
|
||||
BlockItemPin * addPin(BlockItemPin * pin, bool update_ = true);
|
||||
BlockItemPin * addPin(Qt::Alignment align, int bus_type, const QString & text, bool update_ = true);
|
||||
void removePin(BlockItemPin * pin);
|
||||
void addDecor(QGraphicsItem * item);
|
||||
void addDecor(QGraphicsItem & item);
|
||||
void removeDecor(QGraphicsItem * item);
|
||||
QVector<BlockItemPin * > takePins();
|
||||
void clearPins();
|
||||
void clearDecors();
|
||||
QVector<BlockItemPin * > pins() const;
|
||||
QList<QGraphicsItem * > decors() const {return decors_;}
|
||||
QList<BlockBusItem * > connectedBuses() const;
|
||||
BlockItemPin * pinByText(const QString & t) const;
|
||||
BlockItemPin * pinAtBus(BlockBusItem * bus) const;
|
||||
QColor color() const {return col;}
|
||||
void setColor(QColor c) {col = c; _resize(size());}
|
||||
QSizeF size() const {return g_main.rect().size();}
|
||||
QRectF sceneRect() const;
|
||||
qreal width() const {return size().width();}
|
||||
qreal height() const {return size().height();}
|
||||
int pinsMargin() const {return pins_margin;}
|
||||
void setSize(QSizeF s) {_resize(s);}
|
||||
void setSize(qreal w, qreal h) {setSize(QSizeF(w, h));}
|
||||
void setWidth(qreal w) {setSize(QSizeF(w, size().height()));}
|
||||
void setHeight(qreal h) {setSize(QSizeF(size().width(), h));}
|
||||
void setPinsMargin(int marg) {if (marg > 1 && marg < 256) pins_margin = marg; arrangePins();}
|
||||
|
||||
QByteArray saveModel();
|
||||
void loadModel(const QByteArray & data);
|
||||
QByteArray save() const;
|
||||
void load(const QByteArray & data);
|
||||
void arrangePins();
|
||||
|
||||
void removeBindings(const QString & bind_name);
|
||||
void removeBindingByProperty(const QString & prop_name);
|
||||
void addBinding(const QString & prop_name, const QString & bind_name);
|
||||
void applyBinding(const QString & bind_name, const QVariant & bind_value);
|
||||
void applyBindings(const PropertyStorage & bindings);
|
||||
void setBindings(const QList<QPair<QString, QString> > & bindings);
|
||||
QList<QPair<QString, QString> > getBindings();
|
||||
QString getBindName(const QString & prop_name) const;
|
||||
QStringList getBindNames() const;
|
||||
QStringList getBindProps() const;
|
||||
|
||||
enum {Type = UserType + 1};
|
||||
|
||||
protected:
|
||||
void _resize(QSizeF s);
|
||||
void _moveToTop(bool only_decors = false);
|
||||
int type() const {return Type;}
|
||||
QRectF boundingRect() const;
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent * event);
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent * event);
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent * event);
|
||||
double left() const {return boundingRect().left();}
|
||||
double right() const {return boundingRect().right();}
|
||||
double top() const {return boundingRect().top();}
|
||||
double bottom() const {return boundingRect().bottom();}
|
||||
void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0);
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant & value);
|
||||
|
||||
QGraphicsRectItem g_main, g_selection;
|
||||
int pins_margin;
|
||||
QColor col;
|
||||
QMap<Qt::Alignment, QVector<BlockItemPin * > > pins_;
|
||||
QList<QGraphicsItem * > decors_;
|
||||
QList<QPair<QString, QString> > prop_bindings; // <property_name, binding_name>
|
||||
|
||||
private:
|
||||
double thickness() const;
|
||||
void setThickness(double w);
|
||||
QRectF selectionRect() const;
|
||||
void setSelectionRect(const QRectF & r);
|
||||
|
||||
QPropertyAnimation anim_thick, anim_sel;
|
||||
QTime t_sel;
|
||||
|
||||
signals:
|
||||
void blockHoverEnter(BlockItem * b);
|
||||
void blockHoverLeave(BlockItem * b);
|
||||
};
|
||||
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const BlockItemPin * p) {
|
||||
ChunkStream cs;
|
||||
cs << cs.chunk(1, int(p->alignment())) << cs.chunk(2, p->busType()) << cs.chunk(3, p->text()) << cs.chunk(4, p->toolTip());
|
||||
s << cs.data(); return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, BlockItemPin *& p) {
|
||||
ChunkStream cs(s);
|
||||
p = new BlockItemPin();
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
case 1: p->setAlignment((Qt::Alignment)cs.getData<int>()); break;
|
||||
case 2: p->setBusType(cs.getData<int>()); break;
|
||||
case 3: p->setText(cs.getData<QString>()); break;
|
||||
case 4: p->setToolTip(cs.getData<QString>()); break;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const BlockItem * b) {s << b->save(); return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, BlockItem *& b) {
|
||||
QByteArray ba; s >> ba;
|
||||
b = new BlockItem();
|
||||
b->load(ba);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
#endif // BLOCKITEM_H
|
||||
163
libs/blockview/blockitempin.cpp
Normal file
163
libs/blockview/blockitempin.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
#include "blockview.h"
|
||||
#include <QApplication>
|
||||
|
||||
|
||||
BlockItemPin::BlockItemPin(Qt::Alignment a, int bus_type_, const QString & text_, QGraphicsObject * _parent): QGraphicsObject(_parent), ell_item(this), text_item(this) {
|
||||
parent_ = 0;
|
||||
setData(1004, "pin");
|
||||
setAcceptHoverEvents(true);
|
||||
text_item.setData(1002, true);
|
||||
ell_item.setData(1003, true);
|
||||
br[Disconnected] = QBrush(Qt::lightGray);
|
||||
br[Connected] = QBrush(Qt::darkGreen);
|
||||
br[Hover] = QBrush(Qt::blue);
|
||||
br[Drop] = QBrush(Qt::green);
|
||||
br[Accept] = QBrush(Qt::green);
|
||||
br[Reject] = QBrush(Qt::red);
|
||||
anim_pin_size.setTargetObject(this);
|
||||
anim_pin_size.setPropertyName("pinSize");
|
||||
anim_pin_size.setEasingCurve(QEasingCurve::OutElastic);
|
||||
anim_pin_size.setDuration(700);
|
||||
anim_accept.setTargetObject(this);
|
||||
anim_accept.setPropertyName("pinSize");
|
||||
anim_accept.setEasingCurve(QEasingCurve::InOutQuad);
|
||||
anim_accept.setDuration(150);
|
||||
connect(&anim_accept, SIGNAL(finished()), this, SLOT(animationAccept()));
|
||||
setState(Disconnected);
|
||||
setAlignment(a);
|
||||
setBusType(bus_type_);
|
||||
setText(text_);
|
||||
setZValue(2.);
|
||||
setDirection(BlockItemPin::InputOutput);
|
||||
_reparent();
|
||||
}
|
||||
|
||||
|
||||
void BlockItemPin::animAccept() {
|
||||
if (!((BlockView *)scene()->views().back())->isBlockAnimationEnabled() && anim_accept.state() != QAbstractAnimation::Running) return;
|
||||
anim_accept.setStartValue(pinSize());
|
||||
anim_accept.setEndValue(10.);
|
||||
anim_accept.start();
|
||||
}
|
||||
|
||||
|
||||
void BlockItemPin::setState(State s) {
|
||||
State os = state_;
|
||||
state_ = s;
|
||||
setBrush(br[int(state_)]);
|
||||
if (s == Accept && os != Accept) {
|
||||
animAccept();
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void BlockItemPin::enlargePin(bool enlarge) {
|
||||
double sz = enlarge ? 12. : 7;
|
||||
if (anim_accept.state() == QAbstractAnimation::Running && enlarge) {
|
||||
anim_accept.stop();
|
||||
resizePin(sz);
|
||||
}
|
||||
if (!((BlockView *)scene()->views().back())->isBlockAnimationEnabled()) {
|
||||
resizePin(sz);
|
||||
return;
|
||||
}
|
||||
if (sz == anim_pin_size.endValue())
|
||||
return;
|
||||
anim_pin_size.stop();
|
||||
anim_pin_size.setStartValue(pinSize());
|
||||
anim_pin_size.setEndValue(sz);
|
||||
anim_pin_size.start();
|
||||
}
|
||||
|
||||
|
||||
void BlockItemPin::resizePin(double r) {
|
||||
ell_item.setRect(-r, -r, r+r, r+r);
|
||||
}
|
||||
|
||||
|
||||
double BlockItemPin::pinSize() const {
|
||||
return ell_item.rect().width() / 2.;
|
||||
}
|
||||
|
||||
|
||||
void BlockItemPin::animationAccept() {
|
||||
if (anim_accept.endValue().toDouble() == 7.) return;
|
||||
anim_accept.setStartValue(pinSize());
|
||||
anim_accept.setEndValue(7.);
|
||||
anim_accept.start();
|
||||
}
|
||||
|
||||
|
||||
void BlockItemPin::_init(bool affect_parent) {
|
||||
text_item.setFont(AlignedTextItem::sceneFont(QApplication::font()));
|
||||
QRectF tbr = text_item.boundingRect();
|
||||
const double r = 7.;
|
||||
ell_item.setRect(-r, -r, r+r, r+r);
|
||||
ell_item.setSpanAngle(16*180);
|
||||
text_item.resetTransform();
|
||||
text_item.setPos(0, -tbr.height() / 2.);
|
||||
text_item.setTransformOriginPoint(0, tbr.height() / 2.);
|
||||
switch (align) {
|
||||
case Qt::AlignBottom: ell_item.setStartAngle(16*0); text_item.setRotation(-90.); text_item.moveBy(0, -r * 1.5); break;
|
||||
case Qt::AlignRight: ell_item.setStartAngle(16*90); text_item.setRotation(0.); text_item.moveBy(-tbr.width() - r * 1.5, 0); break;
|
||||
case Qt::AlignTop: ell_item.setStartAngle(16*180); text_item.setRotation(-90.); text_item.moveBy(0, tbr.width() + r * 1.5); break;
|
||||
case Qt::AlignLeft: ell_item.setStartAngle(16*270); text_item.setRotation(0.); text_item.moveBy(r * 1.5, 0); break;
|
||||
default: break;
|
||||
}
|
||||
if (affect_parent && parent_)
|
||||
parent_->arrangePins();
|
||||
}
|
||||
|
||||
|
||||
void BlockItemPin::_reparent() {
|
||||
if (parentItem() == 0) return;
|
||||
if (qgraphicsitem_cast<BlockItem*>(parentItem()) == 0) return;
|
||||
QPen p = qgraphicsitem_cast<BlockItem*>(parentItem())->g_main.pen();
|
||||
ell_item.setPen(p);
|
||||
if (scene()) {
|
||||
text_item.setFont(AlignedTextItem::sceneFont(scene()->font()));
|
||||
QRectF tbr = text_item.boundingRect();
|
||||
text_item.resetTransform();
|
||||
text_item.setPos(0, -tbr.height() / 2.);
|
||||
text_item.setTransformOriginPoint(0, tbr.height() / 2.);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QGraphicsView * BlockItemPin::_view() const {
|
||||
if (!scene()) return 0;
|
||||
if (scene()->views().isEmpty()) return 0;
|
||||
return scene()->views().back();
|
||||
}
|
||||
|
||||
|
||||
QVariant BlockItemPin::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant & value) {
|
||||
if (change == QGraphicsItem::ItemParentChange)
|
||||
_reparent();
|
||||
return QGraphicsItem::itemChange(change, value);
|
||||
}
|
||||
|
||||
|
||||
void BlockItemPin::hoverEnterEvent(QGraphicsSceneHoverEvent * e) {
|
||||
QGraphicsView * v = _view();
|
||||
bool m_pin_mc = false;
|
||||
if (v) {
|
||||
QMetaObject::invokeMethod(v, "getPinMC", Q_ARG(bool*, &m_pin_mc));
|
||||
QMetaObject::invokeMethod(v, "pinHoverInOut", Qt::QueuedConnection, Q_ARG(BlockItemPin*, this));
|
||||
}
|
||||
if ((state() != Disconnected) && !m_pin_mc) return;
|
||||
saveState();
|
||||
setState(BlockItemPin::Hover);
|
||||
enlargePin(true);
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void BlockItemPin::hoverLeaveEvent(QGraphicsSceneHoverEvent * e) {
|
||||
QGraphicsView * v = _view();
|
||||
restoreState();
|
||||
enlargePin(false);
|
||||
update();
|
||||
if (v) QMetaObject::invokeMethod(v, "pinHoverInOut", Q_ARG(BlockItemPin*, 0));
|
||||
}
|
||||
132
libs/blockview/blockitempin.h
Normal file
132
libs/blockview/blockitempin.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLOCKITEMPIN_H
|
||||
#define BLOCKITEMPIN_H
|
||||
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsObject>
|
||||
#include <QGraphicsEllipseItem>
|
||||
#include <QGraphicsSceneHoverEvent>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QStack>
|
||||
#include <QDebug>
|
||||
#include <QPropertyAnimation>
|
||||
#include <qmath.h>
|
||||
#include "blockbase.h"
|
||||
#include "alignedtextitem.h"
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
|
||||
class BlockItem;
|
||||
class BlockBusItem;
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT BlockItemPin: public QGraphicsObject, public PropertyStorage
|
||||
{
|
||||
friend class BlockView;
|
||||
friend class BlockItem;
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(double pinSize READ pinSize WRITE resizePin DESIGNABLE false SCRIPTABLE false)
|
||||
public:
|
||||
BlockItemPin(Qt::Alignment a = Qt::AlignLeft, int bus_type = 0, const QString & text_ = QString(), QGraphicsObject * parent_ = 0);
|
||||
|
||||
enum State {
|
||||
Disconnected,
|
||||
Connected,
|
||||
Hover,
|
||||
Drop,
|
||||
Accept,
|
||||
Reject
|
||||
};
|
||||
|
||||
enum Direction {
|
||||
None = 0x0,
|
||||
Input = 0x1,
|
||||
Output = 0x2,
|
||||
InputOutput = 0x3
|
||||
};
|
||||
|
||||
void setPen(const QPen & p) {ell_item.setPen(p);}
|
||||
QPen pen() const {return ell_item.pen();}
|
||||
void setBrush(const QBrush & b) {ell_item.setBrush(b);}
|
||||
QBrush brush() const {return ell_item.brush();}
|
||||
|
||||
int busType() const {return bus_type;}
|
||||
Qt::Alignment alignment() const {return align;}
|
||||
Direction direction() const {return dir;}
|
||||
QString text() const {return text_item.text();}
|
||||
State state() const {return state_;}
|
||||
|
||||
void setBusType(int type_) {bus_type = type_;}
|
||||
void setAlignment(Qt::Alignment a) {align = a; _init(true);}
|
||||
void setDirection(Direction d) {dir = d; _init(true);}
|
||||
void setText(const QString & t) {text_item.setText(t); _init(true);}
|
||||
void setState(State s);
|
||||
|
||||
void saveState() {sstate_.push(state_);}
|
||||
bool restoreState() {if (sstate_.isEmpty()) return false; setState(sstate_.pop()); return true;}
|
||||
void clearStateStack() {sstate_.clear();}
|
||||
|
||||
void enlargePin(bool enlarge);
|
||||
|
||||
BlockItem * parent() const {return parent_;}
|
||||
QList<BlockBusItem * > connectedBuses() const {return buses_;}
|
||||
|
||||
enum {Type = UserType + 3};
|
||||
|
||||
public slots:
|
||||
void animAccept();
|
||||
|
||||
protected:
|
||||
void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0) {}
|
||||
QRectF boundingRect() const {return ell_item.boundingRect().translated(ell_item.pos()) | text_item.boundingRect().translated(text_item.pos());}
|
||||
int type() const {return Type;}
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant & value);
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent * e);
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent * e);
|
||||
void _init(bool affect_parent = false);
|
||||
void _reparent();
|
||||
QGraphicsView * _view() const;
|
||||
int bus_type;
|
||||
State state_;
|
||||
QGraphicsEllipseItem ell_item;
|
||||
QGraphicsSimpleTextItem text_item;
|
||||
QStack<State> sstate_;
|
||||
QList<BlockBusItem * > buses_;
|
||||
BlockItem * parent_;
|
||||
Qt::Alignment align;
|
||||
Direction dir;
|
||||
QBrush br[6];
|
||||
|
||||
private slots:
|
||||
void animationAccept();
|
||||
|
||||
private:
|
||||
void resizePin(double r);
|
||||
double pinSize() const;
|
||||
|
||||
QPropertyAnimation anim_pin_size;
|
||||
QPropertyAnimation anim_accept;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // BLOCKITEMPIN_H
|
||||
2054
libs/blockview/blockview.cpp
Normal file
2054
libs/blockview/blockview.cpp
Normal file
@@ -0,0 +1,2054 @@
|
||||
#include "blockview.h"
|
||||
#include <qmath.h>
|
||||
#include <QScrollBar>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QApplication>
|
||||
#include <QAction>
|
||||
#include <QShortcut>
|
||||
#include <QVector2D>
|
||||
#include <QClipboard>
|
||||
#include <QMimeData>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
const QString _BlockView_Mime_ = "_BlockView_copypaste_";
|
||||
|
||||
|
||||
BlockView::BlockView(QWidget * parent): QGraphicsView(parent), tmp_bus(true) {
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
BlockView::BlockView(QGraphicsScene * scene, QWidget * parent): QGraphicsView(scene, parent), tmp_bus(true) {
|
||||
_init();
|
||||
}
|
||||
|
||||
|
||||
BlockView::~BlockView() {
|
||||
}
|
||||
|
||||
|
||||
void BlockView::_init() {
|
||||
qRegisterMetaType<BlockItem*>();
|
||||
qRegisterMetaType<BlockItemPin*>();
|
||||
qRegisterMetaType<BlockBusItem*>();
|
||||
grid_visible = grid_snap = pm_connect = navigation = m_connect = m_trace_with_buses = prev_tcb = minimap = true;
|
||||
mm_drag = moved = new_branch = new_bus = mm_cancel = iconnect = mm_copy = m_pin_mc = mm_thumb = move_bus_point = wheel_zoom = false;
|
||||
match_bus = bus_from = 0;
|
||||
mm_ci = 0;
|
||||
hpin = 0;
|
||||
ghost_ = 0;
|
||||
grid_step = 10.;
|
||||
grid_points = 1;
|
||||
grid_pen = QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 1, Qt::NoPen);
|
||||
thick = 1;
|
||||
thumb_hide_delay = 500;
|
||||
timer_thumb = 0;
|
||||
smode = BlockView::MultiSelection;
|
||||
cur_scl = thumb_scl = prev_app_scale = 1.;
|
||||
_talpha = 0.;
|
||||
ae_enabled = is_block_anim = is_nav_anim = true;
|
||||
nav_prev_aa = nav_prev_imaa = nav_prev_grid = true;
|
||||
square_node = false;
|
||||
thumb_size = QSizeF(200, 200);
|
||||
if (scene() == 0) {
|
||||
scene_ = new QGraphicsScene;
|
||||
setScene(scene_);
|
||||
}
|
||||
scene_ = scene();
|
||||
scene_->setSceneRect(-2500, -2500, 5000, 5000);
|
||||
scene_->setItemIndexMethod(QGraphicsScene::NoIndex);
|
||||
scene_->installEventFilter(this);
|
||||
scene_->addItem(&tmp_bus);
|
||||
widget_thumb.setParent(this);
|
||||
//widget_thumb.setAutoFillBackground(true);
|
||||
//widget_thumb.setStyleSheet("background-color: rgb(255, 0, 0);");
|
||||
widget_thumb.installEventFilter(this);
|
||||
widget_thumb.setMouseTracking(true);
|
||||
widget_thumb.show();
|
||||
widget_thumb.setWindowOpacity(0.);
|
||||
thumb_anim.setTargetObject(this);
|
||||
thumb_anim.setPropertyName("_thumb");
|
||||
thumb_anim.setEasingCurve(QEasingCurve::InCubic);
|
||||
nav_anim.setTargetObject(this);
|
||||
nav_anim.setPropertyName("_nav");
|
||||
nav_anim.setEasingCurve(QEasingCurve::Linear);
|
||||
nav_anim.setDuration(150);
|
||||
connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(checkPaste()));
|
||||
connect(&nav_anim, SIGNAL(finished()), this, SLOT(_navFinished()));
|
||||
connect(scene_, SIGNAL(sceneRectChanged(QRectF)), this, SLOT(adjustThumb()));
|
||||
connect(scene_, SIGNAL(selectionChanged()), this, SLOT(sceneSelectionChanged()));
|
||||
connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(scrolled()));
|
||||
connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(scrolled()));
|
||||
centerOn(scene_->sceneRect().center());
|
||||
setCacheMode(CacheBackground);
|
||||
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
|
||||
setResizeAnchor(QGraphicsView::AnchorViewCenter);
|
||||
setRenderHint(QPainter::Antialiasing);
|
||||
setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
setMouseTracking(true);
|
||||
sel_rect.setZValue(999.);
|
||||
sel_rect.hide();
|
||||
QColor sc = palette().color(QPalette::Highlight);
|
||||
sc.setAlphaF(0.6);
|
||||
QPen pen(sc.darker(200), lineThickness() + 1., Qt::DotLine);
|
||||
pen.setCosmetic(true);
|
||||
sel_rect.setPen(pen);
|
||||
sc.setAlphaF(0.2);
|
||||
sel_rect.setBrush(QBrush(sc));
|
||||
checkPaste(true);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::_updateBack() {
|
||||
setCacheMode(CacheNone);
|
||||
invalidateScene();
|
||||
setCacheMode(CacheBackground);
|
||||
}
|
||||
|
||||
|
||||
bool BlockView::event(QEvent * e) {
|
||||
if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish) {
|
||||
double cscl = appScale(this);
|
||||
QGraphicsView::scale(cscl / prev_app_scale, cscl / prev_app_scale);
|
||||
prev_app_scale = cscl;
|
||||
}
|
||||
return QGraphicsView::event(e);
|
||||
}
|
||||
|
||||
|
||||
bool BlockView::eventFilter(QObject * o, QEvent * e) {
|
||||
if (o == &widget_thumb) {
|
||||
QMouseEvent * me = (QMouseEvent*)e;
|
||||
if(!me) return true;
|
||||
switch (e->type()) {
|
||||
case QEvent::Paint:
|
||||
drawThumb();
|
||||
return true;
|
||||
case QEvent::Enter:
|
||||
thumbShow();
|
||||
break;
|
||||
case QEvent::Leave:
|
||||
restartTimer(timer_thumb, thumb_hide_delay);
|
||||
break;
|
||||
case QEvent::MouseButtonPress:
|
||||
thumb_press = me->pos();
|
||||
widget_thumb.setCursor(Qt::ClosedHandCursor);
|
||||
if (!thumb_vr.contains(thumb_press)) {
|
||||
thumb_vr.moveCenter(thumb_press);
|
||||
scrollFromThumb();
|
||||
}
|
||||
break;
|
||||
case QEvent::MouseButtonRelease:
|
||||
widget_thumb.setCursor(Qt::OpenHandCursor);
|
||||
break;
|
||||
case QEvent::MouseMove:
|
||||
if (me->buttons() == 0)
|
||||
widget_thumb.setCursor(thumb_vr.contains(me->pos()) ? Qt::OpenHandCursor : Qt::CrossCursor);
|
||||
if (me->buttons().testFlag(Qt::LeftButton)) {
|
||||
thumb_vr.translate(me->pos() - thumb_press);
|
||||
scrollFromThumb();
|
||||
thumb_press = me->pos();
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return QGraphicsView::eventFilter(o, e);
|
||||
}
|
||||
if (o == scene_) {
|
||||
QGraphicsSceneMouseEvent * me = (QGraphicsSceneMouseEvent*)e;
|
||||
QList<QGraphicsItem * > mil;
|
||||
QPointF mdp;
|
||||
bool fmm_drag = false;
|
||||
int btncnt = 0;
|
||||
switch (e->type()) {
|
||||
case QEvent::GraphicsSceneMouseDoubleClick:
|
||||
mil = scene_->items(scene_point);
|
||||
foreach (QGraphicsItem * i, mil) {
|
||||
if (i->data(1006) == "item") {
|
||||
//emit blockDoubleClicked((BlockItem * )i);
|
||||
QMetaObject::invokeMethod(this, "blockDoubleClicked", Qt::QueuedConnection, Q_ARG(BlockItem * , (BlockItem*)i));
|
||||
return true;
|
||||
}
|
||||
if (i->data(1005) == "connection") {
|
||||
if (qgraphicsitem_cast<BlockBusItem*>(i)->isBusSelected()) {
|
||||
//emit busDoubleClicked(qgraphicsitem_cast<BlockBusItem*>(i));
|
||||
QMetaObject::invokeMethod(this, "busDoubleClicked", Qt::QueuedConnection, Q_ARG(BlockBusItem * , (BlockBusItem*)i));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
//return true;
|
||||
break;
|
||||
/*case QEvent::GraphicsSceneHoverMove:
|
||||
mil = scene_->items(scene_point);
|
||||
mm_ci = (mil.isEmpty() ? 0 : mil.front());
|
||||
if (mm_ci != 0) {
|
||||
while (mm_ci->data(1005).toString() == "connection") {
|
||||
if (qgraphicsitem_cast<BlockBusItem*>(mm_ci))
|
||||
if (qgraphicsitem_cast<BlockBusItem*>(mm_ci)->isBusSelected())
|
||||
break;
|
||||
if (mil.size() > 1) {
|
||||
mm_ci = mil[1];
|
||||
mil.pop_front();
|
||||
} else {
|
||||
mm_ci = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;*/
|
||||
case QEvent::GraphicsSceneMousePress:
|
||||
if (mm_ci != 0) {
|
||||
if (mm_ci->data(1008).toBool()) {
|
||||
mm_ci = 0;
|
||||
break;
|
||||
}
|
||||
//if (mm_ci->data(1007).toBool()) break;
|
||||
}
|
||||
//qDebug() << "press";
|
||||
if (me->buttons().testFlag(Qt::LeftButton)) btncnt++;
|
||||
if (me->buttons().testFlag(Qt::RightButton)) btncnt++;
|
||||
if (me->buttons().testFlag(Qt::MidButton)) btncnt++;
|
||||
mm_cancel = btncnt >= 2;
|
||||
match_bus = bus_from = 0;
|
||||
hpin = 0;
|
||||
copy_dp = QPointF();
|
||||
//qDebug() << mm_cancel << mm_copy << mm_drag << new_branch << new_bus;
|
||||
if (mm_copy && mm_cancel) {
|
||||
deleteCopyTemp();
|
||||
mm_copy = moved = false;
|
||||
unsetCursor();
|
||||
}
|
||||
if (new_bus && mm_cancel) {
|
||||
new_bus = false;
|
||||
unmarkPins(true);
|
||||
reconnectAll();
|
||||
hideTmpBuses();
|
||||
m_trace_with_buses = prev_tcb;
|
||||
}
|
||||
if (new_branch && mm_cancel) {
|
||||
new_branch = false;
|
||||
hideTmpBuses();
|
||||
m_trace_with_buses = prev_tcb;
|
||||
}
|
||||
if (moved && mm_cancel) {
|
||||
moved = false;
|
||||
restoreSelState();
|
||||
hideTmpBuses();
|
||||
m_trace_with_buses = prev_tcb;
|
||||
}
|
||||
if (mm_cancel) return true;
|
||||
mm_mods = me->modifiers();
|
||||
mm_drag = moved = false;
|
||||
screen_point = me->screenPos();
|
||||
scene_point = me->scenePos();
|
||||
if ((me->button() == Qt::MidButton)) {
|
||||
thumbShow();
|
||||
restartTimer(timer_thumb, thumb_hide_delay);
|
||||
return true;
|
||||
}
|
||||
mil = scene_->items(scene_point);
|
||||
//qDebug() << mil;
|
||||
while (!mil.isEmpty()) {
|
||||
mm_ci = mil.front();
|
||||
if (mm_ci->data(bvidDTHandle).toBool()) return QGraphicsView::eventFilter(o, e);
|
||||
if (mm_ci->data(1008).toBool() || mm_ci->data(1007).toBool()) {
|
||||
mil.pop_front();
|
||||
} else break;
|
||||
}
|
||||
if (mil.isEmpty()) {
|
||||
mm_ci = 0;
|
||||
return true;
|
||||
}
|
||||
while (mm_ci->data(1005).toString() == "connection") {
|
||||
if (qgraphicsitem_cast<BlockBusItem*>(mm_ci))
|
||||
if (qgraphicsitem_cast<BlockBusItem*>(mm_ci)->isBusSelected())
|
||||
break;
|
||||
if (mil.size() > 1) {
|
||||
mm_ci = mil[1];
|
||||
mil.pop_front();
|
||||
} else {
|
||||
mm_ci = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mm_ci->data(1003).toBool()) {
|
||||
if (mil.size() > 1) {
|
||||
mm_ci = mil[1];
|
||||
mil.pop_front();
|
||||
if (mm_ci->data(1003).toBool())
|
||||
if (mil.size() > 1)
|
||||
mm_ci = mil[1];
|
||||
} else
|
||||
mm_ci = 0;
|
||||
}
|
||||
if (mm_ci->data(1002).toBool()) {
|
||||
QGraphicsItem * ti = mm_ci;
|
||||
while (mm_ci->parentItem() != 0)
|
||||
mm_ci = mm_ci->parentItem();
|
||||
if (!ti->data(1010).toString().isEmpty()) { // text item, check for rect
|
||||
BlockItem * bi = qgraphicsitem_cast<BlockItem*>(mm_ci);
|
||||
if (bi) {
|
||||
if (!bi->sceneRect().contains(scene_point)) {
|
||||
//qDebug() << "return";
|
||||
mm_ci = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (mm_ci) {
|
||||
if (mm_ci->data(1004) == "pin" && m_connect) {
|
||||
if (qgraphicsitem_cast<BlockItemPin*>(mm_ci)->state() == BlockItemPin::Hover) {
|
||||
trace_from = mm_ci->scenePos();
|
||||
qgraphicsitem_cast<BlockItemPin*>(mm_ci)->clearStateStack();
|
||||
hideTmpBuses();
|
||||
tmp_bus.setBusType(qgraphicsitem_cast<BlockItemPin*>(mm_ci)->busType());
|
||||
tmp_bus.setEndpointsNumber(3);
|
||||
tmp_bus.show();
|
||||
new_bus = true;
|
||||
qDeleteAll(tmp_buses);
|
||||
tmp_buses.clear();
|
||||
foreach (BlockItemPin * p, last_multiconnect_pl) {
|
||||
tmp_buses << new BlockBusItem(true);
|
||||
tmp_buses.back()->setBusType(p->busType());
|
||||
addItem(tmp_buses.back());
|
||||
}
|
||||
//qDebug() << "new" << ;
|
||||
prev_tcb = m_trace_with_buses;
|
||||
newBusStarted(tmp_bus.busType());
|
||||
markPins(tmp_bus.busType());
|
||||
if (qgraphicsitem_cast<BlockItemPin*>(mm_ci)->alignment() == Qt::AlignLeft ||
|
||||
qgraphicsitem_cast<BlockItemPin*>(mm_ci)->alignment() == Qt::AlignRight)
|
||||
wavetrace.setPreferredDirection(BlockViewWavetrace::Horizontal);
|
||||
else
|
||||
wavetrace.setPreferredDirection(BlockViewWavetrace::Vertical);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
cur_scl = qSqrt(transform().determinant());
|
||||
//return true;
|
||||
break;
|
||||
case QEvent::GraphicsSceneMouseMove:
|
||||
//qDebug() << "move" << (mm_ci != 0 ? mm_ci : 0) << mm_mods << mm_cancel << mm_drag;
|
||||
/*if (ghost_) {
|
||||
ghost_->setPos(quantize(me->scenePos(), grid_step));
|
||||
}*/
|
||||
if (mm_ci)
|
||||
if (mm_ci->data(1008).toBool()) {
|
||||
mm_ci = 0;
|
||||
break;
|
||||
}
|
||||
if (mm_ci->data(1007).toBool()) break;
|
||||
if (mm_ci->data(bvidDTHandle).toBool()) break;
|
||||
if (mm_cancel) return true;
|
||||
if (me->buttons().testFlag(Qt::LeftButton)) {
|
||||
if (!mm_drag) {
|
||||
if ((screen_point - me->screenPos()).manhattanLength() >= QApplication::startDragDistance()) {
|
||||
mm_drag = fmm_drag = true;
|
||||
saveBusesState();
|
||||
}
|
||||
} else {
|
||||
if (tmp_bus.isVisible()) {
|
||||
mil = scene_->items(me->scenePos());
|
||||
hpin = 0;
|
||||
foreach (QGraphicsItem * i, mil)
|
||||
if (i->data(1004) == "pin") {
|
||||
hpin = qgraphicsitem_cast<BlockItemPin*>(i);
|
||||
break;
|
||||
}
|
||||
if (hpin) {
|
||||
if (hpin->state() == BlockItemPin::Accept) {
|
||||
unhoverPins(hpin);
|
||||
hoverAcceptedPin(hpin, true);
|
||||
} else hpin = 0;
|
||||
} else unhoverPins();
|
||||
if (new_branch) {
|
||||
matchBus();
|
||||
break;
|
||||
}
|
||||
trace(trace_from, me->scenePos(), &tmp_bus);
|
||||
for (int i = 0; i < qMin(tmp_buses.size(), last_multiconnect_pl.size()); ++i) {
|
||||
QPointF dp = last_multiconnect_pl[i]->scenePos() - trace_from;
|
||||
//qDebug() << "trace" << i << dp;
|
||||
trace(trace_from + dp, me->scenePos() + dp, tmp_buses[i], false);
|
||||
tmp_buses[i]->show();
|
||||
}
|
||||
matchBus();
|
||||
}
|
||||
}
|
||||
if (tmp_bus.isVisible()) return true;
|
||||
if (mm_mods.testFlag(Qt::ShiftModifier)) {
|
||||
if (fmm_drag) {
|
||||
fmm_drag = false;
|
||||
if (mm_ci) {
|
||||
if ((mm_ci->data(1006) == "item")) {
|
||||
if (!mm_ci->isSelected() && sel_items.isEmpty()) {
|
||||
clearSelection();
|
||||
mm_ci->setSelected(true);
|
||||
}
|
||||
} else {
|
||||
mm_ci = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
sel_items = scene_->selectedItems();
|
||||
deleteCopyTemp();
|
||||
QList<BlockItem * > bi;
|
||||
foreach (QGraphicsItem * i, sel_items) {
|
||||
if (i->data(1006) == "item") {
|
||||
//qDebug() << "copy";
|
||||
bi << qgraphicsitem_cast<BlockItem*>(i);
|
||||
BlockItem * ti = bi.back()->copy();
|
||||
ti->g_main.setPen(QPen(ti->g_main.pen().color(), ti->g_main.pen().widthF(), Qt::DashLine));
|
||||
QColor bc = ti->g_main.brush().color(); bc.setAlphaF(bc.alphaF() * 0.5);
|
||||
ti->g_main.setBrush(bc);
|
||||
copy_items << ti;
|
||||
scene_->addItem(ti);
|
||||
}
|
||||
}
|
||||
QList<BlockBusItem * > ibi = internalBuses(bi);
|
||||
foreach (BlockBusItem * i, ibi) {
|
||||
i = i->copy();
|
||||
i->setOpacity(i->opacity() * 0.5);
|
||||
copy_buses << i;
|
||||
scene_->addItem(i);
|
||||
}
|
||||
mm_copy = true;
|
||||
setCursor(Qt::DragCopyCursor);
|
||||
}
|
||||
} else {
|
||||
if (smode == BlockView::SingleSelection) {
|
||||
if (fmm_drag) {
|
||||
clearSelection();
|
||||
if (mm_ci != 0) {
|
||||
mm_ci->setSelected(true);
|
||||
}
|
||||
saveSelState();
|
||||
}
|
||||
}
|
||||
if (smode == BlockView::MultiSelection) {
|
||||
sel_rect.setRect(QRectF(scene_point, me->scenePos()).normalized());
|
||||
if (fmm_drag) {
|
||||
if (mm_ci == 0) {
|
||||
scene_->addItem(&sel_rect);
|
||||
sel_rect.show();
|
||||
if (!mm_mods.testFlag(Qt::ControlModifier))
|
||||
clearSelection();
|
||||
} else {
|
||||
if (!mm_mods.testFlag(Qt::ControlModifier) && !mm_ci->isSelected()) {
|
||||
clearSelection();
|
||||
mm_ci->setSelected(true);
|
||||
}
|
||||
}
|
||||
saveSelState();
|
||||
if (mm_ci != 0)
|
||||
if (!sel_items.contains(mm_ci))
|
||||
mm_ci = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sel_rect.isVisible())
|
||||
applySelRect(me);
|
||||
else {
|
||||
if (mm_drag && mm_ci != 0) {
|
||||
mdp = (me->scenePos() - scene_point);
|
||||
if (grid_snap)
|
||||
mdp = quantize(mdp, grid_step);
|
||||
if (!mdp.isNull()) {
|
||||
scene_point += mdp;
|
||||
copy_dp += mdp;
|
||||
}
|
||||
if (mm_copy) {
|
||||
if (!mdp.isNull())
|
||||
moved = true;
|
||||
foreach (QGraphicsItem * i, copy_items)
|
||||
i->setPos(i->pos() + mdp);
|
||||
foreach (BlockBusItem * i, copy_buses)
|
||||
i->movePolyline(mdp);
|
||||
}
|
||||
if (!mm_mods.testFlag(Qt::ControlModifier) && !mm_mods.testFlag(Qt::ShiftModifier)) {
|
||||
if (!mdp.isNull())
|
||||
moved = true;
|
||||
foreach (QGraphicsItem * i, sel_items)
|
||||
if (i->flags().testFlag(QGraphicsItem::ItemIsMovable))
|
||||
i->setPos(i->pos() + mdp);
|
||||
if (!me->modifiers().testFlag(Qt::AltModifier))
|
||||
moveBuses(sel_items, mdp);
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (mm_ci)
|
||||
if (mm_ci->data(1100).toBool())
|
||||
return true;
|
||||
}
|
||||
if (me->modifiers().testFlag(Qt::ControlModifier) && me->buttons() != 0 && mm_ci == 0)
|
||||
return true;
|
||||
//qDebug() << "scene mouse";
|
||||
//return true;
|
||||
break;
|
||||
case QEvent::GraphicsSceneMouseRelease:
|
||||
if (me->buttons().testFlag(Qt::LeftButton)) btncnt++;
|
||||
if (me->buttons().testFlag(Qt::RightButton)) btncnt++;
|
||||
if (me->buttons().testFlag(Qt::MidButton)) btncnt++;
|
||||
mm_cancel = btncnt > 0;
|
||||
if (mm_cancel || (me->button() == Qt::MidButton) || (me->button() == Qt::RightButton)) {
|
||||
mm_ci = 0;
|
||||
return true;
|
||||
}
|
||||
if (mm_ci)
|
||||
if (mm_ci->data(1008).toBool()) {
|
||||
mm_ci = 0;
|
||||
break;
|
||||
}
|
||||
if (mm_ci->data(1007).toBool()) break;
|
||||
if (mm_copy) {
|
||||
QList<QGraphicsItem*> ai;
|
||||
blockSignals(true);
|
||||
if (moved) {
|
||||
QList<BlockItem*> ci;
|
||||
QList<BlockBusItem*> bi;
|
||||
foreach (QGraphicsItem * b, sel_items)
|
||||
if (b->data(1006) == "item") {
|
||||
ci << qgraphicsitem_cast<BlockItem*>(b);
|
||||
ai << qgraphicsitem_cast<QGraphicsItem*>(b);
|
||||
}
|
||||
bi = internalBuses(ci);
|
||||
if (!ci.isEmpty()) copyBlocks(ci, copy_dp);
|
||||
if (!bi.isEmpty()) copyBuses(bi, copy_dp);
|
||||
}
|
||||
deleteCopyTemp();
|
||||
blockSignals(false);
|
||||
if (moved) {
|
||||
moved = false;
|
||||
reconnectAll();
|
||||
emitActionEvent(BlockItemBase::BlockCopy, ai);
|
||||
}
|
||||
}
|
||||
if (new_branch) {
|
||||
hideTmpBuses(false);
|
||||
}
|
||||
if (moved && pm_connect) {
|
||||
QList<QGraphicsItem*> ci;
|
||||
foreach (QGraphicsItem * b, sel_items)
|
||||
if (b->data(1006) == "item")
|
||||
ci << b;
|
||||
simplifyBuses();
|
||||
emitActionEvent(BlockItemBase::BlockMove, ci);
|
||||
reconnectAll();
|
||||
}
|
||||
moved = mm_copy = false;
|
||||
if (tmp_bus.isVisible()) {
|
||||
if (!tmp_bus.pol.isEmpty()) {
|
||||
if (match_bus == 0) {
|
||||
BlockBusItem * nb = new BlockBusItem(tmp_bus);
|
||||
addItem(nb, tmp_buses.isEmpty());
|
||||
foreach (BlockBusItem * b, tmp_buses) {
|
||||
nb = new BlockBusItem(*b);
|
||||
addItem(nb, b == tmp_buses.back());
|
||||
}
|
||||
} else {
|
||||
if (connectTmpToBus(match_bus)) {
|
||||
emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem*>() << match_bus);
|
||||
emit connectionsChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
unmarkPins();
|
||||
hideTmpBuses();
|
||||
reconnectAll();
|
||||
BlockItemPin * pin = getPin(scene_->items(me->scenePos()));
|
||||
if (pin)
|
||||
pin->hoverEnterEvent(0);
|
||||
m_trace_with_buses = prev_tcb;
|
||||
}
|
||||
clearBusStates();
|
||||
if (!mm_drag) {
|
||||
switch (smode) {
|
||||
case SingleSelection:
|
||||
clearSelection();
|
||||
if (mm_ci)
|
||||
mm_ci->setSelected(true);
|
||||
break;
|
||||
case MultiSelection:
|
||||
if (mm_ci == 0 || !me->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
clearSelection();
|
||||
if (mm_ci)
|
||||
mm_ci->setSelected(true);
|
||||
} else {
|
||||
if (mm_ci != 0) {
|
||||
if (me->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
if (mm_ci->data(1006) == "item")
|
||||
mm_ci->setSelected(!mm_ci->isSelected());
|
||||
} else
|
||||
mm_ci->setSelected(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
clearSelection();
|
||||
break;
|
||||
}
|
||||
}
|
||||
sel_rect.hide();
|
||||
if (sel_rect.scene())
|
||||
scene_->removeItem(&sel_rect);
|
||||
mm_drag = false;
|
||||
mm_ci = 0;
|
||||
unsetCursor();
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
return QGraphicsView::eventFilter(o, e);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::stopTimer(int & tid) {
|
||||
if (tid > 0) killTimer(tid);
|
||||
tid = 0;
|
||||
}
|
||||
|
||||
|
||||
void BlockView::restartTimer(int & tid, int msecs) {
|
||||
stopTimer(tid);
|
||||
tid = startTimer(msecs);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::timerEvent(QTimerEvent * e) {
|
||||
if (e->timerId() == timer_thumb) {
|
||||
thumbHide();
|
||||
stopTimer(timer_thumb);
|
||||
return;
|
||||
}
|
||||
QGraphicsView::timerEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::wheelEvent(QWheelEvent * e) {
|
||||
if (!navigation) return;
|
||||
if (wheel_zoom || e->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
double scl = 1. - e->delta() / 500.;
|
||||
if (!is_nav_anim || (nav_anim.state() != QPropertyAnimation::Running))
|
||||
nav_target = _nav();
|
||||
QRectF r = nav_target;
|
||||
double vw = viewport()->width(), vh = viewport()->height();
|
||||
double cx = double(e->pos().x()) / vw, cy = double(e->pos().y()) / vh;
|
||||
double pw = r.width(), ph = r.height();
|
||||
r.setWidth(r.width() * scl);
|
||||
r.setHeight(r.width() * vh / vw);
|
||||
r.translate(cx * (pw - r.width()), cy * (ph - r.height()));
|
||||
animateNav(r, scl);
|
||||
return;
|
||||
}
|
||||
if (!wheel_zoom) QGraphicsView::wheelEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::mousePressEvent(QMouseEvent * event) {
|
||||
press_point = event->pos();
|
||||
if (event->buttons().testFlag(Qt::MidButton) || event->buttons().testFlag(Qt::RightButton)) {
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
sel_rect.hide();
|
||||
if (sel_rect.scene())
|
||||
scene_->removeItem(&sel_rect);
|
||||
}
|
||||
QGraphicsView::mousePressEvent(event);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::mouseReleaseEvent(QMouseEvent * event) {
|
||||
unsetCursor();
|
||||
QGraphicsView::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::updateNavRect() {
|
||||
QPointF t = mapToScene(viewport()->rect().topLeft());
|
||||
QPointF b = mapToScene(viewport()->rect().bottomRight());
|
||||
nav_rect = QRectF(t, b);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::scrolled() {
|
||||
updateNavRect();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::mouseMoveEvent(QMouseEvent * event) {
|
||||
if (!event) return;
|
||||
if (navigation) {
|
||||
if (event->buttons().testFlag(Qt::MidButton) || event->buttons().testFlag(Qt::RightButton)) {
|
||||
QPoint dp = (press_point - event->pos());
|
||||
horizontalScrollBar()->setValue(horizontalScrollBar()->value() + dp.x());
|
||||
verticalScrollBar()->setValue(verticalScrollBar()->value() + dp.y());
|
||||
press_point = event->pos();
|
||||
updateNavRect();
|
||||
QRectF nr = nav_anim.endValue().toRectF();
|
||||
nr.moveCenter(_nav().center());
|
||||
nav_anim.setEndValue(nr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
QGraphicsView::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::mouseDoubleClickEvent(QMouseEvent * event) {
|
||||
if (event->buttons().testFlag(Qt::MidButton) || event->buttons().testFlag(Qt::RightButton)) {
|
||||
fitInView();
|
||||
return;
|
||||
}
|
||||
QGraphicsView::mouseDoubleClickEvent(event);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::keyPressEvent(QKeyEvent * e) {
|
||||
BlockItemPin * pin = getPin(items(mapFromGlobal(QCursor::pos())));
|
||||
if (pin) {
|
||||
//qDebug() << "pin" << pin->state();
|
||||
if (pin->state() == BlockItemPin::Hover) {
|
||||
highlightNearPins(pin, e->modifiers());
|
||||
}
|
||||
}
|
||||
if (tmp_bus.isVisible()) {
|
||||
bool retrace = false;
|
||||
if (e->key() == Qt::Key_Shift) {
|
||||
retrace = true;
|
||||
switch (wavetrace.preferredDirection()) {
|
||||
case BlockViewWavetrace::NoTrace: wavetrace.setPreferredDirection(BlockViewWavetrace::Horizontal); break;
|
||||
case BlockViewWavetrace::Horizontal: wavetrace.setPreferredDirection(BlockViewWavetrace::Vertical); break;
|
||||
case BlockViewWavetrace::Vertical: wavetrace.setPreferredDirection(BlockViewWavetrace::NoTrace); break;
|
||||
}
|
||||
}
|
||||
if (e->key() == Qt::Key_Alt) {
|
||||
retrace = true;
|
||||
m_trace_with_buses = !m_trace_with_buses;
|
||||
}
|
||||
if (retrace) {
|
||||
trace(last_trace_from, trace_to, &tmp_bus);
|
||||
for (int i = 0; i < qMin(tmp_buses.size(), last_multiconnect_pl.size()); ++i) {
|
||||
QPointF dp = last_multiconnect_pl[i]->scenePos() - last_trace_from;
|
||||
//qDebug() << "trace" << i << dp;
|
||||
trace(last_trace_from + dp, trace_to + dp, tmp_buses[i], false);
|
||||
tmp_buses[i]->show();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
QGraphicsView::keyPressEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::keyReleaseEvent(QKeyEvent * e) {
|
||||
BlockItemPin * pin = getPin(items(mapFromGlobal(QCursor::pos())));
|
||||
if (pin) {
|
||||
//qDebug() << "pin" << pin->state();
|
||||
if (pin->state() == BlockItemPin::Hover) {
|
||||
highlightNearPins(pin, e->modifiers());
|
||||
}
|
||||
}
|
||||
QGraphicsView::keyReleaseEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::resizeEvent(QResizeEvent * event) {
|
||||
QGraphicsView::resizeEvent(event);
|
||||
thick = lineThickness();
|
||||
adjustThumb();
|
||||
updateNavRect();
|
||||
nav_target = _nav();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::scrollContentsBy(int dx, int dy) {
|
||||
QGraphicsView::scrollContentsBy(dx, dy);
|
||||
if (isHidden()) return;
|
||||
thumbShow();
|
||||
restartTimer(timer_thumb, thumb_hide_delay);
|
||||
QMetaObject::invokeMethod(&widget_thumb, "update", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::drawBackground(QPainter * painter, const QRectF & rect) {
|
||||
// QGraphicsView::drawBackground(painter, rect);
|
||||
if (mm_thumb) return;
|
||||
float rx, ry, sx = grid_step, sy = grid_step;
|
||||
double scl = qRound(1. / qSqrt(transform().determinant()));
|
||||
painter->fillRect(rect, palette().brush(QPalette::Base));
|
||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
if (scl > 0.) {
|
||||
sx *= scl;
|
||||
sy *= scl;
|
||||
}
|
||||
if (!grid_visible) return;
|
||||
rx = quantize(rect.left(), sx);
|
||||
ry = quantize(rect.top(), sy);
|
||||
bool gp = grid_points > 0.5;
|
||||
if (gp) {
|
||||
QPen pp(grid_pen.color(), qMax<int>(grid_points, thick), Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin);
|
||||
pp.setCosmetic(true);
|
||||
painter->setPen(pp);
|
||||
for(int i = 0; i < qCeil(rect.width() / sx) + 1; ++i)
|
||||
for(int j = 0; j < qCeil(rect.height() / sy) + 1; ++j)
|
||||
painter->drawPoint(rx + i * sx, ry + j * sy);
|
||||
}
|
||||
if (grid_pen.style() == Qt::NoPen) return;
|
||||
QPen pen = grid_pen;
|
||||
pen.setWidth(qMax<int>(pen.width(), thick));
|
||||
painter->setPen(grid_pen);
|
||||
for(int i = 0; i < qCeil(rect.width() / sx) + 1; ++i) {
|
||||
double cx = rx + i * sx;
|
||||
painter->drawLine(cx, ry, cx, ry + rect.height());
|
||||
}
|
||||
for(int j = 0; j < qCeil(rect.height() / sy) + 1; ++j) {
|
||||
double cy = ry + j * sy;
|
||||
painter->drawLine(rx, cy, rx + rect.width(), cy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockView::scrollFromThumb() {
|
||||
QRect r(thumb_vr);
|
||||
double scl(thumb_scl);
|
||||
horizontalScrollBar()->setValue(r.x() / scl + horizontalScrollBar()->minimum());
|
||||
verticalScrollBar()->setValue(r.y() / scl + verticalScrollBar()->minimum());
|
||||
}
|
||||
|
||||
|
||||
void BlockView::deleteCopyTemp() {
|
||||
qDeleteAll(copy_items);
|
||||
copy_items.clear();
|
||||
qDeleteAll(copy_buses);
|
||||
copy_buses.clear();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::emitActionEvent(BlockItemBase::Action action, QList<QGraphicsItem * > items) {
|
||||
if (!ae_enabled) return;
|
||||
emit schemeAction(action, items);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::setGhost(BlockItem * item) {
|
||||
clearGhost();
|
||||
if (!item) return;
|
||||
ghost_ = item;
|
||||
ghost_->setOpacity(0.5);
|
||||
addItem(item, false);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::clearGhost() {
|
||||
if (!ghost_) return;
|
||||
delete ghost_;
|
||||
ghost_ = 0;
|
||||
}
|
||||
|
||||
|
||||
void BlockView::drawThumb() {
|
||||
if (!minimap) return;
|
||||
QPainter p(&widget_thumb);
|
||||
QRect wr = widget_thumb.rect().adjusted(0, 0, -1, -1);
|
||||
QSizeF sr = sceneRect().size(), tr;
|
||||
if (sr.width() >= sr.height())
|
||||
thumb_scl = thumb_size.width() / sr.width();
|
||||
else
|
||||
thumb_scl = thumb_size.height() / sr.height();
|
||||
tr = sr * thumb_scl;
|
||||
cur_scl = qSqrt(transform().determinant());
|
||||
thumb_scl /= cur_scl;
|
||||
QSizeF vs(size().width() - verticalScrollBar()->width(), size().height() - horizontalScrollBar()->height());
|
||||
QRectF vr(QPointF(horizontalScrollBar()->value() - horizontalScrollBar()->minimum(),
|
||||
verticalScrollBar()->value() - verticalScrollBar()->minimum()) * thumb_scl, vs * thumb_scl);
|
||||
vr.adjust(0, 0, -1, -1);
|
||||
|
||||
p.setBrush(Qt::lightGray);
|
||||
p.setOpacity(0.5 * _talpha);
|
||||
p.drawRect(wr);
|
||||
p.drawImage(0, 0, im_scene);
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.drawRect(wr);
|
||||
p.setBrush(Qt::white);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
p.drawRect(vr);
|
||||
thumb_sr = wr;
|
||||
thumb_vr = vr.toRect();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::drawSceneThumb() {
|
||||
if (!minimap) return;
|
||||
QRect wr = widget_thumb.rect().adjusted(0, 0, -1, -1);
|
||||
im_scene = QImage(wr.size(), QImage::Format_ARGB32);
|
||||
im_scene.fill(Qt::transparent);
|
||||
QPainter p(&im_scene);
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
mm_thumb = true;
|
||||
scene_->render(&p, im_scene.rect());
|
||||
mm_thumb = false;
|
||||
}
|
||||
|
||||
|
||||
void BlockView::thumbHide() {
|
||||
if (!minimap) {
|
||||
widget_thumb.hide();
|
||||
return;
|
||||
}
|
||||
if (QApplication::widgetAt(QCursor::pos()) == &widget_thumb) return;
|
||||
thumb_anim.stop();
|
||||
thumb_anim.setDuration(1000);
|
||||
thumb_anim.setStartValue(_thumb());
|
||||
thumb_anim.setEndValue(0.);
|
||||
thumb_anim.start();
|
||||
//qDebug() << "hide" << thumb_anim.startValue() << thumb_anim.endValue();
|
||||
//widget_thumb.hide();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::thumbShow() {
|
||||
if (!minimap) return;
|
||||
if (widget_thumb.isHidden() || (_talpha < 0.1)) drawSceneThumb();
|
||||
thumb_anim.stop();
|
||||
/*thumb_anim.setDuration(100);
|
||||
thumb_anim.setStartValue(_thumb());
|
||||
thumb_anim.setEndValue(1.);
|
||||
thumb_anim.start();*/
|
||||
_setThumb(1.);
|
||||
//qDebug() << "show" << thumb_anim.startValue() << thumb_anim.endValue();
|
||||
//widget_thumb.show();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::clearSelection() {
|
||||
sel_items.clear();
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->flags().testFlag(QGraphicsItem::ItemIsSelectable)) i->setSelected(false);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::addItem(QGraphicsItem * item, bool emit_action) {
|
||||
scene_->addItem(item);
|
||||
applyGridStep();
|
||||
if (item->data(1005) == "connection") {
|
||||
loadBus(qgraphicsitem_cast<BlockBusItem*>(item));
|
||||
((BlockBusItem*)item)->setSquareNodes(square_node);
|
||||
connect((BlockBusItem*)item, SIGNAL(destroyed(QObject*)), this, SLOT(removedBus(QObject*)), Qt::UniqueConnection);
|
||||
if (emit_action) emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem*>() << item);
|
||||
emit connectionsChanged();
|
||||
return;
|
||||
}
|
||||
if (item->data(1006) == "item") {
|
||||
connect((BlockItem*)item, SIGNAL(destroyed(QObject*)), this, SLOT(removedBlock(QObject*)), Qt::UniqueConnection);
|
||||
connect((BlockItem*)item, SIGNAL(blockHoverEnter(BlockItem*)), this, SIGNAL(blockHoverEnter(BlockItem*)), Qt::UniqueConnection);
|
||||
connect((BlockItem*)item, SIGNAL(blockHoverLeave(BlockItem*)), this, SIGNAL(blockHoverLeave(BlockItem*)), Qt::UniqueConnection);
|
||||
if (emit_action) emitActionEvent(BlockItemBase::BlockAdd, QList<QGraphicsItem*>() << item);
|
||||
return;
|
||||
}
|
||||
item->setData(1009, "decor");
|
||||
}
|
||||
|
||||
|
||||
QList<BlockBusItem * > BlockView::buses() const {
|
||||
QList<BlockBusItem * > ret;
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->data(1005) == "connection")
|
||||
if (!copy_buses.contains((BlockBusItem*)i))
|
||||
ret << qgraphicsitem_cast<BlockBusItem*>(i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<BlockBusItem * > BlockView::wrongConnectedBuses() const {
|
||||
QList<BlockBusItem * > sl = buses(), ret;
|
||||
QList<BlockItem * > bl = blocks();
|
||||
foreach (BlockItem * b, bl) {
|
||||
QVector<BlockItemPin * > pins = b->pins();
|
||||
foreach (BlockItemPin * p, pins)
|
||||
if (p->state() == BlockItemPin::Reject) {
|
||||
QPointF pp = p->scenePos();
|
||||
foreach (BlockBusItem * s, sl)
|
||||
if (s->pol.contains(pp))
|
||||
if (!ret.contains(s))
|
||||
ret << s;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<BlockItem * > BlockView::blocks() const {
|
||||
QList<BlockItem * > ret;
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->data(1006) == "item")
|
||||
ret << qgraphicsitem_cast<BlockItem*>(i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<QGraphicsItem * > BlockView::decors() const {
|
||||
QList<QGraphicsItem*> ret, gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if ((i->data(1009) == "decor") && !i->data(1008).toBool() && !i->data(1007).toBool() && (i->parentItem() == 0)
|
||||
&& (i != &sel_rect) && (i != &tmp_bus) && !tmp_buses.contains((BlockBusItem*)i))
|
||||
ret << i;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BlockBusItem * BlockView::connectionBus(BlockItem * b0, BlockItem * b1) const {
|
||||
QList<BlockBusItem * > cbl = connectionBuses(b0, b1);
|
||||
if (cbl.isEmpty()) return 0;
|
||||
return cbl.front();
|
||||
}
|
||||
|
||||
|
||||
QList<BlockBusItem * > BlockView::connectionBuses(BlockItem * b0, BlockItem * b1) const {
|
||||
if (!b0 || !b1) return QList<BlockBusItem * >();
|
||||
QSet<BlockBusItem * > bs0 = b0->connectedBuses().toSet(), bs1 = b1->connectedBuses().toSet();
|
||||
return (bs0 & bs1).values();
|
||||
}
|
||||
|
||||
|
||||
bool BlockView::connectPins(BlockItemPin * p0, BlockItemPin * p1) {
|
||||
if (!p0 || !p1) return false;
|
||||
if (p0 == p1) return false;
|
||||
if (p0->busType() != p1->busType()) return false;
|
||||
QList<BlockBusItem * > bl0 = p0->connectedBuses(), bl1 = p1->connectedBuses();
|
||||
if (!(bl0.toSet() & bl1.toSet()).isEmpty()) return true;
|
||||
BlockBusItem * nb = new BlockBusItem();
|
||||
nb->setBusType(p0->busType());
|
||||
//nb->setEndpointsNumber(3);
|
||||
loadBus(nb);
|
||||
if (!bl0.isEmpty() && !bl1.isEmpty()) { // connect two existing buses
|
||||
} else {
|
||||
if ((bl0.isEmpty() && !bl1.isEmpty()) || (bl1.isEmpty() && !bl0.isEmpty())) { // connect empty pin to existing bus
|
||||
BlockItemPin * ep = 0;
|
||||
BlockBusItem * eb = 0;
|
||||
if (bl0.isEmpty()) {ep = p0; eb = bl1[0];}
|
||||
else {ep = p1; eb = bl0[0];}
|
||||
double md = -1; int mi = -1;
|
||||
QPointF sp = ep->scenePos();
|
||||
if (eb->pol.size() == 2) {
|
||||
eb->selSegment = 0;
|
||||
eb->addPoint((eb->pol[0] + eb->pol[1]) / 2.);
|
||||
eb->selPoint = -1;
|
||||
mi = 2;
|
||||
} else {
|
||||
for (int i = 0; i < eb->pol.size(); ++i) {
|
||||
if (eb->ends.contains(i)) continue;
|
||||
double cd = QVector2D(sp - eb->pol[i]).lengthSquared();
|
||||
if (md < 0 || md > cd) {
|
||||
md = cd;
|
||||
mi = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mi < 0) {
|
||||
return false;
|
||||
}
|
||||
trace(ep->scenePos(), eb->pol[mi], nb);
|
||||
if (nb->pol.size() < 2) {
|
||||
delete nb;
|
||||
return false;
|
||||
}
|
||||
nb->pol.pop_back();
|
||||
int lp = eb->pol.size();
|
||||
eb->pol << nb->pol;
|
||||
for (int i = 0; i < nb->pol.size() - 1; ++i)
|
||||
eb->segments << QPair<int, int>(lp + i, lp + i + 1);
|
||||
eb->segments << QPair<int, int>(mi, lp + nb->pol.size() - 1);
|
||||
eb->updateGeometry();
|
||||
delete nb;
|
||||
} else { // connect two empty pins
|
||||
trace(p0->scenePos(), p1->scenePos(), nb);
|
||||
if (nb->pol.isEmpty()) {
|
||||
delete nb;
|
||||
return false;
|
||||
}
|
||||
addItem(nb);
|
||||
}
|
||||
}
|
||||
reconnectAll();
|
||||
emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem*>() << nb);
|
||||
emit connectionsChanged();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void BlockView::setTransform(const QTransform & matrix, bool combine) {
|
||||
QGraphicsView::setTransform(matrix, combine);
|
||||
updateNavRect();
|
||||
nav_target = _nav();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::centerOn(const QPointF & pos) {
|
||||
QGraphicsView::centerOn(pos);
|
||||
updateNavRect();
|
||||
nav_target = _nav();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::centerOn(qreal x, qreal y) {
|
||||
QGraphicsView::centerOn(x, y);
|
||||
updateNavRect();
|
||||
nav_target = _nav();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::centerOn(const QGraphicsItem * item) {
|
||||
QGraphicsView::centerOn(item);
|
||||
updateNavRect();
|
||||
nav_target = _nav();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::fitInView(const QRectF & rect, Qt::AspectRatioMode aspectRatioMode) {
|
||||
QGraphicsView::fitInView(rect, aspectRatioMode);
|
||||
updateNavRect();
|
||||
nav_target = _nav();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::fitInView(qreal x, qreal y, qreal w, qreal h, Qt::AspectRatioMode aspectRatioMode) {
|
||||
QGraphicsView::fitInView(x, y, w, h, aspectRatioMode);
|
||||
updateNavRect();
|
||||
nav_target = _nav();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::fitInView(const QGraphicsItem * item, Qt::AspectRatioMode aspectRatioMode) {
|
||||
QGraphicsView::fitInView(item, aspectRatioMode);
|
||||
updateNavRect();
|
||||
nav_target = _nav();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::fitInView() {
|
||||
QRectF r = _nav();
|
||||
QGraphicsView::fitInView(itemsBoundingRect(), Qt::KeepAspectRatio);
|
||||
updateNavRect();
|
||||
QRectF t = _nav();
|
||||
QGraphicsView::fitInView(r, Qt::KeepAspectRatio);
|
||||
updateNavRect();
|
||||
animateNav(t);
|
||||
}
|
||||
|
||||
|
||||
QRectF BlockView::itemsBoundingRect() const {
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
if (gi.isEmpty()) return QRectF();
|
||||
bool f = true;
|
||||
QRectF ret;
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->isVisible() && (i != &tmp_bus) && !tmp_buses.contains((BlockBusItem*)i)) {
|
||||
if (!(i->data(1007).toBool()) && !i->data(1008).toBool()) {
|
||||
QRectF br = i->mapRectToScene(i->boundingRect());
|
||||
if (br.width() <= 1 || br.height() <= 1) continue;
|
||||
if (f) ret = br;
|
||||
else ret |= br;
|
||||
f = false;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void BlockView::restoreSelState() {
|
||||
foreach (QGraphicsItem * i, sel_items) {
|
||||
i->setPos(i->data(1001).toPointF());
|
||||
}
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->data(1005) == "connection") {
|
||||
BlockBusItem * bi = qgraphicsitem_cast<BlockBusItem*>(i);
|
||||
bi->pol = bi->bpol;
|
||||
bi->prepareGeometryChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockView::saveSelState() {
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
sel_items = scene_->selectedItems();
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
i->setData(1000, i->isSelected());
|
||||
i->setData(1001, i->pos());
|
||||
if (i->data(1005) == "connection")
|
||||
qgraphicsitem_cast<BlockBusItem*>(i)->bpol = qgraphicsitem_cast<BlockBusItem*>(i)->pol;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockView::saveBusesState() {
|
||||
QList<BlockBusItem*> bl = buses();
|
||||
foreach (BlockBusItem * b, bl)
|
||||
b->saveState();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::restoreBusesState() {
|
||||
QList<BlockBusItem*> bl = buses();
|
||||
foreach (BlockBusItem * b, bl)
|
||||
b->restoreState();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::applySelRect(QGraphicsSceneMouseEvent * me) {
|
||||
QList<QGraphicsItem*> ci = sel_rect.collidingItems(Qt::IntersectsItemBoundingRect);
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
bool add = me->modifiers().testFlag(Qt::ControlModifier);
|
||||
if (!add) clearSelection();
|
||||
else {
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
i->setSelected(i->data(1000).toBool());
|
||||
}
|
||||
foreach (QGraphicsItem * i, ci) {
|
||||
i->setSelected(!i->isSelected());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockView::applyGridStep() {
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->type() == QGraphicsItem::UserType + 2)
|
||||
qgraphicsitem_cast<BlockBusItem*>(i)->setGridStep(grid_step);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem * bus, bool primary) {
|
||||
if (primary) {
|
||||
if (hpin)
|
||||
scene_pos_to = hpin->scenePos();
|
||||
last_trace_from = scene_pos_from;
|
||||
trace_to = scene_pos_to;
|
||||
}
|
||||
QRect sr = scene_->sceneRect().toRect();
|
||||
int dx = sr.left() / grid_step, dy = sr.top() / grid_step;
|
||||
//qDebug() << dp;
|
||||
QPoint dp(-dx, -dy), qpt = quantize(scene_pos_to, grid_step).toPoint() / grid_step + dp;
|
||||
QElapsedTimer tm;
|
||||
tm.restart();
|
||||
wavetrace.resize(sr.size() / grid_step);
|
||||
wavetrace.fill(BlockViewWavetrace::Empty);
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->data(1006) == "item") {
|
||||
QRect ir = i->mapRectToScene(i->boundingRect()).toRect().normalized();
|
||||
wavetrace.fill(QRect(ir.topLeft() / grid_step + dp, ir.bottomRight() / grid_step + dp), BlockViewWavetrace::Blocked);
|
||||
QVector<BlockItemPin * > pins = qgraphicsitem_cast<BlockItem * >(i)->pins();
|
||||
foreach (BlockItemPin * p, pins) {
|
||||
if (p->busType() == bus->busType())
|
||||
wavetrace.fill(quantize(p->scenePos(), grid_step).toPoint() / grid_step + dp, BlockViewWavetrace::Empty);
|
||||
}
|
||||
}
|
||||
if (m_trace_with_buses) {
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->data(1005) == "connection") {
|
||||
BlockBusItem * b = qgraphicsitem_cast<BlockBusItem * >(i);
|
||||
if (!b) continue;
|
||||
for (int s = 0; s < b->segments.size(); ++s) {
|
||||
QPointF p0 = b->pol[b->segments[s].first], p1 = b->pol[b->segments[s].second], cp = p0;
|
||||
double sx(0.), sy(0.), dx = qAbs(p1.x() - p0.x()), dy = qAbs(p1.y() - p0.y());
|
||||
double signx = (p1.x() >= p0.x() ? 1. : -1.), signy = (p1.y() >= p0.y() ? 1. : -1.);
|
||||
int steps(0);
|
||||
if ((dx + dy) < grid_step) continue;
|
||||
BlockViewWavetrace::CellState cs = BlockViewWavetrace::Blocked;
|
||||
if (dx >= dy) { // by x
|
||||
sx = grid_step;
|
||||
sy = sx * dy / dx;
|
||||
steps = qRound(dx / grid_step);
|
||||
cs = BlockViewWavetrace::HorizontalBus;
|
||||
} else {
|
||||
sy = grid_step;
|
||||
sx = sy * dx / dy;
|
||||
steps = qRound(dy / grid_step);
|
||||
cs = BlockViewWavetrace::VerticalBus;
|
||||
}
|
||||
sx *= signx;
|
||||
sy *= signy;
|
||||
//qDebug() << "fill" << p0 << "->" << p1 << "in" << steps << sx << sy;
|
||||
for (int j = 0; j <= steps; ++j) {
|
||||
QPoint tp = quantize(cp, grid_step).toPoint() / grid_step + dp;
|
||||
if (tp != qpt)
|
||||
wavetrace.fill(tp, (j > 0 && j < steps) ? cs : BlockViewWavetrace::Blocked);
|
||||
//qDebug() << " set" << cp << ((j > 0 && j < steps) ? cs : BlockViewWavetrace::Blocked);
|
||||
cp += QPointF(sx, sy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bus->clear();
|
||||
if (wavetrace.trace(quantize(scene_pos_from, grid_step).toPoint() / grid_step + dp, qpt)) {
|
||||
wavetrace.gatherPath();
|
||||
foreach (const QPoint & p, wavetrace.path()) {
|
||||
bus->appendPoint((p - dp) * grid_step);
|
||||
}
|
||||
}
|
||||
//qDebug() << quantize(scene_pos_from, grid_step).toPoint() / grid_step + dp << qpt;
|
||||
scene_->update();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::clearBusStates() {
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->data(1005) == "connection") {
|
||||
BlockBusItem * b = qgraphicsitem_cast<BlockBusItem*>(i);
|
||||
b->clearBusState();
|
||||
// if (i != bus_from && i != match_bus)
|
||||
//b->selPoint = b->selSegment = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockView::matchBus() {
|
||||
match_bus = 0;
|
||||
bool bv = tmp_bus.isVisible();
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
QList<BlockBusItem * > buses;
|
||||
QList<BlockItem * > blockl;
|
||||
int sp = -1, ss = -1;
|
||||
QPointF point;
|
||||
iconnect = false;
|
||||
if (!tmp_bus.pol.isEmpty())
|
||||
point = tmp_bus.pol.back();
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
if (i != bus_from) {
|
||||
if (i->data(1005) == "connection")
|
||||
buses << qgraphicsitem_cast<BlockBusItem*>(i);
|
||||
if (i->data(1006) == "item")
|
||||
blockl << qgraphicsitem_cast<BlockItem*>(i);
|
||||
}
|
||||
}
|
||||
foreach (BlockBusItem * b, buses) {
|
||||
b->clearBusState();
|
||||
b->selPoint = b->selSegment = -1;
|
||||
}
|
||||
if (!bv) return;
|
||||
BlockBusItem * b(0);
|
||||
if (m_pin_mc) {
|
||||
foreach (BlockItem * b_, blockl)
|
||||
foreach (BlockItemPin * p_, b_->pins())
|
||||
if (p_->scenePos() == point) {
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
//qDebug() << "1" << buses.size() << tmp_bus.pol;
|
||||
for (int i = 0; i < buses.size(); ++i) {
|
||||
b = buses[i];
|
||||
b->testPoint(point, &sp, &ss, true);
|
||||
//qDebug() << i << sp << ss;
|
||||
if (sp >= 0 || ss >= 0) break;
|
||||
}
|
||||
if ((sp < 0 && ss < 0) || b == 0) return;
|
||||
//qDebug("2");
|
||||
match_bus = b;
|
||||
if ((b->busType() != tmp_bus.busType()) || b->connections_.value(sp, 0) != 0) {
|
||||
b->setBusState(false);
|
||||
} else {
|
||||
if (b->max_ep >= 2) {
|
||||
if (bus_from == 0) {
|
||||
if (ss >= 0) {
|
||||
if (b->endpointCount() >= b->max_ep) {
|
||||
b->setBusState(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (sp >= 0) {
|
||||
if (b->endpointCount() + b->pointSegmentsCount(sp) - 2 >= b->max_ep) {
|
||||
b->setBusState(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int sep = b->endpointCount() + bus_from->endpointCount();
|
||||
if (b->pointSegmentsCount(sp) == 1) sep--;
|
||||
if (bus_from->selPoint >= 0)
|
||||
if (bus_from->pointSegmentsCount(bus_from->selPoint) == 1) sep--;
|
||||
if (sep > b->max_ep) {
|
||||
b->setBusState(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
//b->press_point = point;
|
||||
iconnect = true;
|
||||
b->setBusState(true);
|
||||
b->selPoint = sp;
|
||||
b->selSegment = ss;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool BlockView::connectTmpToBus(BlockBusItem * bus) {
|
||||
if (bus == 0) return false;
|
||||
if (!bus->busState()) return false;
|
||||
if (tmp_bus.pol.size() < 2) return false;
|
||||
int np = bus->selPoint;
|
||||
if (np < 0)
|
||||
np = bus->addPoint(tmp_bus.pol.back());
|
||||
if (np < 0) return false;
|
||||
tmp_bus.pol.pop_back();
|
||||
int lp = bus->pol.size();
|
||||
bus->pol << tmp_bus.pol;
|
||||
for (int i = 0; i < tmp_bus.pol.size() - 1; ++i)
|
||||
bus->segments << QPair<int, int>(lp + i, lp + i + 1);
|
||||
bus->segments << QPair<int, int>(np, lp + tmp_bus.pol.size() - 1);
|
||||
bus->updateGeometry();
|
||||
tmp_bus.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void BlockView::markPins(int bus_type) {
|
||||
unhoverPins();
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
if (i->data(1004) == "pin") {
|
||||
BlockItemPin * p = qgraphicsitem_cast<BlockItemPin*>(i);
|
||||
p->saveState();
|
||||
if (m_pin_mc) {
|
||||
if (p->busType() == bus_type)
|
||||
p->setState(BlockItemPin::Accept);
|
||||
} else {
|
||||
if (p->busType() == bus_type) {
|
||||
if (p->state() == BlockItemPin::Disconnected)
|
||||
p->setState(BlockItemPin::Accept);
|
||||
// else
|
||||
// p->animAccept();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockView::unmarkPins(bool to_normal) {
|
||||
unhoverPins();
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
if (i->data(1004) == "pin") {
|
||||
qgraphicsitem_cast<BlockItemPin*>(i)->restoreState();
|
||||
if (to_normal)
|
||||
while (qgraphicsitem_cast<BlockItemPin*>(i)->restoreState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockView::hoverAcceptedPin(BlockItemPin * pin, bool hover) {
|
||||
if (!pin) return;
|
||||
pin->enlargePin(hover);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::unhoverPins(BlockItemPin* excl_pin) {
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
if (excl_pin == ((BlockItemPin*)i)) continue;
|
||||
if (i->data(1004) == "pin") {
|
||||
((BlockItemPin*)i)->enlargePin(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockView::simplifyBuses() {
|
||||
QList<BlockBusItem*> bl = buses();
|
||||
foreach (BlockBusItem * b, bl)
|
||||
b->simplify();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::moveBuses(const QList<QGraphicsItem * > & items, QPointF dp) {
|
||||
if (dp.isNull()) return;
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
QVector<BlockItemPin * > pins;
|
||||
QList<BlockBusItem * > buses;
|
||||
//qDebug() << "move" << dp;
|
||||
foreach (QGraphicsItem * i, items)
|
||||
if (i->data(1006) == "item" && i->flags().testFlag(QGraphicsItem::ItemIsMovable))
|
||||
pins << qgraphicsitem_cast<BlockItem*>(i)->pins();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->data(1005) == "connection")
|
||||
buses << qgraphicsitem_cast<BlockBusItem*>(i);
|
||||
foreach (BlockBusItem * b, buses) {
|
||||
QList<BlockItemPin * > bpins = b->connections_.values();
|
||||
if (!bpins.isEmpty()) {
|
||||
foreach (BlockItemPin * p, pins)
|
||||
bpins.removeAll(p);
|
||||
if (bpins.isEmpty()) {
|
||||
b->movePolyline(dp);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
foreach (BlockItemPin * p, pins) {
|
||||
QList<int> ends = b->connections_.keys(p);
|
||||
for (int i = 0; i < ends.size(); ++i) {
|
||||
/*int isp = b->segmentPointPair(ends[i]);
|
||||
QPointF sdp;
|
||||
if (isp >= 0 && b->pol.size() > 2) {
|
||||
sdp = b->pol[isp] - b->pol[ends[i]];
|
||||
if (!sdp.isNull()) {
|
||||
if (sdp.x() == 0. && dp.x() != 0.)
|
||||
b->movePoint(isp, QPointF(dp.x(), 0.));
|
||||
if (sdp.y() == 0. && dp.y() != 0.)
|
||||
b->movePoint(isp, QPointF(0., dp.y()));
|
||||
} else {
|
||||
if (p->alignment() == Qt::AlignTop || p->alignment() == Qt::AlignBottom)
|
||||
b->movePoint(isp, QPointF(dp.x(), 0.));
|
||||
if (p->alignment() == Qt::AlignLeft || p->alignment() == Qt::AlignRight)
|
||||
b->movePoint(isp, QPointF(0., dp.y()));
|
||||
}
|
||||
}*/
|
||||
QPointF pdp = dp;
|
||||
double ang = 0.;
|
||||
switch (p->alignment()) {
|
||||
case Qt::AlignRight : pdp.setX(0.); ang = 0.; break;
|
||||
case Qt::AlignTop : pdp.setY(0.); ang = 90.; break;
|
||||
case Qt::AlignLeft : pdp.setX(0.); ang = 180.; break;
|
||||
case Qt::AlignBottom: pdp.setY(0.); ang = 270.; break;
|
||||
default: break;
|
||||
}
|
||||
QVector<int> epl = b->endpointLine(ends[i], ang);
|
||||
foreach (int e, epl)
|
||||
b->movePoint(e, pdp);
|
||||
b->movePoint(ends[i], dp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QList<BlockBusItem * > BlockView::internalBuses(const QList<BlockItem * > & items) {
|
||||
QList<BlockBusItem * > ret;
|
||||
if (items.isEmpty()) return ret;
|
||||
QList<BlockBusItem * > sbl = buses();
|
||||
QSet<BlockItem * > sis = QSet<BlockItem * >::fromList(items);
|
||||
foreach (BlockBusItem * bi, sbl) {
|
||||
if (bi->connectedBlocks().isEmpty()) continue;
|
||||
QSet<BlockItem * > bis = QSet<BlockItem * >::fromList(bi->connectedBlocks());
|
||||
if ((bis - sis).isEmpty())
|
||||
ret << bi;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<BlockItemPin * > BlockView::nearPins(BlockItemPin * pin, Qt::KeyboardModifiers km) {
|
||||
QList<BlockItemPin * > ret;
|
||||
bool up = km.testFlag(Qt::ShiftModifier);
|
||||
bool down = km.testFlag(Qt::ControlModifier);
|
||||
bool ab = km.testFlag(Qt::AltModifier);
|
||||
//qDebug() << "nearPins" << km;
|
||||
if (!pin || (!up && !down)) return ret;
|
||||
const BlockItem * src = pin->parent();
|
||||
if (!src) return ret;
|
||||
bool dirs[2] = {up, down};
|
||||
double dy[2] = {-1, 1};
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (!dirs[i]) continue;
|
||||
const BlockItem * cb = src;
|
||||
BlockItemPin * cpin = pin;
|
||||
//qDebug() << "dir" << dirs[i];
|
||||
while (cpin) {
|
||||
//qDebug() << "cur" << cpin;
|
||||
QList<QGraphicsItem * > il = scene_->items(cpin->scenePos() + QPointF(0., dy[i] * cb->pinsMargin()));
|
||||
BlockItemPin * np = getPin(il);
|
||||
if (np == cpin) break;
|
||||
cpin = np;
|
||||
if (cpin) {
|
||||
if (((cb != cpin->parent()) && !ab) ||
|
||||
(cpin->state() != BlockItemPin::Disconnected)) {
|
||||
break;
|
||||
}
|
||||
cb = cpin->parent();
|
||||
ret << cpin;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
BlockItemPin * BlockView::getPin(const QList<QGraphicsItem *> & list) const {
|
||||
foreach (QGraphicsItem * i, list) {
|
||||
if (i->data(1004) == "pin")
|
||||
return qgraphicsitem_cast<BlockItemPin*>(i);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void BlockView::highlightNearPins(BlockItemPin * pin, Qt::KeyboardModifiers km) {
|
||||
//qDebug() << "restore for" << last_multiconnect_pl.size();
|
||||
foreach (BlockItemPin * p, last_multiconnect_pl)
|
||||
p->restoreState();
|
||||
QList<BlockItemPin * > pl = nearPins(pin, km);
|
||||
foreach (BlockItemPin * p, pl) {
|
||||
p->saveState();
|
||||
p->setState(BlockItemPin::Hover);
|
||||
}
|
||||
last_multiconnect_pl = pl;
|
||||
}
|
||||
|
||||
|
||||
void BlockView::hideTmpBuses(bool clear) {
|
||||
tmp_bus.hide();
|
||||
if (clear) {
|
||||
tmp_bus.clear();
|
||||
qDeleteAll(tmp_buses);
|
||||
tmp_buses.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QList<BlockItem * > BlockView::selectedBlocks() const {
|
||||
QList<BlockItem * > ret;
|
||||
QList<QGraphicsItem * > sil = scene()->selectedItems();
|
||||
foreach (QGraphicsItem * b, sil)
|
||||
if (b->data(1006) == "item")
|
||||
ret << qgraphicsitem_cast<BlockItem*>(b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<QGraphicsItem * > BlockView::selectedDecors() const {
|
||||
QList<QGraphicsItem * > ret, sil = decors();
|
||||
foreach (QGraphicsItem * b, sil)
|
||||
if (b->isSelected())
|
||||
ret << b;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void BlockView::animateNav(QRectF d, double scl) {
|
||||
nav_target = d;
|
||||
if (is_nav_anim) {
|
||||
if (qAbs<double>(scl - 1.) <= 0.1 && (nav_anim.state() != QAbstractAnimation::Running)) {
|
||||
_setNav(d);
|
||||
return;
|
||||
}
|
||||
if (nav_anim.state() != QAbstractAnimation::Running) {
|
||||
nav_prev_aa = renderHints().testFlag(QPainter::Antialiasing);
|
||||
nav_prev_imaa = renderHints().testFlag(QPainter::SmoothPixmapTransform);
|
||||
nav_prev_grid = isGridVisible();
|
||||
setRenderHint(QPainter::Antialiasing, false);
|
||||
setRenderHint(QPainter::SmoothPixmapTransform, false);
|
||||
setGridVisible(false);
|
||||
}
|
||||
nav_anim.stop();
|
||||
nav_anim.setStartValue(_nav());
|
||||
nav_anim.setEndValue(d);
|
||||
nav_anim.start();
|
||||
} else
|
||||
_setNav(d);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::adjustThumb() {
|
||||
if (!scene()) return;
|
||||
QSizeF sr = sceneRect().size(), tr;
|
||||
double scl;
|
||||
if (sr.width() >= sr.height())
|
||||
scl = thumb_size.width() / sr.width();
|
||||
else
|
||||
scl = thumb_size.height() / sr.height();
|
||||
tr = sr * scl;
|
||||
int sx = 0, sy = 0;
|
||||
if (verticalScrollBar()->isVisible() && (verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff))
|
||||
sx = verticalScrollBar()->width();
|
||||
if (horizontalScrollBar()->isVisible() && (horizontalScrollBarPolicy() != Qt::ScrollBarAlwaysOff))
|
||||
sy = horizontalScrollBar()->height();
|
||||
widget_thumb.setGeometry(QRect(QPoint(width() - tr.width() - 10 - sx,
|
||||
height() - tr.height() - 10 - sy), tr.toSize()));
|
||||
}
|
||||
|
||||
|
||||
void BlockView::newBranch(BlockBusItem * item) {
|
||||
bus_from = item;
|
||||
prev_tcb = m_trace_with_buses;
|
||||
newBusStarted(item->busType());
|
||||
markPins(item->busType());
|
||||
new_branch = true;
|
||||
tmp_bus.setBusType(item->busType());
|
||||
if (item->selSegment >= 0) {
|
||||
QPointF ds(item->pol[item->segments[item->selSegment].first] - item->pol[item->segments[item->selSegment].second]);
|
||||
if (ds.x() == 0.) wavetrace.setPreferredDirection(BlockViewWavetrace::Horizontal);
|
||||
if (ds.y() == 0.) wavetrace.setPreferredDirection(BlockViewWavetrace::Vertical);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockView::startBusPointMove(int bus_type) {
|
||||
move_bus_point = true;
|
||||
prev_tcb = m_trace_with_buses;
|
||||
newBusStarted(bus_type);
|
||||
markPins(bus_type);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::endBusPointMove() {
|
||||
move_bus_point = false;
|
||||
unmarkPins();
|
||||
reconnectAll();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::pinHoverInOut(BlockItemPin * pin) {
|
||||
//qDebug() << "pinHoverInOut" << pin << pin->state();
|
||||
highlightNearPins(pin, QApplication::keyboardModifiers());
|
||||
}
|
||||
|
||||
|
||||
void BlockView::checkPaste(bool queued) {
|
||||
const QMimeData * mime = QApplication::clipboard()->mimeData();
|
||||
bool ret = false;
|
||||
if (mime)
|
||||
ret = mime->hasFormat(_BlockView_Mime_);
|
||||
if (queued) QMetaObject::invokeMethod(this, "pasteEnabledChanged", Qt::QueuedConnection, Q_ARG(bool, ret));
|
||||
else emit pasteEnabledChanged(ret);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::setBusSquareNodes(bool yes) {
|
||||
square_node = yes;
|
||||
QList<BlockBusItem * > sbl = buses();
|
||||
foreach (BlockBusItem * b, sbl) {
|
||||
b->setSquareNodes(square_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BlockView::newBranchTrace(BlockBusItem * item, QPointF to) {
|
||||
trace(item->press_pos, to, &tmp_bus);
|
||||
tmp_bus.show();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::newBranchAccept(BlockBusItem * item) {
|
||||
unmarkPins();
|
||||
if (!new_branch) return;
|
||||
new_branch = false;
|
||||
tmp_bus.hide();
|
||||
if (tmp_bus.pol.size() < 2) return;
|
||||
tmp_bus.pol.pop_front();
|
||||
int np = item->addPoint(item->press_pos);
|
||||
if (np < 0) return;
|
||||
if (match_bus) {
|
||||
if (iconnect) tmp_bus.pol.pop_back();
|
||||
else return;
|
||||
}
|
||||
if (item == match_bus) return;
|
||||
int snp = np;
|
||||
int lp = item->pol.size();
|
||||
if (!tmp_bus.pol.isEmpty()) {
|
||||
item->pol << tmp_bus.pol;
|
||||
item->segments << QPair<int, int>(np, lp);
|
||||
for (int i = 0; i < tmp_bus.pol.size() - 1; ++i)
|
||||
item->segments << QPair<int, int>(lp + i, lp + i + 1);
|
||||
}
|
||||
if (match_bus != 0) {
|
||||
if (!iconnect) return;
|
||||
np = match_bus->selPoint;
|
||||
if (np < 0)
|
||||
np = match_bus->addPoint(trace_to);
|
||||
if (np < 0) return;
|
||||
lp = item->pol.size();
|
||||
item->pol << match_bus->pol;
|
||||
for (int i = 0; i < match_bus->segments.size(); ++i)
|
||||
item->segments << QPair<int, int>(match_bus->segments[i].first + lp, match_bus->segments[i].second + lp);
|
||||
if (tmp_bus.pol.isEmpty())
|
||||
item->segments << QPair<int, int>(lp + np, snp);
|
||||
else
|
||||
item->segments << QPair<int, int>(lp + np, lp - 1);
|
||||
match_bus->setProperty("_nodelete_", true);
|
||||
match_bus->deleteLater();
|
||||
match_bus = 0;
|
||||
}
|
||||
item->updateGeometry();
|
||||
emitActionEvent(BlockItemBase::BusAdd, QList<QGraphicsItem*>() << item);
|
||||
emit connectionsChanged();
|
||||
tmp_bus.clear();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::newBranchCancel() {
|
||||
unmarkPins();
|
||||
//qDebug() << "cancel";
|
||||
new_branch = false;
|
||||
hideTmpBuses();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::removedBus(QObject * o) {
|
||||
mm_ci = 0;
|
||||
reconnectAll();
|
||||
BlockBusItem * bus = (BlockBusItem*)o;
|
||||
if (bus->property("_nodelete_").toBool()) return;
|
||||
emitActionEvent(BlockItemBase::BusRemove, QList<QGraphicsItem*>() << bus);
|
||||
emit connectionsChanged();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::removedBlock(QObject * o) {
|
||||
if (o == ghost_) return;
|
||||
emit blockRemoved((BlockItem*)o);
|
||||
emitActionEvent(BlockItemBase::BlockRemove, QList<QGraphicsItem*>() << qgraphicsitem_cast<QGraphicsItem*>((BlockItem*)o));
|
||||
}
|
||||
|
||||
|
||||
void BlockView::removeJunk() {
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
if (i->data(1005) != "connection") continue;
|
||||
BlockBusItem * b = qgraphicsitem_cast<BlockBusItem*>(i);
|
||||
if (b->pol.size() <= 1) {
|
||||
b->deleteLater();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockView::sceneSelectionChanged() {
|
||||
bool ie = scene()->selectedItems().isEmpty();
|
||||
emit copyEnabledChanged(!ie);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::_setThumb(double v) {
|
||||
_talpha = v;
|
||||
QMetaObject::invokeMethod(&widget_thumb, "update", Qt::QueuedConnection);
|
||||
if (_talpha <= 0.01) widget_thumb.hide();
|
||||
else widget_thumb.show();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::_setNav(QRectF v) {
|
||||
double vw = viewport()->width(), vh = viewport()->height();
|
||||
if (vw < 1. || vh < 1. || v.isEmpty()) return;
|
||||
QTransform matrix;
|
||||
double scl = qMin(vw / v.width(), vh / v.height());
|
||||
double ascl = appScale(this);
|
||||
if (scl > 0.02 * ascl && scl < 50.0 * ascl) {
|
||||
matrix.scale(scl, scl);
|
||||
nav_rect = v;
|
||||
QGraphicsView::setTransform(matrix);
|
||||
QGraphicsView::centerOn(v.center());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QRectF BlockView::_nav() const {
|
||||
return nav_rect;
|
||||
}
|
||||
|
||||
|
||||
void BlockView::_navFinished() {
|
||||
setRenderHint(QPainter::Antialiasing, nav_prev_aa);
|
||||
setRenderHint(QPainter::SmoothPixmapTransform, nav_prev_imaa);
|
||||
setGridVisible(nav_prev_grid);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::reconnectAll() {
|
||||
//qDebug() << "reconnect";
|
||||
removeJunk();
|
||||
QList<QGraphicsItem * > gi = scene_->items();
|
||||
QList<BlockItemPin * > pins;
|
||||
QList<BlockBusItem * > buses;
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
if (i->data(1004) == "pin")
|
||||
pins << qgraphicsitem_cast<BlockItemPin*>(i);
|
||||
if (i->data(1005) == "connection")
|
||||
buses << qgraphicsitem_cast<BlockBusItem*>(i);
|
||||
}
|
||||
foreach (BlockItemPin * p, pins) {
|
||||
p->clearStateStack();
|
||||
p->setState(BlockItemPin::Disconnected);
|
||||
p->buses_.clear();
|
||||
}
|
||||
foreach (BlockBusItem * b, buses) {
|
||||
b->connections_.clear();
|
||||
QVector<int> conns(b->endpoints());
|
||||
for (int c = 0; c < conns.size(); ++c) {
|
||||
QPointF cp = b->pol[conns[c]];
|
||||
for (int j = 0; j < pins.size(); ++j) {
|
||||
if (!pins[j]->isVisible()) continue;
|
||||
QPointF pp = pins[j]->scenePos();
|
||||
if ((cp - pp).manhattanLength() <= (grid_step / 2.)) {
|
||||
//qDebug() << "found";
|
||||
if (b->busType() == pins[j]->busType()) {
|
||||
b->connections_[conns[c]] = pins[j];
|
||||
if (!pins[j]->buses_.contains(b))
|
||||
pins[j]->buses_ << b;
|
||||
pins[j]->setState(BlockItemPin::Connected);
|
||||
} else
|
||||
pins[j]->setState(BlockItemPin::Reject);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//qDebug() << pins.size() << buses.size();
|
||||
}
|
||||
|
||||
|
||||
void BlockView::zoom(double factor) {
|
||||
if (!is_nav_anim || (nav_anim.state() != QPropertyAnimation::Running))
|
||||
nav_target = _nav();
|
||||
QRectF r = nav_target;
|
||||
QPoint mp;
|
||||
if (underMouse()) mp = mapFromGlobal(QCursor::pos());
|
||||
else mp = QPoint(viewport()->width() / 2, viewport()->height() / 2);
|
||||
double cx = double(mp.x()) / viewport()->width(), cy = double(mp.y()) / viewport()->height();
|
||||
double pw = r.width(), ph = r.height();
|
||||
r.setWidth(r.width() / factor);
|
||||
r.setHeight(r.height() / factor);
|
||||
r.translate(cx * (pw - r.width()), cy * (ph - r.height()));
|
||||
animateNav(r);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::zoomReset() {
|
||||
cur_scl = qSqrt(transform().determinant());
|
||||
zoom(prev_app_scale / cur_scl);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::copyToClipboard() {
|
||||
QList<BlockItem*> bll = selectedBlocks();
|
||||
QList<QGraphicsItem*> del = selectedDecors();
|
||||
//qDebug() << "copy" << bll.size() << del.size();
|
||||
if (bll.isEmpty() && del.isEmpty()) return;
|
||||
QList<BlockBusItem*> bul = internalBuses(bll);
|
||||
QByteArray ba;
|
||||
QDataStream s(&ba, QIODevice::ReadWrite);
|
||||
s << uint(0x89abcdef) << bll << bul << del;
|
||||
QMimeData * mime = new QMimeData();
|
||||
mime->setData(_BlockView_Mime_, ba);
|
||||
QApplication::clipboard()->setMimeData(mime);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::pasteFromClipboard() {
|
||||
const QMimeData * mime = QApplication::clipboard()->mimeData();
|
||||
if (!mime) return;
|
||||
if (!mime->hasFormat(_BlockView_Mime_)) return;
|
||||
QByteArray ba = mime->data(_BlockView_Mime_);
|
||||
//qDebug() << "paste" << ba.size();
|
||||
if (ba.size() < 4) return;
|
||||
QList<BlockItem*> bll;
|
||||
QList<BlockBusItem*> bul;
|
||||
QList<QGraphicsItem*> del, gl;
|
||||
uint hdr = 0;
|
||||
QDataStream s(ba);
|
||||
s >> hdr;
|
||||
if (hdr != 0x89abcdef) return;
|
||||
s >> bll >> bul >> del;
|
||||
int all = bll.size() + bul.size() + del.size();
|
||||
if (all == 0) return;
|
||||
QRectF br;
|
||||
foreach (BlockItem * b, bll) {
|
||||
br |= b->boundingRect().translated(b->pos());
|
||||
gl << b;
|
||||
}
|
||||
foreach (BlockBusItem * b, bul)
|
||||
gl << b;
|
||||
foreach (QGraphicsItem * b, del)
|
||||
br |= b->boundingRect().translated(b->pos());
|
||||
gl << del;
|
||||
QPointF copy_dp;
|
||||
if (underMouse()) copy_dp = mapToScene(mapFromGlobal(QCursor::pos()));
|
||||
else copy_dp = mapToScene(rect().center());
|
||||
copy_dp -= br.center();
|
||||
copy_dp = quantize(copy_dp, grid_step);
|
||||
ae_enabled = false;
|
||||
if (!bll.isEmpty()) copyBlocks(bll, copy_dp);
|
||||
if (!bul.isEmpty()) copyBuses(bul, copy_dp);
|
||||
foreach (QGraphicsItem * i, del)
|
||||
i->setPos(i->pos() + copy_dp);
|
||||
addItems(del);
|
||||
ae_enabled = true;
|
||||
emitActionEvent(BlockItemBase::Paste, gl);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::selectNone() {
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
i->setSelected(false);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::selectAll() {
|
||||
QList<QGraphicsItem*> gi = scene_->items();
|
||||
foreach (QGraphicsItem * i, gi)
|
||||
if (i->flags().testFlag(QGraphicsItem::ItemIsSelectable))
|
||||
i->setSelected(true);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::removeSelected() {
|
||||
QList<QGraphicsItem*> gi = scene_->selectedItems(), ai;
|
||||
blockSignals(true);
|
||||
QList<BlockBusItem * > sbuses = buses(), dbuses, wbuses = wrongConnectedBuses();
|
||||
//foreach (BlockBusItem * i, wbuses)
|
||||
// sbuses.removeOne(i);
|
||||
foreach (BlockBusItem * i, sbuses)
|
||||
if (i->connectedBlocks().isEmpty())
|
||||
dbuses << i;
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
if (i->data(1006) == "item")
|
||||
ai << qgraphicsitem_cast<QGraphicsItem*>(i);
|
||||
if ((i->data(1006) == "item") || (i->data(1005) == "connection") || (i->data(1009) == "decor")) {
|
||||
scene_->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close));
|
||||
delete i;
|
||||
}
|
||||
}
|
||||
reconnectAll();
|
||||
foreach (BlockBusItem * i, sbuses)
|
||||
if (i->connectedBlocks().isEmpty())
|
||||
if (!dbuses.contains(i))
|
||||
delete i;
|
||||
|
||||
blockSignals(false);
|
||||
foreach (QGraphicsItem * i, ai)
|
||||
emit blockRemoved((BlockItem*)i);
|
||||
emitActionEvent(BlockItemBase::BlockRemove, ai);
|
||||
}
|
||||
|
||||
|
||||
void BlockView::removeAll() {
|
||||
last_multiconnect_pl.clear();
|
||||
QList<QGraphicsItem*> gi = scene_->items(), ai;
|
||||
blockSignals(true);
|
||||
foreach (QGraphicsItem * i, gi) {
|
||||
if (i->data(1006) == "item")
|
||||
ai << qgraphicsitem_cast<QGraphicsItem*>(i);
|
||||
if ((i->data(1006) == "item") || (i->data(1005) == "connection") || (i->data(1009) == "decor")) {
|
||||
if ((i != &sel_rect) && (i != &tmp_bus) && (i->parentItem() == 0) && !(i->data(1008).toBool()) && !(i->data(1007).toBool())) {
|
||||
//qDebug() << "delete" << i->data(1004);
|
||||
scene_->sendEvent(i, new QGraphicsSceneEvent(QEvent::Close));
|
||||
delete i;
|
||||
}
|
||||
}
|
||||
}
|
||||
blockSignals(false);
|
||||
foreach (QGraphicsItem * i, ai)
|
||||
emit blockRemoved((BlockItem*)i);
|
||||
}
|
||||
272
libs/blockview/blockview.h
Normal file
272
libs/blockview/blockview.h
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLOCKVIEW_H
|
||||
#define BLOCKVIEW_H
|
||||
|
||||
#include <QGraphicsView>
|
||||
#include <QGraphicsScene>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QMouseEvent>
|
||||
#include <QDebug>
|
||||
#include <QTime>
|
||||
#include <QPropertyAnimation>
|
||||
#include "blockviewwavetrace.h"
|
||||
#include "blockbusitem.h"
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
|
||||
Q_DECLARE_METATYPE(BlockItem*)
|
||||
Q_DECLARE_METATYPE(BlockItemPin*)
|
||||
Q_DECLARE_METATYPE(BlockBusItem*)
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT BlockView: public QGraphicsView
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS(SelectionMode)
|
||||
|
||||
Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible)
|
||||
Q_PROPERTY(bool snapToGrid READ isSnapToGrid WRITE setSnapToGrid)
|
||||
Q_PROPERTY(QPen gridPen READ gridPen WRITE setGridPen)
|
||||
Q_PROPERTY(double gridStep READ gridStep WRITE setGridStep)
|
||||
Q_PROPERTY(double gridPointsWidth READ gridPointsWidth WRITE setGridPointsWidth)
|
||||
Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
|
||||
Q_PROPERTY(bool postMoveConnect READ isPostMoveConnectEnabled WRITE setPostMoveConnectEnabled)
|
||||
Q_PROPERTY(bool connectByMouse READ isConnectByMouseEnabled WRITE setConnectByMouseEnabled)
|
||||
Q_PROPERTY(bool navigationEnabled READ isNavigationEnabled WRITE setNavigationEnabled)
|
||||
Q_PROPERTY(bool navigateAnimationEnabled READ isNavigateAnimationEnabled WRITE setNavigateAnimationEnabled)
|
||||
Q_PROPERTY(bool blockAnimationEnabled READ isBlockAnimationEnabled WRITE setBlockAnimationEnabled)
|
||||
Q_PROPERTY(bool traceConsiderBuses READ isTraceConsiderBuses WRITE setTraceConsiderBuses)
|
||||
Q_PROPERTY(bool pinMulticonnect READ isPinMulticonnectEnabled WRITE setPinMulticonnectEnabled)
|
||||
Q_PROPERTY(bool miniMap READ isMiniMapEnabled WRITE setMiniMapEnabled)
|
||||
Q_PROPERTY(bool zoomWheelOnly READ isZoomWheelOnly WRITE setZoomWheelOnly)
|
||||
Q_PROPERTY(bool busSquareNodes READ isBusSquareNodes WRITE setBusSquareNodes)
|
||||
|
||||
Q_PROPERTY(double _thumb READ _thumb WRITE _setThumb DESIGNABLE false SCRIPTABLE false)
|
||||
Q_PROPERTY(QRectF _nav READ _nav WRITE _setNav DESIGNABLE false SCRIPTABLE false)
|
||||
|
||||
public:
|
||||
BlockView(QWidget * parent = 0);
|
||||
BlockView(QGraphicsScene * scene, QWidget * parent = 0);
|
||||
~BlockView();
|
||||
|
||||
enum SelectionMode {
|
||||
NoSelection,
|
||||
SingleSelection,
|
||||
MultiSelection
|
||||
};
|
||||
|
||||
QPen gridPen() const {return grid_pen;}
|
||||
bool isGridVisible() const {return grid_visible;}
|
||||
bool isSnapToGrid() const {return grid_snap;}
|
||||
bool isPostMoveConnectEnabled() const {return pm_connect;}
|
||||
bool isNavigationEnabled() const {return navigation;}
|
||||
bool isNavigateAnimationEnabled() const {return is_nav_anim;}
|
||||
bool isBlockAnimationEnabled() const {return is_block_anim;}
|
||||
bool isConnectByMouseEnabled() const {return m_connect;}
|
||||
bool isTraceConsiderBuses() const {return m_trace_with_buses;}
|
||||
bool isPinMulticonnectEnabled() const {return m_pin_mc;}
|
||||
bool isMiniMapEnabled() const {return minimap;}
|
||||
bool isZoomWheelOnly() const {return wheel_zoom;}
|
||||
bool isBusSquareNodes() const {return square_node;}
|
||||
double gridStep() const {return grid_step;}
|
||||
double gridPointsWidth() const {return grid_points;}
|
||||
SelectionMode selectionMode() const {return smode;}
|
||||
void setSelectionMode(SelectionMode mode) {smode = mode;}
|
||||
|
||||
void addItems(QList<QGraphicsItem * > items) {foreach (QGraphicsItem * i, items) addItem(i);}
|
||||
QList<BlockBusItem * > buses() const;
|
||||
QList<BlockBusItem * > wrongConnectedBuses() const;
|
||||
QList<BlockItem * > blocks() const;
|
||||
QList<QGraphicsItem * > decors() const;
|
||||
BlockBusItem * connectionBus(BlockItem * b0, BlockItem * b1) const;
|
||||
QList<BlockBusItem * > connectionBuses(BlockItem * b0, BlockItem * b1) const;
|
||||
bool connectPins(BlockItemPin * p0, BlockItemPin * p1);
|
||||
QList<BlockItem * > selectedBlocks() const;
|
||||
QList<QGraphicsItem * > selectedDecors() const;
|
||||
|
||||
void setTransform(const QTransform & matrix, bool combine = false);
|
||||
void centerOn(const QPointF & pos);
|
||||
void centerOn(qreal x, qreal y);
|
||||
void centerOn(const QGraphicsItem * item);
|
||||
|
||||
void fitInView(const QRectF & rect, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio);
|
||||
void fitInView(qreal x, qreal y, qreal w, qreal h, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio);
|
||||
void fitInView(const QGraphicsItem * item, Qt::AspectRatioMode aspectRatioMode = Qt::IgnoreAspectRatio);
|
||||
void fitInView();
|
||||
|
||||
QRectF itemsBoundingRect() const;
|
||||
|
||||
protected:
|
||||
void _init();
|
||||
void _updateBack();
|
||||
bool event(QEvent * e);
|
||||
bool eventFilter(QObject * o, QEvent * e);
|
||||
void stopTimer(int & tid);
|
||||
void restartTimer(int & tid, int msecs);
|
||||
void timerEvent(QTimerEvent * e);
|
||||
void wheelEvent(QWheelEvent * e);
|
||||
void mousePressEvent(QMouseEvent * event);
|
||||
void mouseReleaseEvent(QMouseEvent * event);
|
||||
void mouseMoveEvent(QMouseEvent * event);
|
||||
void mouseDoubleClickEvent(QMouseEvent * event);
|
||||
void keyPressEvent(QKeyEvent * event);
|
||||
void keyReleaseEvent(QKeyEvent * e);
|
||||
void resizeEvent(QResizeEvent * event);
|
||||
void scrollContentsBy(int dx, int dy);
|
||||
void drawBackground(QPainter * painter, const QRectF & rect);
|
||||
void drawThumb();
|
||||
void drawSceneThumb();
|
||||
void thumbHide();
|
||||
void thumbShow();
|
||||
void restoreSelState();
|
||||
void saveSelState();
|
||||
void saveBusesState();
|
||||
void restoreBusesState();
|
||||
void applySelRect(QGraphicsSceneMouseEvent * me);
|
||||
void applyGridStep();
|
||||
void trace(QPointF scene_pos_from, QPointF scene_pos_to, BlockBusItem * bus, bool primary = true);
|
||||
void clearBusStates();
|
||||
void matchBus();
|
||||
bool connectTmpToBus(BlockBusItem* bus);
|
||||
void markPins(int bus_type);
|
||||
void unmarkPins(bool to_normal = false);
|
||||
void hoverAcceptedPin(BlockItemPin * pin, bool hover);
|
||||
void unhoverPins(BlockItemPin * excl_pin = 0);
|
||||
void simplifyBuses();
|
||||
void moveBuses(const QList<QGraphicsItem * > & items, QPointF dp);
|
||||
QList<BlockBusItem * > internalBuses(const QList<BlockItem * > & items);
|
||||
QList<BlockItemPin * > nearPins(BlockItemPin * pin, Qt::KeyboardModifiers km);
|
||||
BlockItemPin * getPin(const QList<QGraphicsItem * > & list) const;
|
||||
void highlightNearPins(BlockItemPin * pin, Qt::KeyboardModifiers km);
|
||||
void hideTmpBuses(bool clear = true);
|
||||
double _thumb() const {return _talpha;}
|
||||
QRectF _nav() const;
|
||||
void animateNav(QRectF d, double scl = 0.);
|
||||
void scrollFromThumb();
|
||||
void deleteCopyTemp();
|
||||
void emitActionEvent(BlockItemBase::Action action, QList<QGraphicsItem * > items);
|
||||
void setGhost(BlockItem * item);
|
||||
void clearGhost();
|
||||
BlockItem * ghost() const {return ghost_;}
|
||||
|
||||
virtual void loadBus(BlockBusItem * bus) {}
|
||||
virtual void copyBlocks(QList<BlockItem * > items, QPointF offset) {}
|
||||
virtual void copyBuses(QList<BlockBusItem * > items, QPointF offset) {}
|
||||
virtual void newBusStarted(int bus_type) {}
|
||||
|
||||
QGraphicsScene * scene_;
|
||||
QGraphicsRectItem sel_rect;
|
||||
QGraphicsItem * mm_ci;
|
||||
QList<QGraphicsItem * > sel_items;
|
||||
QList<BlockItem * > copy_items;
|
||||
QList<BlockItemPin * > last_multiconnect_pl;
|
||||
QList<BlockBusItem * > copy_buses, tmp_buses;
|
||||
BlockBusItem tmp_bus, * match_bus, * bus_from;
|
||||
BlockItemPin * hpin;
|
||||
BlockItem * ghost_;
|
||||
BlockViewWavetrace wavetrace;
|
||||
QPoint press_point, screen_point, thumb_press;
|
||||
QPointF scene_point, trace_from, last_trace_from, trace_to, copy_dp;
|
||||
QRect thumb_sr, thumb_vr;
|
||||
QRectF nav_target, nav_rect;
|
||||
QSizeF thumb_size;
|
||||
QPen grid_pen;
|
||||
SelectionMode smode;
|
||||
QImage im_scene;
|
||||
QWidget widget_thumb;
|
||||
Qt::KeyboardModifiers mm_mods;
|
||||
QPropertyAnimation thumb_anim, nav_anim;
|
||||
int timer_thumb, thumb_hide_delay, thick;
|
||||
bool mm_drag, new_bus, new_branch, moved, mm_cancel, iconnect, mm_copy, mm_thumb, ae_enabled, is_nav_anim, is_block_anim, move_bus_point;
|
||||
bool grid_visible, grid_snap, pm_connect, navigation, m_connect, m_trace_with_buses, m_pin_mc, minimap, prev_tcb, wheel_zoom;
|
||||
bool nav_prev_aa, nav_prev_imaa, nav_prev_grid, square_node;
|
||||
double grid_step, grid_points, cur_scl, _talpha, thumb_scl;
|
||||
double prev_app_scale;
|
||||
|
||||
protected slots:
|
||||
void getPinMC(bool * v) {if (v) *v = m_pin_mc;}
|
||||
void adjustThumb();
|
||||
void newBranch(BlockBusItem * item);
|
||||
void newBranchTrace(BlockBusItem * item, QPointF to);
|
||||
void newBranchAccept(BlockBusItem * item);
|
||||
void newBranchCancel();
|
||||
void removedBus(QObject * o);
|
||||
void removedBlock(QObject * o);
|
||||
void removeJunk();
|
||||
void sceneSelectionChanged();
|
||||
void updateNavRect();
|
||||
void scrolled();
|
||||
void _setThumb(double v);
|
||||
void _setNav(QRectF v);
|
||||
void _navFinished();
|
||||
void startBusPointMove(int bus_type);
|
||||
void endBusPointMove();
|
||||
void pinHoverInOut(BlockItemPin * pin);
|
||||
void checkPaste(bool queued = false);
|
||||
|
||||
public slots:
|
||||
void setGridPen(const QPen & pen) {grid_pen = pen; _updateBack();}
|
||||
void setGridVisible(bool yes) {grid_visible = yes; _updateBack();}
|
||||
void setSnapToGrid(bool yes) {grid_snap = yes;}
|
||||
void setGridStep(double step) {grid_step = step; applyGridStep(); _updateBack();}
|
||||
void setGridPointsWidth(double width_) {grid_points = width_; _updateBack();}
|
||||
void setPostMoveConnectEnabled(bool on) {pm_connect = on;}
|
||||
void setNavigationEnabled(bool on) {navigation = on;}
|
||||
void setNavigateAnimationEnabled(bool on) {is_nav_anim = on;}
|
||||
void setBlockAnimationEnabled(bool on) {is_block_anim = on;}
|
||||
void setConnectByMouseEnabled(bool on) {m_connect = on;}
|
||||
void setTraceConsiderBuses(bool on) {m_trace_with_buses = on;}
|
||||
void setPinMulticonnectEnabled(bool on) {m_pin_mc = on;}
|
||||
void setMiniMapEnabled(bool on) {minimap = on;}
|
||||
void setZoomWheelOnly(bool on) {wheel_zoom = on;}
|
||||
void setBusSquareNodes(bool yes);
|
||||
|
||||
void zoom(double factor);
|
||||
void zoomIn() {zoom(1.2);}
|
||||
void zoomOut() {zoom(1. / 1.2);}
|
||||
void zoomReset();
|
||||
|
||||
void copyToClipboard();
|
||||
void pasteFromClipboard();
|
||||
|
||||
void reconnectAll();
|
||||
void selectNone();
|
||||
void selectAll();
|
||||
void removeSelected();
|
||||
void removeAll();
|
||||
void clearSelection();
|
||||
void addItem(QGraphicsItem * item, bool emit_action = true);
|
||||
|
||||
signals:
|
||||
void blockDoubleClicked(BlockItem * );
|
||||
void blockHoverEnter(BlockItem * );
|
||||
void blockHoverLeave(BlockItem * );
|
||||
void busDoubleClicked(BlockBusItem * );
|
||||
void schemeAction(BlockItemBase::Action action, QList<QGraphicsItem * > items);
|
||||
void blockRemoved(BlockItem * item);
|
||||
void connectionsChanged();
|
||||
void copyEnabledChanged(bool);
|
||||
void pasteEnabledChanged(bool);
|
||||
|
||||
};
|
||||
|
||||
#endif // BLOCKVIEW_H
|
||||
167
libs/blockview/blockviewwavetrace.cpp
Normal file
167
libs/blockview/blockviewwavetrace.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
#include "blockviewwavetrace.h"
|
||||
|
||||
|
||||
BlockViewWavetrace::BlockViewWavetrace(int width, int height) {
|
||||
max_steps = 512;
|
||||
resize(width, height);
|
||||
setPreferredDirection(Horizontal);
|
||||
}
|
||||
|
||||
|
||||
void BlockViewWavetrace::resize(int width, int height) {
|
||||
wid = width;
|
||||
hei = height;
|
||||
if (field.size() != wid)
|
||||
field.resize(wid);
|
||||
for (int i = 0; i < wid; ++i) {
|
||||
if (field[i].size() != hei) {
|
||||
field[i].resize(hei);
|
||||
field[i].fill(Cell());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockViewWavetrace::fill(short val) {
|
||||
for (int i = 0; i < wid; ++i) {
|
||||
if (i == 0)
|
||||
field[i].fill(val);
|
||||
else
|
||||
memcpy(field[i].data(), field[0].constData(), hei * sizeof(field[0][0]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockViewWavetrace::fill(const QRect & rect, short val) {
|
||||
for (int i = rect.left(); i <= rect.right(); ++i)
|
||||
for (int j = rect.top(); j <= rect.bottom(); ++j)
|
||||
field[i][j].value = field[i][j].direction = val;
|
||||
}
|
||||
|
||||
|
||||
void BlockViewWavetrace::fill(int px, int py, short val) {
|
||||
short p = field[px][py].value;
|
||||
if ((val == HorizontalBus && p == VerticalBus ) ||
|
||||
(val == VerticalBus && p == HorizontalBus))
|
||||
field[px][py].value = Blocked;
|
||||
else
|
||||
field[px][py].value = val;
|
||||
field[px][py].direction = field[px][py].value;
|
||||
}
|
||||
|
||||
|
||||
bool BlockViewWavetrace::trace(const QPoint & start, const QPoint & finish) {
|
||||
st = start;
|
||||
fn = finish;
|
||||
if (dir_ == NoTrace) return true;
|
||||
//qDebug() << "trace" << start << finish;
|
||||
//return true;
|
||||
short cl = 0;
|
||||
QRect frect(0, 0, wid - 1, hei - 1);
|
||||
QVector<QPoint> cpnts, npnts;
|
||||
fill(st, cl);
|
||||
cpnts.push_back(st);
|
||||
if (field[fn.x()][fn.y()].value == (short)Blocked)
|
||||
return false;
|
||||
auto checkAndFill = [this, &npnts, &frect](int x, int y, short acc_dir, short c) {
|
||||
if (!frect.contains(x, y)) return;
|
||||
short p = field[x][y].value;
|
||||
if (p == (short)Empty || p == acc_dir) {
|
||||
npnts.push_back(QPoint(x, y));
|
||||
field[x][y].value = c;
|
||||
}
|
||||
};
|
||||
while (cpnts.size() > 0) {
|
||||
npnts.clear();
|
||||
cl++;
|
||||
if (cl >= max_steps)
|
||||
return false;
|
||||
for (int i = 0; i < cpnts.size(); ++i) {
|
||||
if (cpnts[i] == fn)
|
||||
return true;
|
||||
checkAndFill(cpnts[i].x() - 1, cpnts[i].y() , (short)VerticalBus , cl);
|
||||
checkAndFill(cpnts[i].x() + 1, cpnts[i].y() , (short)VerticalBus , cl);
|
||||
checkAndFill(cpnts[i].x() , cpnts[i].y() - 1, (short)HorizontalBus, cl);
|
||||
checkAndFill(cpnts[i].x() , cpnts[i].y() + 1, (short)HorizontalBus, cl);
|
||||
}
|
||||
cpnts = npnts;
|
||||
//qDebug() << cl << ": " << cpnts.size();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void BlockViewWavetrace::gatherPath() {
|
||||
path_.clear();
|
||||
path_.push_back(fn);
|
||||
if (dir_ == NoTrace) {
|
||||
path_.push_front(st);
|
||||
return;
|
||||
}
|
||||
int pa = -1, ca = -1;
|
||||
bool first = true;
|
||||
short cl = field[fn.x()][fn.y()].value;
|
||||
QRect frect(0, 0, wid, hei);
|
||||
QPoint cpnt = fn;
|
||||
//cout << "start from " << cl << endl;
|
||||
auto checkAndStep = [this, &cpnt, &first, &frect] (int dir, short c, int & ca_, int pa_)->bool {
|
||||
int cx = cpnt.x() + dps[dir].x();
|
||||
int cy = cpnt.y() + dps[dir].y();
|
||||
if (frect.contains(cx, cy)) {
|
||||
const Cell & cell(field[cx][cy]);
|
||||
if (cell.value == c) {
|
||||
if (cell.direction == HorizontalBus || cell.direction == VerticalBus) {
|
||||
if (dps[dir].x() == 0 && cell.direction == VerticalBus)
|
||||
return false;
|
||||
if (dps[dir].y() == 0 && cell.direction == HorizontalBus)
|
||||
return false;
|
||||
}
|
||||
ca_ = QLineF(QPointF(cx, cy), cpnt).angle();
|
||||
if (ca_ != pa_ && !first)
|
||||
path_.push_front(cpnt);
|
||||
cpnt = QPoint(cx, cy);
|
||||
first = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
while (cl > 0) {
|
||||
cl--;
|
||||
pa = ca;
|
||||
|
||||
if (checkAndStep(0, cl, ca, pa)) continue;
|
||||
if (checkAndStep(1, cl, ca, pa)) continue;
|
||||
if (checkAndStep(2, cl, ca, pa)) continue;
|
||||
if (checkAndStep(3, cl, ca, pa)) continue;
|
||||
|
||||
}
|
||||
path_.push_front(st);
|
||||
//cout << path_.size() << endl;
|
||||
}
|
||||
|
||||
|
||||
void BlockViewWavetrace::setPreferredDirection(BlockViewWavetrace::Direction dir) {
|
||||
dir_ = dir;
|
||||
if (dir == BlockViewWavetrace::Horizontal) {
|
||||
dps[0] = QPoint(0, -1);
|
||||
dps[1] = QPoint(0, 1);
|
||||
dps[2] = QPoint(-1, 0);
|
||||
dps[3] = QPoint(1, 0);
|
||||
}
|
||||
if (dir == BlockViewWavetrace::Vertical) {
|
||||
dps[2] = QPoint(0, -1);
|
||||
dps[3] = QPoint(0, 1);
|
||||
dps[0] = QPoint(-1, 0);
|
||||
dps[1] = QPoint(1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const QVector<QPoint> & BlockViewWavetrace::path() const {
|
||||
/*path_.resize(3);
|
||||
path_[0] = st;
|
||||
path_[1] = (st + fn) / 2;
|
||||
path_[2] = fn;*/
|
||||
return path_;
|
||||
}
|
||||
71
libs/blockview/blockviewwavetrace.h
Normal file
71
libs/blockview/blockviewwavetrace.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef BLOCKVIEWWAVETRACE_H
|
||||
#define BLOCKVIEWWAVETRACE_H
|
||||
|
||||
#include "blockitem.h"
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT BlockViewWavetrace {
|
||||
public:
|
||||
BlockViewWavetrace(int width = 1, int height = 1);
|
||||
|
||||
enum CellState {Empty = -1, Blocked = -2, HorizontalBus = -3, VerticalBus = -4};
|
||||
enum Direction {NoTrace, Horizontal, Vertical};
|
||||
|
||||
int width() const {return wid;}
|
||||
int height() const {return hei;}
|
||||
void resize(int width, int height);
|
||||
void resize(const QSize & sz) {resize(sz.width(), sz.height());}
|
||||
void fill(short val = -1);
|
||||
void fill(const QRect & rect, short val = -1);
|
||||
void fill(const QPoint & point, short val = -1) {fill(point.x(), point.y(), val);}
|
||||
void fill(int px, int py, short val);
|
||||
void fill(BlockViewWavetrace::CellState val = Empty) {fill((short)val);}
|
||||
void fill(const QRect & rect, BlockViewWavetrace::CellState val = Empty) {fill(rect, (short)val);}
|
||||
void fill(const QPoint & point, BlockViewWavetrace::CellState val = Empty) {fill(point, (short)val);}
|
||||
void fill(int px, int py, BlockViewWavetrace::CellState val = Empty) {fill(px, py, (short)val);}
|
||||
void clear() {fill(-1);}
|
||||
bool trace(const QPoint & start, const QPoint & finish);
|
||||
Direction preferredDirection() const {return dir_;}
|
||||
void setPreferredDirection(Direction dir);
|
||||
void setMaximumSteps(int steps) {max_steps = steps;}
|
||||
int maximumSteps() const {return max_steps;}
|
||||
void gatherPath();
|
||||
const QVector<QPoint> & path() const;
|
||||
|
||||
private:
|
||||
struct QAD_BLOCKVIEW_EXPORT Cell {
|
||||
Cell(short v = Empty): value(v), direction(0) {}
|
||||
short value;
|
||||
short direction;
|
||||
};
|
||||
|
||||
int wid, hei, max_steps;
|
||||
Direction dir_;
|
||||
QVector<QVector<Cell> > field;
|
||||
QVector<QPoint> path_;
|
||||
QVector<QPoint> jumps;
|
||||
QPoint dps[4], st, fn;
|
||||
|
||||
};
|
||||
|
||||
#endif // BLOCKVIEWWAVETRACE_H
|
||||
944
libs/blockview/drawtools.cpp
Normal file
944
libs/blockview/drawtools.cpp
Normal file
@@ -0,0 +1,944 @@
|
||||
#include "drawtools.h"
|
||||
#include "ui_drawtools.h"
|
||||
#include "alignedtextitem.h"
|
||||
#include <QGraphicsLineItem>
|
||||
#include <QLineEdit>
|
||||
#include <QLabel>
|
||||
#include <QMouseEvent>
|
||||
#include <QFileDialog>
|
||||
#include <QImageReader>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
_DTSizeItem::_DTSizeItem(): QGraphicsObject() {
|
||||
cur_item = 0;
|
||||
grid = 10.;
|
||||
in_process = can_drag = false;
|
||||
setData(1007, true);
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
//qDebug() << &(rects[i]);
|
||||
rects[i].setData(1007, true);
|
||||
rects[i].setData(bvidDTHandle, true);
|
||||
rects[i].setFlag(QGraphicsItem::ItemIgnoresTransformations);
|
||||
rects[i].setZValue(10.);
|
||||
rects[i].setAcceptHoverEvents(true);
|
||||
rects[i].setRect(-5, -5, 10, 10);
|
||||
rects[i].setPen(QPen(Qt::darkBlue));
|
||||
rects[i].setBrush(QBrush(QColor(64, 64, 255, 128)));
|
||||
//rects[i].setData(1100, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_DTSizeItem::~_DTSizeItem() {
|
||||
assignObject(0);
|
||||
//qDebug() << "!!!";
|
||||
}
|
||||
|
||||
|
||||
void _DTSizeItem::assignObject(QGraphicsItem * item) {
|
||||
if (cur_item)
|
||||
if (qgraphicsitem_cast<QGraphicsItem*>(cur_item))
|
||||
cur_item->removeSceneEventFilter(this);
|
||||
cur_item = item;
|
||||
if (!cur_item) {
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
rects[i].hide();
|
||||
rects[i].setParentItem(0);
|
||||
rects[i].removeSceneEventFilter(this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (item)
|
||||
if (item->scene())
|
||||
if (!item->scene()->views().isEmpty())
|
||||
grid = ((BlockView*)(item->scene()->views()[0]))->gridStep();
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem*>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem*>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem*>(cur_item);
|
||||
if (irect || iell || iline) {
|
||||
resizeHandles();
|
||||
is_line = qgraphicsitem_cast<QGraphicsLineItem*>(item);
|
||||
for (int i = 0; i < (is_line ? 2 : 8); ++i) {
|
||||
rects[i].setParentItem(item);
|
||||
rects[i].installSceneEventFilter(this);
|
||||
rects[i].show();
|
||||
}
|
||||
}
|
||||
item->installSceneEventFilter(this);
|
||||
moveRects();
|
||||
}
|
||||
|
||||
|
||||
void _DTSizeItem::moveRects() {
|
||||
if (!cur_item) return;
|
||||
QRectF rect = itemRect(cur_item);
|
||||
QPointF tl = rect.topLeft(), tr = rect.topRight(), bl = rect.bottomLeft(), br = rect.bottomRight();
|
||||
if (is_line) {
|
||||
rects[0].setPos(tl); rects[0].setData(2001, int(Qt::SizeAllCursor));
|
||||
rects[1].setPos(br); rects[1].setData(2001, int(Qt::SizeAllCursor));
|
||||
} else {
|
||||
rects[0].setPos(tl); rects[0].setData(2001, int(Qt::SizeFDiagCursor));
|
||||
rects[1].setPos((tl + tr) / 2.); rects[1].setData(2001, int(Qt::SizeVerCursor));
|
||||
rects[2].setPos(tr); rects[2].setData(2001, int(Qt::SizeBDiagCursor));
|
||||
rects[3].setPos((tr + br) / 2.); rects[3].setData(2001, int(Qt::SizeHorCursor));
|
||||
rects[4].setPos(br); rects[4].setData(2001, int(Qt::SizeFDiagCursor));
|
||||
rects[5].setPos((br + bl) / 2.); rects[5].setData(2001, int(Qt::SizeVerCursor));
|
||||
rects[6].setPos(bl); rects[6].setData(2001, int(Qt::SizeBDiagCursor));
|
||||
rects[7].setPos((bl + tl) / 2.); rects[7].setData(2001, int(Qt::SizeHorCursor));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _DTSizeItem::applyRect() {
|
||||
if (!cur_item) return;
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem*>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem*>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem*>(cur_item);
|
||||
if (irect)
|
||||
irect->setRect(nrect);
|
||||
if (iell)
|
||||
iell->setRect(nrect);
|
||||
if (iline)
|
||||
iline->setLine(QLineF(nrect.topLeft(), nrect.bottomRight()));
|
||||
}
|
||||
|
||||
|
||||
void _DTSizeItem::doubleClick() {
|
||||
QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<QGraphicsSimpleTextItem*>(cur_item);
|
||||
AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem*>(cur_item);
|
||||
QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem*>(cur_item);
|
||||
if (itext || iatext) {
|
||||
QMetaObject::invokeMethod(this, "textEditRequest", Qt::QueuedConnection);
|
||||
}
|
||||
if (ipixmap) {
|
||||
QMetaObject::invokeMethod(this, "pixmapEditRequest", Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _DTSizeItem::resizeHandles() {
|
||||
double sz = QApplication::fontMetrics().size(0, "0").height() / 3.;
|
||||
QRectF r(-sz, -sz, sz*2, sz*2);
|
||||
for (int i = 0; i < 8; ++i)
|
||||
rects[i].setRect(r);
|
||||
}
|
||||
|
||||
|
||||
QRectF _DTSizeItem::itemRect(const QGraphicsItem * item) const {
|
||||
if (!cur_item) return QRectF();
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem*>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem*>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem*>(cur_item);
|
||||
if (irect)
|
||||
return irect->rect();
|
||||
if (iell)
|
||||
return iell->rect();
|
||||
if (iline)
|
||||
return QRectF(iline->line().p1(), iline->line().p2());
|
||||
return QRectF();
|
||||
}
|
||||
|
||||
|
||||
QRectF _DTSizeItem::boundingRect() const {
|
||||
QRectF ret = rects[0].boundingRect().translated(rects[0].pos());
|
||||
for (int i = 1; i < 8; ++i)
|
||||
ret |= rects[i].boundingRect().translated(rects[i].pos());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool _DTSizeItem::sceneEventFilter(QGraphicsItem * watched, QEvent * event) {
|
||||
QGraphicsSceneMouseEvent * me = (QGraphicsSceneMouseEvent * )event;
|
||||
if (watched == cur_item) {
|
||||
if (event->type() == QEvent::Close) {
|
||||
assignObject(0);
|
||||
return true;
|
||||
}
|
||||
if (event->type() == QEvent::GraphicsSceneMouseDoubleClick) {
|
||||
doubleClick();
|
||||
return true;
|
||||
}
|
||||
return QGraphicsItem::sceneEventFilter(watched, event);
|
||||
}
|
||||
if (!cur_item)
|
||||
return QGraphicsItem::sceneEventFilter(watched, event);
|
||||
view_ = 0;
|
||||
switch (event->type()) {
|
||||
case QEvent::GraphicsSceneHoverEnter:
|
||||
if (watched->scene()) if (!watched->scene()->views().isEmpty()) view_ = watched->scene()->views()[0];
|
||||
if (view_) view_->setCursor(Qt::CursorShape(watched->data(2001).toInt()));
|
||||
break;
|
||||
case QEvent::GraphicsSceneHoverLeave:
|
||||
if (watched->scene()) if (!watched->scene()->views().isEmpty()) view_ = watched->scene()->views()[0];
|
||||
if (view_) view_->unsetCursor();
|
||||
break;
|
||||
case QEvent::GraphicsSceneMousePress:
|
||||
can_drag = (me->buttons() == Qt::LeftButton);
|
||||
if (in_process) {
|
||||
nrect = cur_item->data(2000).toRectF();
|
||||
applyRect();
|
||||
moveRects();
|
||||
}
|
||||
in_process = false;
|
||||
pp = quantize(me->scenePos(), grid);
|
||||
cur_item->setData(2000, itemRect(cur_item));
|
||||
return true;
|
||||
case QEvent::GraphicsSceneMouseMove:
|
||||
if (me->buttons().testFlag(Qt::LeftButton)) {
|
||||
sp = quantize(me->scenePos(), grid);
|
||||
if (pp != sp && can_drag) {
|
||||
in_process = true;
|
||||
nrect = itemRect(cur_item);
|
||||
if (is_line) {
|
||||
if (watched == &(rects[0])) nrect.setTopLeft(rects[0].pos() + (sp - pp));
|
||||
if (watched == &(rects[1])) nrect.setBottomRight(rects[1].pos() + (sp - pp));
|
||||
} else {
|
||||
if (watched == &(rects[0])) nrect.setTopLeft(rects[0].pos() + (sp - pp));
|
||||
if (watched == &(rects[1])) nrect.setTop(rects[1].pos().y() + (sp - pp).y());
|
||||
if (watched == &(rects[2])) nrect.setTopRight(rects[2].pos() + (sp - pp));
|
||||
if (watched == &(rects[3])) nrect.setRight(rects[3].pos().x() + (sp - pp).x());
|
||||
if (watched == &(rects[4])) nrect.setBottomRight(rects[4].pos() + (sp - pp));
|
||||
if (watched == &(rects[5])) nrect.setBottom(rects[5].pos().y() + (sp - pp).y());
|
||||
if (watched == &(rects[6])) nrect.setBottomLeft(rects[6].pos() + (sp - pp));
|
||||
if (watched == &(rects[7])) nrect.setLeft(rects[7].pos().x() + (sp - pp).x());
|
||||
nrect = nrect.normalized();
|
||||
}
|
||||
pp = sp;
|
||||
applyRect();
|
||||
moveRects();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
case QEvent::GraphicsSceneMouseRelease:
|
||||
if (in_process)
|
||||
emit sizeChanged();
|
||||
in_process = false;
|
||||
can_drag = false;
|
||||
return true;
|
||||
default: break;
|
||||
}
|
||||
return QGraphicsItem::sceneEventFilter(watched, event);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DrawTools::DrawTools(BlockView * parent): QWidget(parent),
|
||||
actions_Z_up(this), actions_Z_top(this), actions_Z_down(this), actions_Z_bottom(this) {
|
||||
widget_props = new QWidget();
|
||||
ui = new Ui::DrawTools();
|
||||
ui->setupUi(widget_props);
|
||||
ui->labelPen->setMinimumSize(preferredIconSize(1.5, widget_props));
|
||||
ui->labelPen->setMaximumSize(ui->labelPen->minimumSize());
|
||||
ui->labelBrush->setMinimumSize(ui->labelPen->minimumSize());
|
||||
ui->labelBrush->setMaximumSize(ui->labelBrush->minimumSize());
|
||||
widget_props->setEnabled(false);
|
||||
int fh = qMax<int>(QApplication::fontMetrics().size(0, "0").height(), 22);
|
||||
int thick = lineThickness();
|
||||
QSize sz(fh * 2.5, fh);
|
||||
ui->comboLineStyle->setIconSize(sz);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
QPixmap pix(sz);
|
||||
pix.fill();
|
||||
QPainter p(&pix);
|
||||
p.setPen(QPen(Qt::black, thick, (Qt::PenStyle)i));
|
||||
p.drawLine(0, pix.height() / 2, pix.width(), pix.height() / 2);
|
||||
p.end();
|
||||
ui->comboLineStyle->addItem(QIcon(pix), "");
|
||||
}
|
||||
#ifdef Q_OS_MACOS
|
||||
setAlignCompact(true);
|
||||
#else
|
||||
setAlignCompact(false);
|
||||
#endif
|
||||
menu_hor.addActions(QList<QAction*>() << ui->actionLeft << ui->actionHCenter << ui->actionRight);
|
||||
menu_ver.addActions(QList<QAction*>() << ui->actionTop << ui->actionVCenter << ui->actionBottom);
|
||||
ui->buttonAlignHor->setMenu(&menu_hor);
|
||||
ui->buttonAlignVer->setMenu(&menu_ver);
|
||||
new_type = -1;
|
||||
new_item = cur_item = 0;
|
||||
view_ = 0;
|
||||
resize_enabled = true;
|
||||
text_dlg.setLayout(new QBoxLayout(QBoxLayout::TopToBottom));
|
||||
QDialogButtonBox * bbox = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel);
|
||||
connect(bbox, SIGNAL(accepted()), &text_dlg, SLOT(accept()));
|
||||
connect(bbox, SIGNAL(rejected()), &text_dlg, SLOT(reject()));
|
||||
text_dlg.layout()->addWidget(&text_edit);
|
||||
text_dlg.layout()->addWidget(bbox);
|
||||
actions_Z_up.setIcon(QIcon(":/icons/z-up.png")); actions_Z_up.setEnabled(false);
|
||||
actions_Z_top.setIcon(QIcon(":/icons/z-top.png")); actions_Z_top.setEnabled(false);
|
||||
actions_Z_down.setIcon(QIcon(":/icons/z-down.png")); actions_Z_down.setEnabled(false);
|
||||
actions_Z_bottom.setIcon(QIcon(":/icons/z-bottom.png")); actions_Z_bottom.setEnabled(false);
|
||||
actions_add << newAction(QIcon(":/icons/draw-rectangle.png"), 1)
|
||||
<< newAction(QIcon(":/icons/draw-ellipse.png"), 2)
|
||||
<< newAction(QIcon(":/icons/draw-line.png"), 4)
|
||||
<< newAction(QIcon(":/icons/draw-text.png"), 0)
|
||||
<< newAction(QIcon(":/icons/view-preview.png"), 3);
|
||||
buttons_align << ui->buttonAlignTL << ui->buttonAlignTC << ui->buttonAlignTR
|
||||
<< ui->buttonAlignCL << ui->buttonAlignCC << ui->buttonAlignCR
|
||||
<< ui->buttonAlignBL << ui->buttonAlignBC << ui->buttonAlignBR;
|
||||
foreach (QAction * a, actions_add)
|
||||
connect(a, SIGNAL(toggled(bool)), this, SLOT(toggleNewItem(bool)));
|
||||
foreach (QToolButton * b, buttons_align)
|
||||
connect(b, SIGNAL(clicked(bool)), this, SLOT(alignClicked()));
|
||||
connect(ui->buttonImage, SIGNAL(clicked(bool)), this, SLOT(buttonImage_clicked()));
|
||||
connect(ui->buttonImagePaste, SIGNAL(clicked(bool)), this, SLOT(buttonImagePaste_clicked()));
|
||||
connect(ui->buttonFont, SIGNAL(clicked(bool)), this, SLOT(buttonFont_clicked()));
|
||||
connect(ui->buttonTextEdit, SIGNAL(clicked(bool)), this, SLOT(buttonTextEdit_clicked()));
|
||||
connect(ui->spinWidth, SIGNAL(valueChanged(double)), this, SLOT(propertyChanged()));
|
||||
connect(ui->spinWidth, SIGNAL(editingFinished()), this, SLOT(changeFinished()));
|
||||
connect(ui->spinHeight, SIGNAL(valueChanged(double)), this, SLOT(propertyChanged()));
|
||||
connect(ui->spinHeight, SIGNAL(editingFinished()), this, SLOT(changeFinished()));
|
||||
connect(ui->spinThick, SIGNAL(valueChanged(double)), this, SLOT(propertyChanged()));
|
||||
connect(ui->spinThick, SIGNAL(editingFinished()), this, SLOT(changeFinished()));
|
||||
connect(ui->spinScale, SIGNAL(valueChanged(double)), this, SLOT(propertyChanged()));
|
||||
connect(ui->spinScale, SIGNAL(editingFinished()), this, SLOT(changeFinished()));
|
||||
connect(ui->comboText, SIGNAL(editTextChanged(QString)), this, SLOT(propertyChanged()));
|
||||
connect(ui->comboText->lineEdit(), SIGNAL(editingFinished()), this, SLOT(changeFinished()));
|
||||
connect(ui->comboLineStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(comboLineStyleChanged()));
|
||||
connect(ui->colorButtonPen, SIGNAL(colorChanged(QColor)), this, SLOT(propertyChanged()));
|
||||
connect(ui->colorButtonPen, SIGNAL(colorChanged(QColor)), this, SLOT(changeFinished()));
|
||||
connect(ui->colorButtonBrush, SIGNAL(colorChanged(QColor)), this, SLOT(propertyChanged()));
|
||||
connect(ui->colorButtonBrush, SIGNAL(colorChanged(QColor)), this, SLOT(changeFinished()));
|
||||
connect(ui->actionTop, SIGNAL(triggered(bool)), this, SLOT(actionTop_triggered(bool)));
|
||||
connect(ui->actionVCenter, SIGNAL(triggered(bool)), this, SLOT(actionVCenter_triggered(bool)));
|
||||
connect(ui->actionBottom, SIGNAL(triggered(bool)), this, SLOT(actionBottom_triggered(bool)));
|
||||
connect(ui->actionLeft, SIGNAL(triggered(bool)), this, SLOT(actionLeft_triggered(bool)));
|
||||
connect(ui->actionHCenter, SIGNAL(triggered(bool)), this, SLOT(actionHCenter_triggered(bool)));
|
||||
connect(ui->actionRight, SIGNAL(triggered(bool)), this, SLOT(actionRight_triggered(bool)));
|
||||
connect(&font_dlg, SIGNAL(currentFontChanged(QFont)), this, SLOT(propertyChanged()));
|
||||
connect(&size_item, SIGNAL(sizeChanged()), this, SLOT(sizeChanged()));
|
||||
connect(&size_item, SIGNAL(textEditRequest()), this, SLOT(buttonTextEdit_clicked()));
|
||||
connect(&size_item, SIGNAL(pixmapEditRequest()), this, SLOT(buttonImage_clicked()));
|
||||
connect(&actions_Z_up, SIGNAL(triggered(bool)), this, SLOT(actionZ_triggered()));
|
||||
connect(&actions_Z_top, SIGNAL(triggered(bool)), this, SLOT(actionZ_triggered()));
|
||||
connect(&actions_Z_down, SIGNAL(triggered(bool)), this, SLOT(actionZ_triggered()));
|
||||
connect(&actions_Z_bottom, SIGNAL(triggered(bool)), this, SLOT(actionZ_triggered()));
|
||||
setBlockView(parent);
|
||||
retranslate();
|
||||
}
|
||||
|
||||
|
||||
DrawTools::~DrawTools() {
|
||||
size_item.assignObject(0);
|
||||
//delete ui;
|
||||
//delete widget_props;
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::retranslate() {
|
||||
QStringList styles;
|
||||
styles << tr("NoPen") << tr("Solid") << tr("Dash")
|
||||
<< tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
|
||||
for (int i = 0; i < styles.size(); i++) ui->comboLineStyle->setItemText(i, styles[i]);
|
||||
text_dlg.setWindowTitle(tr("Edit text"));
|
||||
actions_Z_up.setText(tr("Bring\nforward"));
|
||||
actions_Z_top.setText(tr("Bring\nto front"));
|
||||
actions_Z_down.setText(tr("Send\nbackward"));
|
||||
actions_Z_bottom.setText(tr("Send\nto back"));
|
||||
actions_add[0]->setText(tr("Draw\nRectangle"));
|
||||
actions_add[1]->setText(tr("Draw\nEllipse"));
|
||||
actions_add[2]->setText(tr("Draw\nLine"));
|
||||
actions_add[3]->setText(tr("Draw\nText"));
|
||||
actions_add[4]->setText(tr("Draw\nImage"));
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::setBlockView(BlockView * v) {
|
||||
if (view_) view_->viewport()->removeEventFilter(this);
|
||||
disconnect(this, SLOT(selectionChanged()));
|
||||
view_ = v;
|
||||
if (!view_) return;
|
||||
view_->addItem(&size_item);
|
||||
view_->viewport()->installEventFilter(this);
|
||||
connect(view_->scene(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::setAlignCompact(bool yes) {
|
||||
ui->widgetAlign2->setVisible(yes);
|
||||
ui->widgetAlign9->setVisible(!yes);
|
||||
}
|
||||
|
||||
|
||||
bool DrawTools::eventFilter(QObject * o, QEvent * e) {
|
||||
QMouseEvent * me = (QMouseEvent*)e;
|
||||
QPointF sp;
|
||||
if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish)
|
||||
ui->labelPen->setMinimumSize(preferredIconSize(1.5, widget_props));
|
||||
if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseMove)
|
||||
sp = quantize(view_->mapToScene(me->pos()), view_->gridStep());
|
||||
QRectF mr;
|
||||
switch (e->type()) {
|
||||
case QEvent::MouseButtonPress:
|
||||
if (new_type < 0) break;
|
||||
if (new_item) {
|
||||
delete new_item;
|
||||
new_item = 0;
|
||||
if (!me->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
foreach (QAction * a, actions_add)
|
||||
a->setChecked(false);
|
||||
new_type = -1;
|
||||
//view_->setCursor(Qt::ArrowCursor);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
new_item = 0;
|
||||
pp = sp;
|
||||
switch (new_type) {
|
||||
case 0:
|
||||
new_item = new AlignedTextItem();
|
||||
((AlignedTextItem*)new_item)->setText("Text");
|
||||
((AlignedTextItem*)new_item)->setPos(sp);
|
||||
break;
|
||||
case 1:
|
||||
new_item = new QGraphicsRectItem();
|
||||
break;
|
||||
case 2:
|
||||
new_item = new QGraphicsEllipseItem();
|
||||
break;
|
||||
case 3:
|
||||
new_item = new QGraphicsPixmapItem(QPixmap(":/icons/view-preview.png"));
|
||||
((QGraphicsPixmapItem*)new_item)->setPos(sp - QPointF(new_item->boundingRect().width() / 2, new_item->boundingRect().height() / 2));
|
||||
break;
|
||||
case 4:
|
||||
new_item = new QGraphicsLineItem(QLineF(sp, sp));
|
||||
break;
|
||||
};
|
||||
if (new_item) {
|
||||
if (new_type == 1 || new_type == 2)
|
||||
((QAbstractGraphicsShapeItem*)new_item)->setBrush(Qt::white);
|
||||
new_item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);
|
||||
new_item->setData(1100, true);
|
||||
emit itemCreated(new_item);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case QEvent::MouseMove:
|
||||
if (me->buttons().testFlag(Qt::LeftButton)) {
|
||||
if (new_item) {
|
||||
mr = new_item->mapRectFromScene(QRectF(pp, sp).normalized());
|
||||
//mr = QRectF(pp, sp).normalized();
|
||||
switch (new_type) {
|
||||
case 0:
|
||||
((AlignedTextItem*)new_item)->setPos(sp);
|
||||
break;
|
||||
case 1:
|
||||
((QGraphicsRectItem*)new_item)->setRect(mr);
|
||||
break;
|
||||
case 2:
|
||||
((QGraphicsEllipseItem*)new_item)->setRect(mr);
|
||||
break;
|
||||
case 3:
|
||||
((QGraphicsPixmapItem*)new_item)->setPos(sp - QPointF(new_item->boundingRect().width() / 2, new_item->boundingRect().height() / 2));
|
||||
break;
|
||||
case 4:
|
||||
((QGraphicsLineItem*)new_item)->setLine(QLineF(pp, sp));
|
||||
break;
|
||||
};
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case QEvent::MouseButtonRelease:
|
||||
if (new_item) {
|
||||
if (new_item->boundingRect().isEmpty())
|
||||
delete new_item;
|
||||
else {
|
||||
emit itemAddConfirm(new_item);
|
||||
if (view_) {
|
||||
view_->selectNone();
|
||||
new_item->setSelected(true);
|
||||
}
|
||||
}
|
||||
new_item = 0;
|
||||
if (!me->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
foreach (QAction * a, actions_add)
|
||||
a->setChecked(false);
|
||||
new_type = -1;
|
||||
//view_->setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return QObject::eventFilter(o, e);
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::changeEvent(QEvent * e) {
|
||||
QWidget::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
ui->retranslateUi(this);
|
||||
retranslate();
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QComboBox * DrawTools::textEditCombo() const {
|
||||
return ui->comboText;
|
||||
}
|
||||
|
||||
/*
|
||||
void DrawTools::changeEvent(QEvent * e) {
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
ui->retranslateUi(this);
|
||||
return;
|
||||
}
|
||||
QObject::changeEvent(e);
|
||||
}
|
||||
*/
|
||||
|
||||
QAction * DrawTools::newAction(const QIcon & icon, int type) {
|
||||
QAction * ret = new QAction(icon, QString(), this);
|
||||
ret->setCheckable(true);
|
||||
ret->setData(type);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::toggleNewItem(bool on) {
|
||||
QAction * sa = (QAction * )sender();
|
||||
foreach (QAction * a, actions_add)
|
||||
if (a != sa)
|
||||
a->setChecked(false);
|
||||
if (!on) {
|
||||
new_type = -1;
|
||||
view_->unsetCursor();
|
||||
return;
|
||||
}
|
||||
new_type = sa->data().toInt();
|
||||
view_->setCursor(Qt::CrossCursor);
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::alignClicked() {
|
||||
QToolButton * sb = (QToolButton * )sender();
|
||||
foreach (QToolButton * b, buttons_align)
|
||||
if (b != sb)
|
||||
b->setChecked(false);
|
||||
sb->setChecked(true);
|
||||
align = 0;
|
||||
QString als = sb->objectName().right(2).toLower();
|
||||
if (als[0] == 't') align |= Qt::AlignTop;
|
||||
if (als[0] == 'c') align |= Qt::AlignVCenter;
|
||||
if (als[0] == 'b') align |= Qt::AlignBottom;
|
||||
if (als[1] == 'l') align |= Qt::AlignLeft;
|
||||
if (als[1] == 'c') align |= Qt::AlignHCenter;
|
||||
if (als[1] == 'r') align |= Qt::AlignRight;
|
||||
propertyChanged();
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::setToolButtonsEnabled(bool pen, bool brush, bool wid_hei) {
|
||||
ui->labelPen->setEnabled(pen);
|
||||
ui->colorButtonPen->setEnabled(pen);
|
||||
ui->labelBrush->setEnabled(brush);
|
||||
ui->colorButtonBrush->setEnabled(brush);
|
||||
ui->spinWidth->setEnabled(wid_hei);
|
||||
ui->spinHeight->setEnabled(wid_hei);
|
||||
ui->labelWidth->setEnabled(wid_hei);
|
||||
ui->labelHeight->setEnabled(wid_hei);
|
||||
ui->labelPen->setVisible(pen);
|
||||
ui->colorButtonPen->setVisible(pen);
|
||||
ui->labelBrush->setVisible(brush);
|
||||
ui->colorButtonBrush->setVisible(brush);
|
||||
ui->spinWidth->setVisible(wid_hei);
|
||||
ui->spinHeight->setVisible(wid_hei);
|
||||
ui->labelWidth->setVisible(wid_hei);
|
||||
ui->labelHeight->setVisible(wid_hei);
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::blockPropSignals(bool block_) {
|
||||
ui->spinWidth->blockSignals(block_);
|
||||
ui->spinHeight->blockSignals(block_);
|
||||
ui->spinThick->blockSignals(block_);
|
||||
ui->comboText->blockSignals(block_);
|
||||
ui->comboLineStyle->blockSignals(block_);
|
||||
ui->colorButtonPen->blockSignals(block_);
|
||||
ui->colorButtonBrush->blockSignals(block_);
|
||||
ui->actionTop->blockSignals(block_);
|
||||
ui->actionVCenter->blockSignals(block_);
|
||||
ui->actionBottom->blockSignals(block_);
|
||||
ui->actionHCenter->blockSignals(block_);
|
||||
ui->actionLeft->blockSignals(block_);
|
||||
ui->actionRight->blockSignals(block_);
|
||||
foreach (QToolButton * b, buttons_align)
|
||||
b->blockSignals(block_);
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::actionAlignTrigger(bool vert, Qt::AlignmentFlag value) {
|
||||
blockPropSignals(true);
|
||||
if (vert) foreach (QAction * a, menu_ver.actions()) a->setChecked(false);
|
||||
else foreach (QAction * a, menu_hor.actions()) a->setChecked(false);
|
||||
align = align & (vert ? Qt::AlignHorizontal_Mask : Qt::AlignVertical_Mask);
|
||||
align |= value;
|
||||
((QAction*)sender())->setChecked(true);
|
||||
blockPropSignals(false);
|
||||
propertyChanged();
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::emitZAvailabe(QGraphicsItem * item) {
|
||||
BlockView * view = 0;
|
||||
if (item) if (item->scene()) if (!item->scene()->views().isEmpty()) view = qobject_cast<BlockView * >(item->scene()->views()[0]);
|
||||
if (view == 0) {
|
||||
moveZUpAvailable(false);
|
||||
moveZDownAvailable(false);
|
||||
return;
|
||||
}
|
||||
QList<QGraphicsItem * > dl;
|
||||
if (item->parentItem() == 0) dl = view->decors();
|
||||
else if (item->parentItem()->data(1006) == "item") dl = ((BlockItem*)(item->parentItem()))->decors_;
|
||||
if (dl.size() <= 1) {
|
||||
moveZUpAvailable(false);
|
||||
moveZDownAvailable(false);
|
||||
return;
|
||||
}
|
||||
int ind = dl.indexOf(item);
|
||||
if (ind < 0) {
|
||||
moveZUpAvailable(false);
|
||||
moveZDownAvailable(false);
|
||||
} else {
|
||||
moveZUpAvailable(ind < dl.size() - 1);
|
||||
moveZDownAvailable(ind > 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::selectionChanged() {
|
||||
cur_item = 0;
|
||||
size_item.assignObject(0);
|
||||
if (!view_) {
|
||||
emitZAvailabe();
|
||||
return;
|
||||
}
|
||||
QList<QGraphicsItem * > sil = view_->scene()->selectedItems();
|
||||
if (sil.size() != 1) {
|
||||
emitZAvailabe();
|
||||
widget_props->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
widget_props->setEnabled(true);
|
||||
cur_item = sil[0];
|
||||
if (!cur_item) {
|
||||
emitZAvailabe();
|
||||
return;
|
||||
}
|
||||
QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<QGraphicsSimpleTextItem*>(cur_item);
|
||||
AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem*>(cur_item);
|
||||
QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem*>(cur_item);
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem*>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem*>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem*>(cur_item);
|
||||
blockPropSignals(true);
|
||||
if (itext) {
|
||||
ui->stackedProperties->setCurrentIndex(0);
|
||||
ui->comboText->setEditText(itext->text());
|
||||
ui->colorButtonPen->setColor(itext->brush().color());
|
||||
font_dlg.blockSignals(true);
|
||||
font_dlg.setCurrentFont(itext->font());
|
||||
font_dlg.blockSignals(false);
|
||||
setToolButtonsEnabled(true, false, false);
|
||||
ui->widgetAlign2->setEnabled(false);
|
||||
ui->widgetAlign9->setEnabled(false);
|
||||
size_item.assignObject(itext);
|
||||
} else if (iatext) {
|
||||
ui->stackedProperties->setCurrentIndex(0);
|
||||
ui->comboText->setEditText(iatext->text());
|
||||
ui->colorButtonPen->setColor(iatext->brush().color());
|
||||
font_dlg.blockSignals(true);
|
||||
font_dlg.setCurrentFont(iatext->font());
|
||||
font_dlg.blockSignals(false);
|
||||
setToolButtonsEnabled(true, false, false);
|
||||
foreach (QAction * a, menu_hor.actions()) a->setChecked(false);
|
||||
foreach (QAction * a, menu_ver.actions()) a->setChecked(false);
|
||||
align = iatext->alignment();
|
||||
QString als;
|
||||
if (align.testFlag(Qt::AlignTop)) {als += "T"; ui->actionTop->setChecked(true);}
|
||||
if (align.testFlag(Qt::AlignVCenter)) {als += "C"; ui->actionVCenter->setChecked(true);}
|
||||
if (align.testFlag(Qt::AlignBottom)) {als += "B"; ui->actionBottom->setChecked(true);}
|
||||
if (align.testFlag(Qt::AlignLeft)) {als += "L"; ui->actionLeft->setChecked(true);}
|
||||
if (align.testFlag(Qt::AlignHCenter)) {als += "C"; ui->actionHCenter->setChecked(true);}
|
||||
if (align.testFlag(Qt::AlignRight)) {als += "R"; ui->actionRight->setChecked(true);}
|
||||
foreach (QToolButton * b, buttons_align)
|
||||
b->setChecked(false);
|
||||
foreach (QToolButton * b, buttons_align)
|
||||
if (b->objectName().endsWith(als)) {
|
||||
b->setChecked(true);
|
||||
break;
|
||||
}
|
||||
ui->widgetAlign2->setEnabled(true);
|
||||
ui->widgetAlign9->setEnabled(true);
|
||||
size_item.assignObject(iatext);
|
||||
} else if (ipixmap) {
|
||||
ui->stackedProperties->setCurrentIndex(2);
|
||||
ui->spinScale->setValue(sqrt(ipixmap->transform().determinant()));
|
||||
setToolButtonsEnabled(false, false, false);
|
||||
size_item.assignObject(ipixmap);
|
||||
} else if (irect || iell) {
|
||||
ui->stackedProperties->setCurrentIndex(1);
|
||||
QAbstractGraphicsShapeItem * ishape(0);
|
||||
if (irect) {
|
||||
ishape = irect;
|
||||
ui->spinWidth->setValue(irect->rect().width());
|
||||
ui->spinHeight->setValue(irect->rect().height());
|
||||
}
|
||||
if (iell) {
|
||||
ishape = iell;
|
||||
ui->spinWidth->setValue(iell->rect().width());
|
||||
ui->spinHeight->setValue(iell->rect().height());
|
||||
}
|
||||
if (ishape) {
|
||||
ui->colorButtonPen->setColor(ishape->pen().color());
|
||||
ui->colorButtonBrush->setColor(ishape->brush().color());
|
||||
ui->spinThick->setValue(ishape->pen().widthF());
|
||||
ui->comboLineStyle->setCurrentIndex(qMin<int>((int)ishape->pen().style(), ui->comboLineStyle->count() - 1));
|
||||
setToolButtonsEnabled(true, true, true);
|
||||
if (resize_enabled)
|
||||
size_item.assignObject(ishape);
|
||||
}
|
||||
} else if (iline) {
|
||||
ui->stackedProperties->setCurrentIndex(1);
|
||||
ui->colorButtonPen->setColor(iline->pen().color());
|
||||
ui->spinThick->setValue(iline->pen().widthF());
|
||||
ui->comboLineStyle->setCurrentIndex(qMin<int>((int)iline->pen().style(), ui->comboLineStyle->count() - 1));
|
||||
setToolButtonsEnabled(true, false, false);
|
||||
if (resize_enabled)
|
||||
size_item.assignObject(iline);
|
||||
} else {
|
||||
ui->stackedProperties->setCurrentIndex(3);
|
||||
widget_props->setEnabled(false);
|
||||
}
|
||||
emitZAvailabe(cur_item);
|
||||
blockPropSignals(false);
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::sizeChanged() {
|
||||
blockPropSignals(true);
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem*>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem*>(cur_item);
|
||||
if (irect || iell) {
|
||||
if (irect) {
|
||||
ui->spinWidth->setValue(irect->rect().width());
|
||||
ui->spinHeight->setValue(irect->rect().height());
|
||||
}
|
||||
if (iell) {
|
||||
ui->spinWidth->setValue(iell->rect().width());
|
||||
ui->spinHeight->setValue(iell->rect().height());
|
||||
}
|
||||
}
|
||||
blockPropSignals(false);
|
||||
changeFinished();
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::propertyChanged() {
|
||||
if (!cur_item) return;
|
||||
QGraphicsSimpleTextItem * itext = qgraphicsitem_cast<QGraphicsSimpleTextItem*>(cur_item);
|
||||
AlignedTextItem * iatext = qgraphicsitem_cast<AlignedTextItem*>(cur_item);
|
||||
QGraphicsPixmapItem * ipixmap = qgraphicsitem_cast<QGraphicsPixmapItem*>(cur_item);
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem*>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem*>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem*>(cur_item);
|
||||
if (itext) {
|
||||
QRectF obr = itext->boundingRect();
|
||||
itext->setFont(font_dlg.currentFont());
|
||||
itext->setText(ui->comboText->currentText());
|
||||
QRectF nbr = itext->boundingRect();
|
||||
QSizeF ds = (obr.size() - nbr.size()) / 2.;
|
||||
itext->setPos(itext->pos() + QPointF(ds.width(), ds.height()));
|
||||
itext->setBrush(ui->colorButtonPen->color());
|
||||
} else if (iatext) {
|
||||
iatext->setFont(font_dlg.currentFont());
|
||||
iatext->setText(ui->comboText->currentText());
|
||||
iatext->setBrush(ui->colorButtonPen->color());
|
||||
iatext->setAlignment(align);
|
||||
} else if (ipixmap) {
|
||||
QTransform t = ipixmap->transform();
|
||||
double det = sqrt(t.determinant());
|
||||
QSizeF os = ipixmap->boundingRect().size() * det;
|
||||
if (det != 0.) t.scale(1. / det, 1. / det);
|
||||
det = ui->spinScale->value();
|
||||
t.scale(det, det);
|
||||
ipixmap->setTransform(t);
|
||||
QSizeF ns = ipixmap->boundingRect().size() * det;
|
||||
QSizeF ds = (os - ns) / 2.;
|
||||
ipixmap->setPos(ipixmap->pos() + QPointF(ds.width(), ds.height()));
|
||||
} else if (irect || iell) {
|
||||
QAbstractGraphicsShapeItem * ishape(0);
|
||||
if (irect) {
|
||||
ishape = irect;
|
||||
irect->setRect(QRectF(irect->rect().topLeft(), QSizeF(ui->spinWidth->value(), ui->spinHeight->value())));
|
||||
}
|
||||
if (iell) {
|
||||
ishape = iell;
|
||||
iell->setRect(QRectF(iell->rect().topLeft(), QSizeF(ui->spinWidth->value(), ui->spinHeight->value())));
|
||||
}
|
||||
if (ishape) {
|
||||
ishape->setPen(QPen(ui->colorButtonPen->color(), ui->spinThick->value(), (Qt::PenStyle)ui->comboLineStyle->currentIndex()));
|
||||
ishape->setBrush(ui->colorButtonBrush->color());
|
||||
if (resize_enabled)
|
||||
size_item.assignObject(ishape);
|
||||
}
|
||||
} else if (iline) {
|
||||
iline->setPen(QPen(ui->colorButtonPen->color(), ui->spinThick->value(), (Qt::PenStyle)ui->comboLineStyle->currentIndex()));
|
||||
if (resize_enabled)
|
||||
size_item.assignObject(iline);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::comboLineStyleChanged() {
|
||||
if (!cur_item) return;
|
||||
QGraphicsRectItem * irect = qgraphicsitem_cast<QGraphicsRectItem*>(cur_item);
|
||||
QGraphicsEllipseItem * iell = qgraphicsitem_cast<QGraphicsEllipseItem*>(cur_item);
|
||||
QGraphicsLineItem * iline = qgraphicsitem_cast<QGraphicsLineItem*>(cur_item);
|
||||
if (irect || iell) {
|
||||
QAbstractGraphicsShapeItem * ishape(0);
|
||||
if (irect)
|
||||
ishape = irect;
|
||||
if (iell)
|
||||
ishape = iell;
|
||||
if (ishape) {
|
||||
QPen p(ishape->pen());
|
||||
p.setStyle((Qt::PenStyle)ui->comboLineStyle->currentIndex());
|
||||
ishape->setPen(p);
|
||||
changeFinished();
|
||||
}
|
||||
} else if (iline) {
|
||||
QPen p(iline->pen());
|
||||
p.setStyle((Qt::PenStyle)ui->comboLineStyle->currentIndex());
|
||||
iline->setPen(p);
|
||||
changeFinished();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::buttonImage_clicked() {
|
||||
QGraphicsPixmapItem * pi = qgraphicsitem_cast<QGraphicsPixmapItem * >(cur_item);
|
||||
if (!pi) return;
|
||||
QList<QByteArray> sif(QImageReader::supportedImageFormats());
|
||||
QString f;
|
||||
foreach (const QByteArray & i, sif) {
|
||||
if (!f.isEmpty()) f += " ";
|
||||
f += "*.";
|
||||
f += i;
|
||||
}
|
||||
QString ret = QFileDialog::getOpenFileName(0, tr("Select image"), prev_dir, QString("Images(%1)").arg(f));
|
||||
if (ret.isEmpty()) return;
|
||||
QImage im(ret);
|
||||
if (im.isNull()) return;
|
||||
prev_dir = ret;
|
||||
QRectF obr = pi->boundingRect();
|
||||
pi->setPixmap(QPixmap::fromImage(im));
|
||||
QRectF nbr = pi->boundingRect();
|
||||
QSizeF ds = (obr.size() - nbr.size()) / 2.;
|
||||
pi->setPos(pi->pos() + QPointF(ds.width(), ds.height()));
|
||||
changeFinished();
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::buttonImagePaste_clicked() {
|
||||
QGraphicsPixmapItem * pi = qgraphicsitem_cast<QGraphicsPixmapItem * >(cur_item);
|
||||
if (!pi) return;
|
||||
QPixmap pm = QApplication::clipboard()->pixmap();
|
||||
if (pm.isNull()) return;
|
||||
QRectF obr = pi->boundingRect();
|
||||
pi->setPixmap(pm);
|
||||
QRectF nbr = pi->boundingRect();
|
||||
QSizeF ds = (obr.size() - nbr.size()) / 2.;
|
||||
pi->setPos(pi->pos() + QPointF(ds.width(), ds.height()));
|
||||
changeFinished();
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::buttonFont_clicked() {
|
||||
if (!cur_item) return;
|
||||
QGraphicsSimpleTextItem * ti = qgraphicsitem_cast<QGraphicsSimpleTextItem * >(cur_item);
|
||||
AlignedTextItem * ati = qgraphicsitem_cast<AlignedTextItem * >(cur_item);
|
||||
if (!ti && !ati) return;
|
||||
QFont font_prev;
|
||||
if (ti) font_prev = ti->font();
|
||||
if (ati) font_prev = ati->font();
|
||||
font_dlg.blockSignals(true);
|
||||
font_dlg.setCurrentFont(font_prev);
|
||||
font_dlg.blockSignals(false);
|
||||
if (font_dlg.exec() == QDialog::Rejected)
|
||||
font_dlg.setCurrentFont(font_prev);
|
||||
else
|
||||
changeFinished();
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::buttonTextEdit_clicked() {
|
||||
text_dlg.setWindowIcon(QApplication::activeWindow()->windowIcon());
|
||||
text_edit.setPlainText(ui->comboText->lineEdit()->text());
|
||||
text_edit.selectAll();
|
||||
text_edit.setFocus();
|
||||
if (text_dlg.exec() == QDialog::Rejected)
|
||||
return;
|
||||
ui->comboText->lineEdit()->setText(text_edit.toPlainText());
|
||||
propertyChanged();
|
||||
changeFinished();
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::actionZ_triggered() {
|
||||
if (!cur_item) return;
|
||||
if (cur_item->data(1009) == "decor") {
|
||||
BlockView * view = 0;
|
||||
if (cur_item->scene()) if (!cur_item->scene()->views().isEmpty())
|
||||
view = qobject_cast<BlockView * >(cur_item->scene()->views()[0]);
|
||||
if (!view) return;
|
||||
QGraphicsScene * scene = view->scene();
|
||||
QList<QGraphicsItem*> dl = view->decors();
|
||||
scene->blockSignals(true);
|
||||
foreach (QGraphicsItem * d, dl) scene->removeItem(d);
|
||||
int ind = dl.indexOf(cur_item);
|
||||
dl.removeAt(ind);
|
||||
if (sender() == &actions_Z_up) dl.insert(ind + 1, cur_item);
|
||||
if (sender() == &actions_Z_top) dl.append(cur_item);
|
||||
if (sender() == &actions_Z_down) dl.insert(ind - 1, cur_item);
|
||||
if (sender() == &actions_Z_bottom) dl.prepend(cur_item);
|
||||
foreach (QGraphicsItem * d, dl) scene->addItem(d);
|
||||
scene->blockSignals(false);
|
||||
}
|
||||
if (cur_item->data(1011).toBool()) {
|
||||
BlockItem * bi = qgraphicsitem_cast<BlockItem*>(cur_item->parentItem());
|
||||
if (!bi) return;
|
||||
QList<QGraphicsItem*> dl = bi->decors_;
|
||||
foreach (QGraphicsItem * d, dl) d->setParentItem(0);
|
||||
int ind = dl.indexOf(cur_item);
|
||||
dl.removeAt(ind);
|
||||
if (sender() == &actions_Z_up) dl.insert(ind + 1, cur_item);
|
||||
if (sender() == &actions_Z_top) dl.append(cur_item);
|
||||
if (sender() == &actions_Z_down) dl.insert(ind - 1, cur_item);
|
||||
if (sender() == &actions_Z_bottom) dl.prepend(cur_item);
|
||||
bi->decors_ = dl;
|
||||
foreach (QGraphicsItem * d, dl) d->setParentItem(bi);
|
||||
}
|
||||
size_item.assignObject(cur_item);
|
||||
emitZAvailabe(cur_item);
|
||||
emit itemZChanged(cur_item);
|
||||
}
|
||||
|
||||
|
||||
void DrawTools::setResizeHandlesEnabled(bool on) {
|
||||
resize_enabled = on;
|
||||
if (!on) {
|
||||
size_item.assignObject(0);
|
||||
return;
|
||||
}
|
||||
if (cur_item && on)
|
||||
propertyChanged();
|
||||
}
|
||||
160
libs/blockview/drawtools.h
Normal file
160
libs/blockview/drawtools.h
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DRAWTOOLS_H
|
||||
#define DRAWTOOLS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QAction>
|
||||
#include <QFontDialog>
|
||||
#include <QToolButton>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QMenu>
|
||||
#include "blockview.h"
|
||||
#include "qad_blockview_export.h"
|
||||
|
||||
|
||||
class QComboBox;
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT _DTSizeItem: public QGraphicsObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
_DTSizeItem();
|
||||
~_DTSizeItem();
|
||||
|
||||
void assignObject(QGraphicsItem * item);
|
||||
|
||||
protected:
|
||||
void moveRects();
|
||||
void applyRect();
|
||||
void doubleClick();
|
||||
void resizeHandles();
|
||||
QRectF itemRect(const QGraphicsItem * item) const;
|
||||
QRectF boundingRect() const;
|
||||
void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0) {}
|
||||
bool sceneEventFilter(QGraphicsItem * watched, QEvent * event);
|
||||
|
||||
QGraphicsItem * cur_item;
|
||||
QGraphicsView * view_;
|
||||
QGraphicsRectItem rects[8];
|
||||
QPointF pp, sp;
|
||||
QRectF nrect;
|
||||
qreal grid;
|
||||
bool in_process, can_drag, is_line;
|
||||
|
||||
signals:
|
||||
void sizeChanged();
|
||||
void textEditRequest();
|
||||
void pixmapEditRequest();
|
||||
|
||||
};
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class DrawTools;
|
||||
}
|
||||
|
||||
|
||||
class QAD_BLOCKVIEW_EXPORT DrawTools: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool resizeHandlesEnabled READ isResizeHandlesEnabled WRITE setResizeHandlesEnabled)
|
||||
public:
|
||||
explicit DrawTools(BlockView * parent = 0);
|
||||
~DrawTools();
|
||||
|
||||
void setBlockView(BlockView * v);
|
||||
void resetSizeTool() {size_item.assignObject(0);}
|
||||
bool isResizeHandlesEnabled() const {return resize_enabled;}
|
||||
void setAlignCompact(bool yes);
|
||||
|
||||
QComboBox * textEditCombo() const;
|
||||
QList<QAction * > actionsForAdd() const {return actions_add;}
|
||||
QList<QAction * > actionsForZ() const {return QList<QAction * >() << &actions_Z_bottom << &actions_Z_down << &actions_Z_up << &actions_Z_top;}
|
||||
QWidget * propertyWidget() const {return widget_props;}
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject * o, QEvent * e);
|
||||
void changeEvent(QEvent * e);
|
||||
|
||||
QAction * newAction(const QIcon & icon, int type);
|
||||
void setToolButtonsEnabled(bool pen, bool brush, bool wid_hei);
|
||||
void blockPropSignals(bool block_);
|
||||
void actionAlignTrigger(bool vert, Qt::AlignmentFlag value);
|
||||
void emitZAvailabe(QGraphicsItem * item = 0);
|
||||
|
||||
QWidget * widget_props;
|
||||
Ui::DrawTools * ui;
|
||||
BlockView * view_;
|
||||
QList<QAction * > actions_add;
|
||||
mutable QAction actions_Z_up, actions_Z_top, actions_Z_down, actions_Z_bottom;
|
||||
QList<QToolButton * > buttons_align;
|
||||
QGraphicsItem * new_item, * cur_item;
|
||||
QFontDialog font_dlg;
|
||||
QPointF pp;
|
||||
QDialog text_dlg;
|
||||
QPlainTextEdit text_edit;
|
||||
QMenu menu_hor, menu_ver;
|
||||
_DTSizeItem size_item;
|
||||
Qt::Alignment align;
|
||||
int new_type;
|
||||
bool resize_enabled;
|
||||
QString prev_dir;
|
||||
|
||||
private slots:
|
||||
void toggleNewItem(bool on);
|
||||
void alignClicked();
|
||||
void selectionChanged();
|
||||
void sizeChanged();
|
||||
void propertyChanged();
|
||||
void comboLineStyleChanged();
|
||||
void changeFinished() {if (cur_item) emit itemEdited(cur_item);}
|
||||
void moveZUpAvailable(bool yes) {actions_Z_up.setEnabled(yes); actions_Z_top.setEnabled(yes);}
|
||||
void moveZDownAvailable(bool yes) {actions_Z_down.setEnabled(yes); actions_Z_bottom.setEnabled(yes);}
|
||||
|
||||
void buttonImage_clicked();
|
||||
void buttonImagePaste_clicked();
|
||||
void buttonFont_clicked();
|
||||
void buttonTextEdit_clicked();
|
||||
|
||||
void actionTop_triggered(bool on) {actionAlignTrigger(true, Qt::AlignTop);}
|
||||
void actionVCenter_triggered(bool on) {actionAlignTrigger(true, Qt::AlignVCenter);}
|
||||
void actionBottom_triggered(bool on) {actionAlignTrigger(true, Qt::AlignBottom);}
|
||||
void actionLeft_triggered(bool on) {actionAlignTrigger(false, Qt::AlignLeft);}
|
||||
void actionHCenter_triggered(bool on) {actionAlignTrigger(false, Qt::AlignHCenter);}
|
||||
void actionRight_triggered(bool on) {actionAlignTrigger(false, Qt::AlignRight);}
|
||||
void actionZ_triggered();
|
||||
|
||||
public slots:
|
||||
void setResizeHandlesEnabled(bool on);
|
||||
|
||||
signals:
|
||||
void itemCreated(QGraphicsItem * item);
|
||||
void itemAddConfirm(QGraphicsItem * item);
|
||||
void itemEdited(QGraphicsItem * item);
|
||||
void itemZChanged(QGraphicsItem * item);
|
||||
|
||||
private:
|
||||
void retranslate();
|
||||
};
|
||||
|
||||
|
||||
#endif // DRAWTOOLS_H
|
||||
821
libs/blockview/drawtools.ui
Normal file
821
libs/blockview/drawtools.ui
Normal file
@@ -0,0 +1,821 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>DrawTools</class>
|
||||
<widget class="QWidget" name="DrawTools">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1197</width>
|
||||
<height>268</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedProperties">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="pageText">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonFont">
|
||||
<property name="text">
|
||||
<string>Font ...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_blockview.qrc">
|
||||
<normaloff>:/icons/draw-text.png</normaloff>:/icons/draw-text.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Text:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboText">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<property name="maxVisibleItems">
|
||||
<number>32</number>
|
||||
</property>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::NoInsert</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonTextEdit">
|
||||
<property name="toolTip">
|
||||
<string>Edit text ...</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Edit text ...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../application/qad_application.qrc">
|
||||
<normaloff>:/icons/document-edit.png</normaloff>:/icons/document-edit.png</iconset>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonIconOnly</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetAlign2" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonAlignHor">
|
||||
<property name="text">
|
||||
<string>Align center left</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_blockview.qrc">
|
||||
<normaloff>:/icons/align-hor.png</normaloff>:/icons/align-hor.png</iconset>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::InstantPopup</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonAlignVer">
|
||||
<property name="text">
|
||||
<string>Align center left</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_blockview.qrc">
|
||||
<normaloff>:/icons/align-ver.png</normaloff>:/icons/align-ver.png</iconset>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::InstantPopup</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetAlign9" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item row="1" column="1">
|
||||
<widget class="QToolButton" name="buttonAlignCC">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Align center</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_blockview.qrc">
|
||||
<normaloff>:/icons/align-center-center.png</normaloff>:/icons/align-center-center.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>27</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QToolButton" name="buttonAlignCR">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Align center right</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_blockview.qrc">
|
||||
<normaloff>:/icons/align-center-right.png</normaloff>:/icons/align-center-right.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>27</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QToolButton" name="buttonAlignCL">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Align center left</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_blockview.qrc">
|
||||
<normaloff>:/icons/align-center-left.png</normaloff>:/icons/align-center-left.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>27</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QToolButton" name="buttonAlignTR">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Align top right</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_blockview.qrc">
|
||||
<normaloff>:/icons/align-top-right.png</normaloff>:/icons/align-top-right.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>27</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QToolButton" name="buttonAlignBR">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Align bottom right</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_blockview.qrc">
|
||||
<normaloff>:/icons/align-bottom-right.png</normaloff>:/icons/align-bottom-right.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>27</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QToolButton" name="buttonAlignBC">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Align bottom center</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_blockview.qrc">
|
||||
<normaloff>:/icons/align-bottom-center.png</normaloff>:/icons/align-bottom-center.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>27</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QToolButton" name="buttonAlignTL">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Align top left</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_blockview.qrc">
|
||||
<normaloff>:/icons/align-top-left.png</normaloff>:/icons/align-top-left.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>27</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QToolButton" name="buttonAlignTC">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Align top center</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_blockview.qrc">
|
||||
<normaloff>:/icons/align-top-center.png</normaloff>:/icons/align-top-center.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>27</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QToolButton" name="buttonAlignBL">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Align bottom left</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_blockview.qrc">
|
||||
<normaloff>:/icons/align-bottom-left.png</normaloff>:/icons/align-bottom-left.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>27</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="pageDim">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinWidth">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QDoubleSpinBox" name="spinHeight">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelWidth">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Width: </string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinThick">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelThickness">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Thickness: </string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="labelHeight">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Height:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="labelStyle">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Style:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QComboBox" name="comboLineStyle"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="pageImage">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonImage">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load image ...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../application/qad_application.qrc">
|
||||
<normaloff>:/icons/document-open.png</normaloff>:/icons/document-open.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonImagePaste">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Paste image ...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_blockview.qrc">
|
||||
<normaloff>:/icons/view-preview.png</normaloff>:/icons/view-preview.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Scale:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinScale">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="pageEmpty"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelPen">
|
||||
<property name="pixmap">
|
||||
<pixmap resource="qad_blockview.qrc">:/icons/format-stroke-color.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ColorButton" name="colorButtonPen">
|
||||
<property name="useNativeDialog">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="useAlphaChannel">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelBrush">
|
||||
<property name="pixmap">
|
||||
<pixmap resource="qad_blockview.qrc">:/icons/format-fill-color.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ColorButton" name="colorButtonBrush">
|
||||
<property name="useNativeDialog">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="useAlphaChannel">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<action name="actionTop">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Top</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionVCenter">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Center</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Center</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionBottom">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Bottom</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Bottom</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionHCenter">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Center</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Center</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionLeft">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Left</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Left</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRight">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Right</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Right</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ColorButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>colorbutton.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../application/qad_application.qrc"/>
|
||||
<include location="qad_blockview.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
384
libs/blockview/lang/qad_blockview_en.ts
Normal file
384
libs/blockview/lang/qad_blockview_en.ts
Normal file
@@ -0,0 +1,384 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="en_US">
|
||||
<context>
|
||||
<name>BlockBusItem</name>
|
||||
<message>
|
||||
<location filename="../blockbusitem.cpp" line="500"/>
|
||||
<source>Add point: Ctrl + LeftClick
|
||||
Remove point\segment: Ctrl + RightClick
|
||||
Remove connection: Shift + RightClick
|
||||
Move point\segment: Shift + LeftPress
|
||||
Change trace mode: press Shift, when mouse move</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>BlockEditor</name>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="14"/>
|
||||
<source>Block editor</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="32"/>
|
||||
<source>Block parameters</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="59"/>
|
||||
<source>Width:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="79"/>
|
||||
<source>Heigth:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="99"/>
|
||||
<source>Pins margin:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="119"/>
|
||||
<source>Color:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="130"/>
|
||||
<source>Pins</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="179"/>
|
||||
<source>Name</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="184"/>
|
||||
<source>Bus</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="194"/>
|
||||
<source>Add</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="205"/>
|
||||
<source>Clone</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="232"/>
|
||||
<source>Remove selected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="243"/>
|
||||
<source>Remove all</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="346"/>
|
||||
<source>Save</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="353"/>
|
||||
<location filename="../blockeditor.ui" line="383"/>
|
||||
<source>Ctrl+S</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="376"/>
|
||||
<source>Save as ...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="406"/>
|
||||
<source>Load ...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="413"/>
|
||||
<source>Ctrl+O</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="433"/>
|
||||
<source>Clear</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="450"/>
|
||||
<source>Remove items</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="453"/>
|
||||
<source>Del</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DrawTools</name>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="14"/>
|
||||
<source>Form</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="51"/>
|
||||
<source>Font ...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="62"/>
|
||||
<source>Text:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="91"/>
|
||||
<location filename="../drawtools.ui" line="94"/>
|
||||
<source>Edit text ...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="123"/>
|
||||
<location filename="../drawtools.ui" line="137"/>
|
||||
<location filename="../drawtools.ui" line="230"/>
|
||||
<source>Align center left</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="178"/>
|
||||
<source>Align center</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="204"/>
|
||||
<source>Align center right</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="256"/>
|
||||
<source>Align top right</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="282"/>
|
||||
<source>Align bottom right</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="308"/>
|
||||
<source>Align bottom center</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="334"/>
|
||||
<source>Align top left</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="360"/>
|
||||
<source>Align top center</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="386"/>
|
||||
<source>Align bottom left</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="471"/>
|
||||
<source>Width: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="506"/>
|
||||
<source>Thickness: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="522"/>
|
||||
<source>Height:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="538"/>
|
||||
<source>Style:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="591"/>
|
||||
<source>Load image ...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="608"/>
|
||||
<source>Paste image ...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="641"/>
|
||||
<source>Scale:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="750"/>
|
||||
<source>Top</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="758"/>
|
||||
<location filename="../drawtools.ui" line="761"/>
|
||||
<location filename="../drawtools.ui" line="780"/>
|
||||
<location filename="../drawtools.ui" line="783"/>
|
||||
<source>Center</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="769"/>
|
||||
<location filename="../drawtools.ui" line="772"/>
|
||||
<source>Bottom</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="791"/>
|
||||
<location filename="../drawtools.ui" line="794"/>
|
||||
<source>Left</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="802"/>
|
||||
<location filename="../drawtools.ui" line="805"/>
|
||||
<source>Right</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="333"/>
|
||||
<source>NoPen</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="333"/>
|
||||
<source>Solid</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="333"/>
|
||||
<source>Dash</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="334"/>
|
||||
<source>Dot</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="334"/>
|
||||
<source>Dash-Dot</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="334"/>
|
||||
<source>Dash-Dot-Dot</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="336"/>
|
||||
<source>Edit text</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="337"/>
|
||||
<source>Bring
|
||||
forward</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="338"/>
|
||||
<source>Bring
|
||||
to front</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="339"/>
|
||||
<source>Send
|
||||
backward</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="340"/>
|
||||
<source>Send
|
||||
to back</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="341"/>
|
||||
<source>Draw
|
||||
Rectangle</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="342"/>
|
||||
<source>Draw
|
||||
Ellipse</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="343"/>
|
||||
<source>Draw
|
||||
Line</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="344"/>
|
||||
<source>Draw
|
||||
Text</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="345"/>
|
||||
<source>Draw
|
||||
Image</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="837"/>
|
||||
<source>Select image</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PinAlignDelegate</name>
|
||||
<message>
|
||||
<location filename="../blockeditor.cpp" line="356"/>
|
||||
<source>Left</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.cpp" line="357"/>
|
||||
<source>Right</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.cpp" line="358"/>
|
||||
<source>Top</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.cpp" line="359"/>
|
||||
<source>Bottom</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.cpp" line="361"/>
|
||||
<source>unknown</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
422
libs/blockview/lang/qad_blockview_ru.ts
Normal file
422
libs/blockview/lang/qad_blockview_ru.ts
Normal file
@@ -0,0 +1,422 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="ru_RU">
|
||||
<context>
|
||||
<name>BlockBusItem</name>
|
||||
<message>
|
||||
<source>Add point: Ctrl + LeftClick
|
||||
Remove point\segment: Ctrl + RightClick
|
||||
New branch: Shift + LeftClick
|
||||
Remove connection: Shift + RightClick</source>
|
||||
<translation type="vanished">Добавить точку: Ctrl + LeftClick
|
||||
Удалить точку\сегмент: Ctrl + RightClick
|
||||
Новая ветка: Shift + LeftClick
|
||||
Удалить шину: Shift + RightClick</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Add point: Ctrl + LeftClick
|
||||
Remove point\segment: Ctrl + RightClick
|
||||
Remove connection: Shift + RightClick
|
||||
Move point\segment: Shift + mouse move
|
||||
Change trace mode: press Shift, when mouse move</source>
|
||||
<translation type="obsolete">Добавить точку: Ctrl + LeftClick
|
||||
Удалить точку\сегмент: Ctrl + RightClick
|
||||
Удалить шину: Shift + RightClick
|
||||
Переместить точку\сегмент: Shift + двига</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockbusitem.cpp" line="500"/>
|
||||
<source>Add point: Ctrl + LeftClick
|
||||
Remove point\segment: Ctrl + RightClick
|
||||
Remove connection: Shift + RightClick
|
||||
Move point\segment: Shift + LeftPress
|
||||
Change trace mode: press Shift, when mouse move</source>
|
||||
<translation>Добавить точку: Ctrl + LeftClick
|
||||
Удалить точку\сегмент: Ctrl + RightClick
|
||||
Удалить шину: Shift + RightClick
|
||||
Переместить точку\сегмент: Shift + LeftPress
|
||||
Поменять режим трассировки: нажать Shift, во время перемещения мыши</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>BlockEditor</name>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="14"/>
|
||||
<source>Block editor</source>
|
||||
<translation>Редактор блока</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="32"/>
|
||||
<source>Block parameters</source>
|
||||
<translation>Параметры блока</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="59"/>
|
||||
<source>Width:</source>
|
||||
<translation>Ширина:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="79"/>
|
||||
<source>Heigth:</source>
|
||||
<translation>Высота:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="99"/>
|
||||
<source>Pins margin:</source>
|
||||
<translation>Поля пина:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="119"/>
|
||||
<source>Color:</source>
|
||||
<translation>Цвет:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="130"/>
|
||||
<source>Pins</source>
|
||||
<translation>Пины</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="179"/>
|
||||
<source>Name</source>
|
||||
<translation>Имя</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="184"/>
|
||||
<source>Bus</source>
|
||||
<translation>Шина</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="194"/>
|
||||
<source>Add</source>
|
||||
<translation>Добавить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="205"/>
|
||||
<source>Clone</source>
|
||||
<translation>Клонировать</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="232"/>
|
||||
<source>Remove selected</source>
|
||||
<translation>Удалить выбранные</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="243"/>
|
||||
<source>Remove all</source>
|
||||
<translation>Удалить все</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="346"/>
|
||||
<source>Save</source>
|
||||
<translation>Сохранить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="353"/>
|
||||
<location filename="../blockeditor.ui" line="383"/>
|
||||
<source>Ctrl+S</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="376"/>
|
||||
<source>Save as ...</source>
|
||||
<translation>Сохранить как ...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="406"/>
|
||||
<source>Load ...</source>
|
||||
<translation>Открыть ...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="413"/>
|
||||
<source>Ctrl+O</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="433"/>
|
||||
<source>Clear</source>
|
||||
<translation>Очистить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="450"/>
|
||||
<source>Remove items</source>
|
||||
<translation>Удалить элементы</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.ui" line="453"/>
|
||||
<source>Del</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>DrawTools</name>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="14"/>
|
||||
<source>Form</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="51"/>
|
||||
<source>Font ...</source>
|
||||
<translation>Шрифт ...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="62"/>
|
||||
<source>Text:</source>
|
||||
<translation>Текст:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="91"/>
|
||||
<location filename="../drawtools.ui" line="94"/>
|
||||
<source>Edit text ...</source>
|
||||
<translation>Изменить текст ...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="123"/>
|
||||
<location filename="../drawtools.ui" line="137"/>
|
||||
<location filename="../drawtools.ui" line="230"/>
|
||||
<source>Align center left</source>
|
||||
<translation>Выравнивание слева по центру</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="178"/>
|
||||
<source>Align center</source>
|
||||
<translation>Выравнивание по центру</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="204"/>
|
||||
<source>Align center right</source>
|
||||
<translation>Выравнивание справа по центру</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="256"/>
|
||||
<source>Align top right</source>
|
||||
<translation>Выравнивание справа сверху</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="282"/>
|
||||
<source>Align bottom right</source>
|
||||
<translation>Выравнивание справа снизу</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="308"/>
|
||||
<source>Align bottom center</source>
|
||||
<translation>Выравнивание снизу по центру</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="334"/>
|
||||
<source>Align top left</source>
|
||||
<translation>Выравнивание слева сверху</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="360"/>
|
||||
<source>Align top center</source>
|
||||
<translation>Выравнивание сверху по центру</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="386"/>
|
||||
<source>Align bottom left</source>
|
||||
<translation>Выравнивание снизу слева</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Size: </source>
|
||||
<translation type="vanished">Размер: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="471"/>
|
||||
<source>Width: </source>
|
||||
<translation>Ширина: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="506"/>
|
||||
<source>Thickness: </source>
|
||||
<translation>Толщина: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="522"/>
|
||||
<source>Height:</source>
|
||||
<translation>Высота:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="538"/>
|
||||
<source>Style:</source>
|
||||
<translation>Стиль:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="591"/>
|
||||
<source>Load image ...</source>
|
||||
<translation>Загрузить картинку ...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="608"/>
|
||||
<source>Paste image ...</source>
|
||||
<translation>Вставить картинку ...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="641"/>
|
||||
<source>Scale:</source>
|
||||
<translation>Масштаб:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="750"/>
|
||||
<source>Top</source>
|
||||
<translation>Верх</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="758"/>
|
||||
<location filename="../drawtools.ui" line="761"/>
|
||||
<location filename="../drawtools.ui" line="780"/>
|
||||
<location filename="../drawtools.ui" line="783"/>
|
||||
<source>Center</source>
|
||||
<translation>Центр</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="769"/>
|
||||
<location filename="../drawtools.ui" line="772"/>
|
||||
<source>Bottom</source>
|
||||
<translation>Низ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="791"/>
|
||||
<location filename="../drawtools.ui" line="794"/>
|
||||
<source>Left</source>
|
||||
<translation>Лево</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.ui" line="802"/>
|
||||
<location filename="../drawtools.ui" line="805"/>
|
||||
<source>Right</source>
|
||||
<translation>Право</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="333"/>
|
||||
<source>NoPen</source>
|
||||
<translation>НетЛинии</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="333"/>
|
||||
<source>Solid</source>
|
||||
<translation>Сплошная</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="333"/>
|
||||
<source>Dash</source>
|
||||
<translation>Штриховая</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="334"/>
|
||||
<source>Dot</source>
|
||||
<translation>Пунктирная</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="334"/>
|
||||
<source>Dash-Dot</source>
|
||||
<translation>ШтрихПунктирная</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="334"/>
|
||||
<source>Dash-Dot-Dot</source>
|
||||
<translation>ШтрихПунктирПунктирная</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="336"/>
|
||||
<source>Edit text</source>
|
||||
<translation>Редактировать текст</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="337"/>
|
||||
<source>Bring
|
||||
forward</source>
|
||||
<translation>Переместить
|
||||
выше</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="338"/>
|
||||
<source>Bring
|
||||
to front</source>
|
||||
<translation>На передний
|
||||
фон</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="339"/>
|
||||
<source>Send
|
||||
backward</source>
|
||||
<translation>Переместить
|
||||
ниже</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="340"/>
|
||||
<source>Send
|
||||
to back</source>
|
||||
<translation>На задний
|
||||
фон</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="341"/>
|
||||
<source>Draw
|
||||
Rectangle</source>
|
||||
<translation>Нарисовать
|
||||
прямоугольник</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="342"/>
|
||||
<source>Draw
|
||||
Ellipse</source>
|
||||
<translation>Нарисовать
|
||||
эллипс</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="343"/>
|
||||
<source>Draw
|
||||
Line</source>
|
||||
<translation>Нарисовать
|
||||
линию</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="344"/>
|
||||
<source>Draw
|
||||
Text</source>
|
||||
<translation>Нарисовать
|
||||
текст</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="345"/>
|
||||
<source>Draw
|
||||
Image</source>
|
||||
<translation>Нарисовать
|
||||
картинку</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../drawtools.cpp" line="837"/>
|
||||
<source>Select image</source>
|
||||
<translation>Выбрать картинку</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PinAlignDelegate</name>
|
||||
<message>
|
||||
<location filename="../blockeditor.cpp" line="356"/>
|
||||
<source>Left</source>
|
||||
<translation>Лево</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.cpp" line="357"/>
|
||||
<source>Right</source>
|
||||
<translation>Право</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.cpp" line="358"/>
|
||||
<source>Top</source>
|
||||
<translation>Верх</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.cpp" line="359"/>
|
||||
<source>Bottom</source>
|
||||
<translation>Низ</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../blockeditor.cpp" line="361"/>
|
||||
<source>unknown</source>
|
||||
<translation>неизвестно</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
2
libs/blockview/lang/update.bat
Normal file
2
libs/blockview/lang/update.bat
Normal file
@@ -0,0 +1,2 @@
|
||||
lupdate ../ -ts qad_blockview_ru.ts
|
||||
lupdate ../ -ts qad_blockview_en.ts
|
||||
1
libs/blockview/plugin/CMakeLists.txt
Normal file
1
libs/blockview/plugin/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
qad_plugin(blockview "Gui;Widgets" "")
|
||||
69
libs/blockview/plugin/blockviewplugin.cpp
Normal file
69
libs/blockview/plugin/blockviewplugin.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "blockview.h"
|
||||
#include "blockviewplugin.h"
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
|
||||
BlockViewPlugin::BlockViewPlugin(QObject * parent): QObject(parent) {
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
|
||||
void BlockViewPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
|
||||
if (m_initialized)
|
||||
return;
|
||||
|
||||
// Add extension registrations, etc. here
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
|
||||
bool BlockViewPlugin::isInitialized() const {
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
|
||||
QWidget * BlockViewPlugin::createWidget(QWidget * parent) {
|
||||
return new BlockView(parent);
|
||||
}
|
||||
|
||||
|
||||
QString BlockViewPlugin::name() const {
|
||||
return QLatin1String("BlockView");
|
||||
}
|
||||
|
||||
|
||||
QString BlockViewPlugin::group() const {
|
||||
return QLatin1String("Display Widgets");
|
||||
}
|
||||
|
||||
|
||||
QIcon BlockViewPlugin::icon() const {
|
||||
return QIcon(":/icons/blockview.png");
|
||||
}
|
||||
|
||||
|
||||
QString BlockViewPlugin::toolTip() const {
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
|
||||
QString BlockViewPlugin::whatsThis() const {
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
|
||||
bool BlockViewPlugin::isContainer() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QString BlockViewPlugin::domXml() const {
|
||||
return QLatin1String("<widget class=\"BlockView\" name=\"blockView\">\n</widget>\n");
|
||||
}
|
||||
|
||||
|
||||
QString BlockViewPlugin::includeFile() const {
|
||||
return QLatin1String("blockview.h");
|
||||
}
|
||||
|
||||
36
libs/blockview/plugin/blockviewplugin.h
Normal file
36
libs/blockview/plugin/blockviewplugin.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef BLOCKVIEWPLUGIN_H
|
||||
#define BLOCKVIEWPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#if QT_VERSION >= 0x050000
|
||||
# include <QtUiPlugin/QDesignerCustomWidgetInterface>
|
||||
#else
|
||||
# include <QDesignerCustomWidgetInterface>
|
||||
#endif
|
||||
|
||||
class BlockViewPlugin: public QObject, public QDesignerCustomWidgetInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||
|
||||
public:
|
||||
BlockViewPlugin(QObject * parent = 0);
|
||||
|
||||
bool isContainer() const;
|
||||
bool isInitialized() const;
|
||||
QIcon icon() const;
|
||||
QString domXml() const;
|
||||
QString group() const;
|
||||
QString includeFile() const;
|
||||
QString name() const;
|
||||
QString toolTip() const;
|
||||
QString whatsThis() const;
|
||||
QWidget * createWidget(QWidget * parent);
|
||||
void initialize(QDesignerFormEditorInterface * core);
|
||||
|
||||
private:
|
||||
bool m_initialized;
|
||||
|
||||
};
|
||||
|
||||
#endif // BLOCKVIEWPLUGIN_H
|
||||
17
libs/blockview/plugin/qad_blockview.cpp
Normal file
17
libs/blockview/plugin/qad_blockview.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "qad_blockview.h"
|
||||
#include "blockviewplugin.h"
|
||||
|
||||
QADBlockView::QADBlockView(QObject * parent): QObject(parent)
|
||||
{
|
||||
m_widgets.append(new BlockViewPlugin(this));
|
||||
}
|
||||
|
||||
|
||||
QList<QDesignerCustomWidgetInterface * > QADBlockView::customWidgets() const {
|
||||
return m_widgets;
|
||||
}
|
||||
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
Q_EXPORT_PLUGIN2(qad_graphic_plugin, QADBlockView)
|
||||
#endif
|
||||
23
libs/blockview/plugin/qad_blockview.h
Normal file
23
libs/blockview/plugin/qad_blockview.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef QAD_BLOCKVIEW_H
|
||||
#define QAD_BLOCKVIEW_H
|
||||
|
||||
#include <QtDesigner/QtDesigner>
|
||||
#include <QtCore/qplugin.h>
|
||||
|
||||
class QADBlockView: public QObject, public QDesignerCustomWidgetCollectionInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
|
||||
#if QT_VERSION >= 0x050000
|
||||
Q_PLUGIN_METADATA(IID "qad.blockview")
|
||||
#endif
|
||||
public:
|
||||
explicit QADBlockView(QObject * parent = 0);
|
||||
virtual QList<QDesignerCustomWidgetInterface * > customWidgets() const;
|
||||
|
||||
private:
|
||||
QList<QDesignerCustomWidgetInterface * > m_widgets;
|
||||
|
||||
};
|
||||
|
||||
#endif // QAD_BLOCKVIEW_H
|
||||
51
libs/blockview/qad_blockview.qrc
Normal file
51
libs/blockview/qad_blockview.qrc
Normal file
@@ -0,0 +1,51 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>../../icons/draw-line.png</file>
|
||||
<file>../../icons/align-hor.png</file>
|
||||
<file>../../icons/align-ver.png</file>
|
||||
<file>../../icons/dialog-close.png</file>
|
||||
<file>../../icons/edit-clear.png</file>
|
||||
<file>../../icons/edit-guides.png</file>
|
||||
<file>../../icons/view-grid.png</file>
|
||||
<file>../../icons/zoom-fit-best.png</file>
|
||||
<file>../../icons/configure.png</file>
|
||||
<file>../../icons/document-save.png</file>
|
||||
<file>../../icons/edit-clear-locationbar-rtl.png</file>
|
||||
<file>../../icons/edit-find.png</file>
|
||||
<file>../../icons/list-add.png</file>
|
||||
<file>../../icons/edit-delete.png</file>
|
||||
<file>../../icons/item.png</file>
|
||||
<file>../../icons/node-add.png</file>
|
||||
<file>../../icons/node.png</file>
|
||||
<file>../../icons/edit-copy.png</file>
|
||||
<file>../../icons/edit-paste.png</file>
|
||||
<file>../../icons/expand_s_x.png</file>
|
||||
<file>../../icons/expand_s_y.png</file>
|
||||
<file>../../icons/expand_x.png</file>
|
||||
<file>../../icons/expand_y.png</file>
|
||||
<file>../../icons/border-line.png</file>
|
||||
<file>../../icons/legend.png</file>
|
||||
<file>../../icons/blockview.png</file>
|
||||
<file>../../icons/view-fullscreen.png</file>
|
||||
<file>../../icons/draw-ellipse.png</file>
|
||||
<file>../../icons/draw-rectangle.png</file>
|
||||
<file>../../icons/draw-text.png</file>
|
||||
<file>../../icons/view-preview.png</file>
|
||||
<file>../../icons/format-fill-color.png</file>
|
||||
<file>../../icons/format-stroke-color.png</file>
|
||||
<file>../../icons/document-open.png</file>
|
||||
<file>../../icons/align-bottom-center.png</file>
|
||||
<file>../../icons/align-bottom-left.png</file>
|
||||
<file>../../icons/align-bottom-right.png</file>
|
||||
<file>../../icons/align-center-center.png</file>
|
||||
<file>../../icons/align-center-left.png</file>
|
||||
<file>../../icons/align-center-right.png</file>
|
||||
<file>../../icons/align-top-center.png</file>
|
||||
<file>../../icons/align-top-left.png</file>
|
||||
<file>../../icons/align-top-right.png</file>
|
||||
<file>../../icons/z-bottom.png</file>
|
||||
<file>../../icons/z-down.png</file>
|
||||
<file>../../icons/z-top.png</file>
|
||||
<file>../../icons/z-up.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
27
libs/doc/CMakeLists.txt
Normal file
27
libs/doc/CMakeLists.txt
Normal file
@@ -0,0 +1,27 @@
|
||||
include(CheckIncludeFileCXX)
|
||||
set(CHECK_INCLUDES "-include stdio.h")
|
||||
if(WIN32)
|
||||
set(CHECK_INCLUDES "-include windows.h -include stdio.h")
|
||||
endif()
|
||||
set(_mkd_header_found 0)
|
||||
check_include_file_cxx("mkdio.h" MARKDOWN_HEADER_MKDIO ${CHECK_INCLUDES})
|
||||
if (MARKDOWN_HEADER_MKDIO OR APPLE)
|
||||
set(_mkd_header_found 1)
|
||||
add_definitions("-DMARKDOWN_HEADER=\"mkdio.h\"")
|
||||
else()
|
||||
check_include_file_cxx("markdown/markdown.h" MARKDOWN_HEADER_MARKDOWN ${CHECK_INCLUDES})
|
||||
if (MARKDOWN_HEADER_MARKDOWN)
|
||||
set(_mkd_header_found 1)
|
||||
add_definitions("-DMARKDOWN_HEADER=\"markdown/markdown.h\"")
|
||||
endif()
|
||||
endif()
|
||||
find_library(MARKDOWN_LIBRARY markdown)
|
||||
if (MARKDOWN_LIBRARY)
|
||||
qad_library(doc "Core" "${MARKDOWN_LIBRARY}")
|
||||
if(NOT _mkd_header_found)
|
||||
message(STATUS "Found markdown library, but *.h missing!")
|
||||
endif()
|
||||
else()
|
||||
add_definitions("-DNO_MARKDOWN")
|
||||
qad_library(doc "Core" "")
|
||||
endif()
|
||||
87
libs/doc/markdown.cpp
Normal file
87
libs/doc/markdown.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "markdown.h"
|
||||
#include <QDebug>
|
||||
#ifndef NO_MARKDOWN
|
||||
extern "C" {
|
||||
#include MARKDOWN_HEADER
|
||||
}
|
||||
#ifndef mkd_flags_are
|
||||
# ifndef MKD_DLEXTRA
|
||||
# define MKD_DLEXTRA 0x01000000
|
||||
# endif
|
||||
# ifndef MKD_FENCEDCODE
|
||||
# define MKD_FENCEDCODE 0x02000000
|
||||
# endif
|
||||
# ifndef MKD_EXTRA_FOOTNOTE
|
||||
# define MKD_EXTRA_FOOTNOTE 0x00200000
|
||||
# endif
|
||||
# ifndef MKD_TOC
|
||||
# define MKD_TOC 0x00001000
|
||||
# endif
|
||||
# ifndef MKD_AUTOLINK
|
||||
# define MKD_AUTOLINK 0x00004000
|
||||
# endif
|
||||
# ifndef MKD_GITHUBTAGS
|
||||
# define MKD_GITHUBTAGS 0x08000000
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static QString markdown_css = "table { margin: 5px; background-color: #cccccc; }"
|
||||
"table tr { background-color: white; }"
|
||||
"table td { vertical-align: middle; padding: 5px;}"
|
||||
"table th { padding: 5px; };"
|
||||
;
|
||||
|
||||
QString md2html(const QByteArray & src) {
|
||||
static bool _is_mkd_init = false;
|
||||
if (src.isEmpty()) return QString();
|
||||
if (!_is_mkd_init) {
|
||||
_is_mkd_init = true;
|
||||
mkd_initialize();
|
||||
}
|
||||
#ifdef _MARKDOWN_D
|
||||
DWORD flagm = (MKD_DLEXTRA | MKD_FENCEDCODE);
|
||||
Document
|
||||
#endif
|
||||
#ifdef _MKDIO_D
|
||||
#ifdef mkd_flags_are
|
||||
mkd_flag_t * flagm = mkd_flags();
|
||||
mkd_set_flag_num(flagm, MKD_DLEXTRA);
|
||||
mkd_set_flag_num(flagm, MKD_FENCEDCODE);
|
||||
#else
|
||||
mkd_flag_t flagm = (MKD_DLEXTRA | MKD_FENCEDCODE | MKD_GITHUBTAGS | MKD_AUTOLINK);
|
||||
#endif
|
||||
MMIOT
|
||||
#endif
|
||||
* doc = mkd_string(src.constData(), src.size(), 0);
|
||||
if (!doc) return QString();
|
||||
mkd_compile(doc, flagm);
|
||||
char * html = 0;
|
||||
int len = mkd_document(doc, &html);
|
||||
if (!html) {
|
||||
mkd_cleanup(doc);
|
||||
return QString();
|
||||
}
|
||||
QString ret = QString::fromUtf8(html, len);
|
||||
mkd_cleanup(doc);
|
||||
QString title = QTextStream(&ret, QIODevice::ReadOnly).readLine();
|
||||
title = title.mid(title.indexOf(">")+1);
|
||||
title = title.left(title.indexOf("<"));
|
||||
QString header = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
|
||||
"<html>\n<head>\n"
|
||||
"<meta name=\"qrichtext\" content=\"1\" />\n"
|
||||
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
|
||||
header.append("<title>" + title + "</title>\n");
|
||||
header.append("<style>" + markdown_css + "</style>\n");
|
||||
header.append("</head>\n<body>\n");
|
||||
ret.prepend(header);
|
||||
ret.append("</body>\n</html>\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
QString md2html(const QByteArray & src) {
|
||||
return src;
|
||||
}
|
||||
|
||||
#endif
|
||||
30
libs/doc/markdown.h
Normal file
30
libs/doc/markdown.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QAD_MARKDOWN_H
|
||||
#define QAD_MARKDOWN_H
|
||||
|
||||
#include <QString>
|
||||
#include "qad_doc_export.h"
|
||||
|
||||
|
||||
QAD_DOC_EXPORT QString md2html(const QByteArray & src);
|
||||
|
||||
|
||||
#endif // QAD_MARKDOWN_H
|
||||
1
libs/graphic/CMakeLists.txt
Normal file
1
libs/graphic/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
qad_library(graphic "Gui;Widgets;OpenGL" "qad_widgets;qad_utils;${OPENGL_LIBRARIES}")
|
||||
1745
libs/graphic/graphic.cpp
Normal file
1745
libs/graphic/graphic.cpp
Normal file
@@ -0,0 +1,1745 @@
|
||||
#include "graphic.h"
|
||||
#include "qad_types.h"
|
||||
#include "uglwidget.h"
|
||||
#include "ui_graphic.h"
|
||||
#include "ui_graphic_conf.h"
|
||||
#include <QMetaObject>
|
||||
#include <QMessageBox>
|
||||
#include <QTapAndHoldGesture>
|
||||
#include <QPanGesture>
|
||||
#include <QPinchGesture>
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||
# include <QRandomGenerator>
|
||||
#endif
|
||||
#ifndef Q_OS_ANDROID
|
||||
# define HAS_GL
|
||||
#endif
|
||||
#ifdef HAS_GL
|
||||
# ifndef GL_MULTISAMPLE
|
||||
# define GL_MULTISAMPLE 0x809D
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
__GraphicRegistrator__ __graphic_registrator__;
|
||||
|
||||
|
||||
Graphic::Graphic(QWidget * parent): QFrame(parent), canvas(0), line_x_min(this), line_x_max(this), line_y_min(this), line_y_max(this) {
|
||||
canvas_gl = 0;
|
||||
gesture_angle = 45.;
|
||||
leg_update = true;
|
||||
visible_update = fullscr = need_mouse_pan = false;
|
||||
gestures =
|
||||
#ifdef Q_OS_ANDROID
|
||||
true;
|
||||
#else
|
||||
false;
|
||||
#endif
|
||||
ui = new Ui::Graphic();
|
||||
ui->setupUi(this);
|
||||
line_x_min.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
line_x_max.setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
((QBoxLayout * )ui->widgetLY->layout())->insertWidget(0, &line_y_min);
|
||||
((QBoxLayout * )ui->widgetLY->layout())->addWidget(&line_y_max);
|
||||
((QBoxLayout * )ui->widgetLX->layout())->insertWidget(0, &line_x_min);
|
||||
((QBoxLayout * )ui->widgetLX->layout())->addWidget(&line_x_max);
|
||||
tm.restart();
|
||||
grid_numbers_x = grid_numbers_y = 1;
|
||||
LN10 = qLn(10.);
|
||||
line_x_min.setClearButtonVisible(true);
|
||||
line_x_max.setClearButtonVisible(true);
|
||||
line_y_min.setClearButtonVisible(true);
|
||||
line_y_max.setClearButtonVisible(true);
|
||||
connect(&line_x_min, SIGNAL(valueChanged(double)), this, SLOT(lineXMinChanged(double)));
|
||||
connect(&line_x_max, SIGNAL(valueChanged(double)), this, SLOT(lineXMaxChanged(double)));
|
||||
connect(&line_y_min, SIGNAL(valueChanged(double)), this, SLOT(lineYMinChanged(double)));
|
||||
connect(&line_y_max, SIGNAL(valueChanged(double)), this, SLOT(lineYMaxChanged(double)));
|
||||
connect(ui->canvas_raster, SIGNAL(paintEvent(QPaintEvent * )), this, SLOT(canvasPaintEvent()));
|
||||
prepareCanvas(ui->canvas_raster);
|
||||
#ifdef HAS_GL
|
||||
canvas_gl = new UGLWidget();
|
||||
ui->layoutCanvas->addWidget(canvas_gl);
|
||||
connect(canvas_gl, SIGNAL(paintSignal()), this, SLOT(canvasPaintEvent()));
|
||||
prepareCanvas(canvas_gl);
|
||||
#endif
|
||||
icon_exp_x = QIcon(":/icons/expand_x.png");
|
||||
icon_exp_y = QIcon(":/icons/expand_y.png");
|
||||
icon_exp_sx = QIcon(":/icons/expand_s_x.png");
|
||||
icon_exp_sy = QIcon(":/icons/expand_s_y.png");
|
||||
icon_pause_b = QImage(":/icons/pause-back.png");
|
||||
icon_pause_f = QImage(":/icons/pause-front.png");
|
||||
aupdate = grid = isFit = navigation = true;
|
||||
aalias = bufferActive = isOGL = cancel = guides = hasLblX = hasLblY = isHover = false;
|
||||
pause_ = only_expand_x = only_expand_y = false;
|
||||
limit_.setCoords(-DBL_MAX, -DBL_MAX, DBL_MAX, DBL_MAX);
|
||||
eminx = eminy = DBL_MAX;
|
||||
emaxx = emaxy = DBL_MIN;
|
||||
grad_x = grad_y = Auto;
|
||||
axis_type_x = Numeric;
|
||||
min_repaint_int = 25;
|
||||
inc_x = 1.;
|
||||
buffer = 0;
|
||||
gridx = gridy = 1.;
|
||||
history = 5.;
|
||||
visible_time = -1.;
|
||||
thick = lineThickness();
|
||||
pause_phase = 0.;
|
||||
def_rect.setRect(0., 0., 1., 1.);
|
||||
selrect = def_rect;
|
||||
margins_.setRect(4, 4, 4, 4);
|
||||
curaction = gaMove;
|
||||
selbrush.setStyle(Qt::SolidPattern);
|
||||
selbrush.setColor(QColor(60, 175, 255, 100));
|
||||
text_color = palette().color(QPalette::WindowText);
|
||||
grid_pen = QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 0., Qt::DotLine);
|
||||
graphics.append(GraphicType());
|
||||
curGraphic = 0;
|
||||
selpen = palette().color(QPalette::WindowText);
|
||||
selpen.setStyle(Qt::DashLine);
|
||||
back_color = palette().color(QPalette::Base);
|
||||
buttons_ = AllButtons;
|
||||
setOpenGL(false);
|
||||
setButtonsPosition(Graphic::Left);
|
||||
setAntialiasing(false);
|
||||
setCaption("");
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
ui->layoutButtons->update();
|
||||
updateLegend();
|
||||
setRectToLines();
|
||||
conf = new GraphicConf(graphics, this);
|
||||
}
|
||||
|
||||
|
||||
Graphic::~Graphic() {
|
||||
delete conf;
|
||||
if (buffer != 0) delete buffer;
|
||||
}
|
||||
|
||||
|
||||
void Graphic::changeEvent(QEvent * e) {
|
||||
QFrame::changeEvent(e);
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
ui->retranslateUi(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Graphic::resizeEvent(QResizeEvent *) {
|
||||
if (leg_update) updateLegend(false);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::timerEvent(QTimerEvent * ) {
|
||||
pause_phase += 0.02;
|
||||
if (pause_phase > 1.)
|
||||
pause_phase -= 1.;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
bool Graphic::eventFilter(QObject * o, QEvent * e) {
|
||||
if (o == canvas) {
|
||||
switch (e->type()) {
|
||||
case QEvent::Gesture:
|
||||
if (!navigation || !gestures) break;
|
||||
foreach (QGesture * g, ((QGestureEvent*)e)->gestures())
|
||||
procGesture(g);
|
||||
break;
|
||||
case QEvent::KeyPress: {
|
||||
int k = ((QKeyEvent*)e)->key();
|
||||
if ((k == Qt::Key_Back || k == Qt::Key_Escape) && fullscr) {
|
||||
leaveFullscreen();
|
||||
return true;
|
||||
}
|
||||
} break;
|
||||
case QEvent::TouchBegin:
|
||||
if (!navigation || !gestures) break;
|
||||
need_mouse_pan = true;
|
||||
break;
|
||||
case QEvent::TouchUpdate: {
|
||||
if (!navigation || !gestures) break;
|
||||
QList<QTouchEvent::TouchPoint> tpl = ((QTouchEvent*)e)->touchPoints();
|
||||
if (tpl.size() == 2) {
|
||||
need_mouse_pan = false;
|
||||
QPointF dp = tpl[0].scenePos() - tpl[1].scenePos();
|
||||
gesture_angle = rad2deg_qpie * qAtan2(qAbs(dp.y()), qAbs(dp.x()));
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
return QFrame::eventFilter(o, e);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::prepareCanvas(QWidget * w) {
|
||||
connect(w, SIGNAL(mouseMoveEvent(QMouseEvent * )), this, SLOT(canvasMouseMoveEvent(QMouseEvent * )));
|
||||
connect(w, SIGNAL(mousePressEvent(QMouseEvent * )), this, SLOT(canvasMousePressEvent(QMouseEvent * )));
|
||||
connect(w, SIGNAL(mouseReleaseEvent(QMouseEvent * )), this, SLOT(canvasMouseReleaseEvent(QMouseEvent * )));
|
||||
connect(w, SIGNAL(mouseDoubleClickEvent(QMouseEvent*)), this, SLOT(canvasMouseDoubleClickEvent(QMouseEvent * )));
|
||||
connect(w, SIGNAL(wheelEvent(QWheelEvent * )), this, SLOT(canvasWheelEvent(QWheelEvent * )));
|
||||
connect(w, SIGNAL(leaveEvent(QEvent * )), this, SLOT(canvasLeaveEvent(QEvent * )));
|
||||
connect(w, SIGNAL(keyPressEvent(QKeyEvent * )), this, SLOT(canvasKeyPressEvent(QKeyEvent * )));
|
||||
w->grabGesture(Qt::TapAndHoldGesture);
|
||||
w->grabGesture(Qt::PanGesture);
|
||||
w->grabGesture(Qt::PinchGesture);
|
||||
w->setMouseTracking(true);
|
||||
w->installEventFilter(this);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::procGesture(QGesture * g) {
|
||||
if (!g) return;
|
||||
switch (g->gestureType()) {
|
||||
case Qt::PanGesture: {
|
||||
if (need_mouse_pan) break;
|
||||
QPanGesture * pg = (QPanGesture*)g;
|
||||
QPointF dp = -pg->delta();
|
||||
dp.rx() /= getScaleX();
|
||||
dp.ry() /= getScaleY();
|
||||
selrect.translate(dp);
|
||||
totalUpdate();
|
||||
} break;
|
||||
case Qt::PinchGesture: {
|
||||
QPinchGesture * pg = (QPinchGesture*)g;
|
||||
Qt::KeyboardModifiers km = Qt::NoModifier;
|
||||
if (gesture_angle <= 20.) km = Qt::ControlModifier;
|
||||
if (gesture_angle >= 70.) km = Qt::ShiftModifier;
|
||||
QPoint cp = pg->centerPoint().toPoint();
|
||||
if (!fullscr) cp = mapFromGlobal(cp);
|
||||
procZoom(cp, (pg->scaleFactor() - 1.) * 500., km);
|
||||
totalUpdate();
|
||||
} break;
|
||||
case Qt::TapAndHoldGesture: {
|
||||
QTapAndHoldGesture * pg = (QTapAndHoldGesture*)g;
|
||||
if (pg->state() == Qt::GestureStarted)
|
||||
QMetaObject::invokeMethod(this, "enterFullscreen", Qt::QueuedConnection);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Graphic::procZoom(QPointF view_center, double dzoom, Qt::KeyboardModifiers km) {
|
||||
double scl, wid = canvas->width() - gridborder.x() - margins_.width() - margins_.left(), hei = canvas->height() - gridborder.y() - margins_.height() - margins_.top();
|
||||
double px = view_center.x() - gridborder.x() - margins_.left(), py = hei - view_center.y() + margins_.height();
|
||||
px = px / wid * selrect.width() + selrect.x();
|
||||
py = py / hei * selrect.height() + selrect.y();
|
||||
scl = 1. - dzoom / 500.;
|
||||
if (km == Qt::NoModifier)
|
||||
selrect.setRect(px - (px - selrect.x()) * scl, py - (py - selrect.y()) * scl, selrect.width() * scl, selrect.height() * scl);
|
||||
else {
|
||||
if (km == Qt::ControlModifier)
|
||||
selrect.setRect(px - (px - selrect.x()) * scl, selrect.y(), selrect.width() * scl, selrect.height());
|
||||
if (km == Qt::ShiftModifier)
|
||||
selrect.setRect(selrect.x(), py - (py - selrect.y()) * scl, selrect.width(), selrect.height() * scl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Graphic::totalUpdate() {
|
||||
isFit = false;
|
||||
emit visualRectChanged();
|
||||
update(true);
|
||||
setRectToLines();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::canvasPaintEvent() {
|
||||
if (is_lines_update) return;
|
||||
int wid = canvas->width(), hei = canvas->height();
|
||||
if (canvas->isHidden() || wid <= 1 || hei <= 1) return;
|
||||
lastw = wid;
|
||||
lasth = hei;
|
||||
font_sz = fontMetrics().size(0, "0");
|
||||
font_sz.setHeight(font_sz.height() * 1.);
|
||||
#ifdef Q_OS_ANDROID
|
||||
font_sz.setWidth(font_sz.width() * 6);
|
||||
#else
|
||||
font_sz.setWidth(font_sz.width() * 8);
|
||||
#endif
|
||||
thick = lineThickness();
|
||||
if (buffer != 0) if (buffer->width() != wid || buffer->height() != hei) {delete buffer; buffer = 0;}
|
||||
if (buffer == 0) buffer = new QImage(wid, hei, QImage::Format_RGB32);
|
||||
if (bufferActive) {
|
||||
QPainter p(canvas);
|
||||
p.drawImage(0, 0, *buffer);
|
||||
painter = &p;
|
||||
fp_size.clear();
|
||||
if (curpos != startpos) drawAction();
|
||||
drawGuides();
|
||||
return;
|
||||
}
|
||||
QPainter p;
|
||||
#ifdef HAS_GL
|
||||
if (isOGL) {
|
||||
p.fillRect(canvas->rect(), Qt::black);
|
||||
glClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
p.begin(canvas);
|
||||
} else
|
||||
#endif
|
||||
p.begin(buffer);
|
||||
p.fillRect(canvas->rect(), back_color);
|
||||
painter = &p;
|
||||
p.setFont(font());
|
||||
gridborder = QPoint(5, 5);
|
||||
if (grid) {
|
||||
gridborder += QPoint(font_sz.width(), font_sz.height());
|
||||
if (hasLblY) gridborder += QPoint(font_sz.height(), 0);
|
||||
if (hasLblX) gridborder += QPoint(0, font_sz.height());
|
||||
}
|
||||
painter->setClipping(true);
|
||||
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
|
||||
emit beforeGraphicPaintEvent(painter);
|
||||
painter->setClipping(false);
|
||||
if (grid)
|
||||
drawGrid();
|
||||
p.setRenderHint(QPainter::Antialiasing, aalias);
|
||||
#ifndef ANDROID
|
||||
if (isOGL) {
|
||||
if (aalias) glEnable(GL_MULTISAMPLE);
|
||||
else glDisable(GL_MULTISAMPLE);
|
||||
}
|
||||
#endif
|
||||
fp_size.clear();
|
||||
if (!aalias) p.translate(-0.5, -0.5);
|
||||
drawGraphics();
|
||||
drawGuides();
|
||||
if (pause_) drawPause();
|
||||
emit graphicPaintEvent(painter);
|
||||
p.end();
|
||||
if (isOGL) return;
|
||||
p.begin(canvas);
|
||||
p.drawImage(0, 0, *buffer);
|
||||
p.end();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::canvasMouseMoveEvent(QMouseEvent * e) {
|
||||
isHover = true;
|
||||
curpos = e->pos();
|
||||
curpos_r = canvas2real(curpos);
|
||||
QPointF dp;
|
||||
QString cursorstr = tr("Cursor: ") + pointCoords(curpos_r);
|
||||
emit graphicMouseMoveEvent(curpos_r, e->buttons());
|
||||
if (e->buttons() == Qt::NoButton) {
|
||||
ui->status->setText(cursorstr);
|
||||
if (guides) update();
|
||||
return;
|
||||
}
|
||||
if (!navigation) return;
|
||||
if (gestures) {
|
||||
if (!need_mouse_pan) return;
|
||||
curaction = gaMove;
|
||||
} else
|
||||
if (curaction != gaMove && (e->buttons() & Qt::RightButton) == Qt::RightButton) return;
|
||||
switch (curaction) {
|
||||
case gaZoomInRect:
|
||||
ui->status->setText(tr("Selection") + ": " + pointCoords(startpos_r) + " -> " +
|
||||
pointCoords(curpos_r) + ", " + tr("Size") + ": " + pointCoords(absPoint(curpos_r - startpos_r)));
|
||||
repaintCanvas(true);
|
||||
break;
|
||||
case gaZoomRangeX:
|
||||
ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.x(), 'f', 3) +
|
||||
" -> " + QString::number(curpos_r.x(), 'f', 3) + ", " + tr("Length") + ": " +
|
||||
QString::number(qAbs(curpos_r.x() - startpos_r.x()), 'f', 3));
|
||||
repaintCanvas(true);
|
||||
break;
|
||||
case gaZoomRangeY:
|
||||
ui->status->setText(tr("Range") + ": " + QString::number(startpos_r.y(), 'f', 3) +
|
||||
" -> " + QString::number(curpos_r.y(), 'f', 3) + ", " + tr("Length") + ": " +
|
||||
QString::number(qAbs(curpos_r.y() - startpos_r.y()), 'f', 3));
|
||||
repaintCanvas(true);
|
||||
break;
|
||||
case gaMove:
|
||||
dp = e->pos() - prevpos;
|
||||
dp.rx() *= selrect.width() / double(gridborder.x() + 5 - lastw);
|
||||
dp.ry() *= selrect.height() / double(lasth - gridborder.y() - 5);
|
||||
if (e->modifiers() == Qt::ControlModifier)
|
||||
dp.setY(0.);
|
||||
if (e->modifiers() == Qt::ShiftModifier)
|
||||
dp.setX(0.);
|
||||
selrect.translate(dp);
|
||||
totalUpdate();
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
prevpos = e->pos();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::canvasMousePressEvent(QMouseEvent * e) {
|
||||
emit graphicMousePressEvent(canvas2real(QPointF(e->pos())), e->button());
|
||||
if (!navigation) return;
|
||||
if (gestures && !need_mouse_pan) return;
|
||||
#ifdef HAS_GL
|
||||
canvas_gl->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor);
|
||||
#endif
|
||||
ui->canvas_raster->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor);
|
||||
prevpos = e->pos();
|
||||
startpos = prevpos;
|
||||
startpos_r = canvas2real(startpos);
|
||||
if (cancel || gestures) return;
|
||||
if (e->button() == Qt::MidButton) curaction = gaMove;
|
||||
if (e->button() == Qt::RightButton) {
|
||||
if (bufferActive) {
|
||||
curpos = startpos;
|
||||
curpos_r = canvas2real(curpos);
|
||||
repaintCanvas(true);
|
||||
swapToNormal();
|
||||
cancel = true;
|
||||
return;
|
||||
} else {
|
||||
prevaction = curaction;
|
||||
curaction = gaMove;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (e->button() == Qt::LeftButton) {
|
||||
if (e->modifiers() == Qt::ControlModifier) curaction = gaZoomRangeX;
|
||||
else if (e->modifiers() == Qt::ShiftModifier) curaction = gaZoomRangeY;
|
||||
else curaction = gaZoomInRect;
|
||||
switch (curaction) {
|
||||
case gaZoomInRect:
|
||||
case gaZoomRangeX:
|
||||
case gaZoomRangeY:
|
||||
swapToBuffer();
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
setCurrentAction(curaction);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::canvasMouseReleaseEvent(QMouseEvent * e) {
|
||||
emit graphicMouseReleaseEvent(canvas2real(QPointF(e->pos())), e->button());
|
||||
if (gestures) return;
|
||||
need_mouse_pan = false;
|
||||
if (!navigation) return;
|
||||
#ifdef HAS_GL
|
||||
canvas_gl->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor);
|
||||
#endif
|
||||
ui->canvas_raster->setCursor(guides ? Qt::BlankCursor : Qt::ArrowCursor);
|
||||
QPointF tlp, brp;
|
||||
QRect sr;
|
||||
sr = QRect(startpos, curpos).normalized();
|
||||
if (cancel) {
|
||||
if (e->buttons() == Qt::NoButton) cancel = false;
|
||||
return;
|
||||
}
|
||||
if (e->button() == Qt::RightButton && curaction == gaMove) {
|
||||
curaction = prevaction;
|
||||
return;
|
||||
}
|
||||
if (e->button() == Qt::LeftButton && (e->buttons() & Qt::RightButton) != Qt::RightButton) {
|
||||
if (curpos != startpos) {
|
||||
tlp = canvas2real(sr.topLeft());
|
||||
brp = canvas2real(sr.bottomRight());
|
||||
isFit = false;
|
||||
switch (curaction) {
|
||||
case gaZoomInRect:
|
||||
if (sr.width() <= 1 || sr.height() <= 1) break;
|
||||
selrect.setCoords(tlp.x(), brp.y(), brp.x(), tlp.y());
|
||||
setRectToLines();
|
||||
break;
|
||||
case gaZoomRangeX:
|
||||
if (sr.width() <= 1) break;
|
||||
findGraphicsRect(tlp.x(), brp.x());
|
||||
break;
|
||||
case gaZoomRangeY:
|
||||
if (sr.height() <= 1) break;
|
||||
findGraphicsRect(0., 0., brp.y(), tlp.y());
|
||||
break;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
swapToNormal();
|
||||
update(true);
|
||||
}
|
||||
QPointF rp = canvas2real(QPointF(e->pos()));
|
||||
ui->status->setText(tr("Cursor") + ": " + pointCoords(rp));
|
||||
emit visualRectChanged();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::canvasMouseDoubleClickEvent(QMouseEvent * ) {
|
||||
autofit();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::canvasWheelEvent(QWheelEvent * e) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
emit graphicWheelEvent(canvas2real(e->position()), e->delta()/* TODO: test use angleDelta()*/);
|
||||
#else
|
||||
emit graphicWheelEvent(canvas2real(QPointF(e->pos())), e->delta());
|
||||
#endif
|
||||
if (gestures) return;
|
||||
if (!navigation) return;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
procZoom(e->position(), e->delta(), e->modifiers());
|
||||
#else
|
||||
procZoom(e->pos(), e->delta(), e->modifiers());
|
||||
#endif
|
||||
totalUpdate();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::zoom(float factor) {
|
||||
double wid = canvas->width() - gridborder.x() - margins_.width() - margins_.left(), hei = canvas->height() - gridborder.y() - margins_.height() - margins_.top();
|
||||
double px = wid / 2, py = hei / 2;
|
||||
px = px / wid * selrect.width() + selrect.x();
|
||||
py = py / hei * selrect.height() + selrect.y();
|
||||
selrect.setRect(px - (px - selrect.x()) * factor, py - (py - selrect.y()) * factor, selrect.width() * factor, selrect.height() * factor);
|
||||
isFit = false;
|
||||
update(true);
|
||||
setRectToLines();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::fullscreen() {
|
||||
if (fullscr) leaveFullscreen();
|
||||
else enterFullscreen();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::canvasLeaveEvent(QEvent * ) {
|
||||
isHover = false;
|
||||
if (guides) update(true);
|
||||
ui->status->setText(tr("Cursor") + ": ( ; )");
|
||||
leaveFullscreen();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::canvasKeyPressEvent(QKeyEvent * e) {
|
||||
switch (e->key()) {
|
||||
case Qt::Key_Escape: leaveFullscreen();
|
||||
default: break;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void Graphic::clear() {
|
||||
for (int i = 0; i < graphics.size(); ++i) {
|
||||
graphics[i].polyline.clear();
|
||||
graphics[i].polyline_pause.clear();
|
||||
graphics[i].max_x = 0.;
|
||||
graphics[i].cvrect = QRectF();
|
||||
}
|
||||
if (isFit) on_buttonAutofit_clicked();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setAntialiasing(bool enabled) {
|
||||
if (aalias == enabled) return;
|
||||
aalias = enabled;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setPaused(bool yes) {
|
||||
pause_ = yes;
|
||||
ui->checkPause->blockSignals(true);
|
||||
ui->checkPause->setChecked(yes);
|
||||
ui->checkPause->blockSignals(false);
|
||||
for (int i = 0; i < graphics.size(); ++i)
|
||||
graphics[i].cvrect = QRectF();
|
||||
if (!pause_) {
|
||||
killTimer(timer_pause);
|
||||
timer_pause = 0;
|
||||
update(true);
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < graphics.size(); ++i) {
|
||||
graphics[i].polyline_pause = graphics[i].polyline;
|
||||
graphics[i].polyline_pause.detach();
|
||||
graphics[i].max_x_pause = graphics[i].max_x;
|
||||
}
|
||||
timer_pause = startTimer(40);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setHistorySize(double val) {
|
||||
history = val;
|
||||
double x;
|
||||
for (int i = 0; i < graphics.size(); ++i) {
|
||||
QPolygonF & pol(graphics[i].polyline);
|
||||
if (pol.isEmpty() || history <= 0.) continue;
|
||||
graphics[i].cvrect = QRectF();
|
||||
x = pol.back().x() - history;
|
||||
for (int j = pol.size() - 2; j >= 0 ; --j)
|
||||
if (pol[j].x() < x) {
|
||||
pol.erase(pol.begin(), pol.begin() + j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setMaxVisibleTime(double val) {
|
||||
visible_time = val;
|
||||
if (isFit) on_buttonAutofit_clicked();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setOnlyExpandY(bool yes) {
|
||||
only_expand_y = yes;
|
||||
ui->checkExpandY->blockSignals(true);
|
||||
ui->checkExpandY->setCheckable(yes);
|
||||
ui->checkExpandY->blockSignals(false);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setOnlyExpandX(bool yes) {
|
||||
only_expand_x = yes;
|
||||
ui->checkExpandX->blockSignals(true);
|
||||
ui->checkExpandX->setCheckable(yes);
|
||||
ui->checkExpandX->blockSignals(false);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setGesturesNavigation(bool yes) {
|
||||
gestures = yes;
|
||||
}
|
||||
|
||||
|
||||
Graphic::GraphicsData Graphic::graphicsData() const {
|
||||
GraphicsData ret;
|
||||
ret.resize(graphics.size());
|
||||
for (int i = 0; i < graphics.size(); ++i)
|
||||
ret[i] = graphics[i].polyline;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QByteArray Graphic::graphicsDataRaw() const {
|
||||
QByteArray ret;
|
||||
QDataStream s(&ret, QIODevice::WriteOnly);
|
||||
s << graphicsData();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setGraphicsData(const Graphic::GraphicsData & gd) {
|
||||
setGraphicsCount(gd.size());
|
||||
for (int i = 0; i < gd.size(); ++i)
|
||||
setGraphicData(gd[i], i, false);
|
||||
updateGraphics();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setGraphicsDataRaw(const QByteArray & ba) {
|
||||
if (ba.isEmpty()) {
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
Graphic::GraphicsData gd;
|
||||
QDataStream s(ba);
|
||||
s >> gd;
|
||||
setGraphicsData(gd);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setButtons(Graphic::Buttons b) {
|
||||
buttons_ = b;
|
||||
ui->buttonAutofit->setVisible(b.testFlag(Autofit));
|
||||
ui->checkGrid->setVisible(b.testFlag(Grid));
|
||||
ui->checkGuides->setVisible(b.testFlag(CursorAxis));
|
||||
ui->checkExpandY->setVisible(b.testFlag(OnlyExpandY));
|
||||
ui->checkExpandX->setVisible(b.testFlag(OnlyExpandX));
|
||||
ui->buttonFullscreen->setVisible(b.testFlag(Fullscreen));
|
||||
ui->checkBorderInputs->setVisible(b.testFlag(BorderInputs));
|
||||
ui->checkLegend->setVisible(b.testFlag(Legend));
|
||||
ui->buttonClear->setVisible(b.testFlag(Clear));
|
||||
ui->buttonConfigure->setVisible(b.testFlag(Configure));
|
||||
ui->buttonSave->setVisible(b.testFlag(Save));
|
||||
ui->buttonClose->setVisible(b.testFlag(Close));
|
||||
ui->checkPause->setVisible(b.testFlag(Pause));
|
||||
if (ui->buttonAutofit->isVisible() || ui->checkGrid->isVisible() || ui->checkGuides->isVisible() ||
|
||||
ui->buttonConfigure->isVisible() || ui->buttonSave->isVisible() || ui->checkPause->isVisible())
|
||||
ui->verticalSpacer->changeSize(0, 30, QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
else
|
||||
ui->verticalSpacer->changeSize(0, 0, QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
ui->layoutButtons->update();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setButtonsPosition(Graphic::Alignment a) {
|
||||
align = a;
|
||||
ui->widgetLeft->hide();
|
||||
ui->widgetRight->hide();
|
||||
switch (a) {
|
||||
case Graphic::Left:
|
||||
ui->widgetLeft->setLayout(ui->layoutButtons);
|
||||
ui->widgetLeft->show();
|
||||
break;
|
||||
case Graphic::Right:
|
||||
ui->widgetRight->setLayout(ui->layoutButtons);
|
||||
ui->widgetRight->show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Graphic::addPoint(const QPointF & p, int graphic, bool update_) {
|
||||
if (graphic >= graphics.size() || graphic < 0) return;
|
||||
GraphicType & t(graphics[graphic]);
|
||||
if (!t.cvrect.isNull() && !pause_) {
|
||||
if (t.cvrect.top() < p.y()) t.cvrect.setTop(p.y());
|
||||
if (t.cvrect.bottom() > p.y()) t.cvrect.setBottom(p.y());
|
||||
if (t.cvrect.right() < p.x()) t.cvrect.setRight(p.x());
|
||||
if (t.cvrect.left() > p.x()) t.cvrect.setLeft(p.x());
|
||||
}
|
||||
if (t.polyline.size() == 0) t.max_x = p.x();
|
||||
t.polyline << p;
|
||||
if (t.max_x < p.x()) t.max_x = p.x();
|
||||
tick(graphic, true, update_);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setGraphicData(const QVector<QPointF> & g, int graphic, bool update_) {
|
||||
if (graphic >= graphics.size() || graphic < 0) return;
|
||||
GraphicType & t(graphics[graphic]);
|
||||
t.cvrect = QRectF();
|
||||
t.polyline.clear();
|
||||
t.polyline = g;
|
||||
if (t.polyline.size() == 0) {
|
||||
t.max_x = 0.;
|
||||
tick(graphic, false, update_);
|
||||
return;
|
||||
}
|
||||
t.max_x = t.polyline[0].x();
|
||||
for (int i = 1; i < t.polyline.size(); ++i)
|
||||
if (t.max_x < t.polyline[i].x())
|
||||
t.max_x = t.polyline[i].x();
|
||||
tick(graphic, false, update_);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setGraphicProperties(int graphic, const QString & name, const QColor& color, Qt::PenStyle style, double width, bool visible) {
|
||||
if (graphic < 0 || graphic >= graphics.size()) return;
|
||||
graphics[graphic].name = name;
|
||||
graphics[graphic].pen.setColor(color);
|
||||
graphics[graphic].pen.setStyle(style);
|
||||
graphics[graphic].pen.setWidth(width);
|
||||
graphics[graphic].visible = visible;
|
||||
updateLegend();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::addGraphic(const QString & name, const QColor & color, Qt::PenStyle style, double width, bool visible) {
|
||||
graphics << GraphicType(name, color, style, width, visible);
|
||||
updateLegend();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setVisualRect(const QRectF & rect) {
|
||||
selrect = rect;
|
||||
isFit = false;
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setDefaultRect(const QRectF & rect) {
|
||||
def_rect = rect;
|
||||
if (isFit) autofit();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::saveImage() {
|
||||
QString str = QFileDialog::getSaveFileName(this, tr("Save Image"), ppath, "PNG(*.png);;JPEG(*.jpg *.jpeg);;BMP(*.bmp);;TIFF(*.tiff *.tif);;PPM(*.ppm)");
|
||||
if (str == "") return;
|
||||
ppath = str;
|
||||
QPixmap im(canvas->size());
|
||||
canvas->render(&im);
|
||||
im.save(ppath);
|
||||
update(true);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setOpenGL(bool on) {
|
||||
#ifdef HAS_GL
|
||||
isOGL = on;
|
||||
if (on) {
|
||||
ui->canvas_raster->hide();
|
||||
canvas_gl->show();
|
||||
canvas = canvas_gl;
|
||||
} else {
|
||||
canvas_gl->hide();
|
||||
ui->canvas_raster->show();
|
||||
canvas = ui->canvas_raster;
|
||||
}
|
||||
#else
|
||||
isOGL = false;
|
||||
ui->canvas_raster->show();
|
||||
canvas = ui->canvas_raster;
|
||||
#endif
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::update(bool force) {
|
||||
repaintCanvas(force);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setGraphicsCount(int arg, bool update) {
|
||||
if (arg < 0) return;
|
||||
while (graphics.size() < arg) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||
graphics.append(GraphicType(tr("y(x)"), QColor::fromHsv((graphics.size() * 55) % 360, 255, 255 - QRandomGenerator::global()->generate() % 115)));
|
||||
#else
|
||||
graphics.append(GraphicType(tr("y(x)"), QColor::fromHsv((graphics.size() * 55) % 360, 255, 255 - qrand() % 115)));
|
||||
#endif
|
||||
}
|
||||
while (graphics.size() > arg) {
|
||||
delete graphics.back().pb;
|
||||
graphics.pop_back();
|
||||
}
|
||||
if (update) updateLegend();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::removeGraphic(int arg, bool update) {
|
||||
if (arg < 0 || arg >= graphics.size()) return;
|
||||
delete graphics[arg].pb;
|
||||
graphics.remove(arg);
|
||||
if (update) updateLegend();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::findGraphicsRect(double start_x, double end_x, double start_y, double end_y) {
|
||||
double cx, cy, maxX, minX, maxY, minY, vx;
|
||||
bool isRangeX = (start_x != end_x), isRangeY = (start_y != end_y);
|
||||
bool can_fast = (start_x == 0 && end_x == 0 && start_y == 0 && end_y == 0);
|
||||
bool anyVisible = false, isTimeLimit = (visible_time > 0.) && !(isRangeX || isRangeY);
|
||||
vx = -DBL_MAX;
|
||||
minY = minX = DBL_MAX;
|
||||
maxY = maxX = -DBL_MAX;
|
||||
foreach (const GraphicType & t, graphics) {
|
||||
if (!t.visible) continue;
|
||||
if (vx < (pause_ ? t.max_x_pause : t.max_x)) vx = (pause_ ? t.max_x_pause : t.max_x);
|
||||
}
|
||||
vx -= visible_time;
|
||||
for (int g = 0; g < graphics.size(); g++) {
|
||||
GraphicType & t(graphics[g]);
|
||||
if (!t.visible) continue;
|
||||
const QPolygonF & pol(pause_ ? t.polyline_pause : t.polyline);
|
||||
if (pol.isEmpty()) continue;
|
||||
bool f = true;
|
||||
if (t.cvrect.isNull() || !can_fast) {
|
||||
for (int i = 0; i < pol.size(); i++) {
|
||||
cx = pol[i].x();
|
||||
cy = pol[i].y();
|
||||
if ((start_x > cx || end_x < cx) && isRangeX) continue;
|
||||
if ((start_y > cy || end_y < cy) && isRangeY) continue;
|
||||
if ((cx < vx) && isTimeLimit) continue;
|
||||
if (f) {
|
||||
t.cvrect.setRect(cx, cy, 0, 0);
|
||||
f = false;
|
||||
} else {
|
||||
if (t.cvrect.top() < cy) t.cvrect.setTop(cy);
|
||||
if (t.cvrect.bottom() > cy) t.cvrect.setBottom(cy);
|
||||
if (t.cvrect.right() < cx) t.cvrect.setRight(cx);
|
||||
if (t.cvrect.left() > cx) t.cvrect.setLeft(cx);
|
||||
}
|
||||
}
|
||||
if (f) continue;
|
||||
}
|
||||
anyVisible = true;
|
||||
if (maxY < t.cvrect.top()) maxY = t.cvrect.top();
|
||||
if (minY > t.cvrect.bottom()) minY = t.cvrect.bottom();
|
||||
if (maxX < t.cvrect.right()) maxX = t.cvrect.right();
|
||||
if (minX > t.cvrect.left()) minX = t.cvrect.left();
|
||||
if (!can_fast) t.cvrect = QRectF();
|
||||
}
|
||||
if (!anyVisible) {
|
||||
grect = def_rect;
|
||||
setRectToLines();
|
||||
return;
|
||||
}
|
||||
if (maxX > limit_.right()) maxX = limit_.right();
|
||||
if (minX > limit_.right()) minX = limit_.right();
|
||||
if (minX < limit_.left()) minX = limit_.left();
|
||||
if (maxX < limit_.left()) maxX = limit_.left();
|
||||
if (maxY > limit_.bottom()) maxY = limit_.bottom();
|
||||
if (minY > limit_.bottom()) minY = limit_.bottom();
|
||||
if (minY < limit_.top()) minY = limit_.top();
|
||||
if (maxY < limit_.top()) maxY = limit_.top();
|
||||
if (minX > maxX) qSwap<double>(minX, maxX);
|
||||
if (minY > maxY) qSwap<double>(minY, maxY);
|
||||
if (qAbs<double>(minX - maxX) < 1E-60) {minX -= defaultRect().width()/2; maxX += defaultRect().width()/2;}
|
||||
if (qAbs<double>(minY - maxY) < 1E-60) {minY -= defaultRect().height()/2; maxY += defaultRect().height()/2;}
|
||||
if (only_expand_x) {
|
||||
if (minX > eminx) minX = eminx;
|
||||
if (maxX < emaxx) maxX = emaxx;
|
||||
}
|
||||
if (only_expand_y) {
|
||||
if (minY > eminy) minY = eminy;
|
||||
if (maxY < emaxy) maxY = emaxy;
|
||||
}
|
||||
eminx = minX; emaxx = maxX;
|
||||
eminy = minY; emaxy = maxY;
|
||||
if (isRangeX) selrect.setRect(start_x, minY, end_x - start_x, maxY - minY);
|
||||
else if (isRangeY) selrect.setRect(minX, start_y, maxX - minX, end_y - start_y);
|
||||
else grect.setRect(minX, minY, maxX - minX, maxY - minY);
|
||||
grect = grect.normalized();
|
||||
if (isFit) {
|
||||
if (visible_time > 0.) {
|
||||
if (grect.width() > visible_time)
|
||||
grect.setLeft(grect.right() - visible_time);
|
||||
}
|
||||
selrect = grect;
|
||||
}
|
||||
setRectToLines();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::drawAction() {
|
||||
int wid = canvas->width(), hei = canvas->height() - gridborder.y(), sx = startpos.x(), sy = startpos.y(), cx = curpos.x(), cy = curpos.y();
|
||||
painter->setPen(selpen);
|
||||
painter->setBrush(selbrush);
|
||||
switch (curaction) {
|
||||
case gaZoomInRect: {
|
||||
QSizeF rsz = QRectF(startpos_r, curpos_r).normalized().size();
|
||||
painter->drawRect(QRect(startpos, curpos));
|
||||
fp_size = " x " + pointCoords(QPointF(rsz.width(), rsz.height()));
|
||||
} break;
|
||||
case gaZoomRangeX:
|
||||
painter->drawLine(sx, hei, sx, 0);
|
||||
painter->drawLine(cx, hei, cx, 0);
|
||||
painter->fillRect(sx, 0, cx - sx, hei, selbrush);
|
||||
fp_size = " x " + pointCoords(QPointF(qAbs(startpos_r.x() - curpos_r.x()), 0.), true, false);
|
||||
break;
|
||||
case gaZoomRangeY:
|
||||
painter->drawLine(gridborder.x(), sy, wid, sy);
|
||||
painter->drawLine(gridborder.x(), cy, wid, cy);
|
||||
painter->fillRect(gridborder.x(), sy, wid - gridborder.x(), cy - sy, selbrush);
|
||||
fp_size = " x " + pointCoords(QPointF(0., qAbs(startpos_r.y() - curpos_r.y())), false, true);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Graphic::drawGrid() {
|
||||
int gbx = gridborder.x(), gby = gridborder.y(), cwid = canvas->width(), chei = canvas->height();
|
||||
double px, py, range, step, start;
|
||||
int wid = cwid - gbx - 5, hei = chei - gby - 5, cx, cy, cnt;
|
||||
QRect rect;
|
||||
QPair<QString, QString> str;
|
||||
|
||||
range = selrect.bottom() - selrect.top();
|
||||
if (grad_y == Graphic::Auto) step = splitRange(range, hei / gridy / font_sz.height() / 1.4);
|
||||
else step = gridy;
|
||||
start = roundTo(canvas2realY(-hei), step) - step;
|
||||
py = start + step;
|
||||
cy = 0;
|
||||
cx = gbx - 5;
|
||||
grid_pen.setWidth(qMax<int>(qMax<int>(qRound(thick / 1.4), 1), grid_pen.width()));
|
||||
QFont sf = font();
|
||||
QFont nf = sf;
|
||||
sf.setPointSizeF(qMax<qreal>(sf.pointSizeF() / 1.6, 7.));
|
||||
QFontMetrics fm(nf), sfm(sf);
|
||||
if (step > 0.) {
|
||||
cnt = 1000;
|
||||
while (cnt-- > 0) {
|
||||
py -= step;
|
||||
if (fabs(py) < step * .5) py = 0.;
|
||||
cy = real2canvasY(py);
|
||||
if (cy < 0) continue;
|
||||
if (cy > hei + 5) break;
|
||||
painter->setPen(grid_pen);
|
||||
painter->drawLine(gbx, cy, cwid, cy);
|
||||
str = gridMark(py * grid_numbers_y);
|
||||
painter->setPen(text_color);
|
||||
cy += font_sz.height() / 4.;
|
||||
int dx = font_sz.height() / 8.;
|
||||
if (!str.second.isEmpty()) {
|
||||
rect = sfm.boundingRect(str.second);
|
||||
painter->setFont(sf);
|
||||
painter->drawText(cx - rect.width() - dx, cy - font_sz.height() / 2.5, str.second);
|
||||
dx += rect.width() + font_sz.height() / 6.;
|
||||
}
|
||||
rect = fm.boundingRect(str.first);
|
||||
painter->setFont(nf);
|
||||
painter->drawText(cx - rect.width() - dx, cy, str.first);
|
||||
}
|
||||
}
|
||||
cy = real2canvasY(0.);
|
||||
if (cy >= 0 && cy <= (hei + 5)) {
|
||||
QPen _p(grid_pen);
|
||||
_p.setStyle(Qt::SolidLine);
|
||||
painter->setPen(_p);
|
||||
painter->drawLine(gbx, cy, cwid, cy);
|
||||
}
|
||||
if (hasLblY) {
|
||||
painter->setPen(text_color);
|
||||
painter->save();
|
||||
painter->translate(5, hei);
|
||||
painter->rotate(-90.);
|
||||
painter->drawText(0, 0, hei, font_sz.height(), Qt::AlignCenter, label_y);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
cy = chei - font_sz.height() / 4;
|
||||
if (hasLblX) cy -= font_sz.height();
|
||||
range = selrect.right() - selrect.left();
|
||||
QString df;
|
||||
if (axis_type_x == Graphic::Numeric) {
|
||||
if (grad_x == Graphic::Auto) step = splitRange(range, wid / gridx / font_sz.width() * 1.4);
|
||||
else step = gridx;
|
||||
start = roundTo(canvas2realX(wid), step) + step;
|
||||
px = start + step;
|
||||
if (step > 0.) {
|
||||
cnt = 1000;
|
||||
while (cnt-- > 0) {
|
||||
px -= step;
|
||||
if (fabs(px) < step * .5) px = 0.;
|
||||
cx = real2canvasX(px);
|
||||
if (cx > cwid) continue;
|
||||
if (cx < gbx) break;
|
||||
painter->setPen(grid_pen);
|
||||
painter->drawLine(cx, hei + 5, cx, 0);
|
||||
painter->setPen(text_color);
|
||||
int dx = -font_sz.height() / 4.;
|
||||
painter->setFont(nf);
|
||||
str = gridMark(px * grid_numbers_x);
|
||||
rect = fm.boundingRect(str.first);
|
||||
painter->drawText(cx + dx, cy, str.first);
|
||||
dx += rect.width() + font_sz.height() / 6.;
|
||||
if (!str.second.isEmpty()) {
|
||||
rect = sfm.boundingRect(str.second);
|
||||
painter->setFont(sf);
|
||||
painter->drawText(cx + dx, cy - font_sz.height() / 4., str.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
cx = real2canvasX(0.);
|
||||
if (cx <= cwid && cx >= gbx) {
|
||||
QPen _p(grid_pen);
|
||||
_p.setStyle(Qt::SolidLine);
|
||||
painter->setPen(_p);
|
||||
painter->drawLine(cx, hei + 5, cx, 0);
|
||||
}
|
||||
} else {
|
||||
int cur_scl[7] = {0,0,0,0,0,0,0};
|
||||
step = splitRangeDate(range, wid / gridx / font_sz.width() * 1.4, &df, cur_scl);
|
||||
start = roundTo(canvas2realX(wid), step) + step;
|
||||
px = start + step;
|
||||
QDateTime cd = QDateTime::fromMSecsSinceEpoch(px * grid_numbers_x);
|
||||
roundDateTime(cd, cur_scl);
|
||||
addDateTime(cd, cur_scl);
|
||||
if (step > 0.) {
|
||||
cnt = 1000;
|
||||
while (cnt-- > 0) {
|
||||
addDateTime(cd, cur_scl, -1);
|
||||
cx = real2canvasX(cd.toMSecsSinceEpoch() / grid_numbers_x);
|
||||
if (cx > cwid) continue;
|
||||
if (cx < gbx) break;
|
||||
painter->setPen(grid_pen);
|
||||
painter->drawLine(cx, hei + 5, cx, 0);
|
||||
painter->setPen(text_color);
|
||||
int dx = -font_sz.height() / 4.;
|
||||
painter->setFont(nf);
|
||||
str.first = cd.toString(df);
|
||||
painter->drawText(cx + dx, cy, str.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
painter->setPen(text_color);
|
||||
painter->setFont(nf);
|
||||
if (hasLblX) {
|
||||
painter->setPen(text_color);
|
||||
painter->drawText(gbx, chei - font_sz.height(), wid, font_sz.height(), Qt::AlignCenter, label_x);
|
||||
}
|
||||
|
||||
painter->setPen(QPen(grid_pen.color(), qMax<int>(thick, grid_pen.width())));
|
||||
painter->drawRect(gbx, -1, wid + 6, hei + 6);
|
||||
}
|
||||
|
||||
|
||||
QPair<QString, QString> Graphic::gridMark(double v) const {
|
||||
QPair<QString, QString> ret;
|
||||
if ((qAbs(v) >= 1E+4 || qAbs(v) <= 1E-4) && v != 0.) {
|
||||
int p = qFloor(qLn(qAbs(v)) / LN10);
|
||||
v /= qPow(10., p);
|
||||
if (v == 10.) {
|
||||
v = 1.;
|
||||
p += 1;
|
||||
}
|
||||
ret.first = QString::fromUtf8("%1·10").arg(v);
|
||||
ret.second = QString::number(p);
|
||||
} else
|
||||
ret.first = QString::number(v);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void Graphic::drawGraphics() {
|
||||
if (isHover)
|
||||
ui->status->setText(tr("Cursor: ") + pointCoords(canvas2real(QPointF(curpos))));
|
||||
QPointF srp = -selrect.topLeft();
|
||||
double sclx, scly, wid = canvas->width(), hei = canvas->height();
|
||||
sclx = (wid - gridborder.x() - margins_.left() - margins_.width()) / selrect.width();
|
||||
scly = (hei - gridborder.y() - margins_.top() - margins_.height()) / selrect.height();
|
||||
painter->setClipping(true);
|
||||
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
|
||||
painter->translate(gridborder.x() + margins_.left(), hei - gridborder.y() - margins_.top());
|
||||
painter->scale(sclx, -scly);
|
||||
painter->translate(srp);
|
||||
QTransform mat = painter->transform();
|
||||
painter->resetTransform();
|
||||
painter->setWorldMatrixEnabled(false);
|
||||
QPolygonF cpol;
|
||||
QPen pen;
|
||||
for (int i = 0; i < graphics.size(); ++i) {
|
||||
GraphicType & t(graphics[i]);
|
||||
QPolygonF & rpol(pause_ ? t.polyline_pause : t.polyline);
|
||||
if (t.visible && !rpol.isEmpty()) {
|
||||
pen = t.pen;
|
||||
if (qRound(pen.widthF()) == pen.widthF()) pen.setWidth(pen.width()*thick);
|
||||
else pen.setWidthF(pen.widthF()*thick);
|
||||
pen.setCosmetic(true);
|
||||
if (t.lines) {
|
||||
painter->setPen(pen);
|
||||
if (t.fill) {
|
||||
cpol = rpol;
|
||||
painter->setBrush(t.fill_color);
|
||||
painter->drawPolygon(mat.map(cpol));
|
||||
} else
|
||||
painter->drawPolyline(mat.map(rpol));
|
||||
}
|
||||
if (t.points) {
|
||||
if (qRound(t.pointWidth) == t.pointWidth) pen.setWidth(qRound(t.pointWidth*thick));
|
||||
else pen.setWidthF(t.pointWidth*thick);
|
||||
painter->setPen(pen);
|
||||
painter->drawPoints(mat.map(rpol));
|
||||
}
|
||||
}
|
||||
}
|
||||
painter->setWorldMatrixEnabled(true);
|
||||
}
|
||||
|
||||
|
||||
QString Graphic::pointCoords(QPointF point, bool x, bool y) {
|
||||
QString ret = "(";
|
||||
if (x) {
|
||||
if (axis_type_x == Numeric)
|
||||
ret += QString::number(point.x(), 'f', 3);
|
||||
else
|
||||
ret += QDateTime::fromMSecsSinceEpoch(point.x()).toString();
|
||||
}
|
||||
if (y) {
|
||||
if (ret.size() > 1) ret += " ; ";
|
||||
ret += QString::number(point.y(), 'f', 3);
|
||||
}
|
||||
ret += ")";
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void Graphic::drawGuides() {
|
||||
if (!guides || !isHover) return;
|
||||
int wid = canvas->width(), hei = canvas->height();
|
||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
painter->setPen(QPen(grid_pen.color(), qMax<int>(qRound(thick / 1.4), 1)));
|
||||
painter->resetTransform();
|
||||
painter->setClipping(true);
|
||||
painter->setClipRect(QRect(gridborder.x(), 0, wid - gridborder.x(), hei - gridborder.y()));
|
||||
painter->drawLine(0, curpos.y(), wid, curpos.y());
|
||||
painter->drawLine(curpos.x(), 0, curpos.x(), hei);
|
||||
QString str = pointCoords(canvas2real(curpos)) + fp_size;
|
||||
QFontMetrics fm(font());
|
||||
QRect r = fm.boundingRect(str);
|
||||
QPoint p = curpos + QPoint(font_sz.height() / 4., -font_sz.height() / 4.);
|
||||
if (r.width() + curpos.x() > wid - font_sz.height() / 2.) p.setX(curpos.x() - r.width() - font_sz.height() / 4.);
|
||||
if (curpos.y() - r.height() < font_sz.height() / 8.) p.setY(curpos.y() + r.height() - font_sz.height() / 8.);
|
||||
painter->setPen(text_color);
|
||||
painter->drawText(p, str);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::drawPause() {
|
||||
painter->setClipping(false);
|
||||
painter->save();
|
||||
painter->resetTransform();
|
||||
painter->translate(canvas->width() - icon_pause_b.width() - 6, 6);
|
||||
double o = (0.5 - pause_phase) * 2;
|
||||
painter->setOpacity(o*o);
|
||||
painter->drawImage(0, 0, icon_pause_b);
|
||||
painter->setOpacity(1.);
|
||||
painter->drawImage(0, 0, icon_pause_f);
|
||||
painter->restore();
|
||||
painter->setClipping(true);
|
||||
}
|
||||
|
||||
|
||||
double Graphic::splitRange(double range, int count) {
|
||||
double digits, step, tln;
|
||||
range = qAbs<double>(range);
|
||||
tln = qFloor(qLn(range) / LN10);
|
||||
for (int i = 0; i <= 5; ++i) {
|
||||
digits = qPow(10., tln - i);
|
||||
step = qRound(range / count / digits);
|
||||
if (step > 0.) {
|
||||
digits = qPow(10., tln - i - 1);
|
||||
step = qRound(range / count / digits);
|
||||
break;
|
||||
}
|
||||
}
|
||||
double step5 = qRound(step / 5.) * 5., step10 = qRound(step / 10.) * 10.;
|
||||
double err5 = qAbs<double>(step - step5), err10 = qAbs<double>(step - step10);
|
||||
step = (err5 < err10 ? step5 : step10) * digits;
|
||||
return step;
|
||||
}
|
||||
|
||||
|
||||
double Graphic::splitRangeDate(double range, int count, QString * format, int step[7]) {
|
||||
double ret = splitRange(range, count);
|
||||
if (ret < 1000. * 1) {*format = "ss.zzz"; step[0] = ret;}
|
||||
else if (ret < 1000. * 60) {*format = "h:m:ss"; step[1] = qRound(ret / 1000);}
|
||||
else if (ret < 1000. * 60 * 60) {*format = "h:mm"; step[2] = qRound(ret / 1000 / 60);}
|
||||
else if (ret < 1000. * 60 * 60 * 24) {*format = "dd(ddd) hh"; step[3] = qRound(ret / 1000 / 60 / 60);}
|
||||
else if (ret < 1000. * 60 * 60 * 24 * 30) {*format = "MMM dd"; step[4] = qRound(ret / 1000 / 60 / 60 / 24);}
|
||||
else if (ret < 1000. * 60 * 60 * 24 * 30 * 12) {*format = "yyyy MMM"; step[5] = qRound(ret / 1000 / 60 / 60 / 24 / 30);}
|
||||
else {*format = "yyyy"; step[6] = qRound(ret / 1000 / 60 / 60 / 24 / 30 / 12);}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
double Graphic::roundTo(double value, double round_to) {
|
||||
if (round_to == 0.) return value;
|
||||
return qRound(value / round_to) * round_to;
|
||||
}
|
||||
|
||||
|
||||
void Graphic::roundDateTime(QDateTime & dt, int c[7]) {
|
||||
QDate d(dt.date()); QTime t(dt.time());
|
||||
if (c[1] != 0) t.setHMS(t.hour(), t.minute(), t.second());
|
||||
if (c[2] != 0) t.setHMS(t.hour(), t.minute(), 0);
|
||||
if (c[3] != 0) t.setHMS(t.hour(), 0, 0);
|
||||
if (c[4] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), d.month(), d.day());}
|
||||
if (c[5] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), d.month(), 1);}
|
||||
if (c[6] != 0) {t.setHMS(0, 0, 0); d.setDate(d.year(), 1, 1);}
|
||||
dt = QDateTime(d, t);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::addDateTime(QDateTime & dt, int c[7], int mul) {
|
||||
if (c[0] != 0) dt = dt.addMSecs(mul * c[0]);
|
||||
if (c[1] != 0) dt = dt.addSecs(mul * c[1]);
|
||||
if (c[2] != 0) dt = dt.addSecs(mul * c[2] * 60);
|
||||
if (c[3] != 0) dt = dt.addSecs(mul * c[3] * 60 * 60);
|
||||
if (c[4] != 0) dt = dt.addDays(mul * c[4]);
|
||||
if (c[5] != 0) dt = dt.addMonths(mul * c[5]);
|
||||
if (c[6] != 0) dt = dt.addYears(mul * c[6]);
|
||||
}
|
||||
|
||||
|
||||
double Graphic::canvas2realX(double px) const {
|
||||
int gbx = gridborder.x() + margins_.left(), cwid = lastw, wid = cwid - gbx - margins_.width();
|
||||
double cx = px - gbx, sclx = selrect.width() / (double)wid;
|
||||
return cx * sclx + selrect.x();
|
||||
}
|
||||
|
||||
|
||||
double Graphic::canvas2realY(double py) const {
|
||||
int gby = gridborder.y() + margins_.top(), chei = lasth, hei = chei - gby - margins_.height();
|
||||
double cy = chei - py - gby, scly = selrect.height() / (double)hei;
|
||||
return cy * scly + selrect.y();
|
||||
}
|
||||
|
||||
|
||||
double Graphic::real2canvasX(double px) const {
|
||||
int gbx = gridborder.x() + margins_.left(), cwid = lastw, wid = cwid - gbx - margins_.width();
|
||||
double sclx = selrect.width() / (double)wid;
|
||||
return (px - selrect.x()) / sclx + gbx;
|
||||
}
|
||||
|
||||
|
||||
double Graphic::real2canvasY(double py) const {
|
||||
int gby = gridborder.y() + margins_.top(), chei = lasth, hei = chei - gby - margins_.height();
|
||||
double scly = selrect.height() / (double)hei;
|
||||
return chei - gby - (py - selrect.y()) / scly;
|
||||
}
|
||||
|
||||
|
||||
QPolygonF Graphic::real2canvas(const QPolygonF & real_polygon) const {
|
||||
QPolygonF ret;
|
||||
for (int i=0; i<real_polygon.size(); ++i)
|
||||
ret << real2canvas(real_polygon[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QPolygonF Graphic::canvas2real(const QPolygonF & canvas_polygon) const {
|
||||
QPolygonF ret;
|
||||
for (int i=0; i<canvas_polygon.size(); ++i)
|
||||
ret << canvas2real(canvas_polygon[i]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setCurrentAction(GraphicAction action) {
|
||||
curaction = action;
|
||||
switch (action) {
|
||||
case gaNone:
|
||||
if (guides) setCanvasCursor(Qt::BlankCursor);
|
||||
else setCanvasCursor(Qt::ArrowCursor);
|
||||
break;
|
||||
case gaZoomInRect:
|
||||
setCanvasCursor(Qt::CrossCursor);
|
||||
break;
|
||||
case gaZoomRangeX:
|
||||
setCanvasCursor(Qt::SplitHCursor);
|
||||
break;
|
||||
case gaZoomRangeY:
|
||||
setCanvasCursor(Qt::SplitVCursor);
|
||||
break;
|
||||
case gaMove:
|
||||
setCanvasCursor(Qt::SizeAllCursor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setCanvasCursor(QCursor cursor) {
|
||||
ui->canvas_raster->setCursor(cursor);
|
||||
#ifdef HAS_GL
|
||||
canvas_gl->setCursor(cursor);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Graphic::swapToBuffer() {
|
||||
QImage timg;
|
||||
#ifdef HAS_GL
|
||||
if (isOGL) {
|
||||
timg = canvas_gl->grabFrameBuffer();
|
||||
QPainter p(buffer);
|
||||
p.drawImage(0, 0, timg);
|
||||
p.end();
|
||||
}
|
||||
#endif
|
||||
bufferActive = true;
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setRectToLines() {
|
||||
is_lines_update = true;
|
||||
if (line_x_min.isVisible() && line_x_max.isVisible() && line_y_min.isVisible() && line_y_max.isVisible()) {
|
||||
line_x_min.blockSignals(true); line_x_max.blockSignals(true); line_y_min.blockSignals(true); line_y_max.blockSignals(true);
|
||||
if (!line_x_min.hasFocus()) {
|
||||
if (isFit) line_x_min.setValue(grect.left());
|
||||
else line_x_min.setValue(selrect.left());
|
||||
}
|
||||
if (!line_x_max.hasFocus()) {
|
||||
if(isFit) line_x_max.setValue(grect.right());
|
||||
else line_x_max.setValue(selrect.right());
|
||||
}
|
||||
if (!line_y_min.hasFocus()) {
|
||||
if(isFit) line_y_min.setValue(grect.bottom());
|
||||
else line_y_min.setValue(selrect.bottom());
|
||||
}
|
||||
if (!line_y_max.hasFocus()) {
|
||||
if(isFit) line_y_max.setValue(grect.top());
|
||||
else line_y_max.setValue(selrect.top());
|
||||
}
|
||||
line_x_min.setDefaultText(QString::number(grect.left()).toUpper());
|
||||
line_x_max.setDefaultText(QString::number(grect.right()).toUpper());
|
||||
line_y_min.setDefaultText(QString::number(grect.bottom()).toUpper());
|
||||
line_y_max.setDefaultText(QString::number(grect.top()).toUpper());
|
||||
line_x_min.blockSignals(false); line_x_max.blockSignals(false); line_y_min.blockSignals(false); line_y_max.blockSignals(false);
|
||||
}
|
||||
is_lines_update = false;
|
||||
}
|
||||
|
||||
|
||||
void Graphic::checkLines() {
|
||||
isFit = (line_x_min.isCleared() && line_x_max.isCleared() && line_y_min.isCleared() && line_y_max.isCleared());
|
||||
update(true);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::tick(int index, bool slide, bool update_) {
|
||||
if (slide) {
|
||||
GraphicType & t(graphics[index]);
|
||||
if (history > 0.)
|
||||
while (t.polyline.size() > 1) {
|
||||
if (fabs(t.polyline.back().x() - t.polyline.front().x()) <= history) break;
|
||||
/// TODO: [Graphic] fast autofit while addPoint(double y, ...)
|
||||
if (!t.cvrect.isNull()) {
|
||||
QPointF fp(t.polyline.first());
|
||||
if (qFuzzyCompare(t.cvrect.left(), fp.x()) ||
|
||||
qFuzzyCompare(t.cvrect.right(), fp.x()) ||
|
||||
qFuzzyCompare(t.cvrect.top(), fp.y()) ||
|
||||
qFuzzyCompare(t.cvrect.bottom(), fp.y())) {
|
||||
t.cvrect = QRectF();
|
||||
}
|
||||
}
|
||||
t.polyline.pop_front();
|
||||
}
|
||||
}
|
||||
if (!update_) {
|
||||
if (isFit) findGraphicsRect();
|
||||
return;
|
||||
}
|
||||
if (isFit) findGraphicsRect();
|
||||
if (!slide) {
|
||||
if (aupdate) update();
|
||||
return;
|
||||
}
|
||||
if (aupdate) update();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::on_buttonAutofit_clicked() {
|
||||
isFit = true;
|
||||
bool isEmpty = true;
|
||||
foreach (const GraphicType & t, graphics) {
|
||||
const QPolygonF & pol(pause_ ? t.polyline_pause : t.polyline);
|
||||
if (!pol.isEmpty()) {
|
||||
isEmpty = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isEmpty) grect = def_rect;
|
||||
selrect = grect;
|
||||
findGraphicsRect();
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::on_buttonConfigure_clicked() {
|
||||
conf->graphicItems.clear();
|
||||
for (int i = 0; i < graphics.size(); i++) {
|
||||
GraphicConf::GraphicItem item;
|
||||
item.icon = graphics[i].icon;
|
||||
item.name = graphics[i].name;
|
||||
conf->graphicItems.append(item);
|
||||
}
|
||||
conf->ui->colorGrid->setColor(grid_pen.color());
|
||||
conf->ui->comboStyleGrid->setCurrentIndex((int)grid_pen.style());
|
||||
conf->ui->spinWidthGrid->setValue(grid_pen.widthF());
|
||||
conf->ui->checkOGL->setChecked(isOGL);
|
||||
conf->ui->checkAAlias->setChecked(aalias);
|
||||
conf->ui->checkInputs->setChecked(borderInputsVisible());
|
||||
conf->ui->checkStatus->setChecked(statusVisible());
|
||||
conf->ui->checkLegend->setChecked(legendVisible());
|
||||
conf->ui->checkGridAutoX->setChecked(grad_x == Auto);
|
||||
conf->ui->checkGridAutoY->setChecked(grad_y == Auto);
|
||||
conf->ui->colorBackground->setColor(back_color);
|
||||
conf->ui->colorText->setColor(text_color);
|
||||
conf->ui->spinGridStepX->setValue(gridx);
|
||||
conf->ui->spinGridStepY->setValue(gridy);
|
||||
conf->ui->spinMarginL->setValue(margins_.left());
|
||||
conf->ui->spinMarginT->setValue(margins_.height());
|
||||
conf->ui->spinMarginR->setValue(margins_.width());
|
||||
conf->ui->spinMarginB->setValue(margins_.top());
|
||||
conf->readParams();
|
||||
if (conf->exec() == QDialog::Rejected) return;
|
||||
grid_pen = QPen(conf->ui->colorGrid->color(), conf->ui->spinWidthGrid->value(), (Qt::PenStyle)conf->ui->comboStyleGrid->currentIndex());
|
||||
back_color = conf->ui->colorBackground->color();
|
||||
text_color = conf->ui->colorText->color();
|
||||
grad_x = conf->ui->checkGridAutoX->isChecked() ? Auto : Fixed;
|
||||
grad_y = conf->ui->checkGridAutoY->isChecked() ? Auto : Fixed;
|
||||
gridx = conf->ui->spinGridStepX->value();
|
||||
gridy = conf->ui->spinGridStepY->value();
|
||||
setOpenGL(conf->ui->checkOGL->isChecked());
|
||||
setAntialiasing(conf->ui->checkAAlias->isChecked());
|
||||
setBorderInputsVisible(conf->ui->checkInputs->isChecked());
|
||||
setStatusVisible(conf->ui->checkStatus->isChecked());
|
||||
setLegendVisible(conf->ui->checkLegend->isChecked());
|
||||
setMargins(conf->ui->spinMarginL->value(), conf->ui->spinMarginR->value(), conf->ui->spinMarginT->value(), conf->ui->spinMarginB->value());
|
||||
updateLegend();
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::on_checkGuides_toggled(bool checked) {
|
||||
guides = checked;
|
||||
if (guides) setCanvasCursor(Qt::BlankCursor);
|
||||
else setCanvasCursor(Qt::ArrowCursor);
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::updateLegend(bool es) {
|
||||
QPixmap pix(60, 22);
|
||||
for (int i = 0; i < graphics.size(); i++) {
|
||||
pix.fill(back_color);
|
||||
QPainter p(&pix);
|
||||
QPen pen = graphics[i].pen;
|
||||
if (qRound(pen.widthF()) == pen.widthF()) pen.setWidth(pen.width()*thick);
|
||||
else pen.setWidthF(pen.widthF()*thick);
|
||||
p.setPen(pen);
|
||||
p.drawLine(0, pix.height() / 2, pix.width(), pix.height() / 2);
|
||||
p.end();
|
||||
graphics[i].icon = QIcon(pix);
|
||||
}
|
||||
if (!ui->widgetLegend->isVisibleTo(this)) {
|
||||
if (es) emit graphicSettingsChanged();
|
||||
return;
|
||||
}
|
||||
leg_update = false;
|
||||
int ps = 100;
|
||||
for (int r = 0; r < ui->layoutLegend->rowCount(); ++r)
|
||||
for (int c = 0; c < ui->layoutLegend->columnCount(); ++c) {
|
||||
QLayoutItem * li = ui->layoutLegend->itemAtPosition(r, c);
|
||||
if (!li) continue;
|
||||
if (!li->widget()) continue;
|
||||
while (li->widget()->actions().isEmpty())
|
||||
li->widget()->removeAction(li->widget()->actions()[0]);
|
||||
delete li->widget();
|
||||
}
|
||||
ui->layoutLegend->invalidate();
|
||||
for (int i = 0; i < graphics.size(); i++) {
|
||||
graphics[i].pb = new QCheckBox(graphics[i].name);
|
||||
graphics[i].pb->setIconSize(pix.size());
|
||||
graphics[i].pb->setIcon(graphics[i].icon);
|
||||
graphics[i].pb->setChecked(graphics[i].visible);
|
||||
graphics[i].pb->setProperty("graphic_num", i);
|
||||
graphics[i].pb->setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
QAction * act = new QAction(tr("Check all"), 0);
|
||||
act->setCheckable(true);
|
||||
act->setChecked(true);
|
||||
graphics[i].pb->addAction(act);
|
||||
connect(act, SIGNAL(triggered(bool)), this, SLOT(graphicAllVisibleChange(bool)));
|
||||
connect(graphics[i].pb, SIGNAL(toggled(bool)), this, SLOT(graphicVisibleChange(bool)));
|
||||
int cps = graphics[i].pb->sizeHint().width() + 4;
|
||||
if (cps > ps) ps = cps;
|
||||
}
|
||||
int maxcol = qMax<int>(ui->widgetLegend->width() / ps - 1, 1);
|
||||
int row = 0, col = 0;
|
||||
bool lv = ui->widgetLegend->isVisibleTo(this);
|
||||
ui->widgetLegend->hide();
|
||||
for (int i = 0; i < graphics.size(); i++) {
|
||||
ui->layoutLegend->addWidget(graphics[i].pb,row,col);
|
||||
graphics[i].pb->show();
|
||||
col++;
|
||||
if (col > maxcol) {col = 0; row++;}
|
||||
}
|
||||
ui->widgetLegend->setVisible(lv);
|
||||
leg_update = true;
|
||||
if (es) emit graphicSettingsChanged();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::updateLegendChecks() {
|
||||
for (int i = 0; i < graphics.size(); i++) {
|
||||
if (!graphics[i].pb) continue;
|
||||
bool pbs = graphics[i].pb->blockSignals(true);
|
||||
graphics[i].pb->setChecked(graphics[i].visible);
|
||||
graphics[i].pb->blockSignals(pbs);
|
||||
}
|
||||
emit graphicSettingsChanged();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::graphicVisibleChange(bool checked) {
|
||||
if (visible_update) return;
|
||||
QCheckBox * cb = qobject_cast<QCheckBox*>(sender());
|
||||
int i = cb->property("graphic_num").toInt();
|
||||
graphics[i].visible = checked;
|
||||
if (isFit) on_buttonAutofit_clicked();
|
||||
else update();
|
||||
emit graphicSettingsChanged();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::graphicAllVisibleChange(bool checked) {
|
||||
visible_update = true;
|
||||
for (int i=0; i<graphics.size(); i++) {
|
||||
graphics[i].visible = checked;
|
||||
graphics[i].pb->setChecked(checked);
|
||||
}
|
||||
visible_update = false;
|
||||
if (isFit) on_buttonAutofit_clicked();
|
||||
else update();
|
||||
emit graphicSettingsChanged();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::enterFullscreen() {
|
||||
if (fullscr) return;
|
||||
fullscr = true;
|
||||
canvas->hide();
|
||||
#ifdef Q_OS_ANDROID
|
||||
tm_fscr.restart();
|
||||
QDialog dlg;
|
||||
dlg.setLayout(new QBoxLayout(QBoxLayout::TopToBottom));
|
||||
dlg.layout()->setContentsMargins(0, 0, 0, 0);
|
||||
dlg.layout()->addWidget(canvas);
|
||||
QPushButton * btn = new QPushButton("Leave fullscreen");
|
||||
dlg.layout()->addWidget(btn);
|
||||
connect(btn, SIGNAL(clicked(bool)), this, SLOT(leaveFullscreen()));
|
||||
canvas->show();
|
||||
dlg.showFullScreen();
|
||||
dlg.exec();
|
||||
dlg.layout()->removeWidget(canvas);
|
||||
leaveFullscreen();
|
||||
#else
|
||||
ui->layoutCanvas->removeWidget(canvas);
|
||||
canvas->setParent(0);
|
||||
canvas->showFullScreen();
|
||||
canvas->setFocus();
|
||||
canvas->raise();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Graphic::leaveFullscreen() {
|
||||
#ifdef Q_OS_ANDROID
|
||||
if (tm_fscr.elapsed() < 100) return;
|
||||
#endif
|
||||
if (!fullscr) return;
|
||||
fullscr = false;
|
||||
#ifndef Q_OS_ANDROID
|
||||
canvas->showNormal();
|
||||
canvas->hide();
|
||||
#endif
|
||||
ui->layoutCanvas->addWidget(canvas);
|
||||
canvas->show();
|
||||
}
|
||||
|
||||
|
||||
QString Graphic::caption() const {
|
||||
return ui->labelCaption->text();
|
||||
}
|
||||
|
||||
|
||||
bool Graphic::borderInputsVisible() const {
|
||||
return ui->widgetLX->isVisible();
|
||||
}
|
||||
|
||||
|
||||
bool Graphic::statusVisible() const {
|
||||
return ui->status->isVisible();
|
||||
}
|
||||
|
||||
|
||||
bool Graphic::legendVisible() const {
|
||||
return ui->widgetLegend->isVisible();
|
||||
}
|
||||
|
||||
|
||||
QByteArray Graphic::save() {
|
||||
// QByteArray ba;
|
||||
// QDataStream s(&ba, QIODevice::ReadWrite);
|
||||
// s << openGL() << antialiasing() << borderInputsVisible() << statusVisible() << legendVisible();
|
||||
// s << graphics;
|
||||
// return ba;
|
||||
|
||||
// version '2':
|
||||
ChunkStream cs;
|
||||
cs.add(1, antialiasing()).add(2, openGL()).add(3, borderInputsVisible()).add(4, statusVisible()).add(5, legendVisible());
|
||||
cs.add(6, backgroundColor()).add(7, textColor()).add(8, margins());
|
||||
cs.add(9, gridPen()).add(10, graduationX()).add(11, graduationY()).add(12, graduationStepX()).add(13, graduationStepY());
|
||||
cs.add(14, graphics);
|
||||
cs.add(15, isFit).add(16, visualRect());
|
||||
if (backgroundColor() == palette().color(QPalette::Base) &&
|
||||
textColor() == palette().color(QPalette::WindowText) &&
|
||||
gridColor() == palette().color(QPalette::Disabled, QPalette::WindowText))
|
||||
cs.add(17, true);
|
||||
return cs.data().prepend('2');
|
||||
}
|
||||
|
||||
|
||||
void Graphic::load(QByteArray ba) {
|
||||
if (ba.isEmpty()) return;
|
||||
char ver = ba[0];
|
||||
switch(ver) {
|
||||
case '2': {// version '2':
|
||||
ba.remove(0, 1);
|
||||
QRectF vrect;
|
||||
ChunkStream cs(ba);
|
||||
bool def_colors = false;
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
case 1: setAntialiasing(cs.getData<bool>()); break;
|
||||
case 2: setOpenGL(cs.getData<bool>()); break;
|
||||
case 3: setBorderInputsVisible(cs.getData<bool>()); break;
|
||||
case 4: setStatusVisible(cs.getData<bool>()); break;
|
||||
case 5: setLegendVisible(cs.getData<bool>()); break;
|
||||
case 6: if (!def_colors) setBackgroundColor(cs.getData<QColor>()); break;
|
||||
case 7: if (!def_colors) setTextColor(cs.getData<QColor>()); break;
|
||||
case 8: setMargins(cs.getData<QRect>()); break;
|
||||
case 9: if (!def_colors) setGridPen(cs.getData<QPen>()); break;
|
||||
case 10: setGraduationX(cs.getData<Graduation>()); break;
|
||||
case 11: setGraduationY(cs.getData<Graduation>()); break;
|
||||
case 12: setGraduationStepX(cs.getData<double>()); break;
|
||||
case 13: setGraduationStepY(cs.getData<double>()); break;
|
||||
case 14: graphics = cs.getData<QVector<GraphicType> >(); break;
|
||||
case 15: isFit = cs.getData<bool>(); break;
|
||||
case 16: vrect = cs.getData<QRectF>(); break;
|
||||
case 17: if(cs.getData<bool>()) {
|
||||
setTextColor(palette().color(QPalette::WindowText));
|
||||
setGridPen(QPen(palette().color(QPalette::Disabled, QPalette::WindowText), 0., Qt::DotLine));
|
||||
setBackgroundColor(palette().color(QPalette::Base));
|
||||
def_colors = true;
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
if (!isFit) setVisualRect(vrect);
|
||||
} break;
|
||||
default: {// old version 0:
|
||||
QDataStream s(ba);
|
||||
bool a;
|
||||
s >> a; setOpenGL(a);
|
||||
s >> a; setAntialiasing(a);
|
||||
s >> a; setBorderInputsVisible(a);
|
||||
s >> a; setStatusVisible(a);
|
||||
s >> a;
|
||||
s >> graphics;
|
||||
setLegendVisible(a);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setCaption(const QString & str) {
|
||||
ui->labelCaption->setText(str);
|
||||
ui->labelCaption->setVisible(str.length() > 0);
|
||||
if (aupdate) update();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setGridEnabled(bool enabled) {
|
||||
ui->checkGrid->setChecked(enabled);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setBorderInputsVisible(bool visible) {
|
||||
ui->widgetLX->setVisible(visible);
|
||||
ui->widgetLY->setVisible(visible);
|
||||
ui->checkBorderInputs->setChecked(visible);
|
||||
if (visible) setRectToLines();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setStatusVisible(bool visible) {
|
||||
ui->status->setVisible(visible);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::setLegendVisible(bool visible) {
|
||||
ui->widgetLegend->setVisible(visible);
|
||||
ui->checkLegend->setChecked(visible);
|
||||
updateLegend();
|
||||
}
|
||||
|
||||
|
||||
void Graphic::on_checkExpandY_toggled(bool checked) {
|
||||
only_expand_y = checked;
|
||||
ui->checkExpandY->setIcon(checked ? icon_exp_y : icon_exp_sy);
|
||||
}
|
||||
|
||||
|
||||
void Graphic::on_checkExpandX_toggled(bool checked) {
|
||||
only_expand_x = checked;
|
||||
ui->checkExpandX->setIcon(checked ? icon_exp_x : icon_exp_sx);
|
||||
}
|
||||
461
libs/graphic/graphic.h
Normal file
461
libs/graphic/graphic.h
Normal file
@@ -0,0 +1,461 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRAPHIC_H
|
||||
#define GRAPHIC_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QMouseEvent>
|
||||
#include <QComboBox>
|
||||
#include <QDebug>
|
||||
#include <QGridLayout>
|
||||
#include <QFileDialog>
|
||||
#include <QElapsedTimer>
|
||||
#include <QTranslator>
|
||||
#include <QGestureEvent>
|
||||
#include <qmath.h>
|
||||
#include <float.h>
|
||||
#include "graphic_conf.h"
|
||||
#include "evalspinbox.h"
|
||||
#include "qad_graphic_export.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class Graphic;
|
||||
}
|
||||
|
||||
|
||||
class UGLWidget;
|
||||
|
||||
|
||||
Q_DECLARE_METATYPE(QVector<QPointF>)
|
||||
|
||||
|
||||
class QAD_GRAPHIC_EXPORT Graphic: public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_FLAGS(Buttons)
|
||||
Q_ENUMS(Alignment Graduation AxisType)
|
||||
|
||||
Q_PROPERTY(QString caption READ caption WRITE setCaption)
|
||||
Q_PROPERTY(QString labelX READ labelX WRITE setLabelX)
|
||||
Q_PROPERTY(QString labelY READ labelY WRITE setLabelY)
|
||||
Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
|
||||
Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)
|
||||
|
||||
Q_PROPERTY(int currentGraphic READ currentGraphic WRITE setCurrentGraphic)
|
||||
Q_PROPERTY(int graphicsCount READ graphicsCount WRITE setGraphicsCount)
|
||||
Q_PROPERTY(QString graphicName READ graphicName WRITE setGraphicName)
|
||||
Q_PROPERTY(QPen graphicPen READ graphicPen WRITE setGraphicPen)
|
||||
Q_PROPERTY(QColor graphicColor READ graphicColor WRITE setGraphicColor)
|
||||
Q_PROPERTY(Qt::PenStyle graphicStyle READ graphicStyle WRITE setGraphicStyle)
|
||||
Q_PROPERTY(double graphicLineWidth READ graphicLineWidth WRITE setGraphicLineWidth)
|
||||
Q_PROPERTY(double graphicPointWidth READ graphicPointWidth WRITE setGraphicPointWidth)
|
||||
Q_PROPERTY(QColor graphicFillColor READ graphicFillColor WRITE setGraphicFillColor)
|
||||
Q_PROPERTY(bool graphicLinesEnabled READ graphicLinesEnabled WRITE setGraphicLinesEnabled)
|
||||
Q_PROPERTY(bool graphicPointsEnabled READ graphicPointsEnabled WRITE setGraphicPointsEnabled)
|
||||
Q_PROPERTY(bool graphicFillEnabled READ graphicFillEnabled WRITE setGraphicFillEnabled)
|
||||
|
||||
Q_PROPERTY(bool gridEnabled READ gridEnabled WRITE setGridEnabled)
|
||||
Q_PROPERTY(QPen gridPen READ gridPen WRITE setGridPen)
|
||||
Q_PROPERTY(QColor gridColor READ gridColor WRITE setGridColor)
|
||||
Q_PROPERTY(Qt::PenStyle gridStyle READ gridStyle WRITE setGridStyle)
|
||||
|
||||
Q_PROPERTY(QPen selectionPen READ selectionPen WRITE setSelectionPen)
|
||||
Q_PROPERTY(QColor selectionColor READ selectionColor WRITE setSelectionColor)
|
||||
Q_PROPERTY(Qt::PenStyle selectionStyle READ selectionStyle WRITE setSelectionStyle)
|
||||
Q_PROPERTY(QBrush selectionBrush READ selectionBrush WRITE setSelectionBrush)
|
||||
|
||||
Q_PROPERTY(Alignment buttonsPosition READ buttonsPosition WRITE setButtonsPosition)
|
||||
Q_PROPERTY(Buttons buttons READ buttons WRITE setButtons)
|
||||
Q_PROPERTY(bool navigationEnabled READ navigationEnabled WRITE setNavigationEnabled)
|
||||
Q_PROPERTY(bool openGL READ openGL WRITE setOpenGL)
|
||||
Q_PROPERTY(bool antialiasing READ antialiasing WRITE setAntialiasing)
|
||||
Q_PROPERTY(bool autoUpdate READ autoUpdate WRITE setAutoUpdate)
|
||||
Q_PROPERTY(bool borderInputsVisible READ borderInputsVisible WRITE setBorderInputsVisible)
|
||||
Q_PROPERTY(bool statusVisible READ statusVisible WRITE setStatusVisible)
|
||||
Q_PROPERTY(bool legendVisible READ legendVisible WRITE setLegendVisible)
|
||||
Q_PROPERTY(bool paused READ paused WRITE setPaused)
|
||||
Q_PROPERTY(bool onlyExpandY READ onlyExpandY WRITE setOnlyExpandY)
|
||||
Q_PROPERTY(bool onlyExpandX READ onlyExpandX WRITE setOnlyExpandX)
|
||||
Q_PROPERTY(bool gesturesNavigation READ gesturesNavigation WRITE setGesturesNavigation)
|
||||
Q_PROPERTY(double historySize READ historySize WRITE setHistorySize)
|
||||
Q_PROPERTY(double maxVisibleTime READ maxVisibleTime WRITE setMaxVisibleTime)
|
||||
Q_PROPERTY(double autoXIncrement READ autoXIncrement WRITE setAutoXIncrement)
|
||||
Q_PROPERTY(QRectF limit READ limit WRITE setLimit)
|
||||
Q_PROPERTY(QRect margins READ margins WRITE setMargins)
|
||||
Q_PROPERTY(QRectF visualRect READ visualRect WRITE setVisualRect)
|
||||
Q_PROPERTY(QRectF defaultRect READ defaultRect WRITE setDefaultRect)
|
||||
Q_PROPERTY(int minimumRepaintInterval READ minimumRepaintInterval WRITE setMinimumRepaintInterval)
|
||||
|
||||
Q_PROPERTY(double gridNumbersMultiplierX READ gridNumbersMultiplierX WRITE setGridNumbersMultiplierX)
|
||||
Q_PROPERTY(double gridNumbersMultiplierY READ gridNumbersMultiplierY WRITE setGridNumbersMultiplierY)
|
||||
Q_PROPERTY(Graduation graduationX READ graduationX WRITE setGraduationX)
|
||||
Q_PROPERTY(Graduation graduationY READ graduationY WRITE setGraduationY)
|
||||
Q_PROPERTY(double graduationStepX READ graduationStepX WRITE setGraduationStepX)
|
||||
Q_PROPERTY(double graduationStepY READ graduationStepY WRITE setGraduationStepY)
|
||||
Q_PROPERTY(AxisType axisType READ axisType WRITE setAxisType)
|
||||
|
||||
Q_PROPERTY(Graphic::GraphicsData graphicsData READ graphicsData WRITE setGraphicsData)
|
||||
Q_PROPERTY(QByteArray graphicsDataRaw READ graphicsDataRaw WRITE setGraphicsDataRaw)
|
||||
|
||||
public:
|
||||
Graphic(QWidget * parent = 0);
|
||||
virtual ~Graphic();
|
||||
|
||||
typedef QVector<QVector<QPointF> > GraphicsData;
|
||||
enum GraphicAction {gaNone, gaZoomInRect, gaZoomRangeX, gaZoomRangeY, gaMove};
|
||||
enum Button {NoButtons = 0x0,
|
||||
AllButtons = 0xFFFFFFFF,
|
||||
Autofit = 0x01,
|
||||
Grid = 0x02,
|
||||
CursorAxis = 0x04,
|
||||
OnlyExpandY = 0x08,
|
||||
OnlyExpandX = 0x10,
|
||||
Fullscreen = 0x20,
|
||||
BorderInputs = 0x40,
|
||||
Legend = 0x80,
|
||||
Configure = 0x100,
|
||||
Save = 0x200,
|
||||
Clear = 0x800,
|
||||
Close = 0x1000,
|
||||
Pause = 0x2000,
|
||||
StandartButtons = 0x2FFF
|
||||
};
|
||||
enum Alignment {Left, Right};
|
||||
enum Graduation {Auto, Fixed};
|
||||
enum AxisType {Numeric, DateTime};
|
||||
Q_DECLARE_FLAGS(Buttons, Button)
|
||||
|
||||
QString caption() const;
|
||||
QString labelX() const {return label_x;}
|
||||
QString labelY() const {return label_y;}
|
||||
QString graphicName() const {return graphics[curGraphic].name;}
|
||||
QColor backgroundColor() const {return back_color;}
|
||||
QColor textColor() const {return text_color;}
|
||||
QColor graphicColor() const {return graphics[curGraphic].pen.color();}
|
||||
QColor gridColor() const {return grid_pen.color();}
|
||||
QColor selectionColor() const {return selpen.color();}
|
||||
Qt::PenStyle graphicStyle() const {return graphics[curGraphic].pen.style();}
|
||||
Qt::PenStyle gridStyle() const {return grid_pen.style();}
|
||||
Qt::PenStyle selectionStyle() const {return selpen.style();}
|
||||
double graphicLineWidth() const {return graphics[curGraphic].pen.widthF();}
|
||||
double graphicPointWidth() const {return graphics[curGraphic].pointWidth;}
|
||||
QColor graphicFillColor() const {return graphics[curGraphic].fill_color;}
|
||||
bool graphicVisible() const {return graphics[curGraphic].visible;}
|
||||
bool graphicLinesEnabled() const {return graphics[curGraphic].lines;}
|
||||
bool graphicPointsEnabled() const {return graphics[curGraphic].points;}
|
||||
bool graphicFillEnabled() const {return graphics[curGraphic].fill;}
|
||||
QPen graphicPen() const {return graphics[curGraphic].pen;}
|
||||
QPen gridPen() const {return grid_pen;}
|
||||
QPen selectionPen() const {return selpen;}
|
||||
QBrush selectionBrush() const {return selbrush;}
|
||||
bool navigationEnabled() const {return navigation;}
|
||||
bool openGL() const {return isOGL;}
|
||||
bool antialiasing() const {return aalias;}
|
||||
bool autoUpdate() const {return aupdate;}
|
||||
bool gridEnabled() const {return grid;}
|
||||
bool borderInputsVisible() const;
|
||||
bool statusVisible() const;
|
||||
bool legendVisible() const;
|
||||
bool paused() const {return pause_;}
|
||||
bool onlyExpandY() const {return only_expand_y;}
|
||||
bool onlyExpandX() const {return only_expand_x;}
|
||||
bool gesturesNavigation() const {return gestures;}
|
||||
bool isAutofitted() const {return isFit;}
|
||||
int currentGraphic() const {return curGraphic;}
|
||||
int graphicsCount() const {return graphics.size();}
|
||||
Graphic::Buttons buttons() const {return buttons_;}
|
||||
Graphic::Alignment buttonsPosition() const {return align;}
|
||||
double historySize() const {return history;}
|
||||
double maxVisibleTime() const {return visible_time;}
|
||||
double autoXIncrement() const {return inc_x;}
|
||||
QRectF visualRect() const {return selrect;}
|
||||
QRectF defaultRect() const {return def_rect;}
|
||||
QRectF limit() const {return limit_;}
|
||||
QRect margins() const {return margins_;}
|
||||
int minimumRepaintInterval() const {return min_repaint_int;}
|
||||
double gridNumbersMultiplierX() const {return grid_numbers_x;}
|
||||
double gridNumbersMultiplierY() const {return grid_numbers_y;}
|
||||
Graduation graduationX() const {return grad_x;}
|
||||
Graduation graduationY() const {return grad_y;}
|
||||
double graduationStepX() const {return gridx;}
|
||||
double graduationStepY() const {return gridy;}
|
||||
AxisType axisType() const {return axis_type_x;}
|
||||
QVector<QPointF> graphicData(const int index = 0) const {return graphics[index].polyline;}
|
||||
GraphicsData graphicsData() const;
|
||||
QByteArray graphicsDataRaw() const;
|
||||
QWidget * viewport() const {return canvas;}
|
||||
QByteArray save();
|
||||
void load(QByteArray ba);
|
||||
|
||||
GraphicType graphic(int arg) {if (arg < 0 || arg >= graphics.size()) return GraphicType(); return graphics[arg];}
|
||||
const QVector<GraphicType> & allGraphics() const {return graphics;}
|
||||
void setAllGraphics(const QVector<GraphicType> & g, bool update = true) {graphics = g; if (update) updateLegend();}
|
||||
|
||||
double canvas2realX(double px) const;
|
||||
double canvas2realY(double py) const;
|
||||
double real2canvasX(double px) const;
|
||||
double real2canvasY(double py) const;
|
||||
QPointF canvas2real(QPointF canvas_point) const {return QPointF(canvas2realX(canvas_point.x()), canvas2realY(canvas_point.y()));}
|
||||
QPointF real2canvas(QPointF real_point) const {return QPointF(real2canvasX(real_point.x()), real2canvasY(real_point.y()));}
|
||||
QPolygonF real2canvas(const QPolygonF & real_polygon) const;
|
||||
QPolygonF canvas2real(const QPolygonF & canvas_polygon) const;
|
||||
double getScaleX() const {return real2canvasX(1.) - real2canvasX(0.);}
|
||||
double getScaleY() const {return real2canvasY(1.) - real2canvasY(0.);}
|
||||
QPointF getScale() const {return QPointF(getScaleX(), getScaleY());}
|
||||
|
||||
public slots:
|
||||
void setCaption(const QString & str);
|
||||
void setLabelX(const QString & str) {label_x = str; hasLblX = (str.length() > 0); if (aupdate) update();}
|
||||
void setLabelY(const QString & str) {label_y = str; hasLblY = (str.length() > 0); if (aupdate) update();}
|
||||
void setGraphicName(const QString & str, int index) {graphics[index].name = str; updateLegend(); if (aupdate) update();}
|
||||
void setGraphicName(const QString & str) {graphics[curGraphic].name = str; updateLegend(); if (aupdate) update();}
|
||||
void setBackgroundColor(const QColor & color) {back_color = color; if (aupdate) update(); updateLegend();}
|
||||
void setTextColor(const QColor & color) {text_color = color; if (aupdate) update();}
|
||||
void setGraphicColor(const QColor & color, int index) {graphics[index].pen.setColor(color); updateLegend(); if (aupdate) update();}
|
||||
void setGraphicColor(const QColor & color) {setGraphicColor(color, curGraphic);}
|
||||
void setGridColor(const QColor & color) {grid_pen.setColor(color); if (aupdate) update();}
|
||||
void setSelectionColor(const QColor & color) {selpen.setColor(color);}
|
||||
void setGraphicStyle(const Qt::PenStyle & style, int index) {graphics[index].pen.setStyle(style); updateLegend(); if (aupdate) update();}
|
||||
void setGraphicStyle(const Qt::PenStyle & style) {setGraphicStyle(style, curGraphic);}
|
||||
void setGridStyle(const Qt::PenStyle & style) {grid_pen.setStyle(style); if (aupdate) update();}
|
||||
void setSelectionStyle(const Qt::PenStyle & style) {selpen.setStyle(style);}
|
||||
void setGraphicVisible(bool visible, int index) {graphics[index].visible = visible; updateLegendChecks(); if (aupdate) update();}
|
||||
void setGraphicVisible(bool visible) {setGraphicVisible(visible, curGraphic);}
|
||||
void setGraphicLineWidth(double w, int index) {if (qRound(w) == w) graphics[index].pen.setWidth(qRound(w)); else graphics[index].pen.setWidthF(w); updateLegend(); if (aupdate) update();}
|
||||
void setGraphicLineWidth(double w) {setGraphicLineWidth(w, curGraphic);}
|
||||
void setGraphicPointWidth(double w, int index) {graphics[index].pointWidth = w; updateLegend(); if (aupdate) update();}
|
||||
void setGraphicPointWidth(double w) {setGraphicPointWidth(w, curGraphic);}
|
||||
void setGraphicFillColor(const QColor & w, int index) {graphics[index].fill_color = w; updateLegend(); if (aupdate) update();}
|
||||
void setGraphicFillColor(const QColor & w) {setGraphicFillColor(w, curGraphic);}
|
||||
void setGraphicLinesEnabled(bool w, int index) {graphics[index].lines = w; updateLegend(); if (aupdate) update();}
|
||||
void setGraphicLinesEnabled(bool w) {setGraphicLinesEnabled(w, curGraphic);}
|
||||
void setGraphicPointsEnabled(bool w, int index) {graphics[index].points = w; updateLegend(); if (aupdate) update();}
|
||||
void setGraphicPointsEnabled(bool w) {setGraphicPointsEnabled(w, curGraphic);}
|
||||
void setGraphicFillEnabled(bool w, int index) {graphics[index].fill = w; updateLegend(); if (aupdate) update();}
|
||||
void setGraphicFillEnabled(bool w) {setGraphicFillEnabled(w, curGraphic);}
|
||||
void setGraphicPen(const QPen & pen, int index) {graphics[index].pen = pen; updateLegend(); if (aupdate) update();}
|
||||
void setGraphicPen(const QPen & pen) {setGraphicPen(pen, curGraphic);}
|
||||
void setGridPen(const QPen & pen) {grid_pen = pen; if (aupdate) update();}
|
||||
void setSelectionPen(const QPen & pen) {selpen = pen;}
|
||||
void setSelectionBrush(const QBrush & brush) {selbrush = brush;}
|
||||
void setNavigationEnabled(bool on) {navigation = on;}
|
||||
void setOpenGL(bool on);
|
||||
void setAntialiasing(bool enabled);
|
||||
void setAutoUpdate(bool enabled) {aupdate = enabled;}
|
||||
void setGridEnabled(bool enabled);
|
||||
void setBorderInputsVisible(bool visible);
|
||||
void setStatusVisible(bool visible);
|
||||
void setLegendVisible(bool visible);
|
||||
void setPaused(bool yes);
|
||||
void setButtons(Graphic::Buttons b);
|
||||
void setButtonsPosition(Graphic::Alignment a);
|
||||
void setHistorySize(double val);
|
||||
void setMaxVisibleTime(double val);
|
||||
void setAutoXIncrement(double val) {inc_x = val;}
|
||||
void setLimit(const QRectF & val) {limit_ = val;}
|
||||
void setMargins(const QRect & val) {margins_ = val; update();}
|
||||
void setMargins(int left_, int right_, int top_, int bottom_) {setMargins(QRect(left_, bottom_, right_, top_));}
|
||||
void setLeftMargin(int value) {margins_.moveLeft(value); setMargins(margins_);}
|
||||
void setRightMargin(int value) {margins_.setWidth(value); setMargins(margins_);}
|
||||
void setTopMargin(int value) {margins_.setHeight(value); setMargins(margins_);}
|
||||
void setBottomMargin(int value) {margins_.moveTop(value); setMargins(margins_);}
|
||||
void setMinimumRepaintInterval(const int & val) {min_repaint_int = val;}
|
||||
void setOnlyExpandY(bool yes);
|
||||
void setOnlyExpandX(bool yes);
|
||||
void setGesturesNavigation(bool yes);
|
||||
void setGraphicsData(const GraphicsData & gd);
|
||||
void setGraphicsDataRaw(const QByteArray & ba);
|
||||
|
||||
void setGridNumbersMultiplierX(double value) {grid_numbers_x = value; updateGraphics();}
|
||||
void setGridNumbersMultiplierY(double value) {grid_numbers_y = value; updateGraphics();}
|
||||
void setGraduationX(Graduation value) {grad_x = value; if (aupdate) update();;}
|
||||
void setGraduationY(Graduation value) {grad_y = value; if (aupdate) update();;}
|
||||
void setGraduationStepX(double sx) {gridx = sx; if (aupdate) update();}
|
||||
void setGraduationStepY(double sy) {gridy = sy; if (aupdate) update();}
|
||||
void setGraduationSteps(double sx, double sy) {gridx = sx; gridy = sy; if (aupdate) update();}
|
||||
void setAxisType(AxisType t) {axis_type_x = t; if (aupdate) update();}
|
||||
|
||||
void addPoint(const QPointF & p, int graphic, bool update_ = true);
|
||||
void addPoint(const QPointF & p, bool update = true) {addPoint(p, curGraphic, update);}
|
||||
void addPoint(double x, double y, int graphic, bool update = true) {addPoint(QPointF(x, y), graphic, update);}
|
||||
void addPoint(double x, double y, bool update = true) {addPoint(QPointF(x, y), update);}
|
||||
void addPoint(double y, int graphic, bool update = true) {if (graphics[graphic].polyline.isEmpty()) addPoint(QPointF(0.0, y), graphic, update); else addPoint(QPointF(graphics[graphic].max_x + inc_x, y), graphic, update);}
|
||||
void addPoint(double y, bool update = true) {if (graphics[curGraphic].polyline.isEmpty()) addPoint(QPointF(0.0, y), update); else addPoint(QPointF(graphics[curGraphic].max_x + inc_x, y), update);}
|
||||
void setGraphicData(const QVector<QPointF> & g, int graphic, bool update_ = true);
|
||||
void setGraphicData(const QVector<QPointF> & g) {setGraphicData(g, curGraphic);}
|
||||
void setGraphicProperties(const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true) {setGraphicProperties(curGraphic, name, color, style, width, visible);}
|
||||
void setGraphicProperties(int graphic, const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true);
|
||||
void addGraphic(const QString & name, const QColor & color = Qt::darkRed, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible = true);
|
||||
void addGraphic(const GraphicType & gd, bool update = true) {graphics << gd; if (update) updateLegend();}
|
||||
void setVisualRect(const QRectF & rect);
|
||||
void setDefaultRect(const QRectF & rect);
|
||||
void autofit() {on_buttonAutofit_clicked();}
|
||||
void saveImage();
|
||||
void clear();
|
||||
void update(bool force = false);
|
||||
void updateGraphics() {findGraphicsRect(); update();}
|
||||
void setCurrentGraphic(int arg) {if (arg < 0 || arg >= graphics.size()) return; curGraphic = arg;}
|
||||
void setGraphicsCount(int arg, bool update = true);
|
||||
void removeGraphic(int arg, bool update = true);
|
||||
|
||||
void zoom(float factor);
|
||||
void zoomIn() {zoom(1. / 1.2);}
|
||||
void zoomOut() {zoom(1.2);}
|
||||
void fullscreen();
|
||||
|
||||
protected:
|
||||
virtual void changeEvent(QEvent * e);
|
||||
virtual void resizeEvent(QResizeEvent * );
|
||||
virtual QSize sizeHint() const {return QSize(400, 300);}
|
||||
virtual void timerEvent(QTimerEvent * );
|
||||
virtual bool eventFilter(QObject * o, QEvent * e);
|
||||
|
||||
void prepareCanvas(QWidget * w);
|
||||
void procGesture(QGesture * g);
|
||||
void procZoom(QPointF view_center, double dzoom, Qt::KeyboardModifiers km = Qt::NoModifier);
|
||||
void totalUpdate();
|
||||
void setCurrentAction(GraphicAction action);
|
||||
void findGraphicsRect(double start_x = 0., double end_x = 0., double start_y = 0., double end_y = 0.);
|
||||
void tick(int index, bool slide = true, bool update = true);
|
||||
void repaintCanvas(bool force = false) {if (tm.elapsed() < min_repaint_int && !force) return; tm.restart(); canvas->update();}
|
||||
void drawGraphics();
|
||||
void drawGrid();
|
||||
void drawGuides();
|
||||
void drawPause();
|
||||
void drawAction();
|
||||
void updateLegend(bool es = true);
|
||||
void updateLegendChecks();
|
||||
void setCanvasCursor(QCursor cursor);
|
||||
void swapToBuffer();
|
||||
void swapToNormal() {bufferActive = false;}
|
||||
void setRectToLines();
|
||||
void checkLines();
|
||||
double splitRange(double range, int count = 1);
|
||||
double splitRangeDate(double range, int count = 1, QString * format = 0, int step[7] = 0);
|
||||
double roundTo(double value, double round_to);
|
||||
void roundDateTime(QDateTime & dt, int c[7]);
|
||||
void addDateTime(QDateTime & dt, int c[7], int mul = 1);
|
||||
QPointF absPoint(QPointF point) {return QPointF(qAbs(point.x()), qAbs(point.y()));}
|
||||
QString pointCoords(QPointF point, bool x = true, bool y = true);
|
||||
QPair<QString, QString> gridMark(double v) const;
|
||||
|
||||
Ui::Graphic * ui;
|
||||
UGLWidget * canvas_gl;
|
||||
QWidget * canvas;
|
||||
QImage * buffer;
|
||||
QPainter * painter;
|
||||
QBrush selbrush;
|
||||
QPen grid_pen, selpen;
|
||||
QColor back_color, text_color;
|
||||
QVector<GraphicType> graphics;
|
||||
int curGraphic;
|
||||
GraphicAction curaction, prevaction;
|
||||
QRectF grect, selrect, limit_, def_rect;
|
||||
QRect margins_;
|
||||
QSize font_sz;
|
||||
QPoint startpos, curpos, prevpos, gridborder;
|
||||
QPointF startpos_r, curpos_r;
|
||||
QString label_x, label_y, ppath, fp_size;
|
||||
Graphic::Buttons buttons_;
|
||||
Graphic::Alignment align;
|
||||
GraphicConf * conf;
|
||||
EvalSpinBox line_x_min, line_x_max, line_y_min, line_y_max;
|
||||
QElapsedTimer tm;
|
||||
#ifdef Q_OS_ANDROID
|
||||
QElapsedTimer tm_fscr;
|
||||
#endif
|
||||
QIcon icon_exp_x, icon_exp_y, icon_exp_sx, icon_exp_sy;
|
||||
QImage icon_pause_b, icon_pause_f;
|
||||
Graduation grad_x, grad_y;
|
||||
AxisType axis_type_x;
|
||||
double gridx, gridy, history, visible_time, inc_x, grid_numbers_x, grid_numbers_y, LN10;
|
||||
double eminx, eminy, emaxx, emaxy, pause_phase, gesture_angle;
|
||||
int lastw, lasth, min_repaint_int, timer_pause, thick;
|
||||
bool aalias, aupdate, grid, guides, isFit, isOGL, isHover, bufferActive, cancel, pause_, gestures;
|
||||
bool hasLblX, hasLblY, navigation, only_expand_y, only_expand_x, is_lines_update, leg_update, visible_update, fullscr, need_mouse_pan;
|
||||
|
||||
protected slots:
|
||||
void canvasPaintEvent();
|
||||
void canvasMouseMoveEvent(QMouseEvent * );
|
||||
void canvasMousePressEvent(QMouseEvent * );
|
||||
void canvasMouseReleaseEvent(QMouseEvent * );
|
||||
void canvasMouseDoubleClickEvent(QMouseEvent * );
|
||||
void canvasWheelEvent(QWheelEvent * );
|
||||
void canvasLeaveEvent(QEvent * );
|
||||
void canvasKeyPressEvent(QKeyEvent * );
|
||||
void graphicVisibleChange(bool checked);
|
||||
void graphicAllVisibleChange(bool checked);
|
||||
void lineXMinChanged(double value) {selrect.setLeft(value); checkLines();}
|
||||
void lineXMaxChanged(double value) {selrect.setRight(value); checkLines();}
|
||||
void lineYMinChanged(double value) {selrect.setBottom(value); checkLines();}
|
||||
void lineYMaxChanged(double value) {selrect.setTop(value); checkLines();}
|
||||
void on_buttonClose_clicked() {emit closeRequest(this);}
|
||||
void on_buttonClear_clicked() {clear(); emit cleared();}
|
||||
void on_buttonAutofit_clicked();
|
||||
void on_buttonConfigure_clicked();
|
||||
void on_buttonFullscreen_clicked() {fullscreen();}
|
||||
void on_buttonSave_clicked() {saveImage();}
|
||||
void on_checkGrid_toggled(bool checked) {grid = checked; update();}
|
||||
void on_checkGuides_toggled(bool checked);
|
||||
void on_checkExpandY_toggled(bool checked);
|
||||
void on_checkExpandX_toggled(bool checked);
|
||||
void on_checkBorderInputs_toggled(bool checked) {setBorderInputsVisible(checked);}
|
||||
void on_checkLegend_toggled(bool checked) {setLegendVisible(checked);}
|
||||
void on_checkPause_toggled(bool checked) {setPaused(checked);}
|
||||
void enterFullscreen();
|
||||
void leaveFullscreen();
|
||||
|
||||
signals:
|
||||
void beforeGraphicPaintEvent(QPainter * );
|
||||
void graphicPaintEvent(QPainter * );
|
||||
void graphicMouseMoveEvent(QPointF point, int buttons);
|
||||
void graphicMousePressEvent(QPointF point, int buttons);
|
||||
void graphicMouseReleaseEvent(QPointF point, int buttons);
|
||||
void graphicWheelEvent(QPointF point, int delta);
|
||||
void closeRequest(QWidget * );
|
||||
void cleared();
|
||||
void visualRectChanged();
|
||||
void graphicSettingsChanged();
|
||||
|
||||
};
|
||||
|
||||
|
||||
Q_DECLARE_METATYPE(Graphic::GraphicsData)
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(Graphic::Buttons)
|
||||
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const Graphic::Graduation & v) {s << (int)v; return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, Graphic::Graduation & v) {s >> *((int*)(&v)); return s;}
|
||||
|
||||
|
||||
class QAD_GRAPHIC_EXPORT __GraphicRegistrator__ {
|
||||
public:
|
||||
__GraphicRegistrator__() {
|
||||
qRegisterMetaType<QVector<QPointF> >("QVector<QPointF>");
|
||||
qRegisterMetaType<Graphic::GraphicsData>("Graphic::GraphicsData");
|
||||
qRegisterMetaTypeStreamOperators<Graphic::GraphicsData>("Graphic::GraphicsData");
|
||||
}
|
||||
};
|
||||
|
||||
#endif // GRAPHIC_H
|
||||
443
libs/graphic/graphic.ui
Normal file
443
libs/graphic/graphic.ui
Normal file
@@ -0,0 +1,443 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Graphic</class>
|
||||
<widget class="QFrame" name="Graphic">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>564</width>
|
||||
<height>433</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>150</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QWidget" name="widgetLeft" native="true">
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>-10</x>
|
||||
<y>0</y>
|
||||
<width>33</width>
|
||||
<height>420</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="layoutButtons">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonAutofit">
|
||||
<property name="toolTip">
|
||||
<string>Autofit</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_graphic.qrc">
|
||||
<normaloff>:/icons/view-autofit.png</normaloff>:/icons/view-autofit.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkGrid">
|
||||
<property name="toolTip">
|
||||
<string>Grid</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../widgets/qad_widgets.qrc">
|
||||
<normaloff>:/icons/view-grid.png</normaloff>:/icons/view-grid.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkGuides">
|
||||
<property name="toolTip">
|
||||
<string>Cursor axis</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../widgets/qad_widgets.qrc">
|
||||
<normaloff>:/icons/edit-guides.png</normaloff>:/icons/edit-guides.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkExpandY">
|
||||
<property name="toolTip">
|
||||
<string>Only expand Y</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../widgets/qad_widgets.qrc">
|
||||
<normaloff>:/icons/expand_s_y.png</normaloff>:/icons/expand_s_y.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkExpandX">
|
||||
<property name="toolTip">
|
||||
<string>Only expand X</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../widgets/qad_widgets.qrc">
|
||||
<normaloff>:/icons/expand_s_x.png</normaloff>:/icons/expand_s_x.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonFullscreen">
|
||||
<property name="toolTip">
|
||||
<string>Fullscreen</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../blockview/qad_blockview.qrc">
|
||||
<normaloff>:/icons/view-fullscreen.png</normaloff>:/icons/view-fullscreen.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkBorderInputs">
|
||||
<property name="toolTip">
|
||||
<string>Border inputs</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../widgets/qad_widgets.qrc">
|
||||
<normaloff>:/icons/border-line.png</normaloff>:/icons/border-line.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkLegend">
|
||||
<property name="toolTip">
|
||||
<string>Legend</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../widgets/qad_widgets.qrc">
|
||||
<normaloff>:/icons/legend.png</normaloff>:/icons/legend.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="checkPause">
|
||||
<property name="toolTip">
|
||||
<string>Pause</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="qad_graphic.qrc">
|
||||
<normaloff>:/icons/media-playback-pause.png</normaloff>:/icons/media-playback-pause.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonConfigure">
|
||||
<property name="toolTip">
|
||||
<string>Configure ...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../widgets/qad_widgets.qrc">
|
||||
<normaloff>:/icons/configure.png</normaloff>:/icons/configure.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonSave">
|
||||
<property name="toolTip">
|
||||
<string>Save image ...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../utils/qad_utils.qrc">
|
||||
<normaloff>:/icons/document-save.png</normaloff>:/icons/document-save.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonClear">
|
||||
<property name="toolTip">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../utils/qad_utils.qrc">
|
||||
<normaloff>:/icons/edit-clear.png</normaloff>:/icons/edit-clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="buttonClose">
|
||||
<property name="toolTip">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../widgets/qad_widgets.qrc">
|
||||
<normaloff>:/icons/dialog-close.png</normaloff>:/icons/dialog-close.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>79</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="labelCaption">
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" rowspan="2">
|
||||
<widget class="QWidget" name="widgetRight" native="true"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QWidget" name="widgetLX" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="2" colspan="2">
|
||||
<layout class="QVBoxLayout" name="layoutCanvas">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="UWidget" name="canvas_raster" native="true">
|
||||
<property name="mouseTracking">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<widget class="QWidget" name="widgetLY" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="status">
|
||||
<property name="text">
|
||||
<string>Cursor: ( ; )</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QWidget" name="widgetLegend" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="layoutLegend">
|
||||
<property name="leftMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="horizontalSpacing">
|
||||
<number>4</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>UWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>uwidget.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../utils/qad_utils.qrc"/>
|
||||
<include location="../widgets/qad_widgets.qrc"/>
|
||||
<include location="../blockview/qad_blockview.qrc"/>
|
||||
<include location="qad_graphic.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
107
libs/graphic/graphic_conf.cpp
Normal file
107
libs/graphic/graphic_conf.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
#include "graphic_conf.h"
|
||||
#include "qad_types.h"
|
||||
#include "ui_graphic_conf.h"
|
||||
|
||||
|
||||
GraphicConf::GraphicConf(QVector<GraphicType> & graphics_, QWidget * parent): QDialog(parent), graphics(graphics_) {
|
||||
ui = new Ui::GraphicConf();
|
||||
ui->setupUi(this);
|
||||
QStringList styles;
|
||||
int fh = qMax<int>(fontMetrics().size(0, "0").height(), 22);
|
||||
int thick = lineThickness();
|
||||
QSize sz(fh * 2.5, fh);
|
||||
styles << tr("NoPen") << tr("Solid") << tr("Dash")
|
||||
<< tr("Dot") << tr("Dash-Dot") << tr("Dash-Dot-Dot");
|
||||
ui->comboStyleGrid->setIconSize(sz);
|
||||
ui->comboStyleGraphic->setIconSize(sz);
|
||||
ui->cbGraphicNames->setIconSize(sz);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
QPixmap pix(sz);
|
||||
pix.fill();
|
||||
QPainter p(&pix);
|
||||
p.setPen(QPen(Qt::black, thick, (Qt::PenStyle)i));
|
||||
p.drawLine(0, pix.height() / 2, pix.width(), pix.height() / 2);
|
||||
p.end();
|
||||
ui->comboStyleGraphic->addItem(QIcon(pix), styles[i]);
|
||||
ui->comboStyleGrid->addItem(QIcon(pix), styles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GraphicConf::changeEvent(QEvent * e) {
|
||||
QDialog::changeEvent(e);
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
ui->retranslateUi(this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GraphicConf::readParams() {
|
||||
ui->cbGraphicNames->clear();
|
||||
for (int i = 0; i < graphicItems.size(); i++)
|
||||
ui->cbGraphicNames->addItem(graphicItems[i].icon, graphicItems[i].name);
|
||||
}
|
||||
|
||||
|
||||
void GraphicConf::on_cbGraphicNames_currentIndexChanged(int i) {
|
||||
if (i < 0) return;
|
||||
if (graphicItems.isEmpty()) return;
|
||||
ui->comboStyleGraphic->setCurrentIndex((int)graphics[i].pen.style());
|
||||
ui->colorGraphic->setColor(graphics[i].pen.color());
|
||||
ui->colorFill->setColor(graphics[i].fill_color);
|
||||
ui->spinLineWidthGraphic->setValue(graphics[i].pen.widthF());
|
||||
ui->spinPointWidthGraphic->setValue(graphics[i].pointWidth);
|
||||
ui->checkLines->setChecked(graphics[i].lines);
|
||||
ui->checkPoints->setChecked(graphics[i].points);
|
||||
ui->checkFill->setChecked(graphics[i].fill);
|
||||
}
|
||||
|
||||
|
||||
void GraphicConf::on_colorGraphic_colorChanged(const QColor & c) {
|
||||
if (graphicItems.isEmpty()) return;
|
||||
graphics[ui->cbGraphicNames->currentIndex()].pen.setColor(c);
|
||||
}
|
||||
|
||||
|
||||
void GraphicConf::on_comboStyleGraphic_currentIndexChanged(int index) {
|
||||
if (graphicItems.isEmpty()) return;
|
||||
graphics[ui->cbGraphicNames->currentIndex()].pen.setStyle((Qt::PenStyle)index);
|
||||
}
|
||||
|
||||
|
||||
void GraphicConf::on_spinLineWidthGraphic_valueChanged(double value) {
|
||||
if (graphicItems.isEmpty()) return;
|
||||
if (qRound(value) == value) graphics[ui->cbGraphicNames->currentIndex()].pen.setWidth(qRound(value));
|
||||
else graphics[ui->cbGraphicNames->currentIndex()].pen.setWidthF(value);
|
||||
}
|
||||
|
||||
|
||||
void GraphicConf::on_spinPointWidthGraphic_valueChanged(double value) {
|
||||
if (graphicItems.isEmpty()) return;
|
||||
graphics[ui->cbGraphicNames->currentIndex()].pointWidth = value;
|
||||
}
|
||||
|
||||
|
||||
void GraphicConf::on_checkLines_toggled(bool on) {
|
||||
if (graphicItems.isEmpty()) return;
|
||||
graphics[ui->cbGraphicNames->currentIndex()].lines = on;
|
||||
}
|
||||
|
||||
|
||||
void GraphicConf::on_checkPoints_toggled(bool on) {
|
||||
if (graphicItems.isEmpty()) return;
|
||||
graphics[ui->cbGraphicNames->currentIndex()].points = on;
|
||||
}
|
||||
|
||||
|
||||
void GraphicConf::on_checkFill_toggled(bool on) {
|
||||
if (graphicItems.isEmpty()) return;
|
||||
graphics[ui->cbGraphicNames->currentIndex()].fill = on;
|
||||
}
|
||||
|
||||
|
||||
void GraphicConf::on_colorFill_colorChanged(const QColor & color) {
|
||||
if (graphicItems.isEmpty()) return;
|
||||
graphics[ui->cbGraphicNames->currentIndex()].fill_color = color;
|
||||
}
|
||||
111
libs/graphic/graphic_conf.h
Normal file
111
libs/graphic/graphic_conf.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
QAD - Qt ADvanced
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GRAPHIC_CONF_H
|
||||
#define GRAPHIC_CONF_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QCheckBox>
|
||||
#include <QPen>
|
||||
#include <QPainter>
|
||||
#include "qad_graphic_export.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class GraphicConf;
|
||||
}
|
||||
|
||||
|
||||
struct QAD_GRAPHIC_EXPORT GraphicType {
|
||||
GraphicType(QString name_ = "y(x)", QColor color = Qt::red, Qt::PenStyle style = Qt::SolidLine, double width = 0., bool visible_ = true) {
|
||||
pen.setColor(color);
|
||||
pen.setStyle(style);
|
||||
lines = true;
|
||||
points = false;
|
||||
fill = false;
|
||||
fill_color = Qt::yellow;
|
||||
if (qRound(width) == width) pen.setWidth(qRound(width));
|
||||
else pen.setWidthF(width);
|
||||
pen.setWidth(1);
|
||||
pen.setCosmetic(true);
|
||||
max_x = 0.;
|
||||
name = name_;
|
||||
visible = visible_;
|
||||
pointWidth = 2.;
|
||||
pb = new QCheckBox(name);
|
||||
}
|
||||
//~GraphicType() {delete pb;}
|
||||
QString name;
|
||||
QPolygonF polyline;
|
||||
QPolygonF polyline_pause;
|
||||
QPen pen;
|
||||
QColor fill_color;
|
||||
bool lines;
|
||||
bool points;
|
||||
bool fill;
|
||||
double pointWidth;
|
||||
double max_x;
|
||||
double max_x_pause;
|
||||
QCheckBox * pb;
|
||||
QIcon icon;
|
||||
bool visible;
|
||||
QRectF cvrect;
|
||||
};
|
||||
|
||||
|
||||
inline QDataStream & operator <<(QDataStream & s, const GraphicType & v) {s << v.name << v.pen << v.fill_color << v.lines << v.points << v.fill << v.pointWidth << v.visible; return s;}
|
||||
inline QDataStream & operator >>(QDataStream & s, GraphicType & v) {s >> v.name >> v.pen >> v.fill_color >> v.lines >> v.points >> v.fill >> v.pointWidth >> v.visible; return s;}
|
||||
|
||||
|
||||
class QAD_GRAPHIC_EXPORT GraphicConf: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class Graphic;
|
||||
public:
|
||||
explicit GraphicConf(QVector<GraphicType> & graphics_, QWidget * parent = 0);
|
||||
|
||||
struct QAD_GRAPHIC_EXPORT GraphicItem {
|
||||
QString name;
|
||||
QIcon icon;
|
||||
};
|
||||
|
||||
void readParams();
|
||||
|
||||
QVector<GraphicType> & graphics;
|
||||
QVector<GraphicItem> graphicItems;
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent * e);
|
||||
|
||||
Ui::GraphicConf * ui;
|
||||
|
||||
private slots:
|
||||
void on_cbGraphicNames_currentIndexChanged(int index);
|
||||
void on_colorGraphic_colorChanged(const QColor &);
|
||||
void on_colorFill_colorChanged(const QColor &);
|
||||
void on_comboStyleGraphic_currentIndexChanged(int index);
|
||||
void on_spinLineWidthGraphic_valueChanged(double value);
|
||||
void on_spinPointWidthGraphic_valueChanged(double value);
|
||||
void on_checkLines_toggled(bool on);
|
||||
void on_checkPoints_toggled(bool on);
|
||||
void on_checkFill_toggled(bool on);
|
||||
|
||||
};
|
||||
|
||||
#endif // GRAPHIC_CONF_H
|
||||
644
libs/graphic/graphic_conf.ui
Normal file
644
libs/graphic/graphic_conf.ui
Normal file
@@ -0,0 +1,644 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GraphicConf</class>
|
||||
<widget class="QDialog" name="GraphicConf">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::WindowModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>500</width>
|
||||
<height>583</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Graphic parameters</string>
|
||||
</property>
|
||||
<property name="modal">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Appearance</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="checkInputs">
|
||||
<property name="text">
|
||||
<string>Border inputs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="checkAAlias">
|
||||
<property name="text">
|
||||
<string>Antialiasing</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="checkStatus">
|
||||
<property name="text">
|
||||
<string>Status bar</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="checkOGL">
|
||||
<property name="text">
|
||||
<string>OpenGL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QCheckBox" name="checkLegend">
|
||||
<property name="text">
|
||||
<string>Legend</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Background color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="ColorButton" name="colorBackground">
|
||||
<property name="useAlphaChannel">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Text color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="ColorButton" name="colorText">
|
||||
<property name="useAlphaChannel">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QGroupBox" name="groupBox_1">
|
||||
<property name="title">
|
||||
<string>Graphics</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QComboBox" name="cbGraphicNames">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="ColorButton" name="colorGraphic">
|
||||
<property name="useAlphaChannel">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Style:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboStyleGraphic"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="checkLines">
|
||||
<property name="text">
|
||||
<string>Lines width:</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinLineWidthGraphic">
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="checkPoints">
|
||||
<property name="text">
|
||||
<string>Points width:</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinPointWidthGraphic">
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999.990000000000009</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="checkFill">
|
||||
<property name="text">
|
||||
<string>Fill:</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="ColorButton" name="colorFill">
|
||||
<property name="useAlphaChannel">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Grid</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Color:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="ColorButton" name="colorGrid">
|
||||
<property name="useAlphaChannel">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Style:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="comboStyleGrid"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Width:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinWidthGrid">
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Step X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Step Y:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="checkGridAutoX">
|
||||
<property name="text">
|
||||
<string>Auto X</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="checkGridAutoY">
|
||||
<property name="text">
|
||||
<string>Auto Y</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="EvalSpinBox" name="spinGridStepY">
|
||||
<property name="expression">
|
||||
<string>30</string>
|
||||
</property>
|
||||
<property name="defaultText">
|
||||
<string>30</string>
|
||||
</property>
|
||||
<property name="clearButtonVisible">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="EvalSpinBox" name="spinGridStepX">
|
||||
<property name="expression">
|
||||
<string>50</string>
|
||||
</property>
|
||||
<property name="defaultText">
|
||||
<string>50</string>
|
||||
</property>
|
||||
<property name="clearButtonVisible">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Margins</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="1" column="5">
|
||||
<widget class="QSpinBox" name="spinMarginR">
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QSpinBox" name="spinMarginB">
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="labelAll">
|
||||
<property name="text">
|
||||
<string>All:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="spinMarginL">
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Right:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Left:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>Bottom:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QSpinBox" name="spinMarginT">
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Top:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QSpinBox" name="spinMarginT_2">
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ColorButton</class>
|
||||
<extends>QPushButton</extends>
|
||||
<header>colorbutton.h</header>
|
||||
<slots>
|
||||
<signal>colorChanged(QColor)</signal>
|
||||
</slots>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>EvalSpinBox</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>evalspinbox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>checkAAlias</tabstop>
|
||||
<tabstop>checkOGL</tabstop>
|
||||
<tabstop>colorBackground</tabstop>
|
||||
<tabstop>colorText</tabstop>
|
||||
<tabstop>colorGrid</tabstop>
|
||||
<tabstop>comboStyleGrid</tabstop>
|
||||
<tabstop>spinWidthGrid</tabstop>
|
||||
<tabstop>cbGraphicNames</tabstop>
|
||||
<tabstop>colorGraphic</tabstop>
|
||||
<tabstop>comboStyleGraphic</tabstop>
|
||||
<tabstop>checkLines</tabstop>
|
||||
<tabstop>spinLineWidthGraphic</tabstop>
|
||||
<tabstop>checkPoints</tabstop>
|
||||
<tabstop>spinPointWidthGraphic</tabstop>
|
||||
<tabstop>buttonBox</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>GraphicConf</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>255</x>
|
||||
<y>641</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>245</x>
|
||||
<y>207</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>checkLines</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>spinLineWidthGraphic</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>322</x>
|
||||
<y>410</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>415</x>
|
||||
<y>411</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>checkPoints</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>spinPointWidthGraphic</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>322</x>
|
||||
<y>434</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>415</x>
|
||||
<y>435</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>GraphicConf</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>294</x>
|
||||
<y>641</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>288</x>
|
||||
<y>268</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>checkFill</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>colorFill</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>322</x>
|
||||
<y>458</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>415</x>
|
||||
<y>460</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinMarginT_2</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>spinMarginT</receiver>
|
||||
<slot>setValue(int)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>259</x>
|
||||
<y>221</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>249</x>
|
||||
<y>191</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinMarginT_2</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>spinMarginR</receiver>
|
||||
<slot>setValue(int)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>268</x>
|
||||
<y>220</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>371</x>
|
||||
<y>220</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinMarginT_2</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>spinMarginB</receiver>
|
||||
<slot>setValue(int)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>233</x>
|
||||
<y>230</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>234</x>
|
||||
<y>252</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>spinMarginT_2</sender>
|
||||
<signal>valueChanged(int)</signal>
|
||||
<receiver>spinMarginL</receiver>
|
||||
<slot>setValue(int)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>213</x>
|
||||
<y>230</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>133</x>
|
||||
<y>229</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
||||
387
libs/graphic/lang/qad_graphic_en.ts
Normal file
387
libs/graphic/lang/qad_graphic_en.ts
Normal file
@@ -0,0 +1,387 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="en_US">
|
||||
<context>
|
||||
<name>Graphic</name>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="53"/>
|
||||
<source>Autofit</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="64"/>
|
||||
<source>Grid</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="81"/>
|
||||
<source>Cursor axis</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="95"/>
|
||||
<source>Only expand Y</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="109"/>
|
||||
<source>Only expand X</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="123"/>
|
||||
<source>Fullscreen</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="134"/>
|
||||
<source>Border inputs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="151"/>
|
||||
<source>Legend</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="168"/>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="182"/>
|
||||
<source>Configure ...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="193"/>
|
||||
<source>Save image ...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="220"/>
|
||||
<source>Clear</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="231"/>
|
||||
<source>Close</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="396"/>
|
||||
<source>Cursor: ( ; )</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="387"/>
|
||||
<location filename="../graphic.cpp" line="1231"/>
|
||||
<source>Cursor: </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="402"/>
|
||||
<source>Selection</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="403"/>
|
||||
<source>Size</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="407"/>
|
||||
<location filename="../graphic.cpp" line="413"/>
|
||||
<source>Range</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="408"/>
|
||||
<location filename="../graphic.cpp" line="414"/>
|
||||
<source>Length</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="525"/>
|
||||
<location filename="../graphic.cpp" line="566"/>
|
||||
<source>Cursor</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="814"/>
|
||||
<source>Save Image</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="865"/>
|
||||
<source>y(x)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="1678"/>
|
||||
<source>Check all</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>GraphicConf</name>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="17"/>
|
||||
<source>Graphic parameters</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="26"/>
|
||||
<source>Appearance</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="34"/>
|
||||
<source>Border inputs</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="41"/>
|
||||
<source>Antialiasing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="48"/>
|
||||
<source>Status bar</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="55"/>
|
||||
<source>OpenGL</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="62"/>
|
||||
<source>Legend</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="82"/>
|
||||
<source>Background color:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="102"/>
|
||||
<source>Text color:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="121"/>
|
||||
<source>Graphics</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="140"/>
|
||||
<location filename="../graphic_conf.ui" line="236"/>
|
||||
<source>Color:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="154"/>
|
||||
<location filename="../graphic_conf.ui" line="250"/>
|
||||
<source>Style:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="164"/>
|
||||
<source>Lines width:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="184"/>
|
||||
<source>Points width:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="207"/>
|
||||
<source>Fill:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="227"/>
|
||||
<source>Grid</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="260"/>
|
||||
<source>Width:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="274"/>
|
||||
<source>Step X:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="281"/>
|
||||
<source>Step Y:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="288"/>
|
||||
<source>Auto X</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="298"/>
|
||||
<source>Auto Y</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="308"/>
|
||||
<location filename="../graphic_conf.ui" line="311"/>
|
||||
<source>30</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="321"/>
|
||||
<location filename="../graphic_conf.ui" line="324"/>
|
||||
<source>50</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="357"/>
|
||||
<source>Margins</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="363"/>
|
||||
<location filename="../graphic_conf.ui" line="373"/>
|
||||
<location filename="../graphic_conf.ui" line="393"/>
|
||||
<location filename="../graphic_conf.ui" line="433"/>
|
||||
<location filename="../graphic_conf.ui" line="453"/>
|
||||
<source> px</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="383"/>
|
||||
<source>All:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="403"/>
|
||||
<source>Right:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="413"/>
|
||||
<source>Left:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="423"/>
|
||||
<source>Bottom:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="443"/>
|
||||
<source>Top:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.cpp" line="13"/>
|
||||
<source>NoPen</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.cpp" line="13"/>
|
||||
<source>Solid</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.cpp" line="13"/>
|
||||
<source>Dash</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.cpp" line="14"/>
|
||||
<source>Dot</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.cpp" line="14"/>
|
||||
<source>Dash-Dot</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.cpp" line="14"/>
|
||||
<source>Dash-Dot-Dot</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="14"/>
|
||||
<source>QPICalculator</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="29"/>
|
||||
<source>Calculator</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="60"/>
|
||||
<source>Expression</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="65"/>
|
||||
<source>Result</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="76"/>
|
||||
<source>Correct</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="83"/>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="100"/>
|
||||
<source>0</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="111"/>
|
||||
<source>Variables</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="139"/>
|
||||
<source>Name</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="144"/>
|
||||
<source>Value</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="169"/>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="290"/>
|
||||
<source>Del</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="219"/>
|
||||
<source>Graphics</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="260"/>
|
||||
<source>On</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="265"/>
|
||||
<source>Function</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
391
libs/graphic/lang/qad_graphic_ru.ts
Normal file
391
libs/graphic/lang/qad_graphic_ru.ts
Normal file
@@ -0,0 +1,391 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="ru_RU">
|
||||
<context>
|
||||
<name>Graphic</name>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="53"/>
|
||||
<source>Autofit</source>
|
||||
<translation>Автомасштаб</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="64"/>
|
||||
<source>Grid</source>
|
||||
<translation>Сетка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="81"/>
|
||||
<source>Cursor axis</source>
|
||||
<translation>Плавающие оси</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="95"/>
|
||||
<source>Only expand Y</source>
|
||||
<translation>Только расширять Y</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="109"/>
|
||||
<source>Only expand X</source>
|
||||
<translation>Только расширять X</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="123"/>
|
||||
<source>Fullscreen</source>
|
||||
<translation>Во весь экран</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="134"/>
|
||||
<source>Border inputs</source>
|
||||
<translation>Граничные поля ввода</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="151"/>
|
||||
<source>Legend</source>
|
||||
<translation>Легенда</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="168"/>
|
||||
<source>Pause</source>
|
||||
<translation>Пауза</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="182"/>
|
||||
<source>Configure ...</source>
|
||||
<translation>Настроить ...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="193"/>
|
||||
<source>Save image ...</source>
|
||||
<translation>Сохранить изображение ...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="220"/>
|
||||
<source>Clear</source>
|
||||
<translation>Очистить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="231"/>
|
||||
<source>Close</source>
|
||||
<translation>Закрыть</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.ui" line="396"/>
|
||||
<source>Cursor: ( ; )</source>
|
||||
<translation>Курсор: ( ; )</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="387"/>
|
||||
<location filename="../graphic.cpp" line="1231"/>
|
||||
<source>Cursor: </source>
|
||||
<translation>Курсор: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="402"/>
|
||||
<source>Selection</source>
|
||||
<translation>Выделение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="403"/>
|
||||
<source>Size</source>
|
||||
<translation>Размер</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="407"/>
|
||||
<location filename="../graphic.cpp" line="413"/>
|
||||
<source>Range</source>
|
||||
<translation>Диапазон</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="408"/>
|
||||
<location filename="../graphic.cpp" line="414"/>
|
||||
<source>Length</source>
|
||||
<translation>Длина</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="525"/>
|
||||
<location filename="../graphic.cpp" line="566"/>
|
||||
<source>Cursor</source>
|
||||
<translation>Курсор</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="814"/>
|
||||
<source>Save Image</source>
|
||||
<translation>Сохранить изображение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="865"/>
|
||||
<source>y(x)</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic.cpp" line="1678"/>
|
||||
<source>Check all</source>
|
||||
<translation>Выбрать все</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>GraphicConf</name>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="17"/>
|
||||
<source>Graphic parameters</source>
|
||||
<translation>Параметры графика</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="26"/>
|
||||
<source>Appearance</source>
|
||||
<translation>Внешний вид</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="34"/>
|
||||
<source>Border inputs</source>
|
||||
<translation>Граничные поля ввода</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="41"/>
|
||||
<source>Antialiasing</source>
|
||||
<translation>Сглаживание</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="48"/>
|
||||
<source>Status bar</source>
|
||||
<translation>Панель статуса</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="55"/>
|
||||
<source>OpenGL</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="62"/>
|
||||
<source>Legend</source>
|
||||
<translation>Легенда</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="82"/>
|
||||
<source>Background color:</source>
|
||||
<translation>Цвет фона:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="102"/>
|
||||
<source>Text color:</source>
|
||||
<translation>Цвет текста:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="121"/>
|
||||
<source>Graphics</source>
|
||||
<translation>Графики</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="140"/>
|
||||
<location filename="../graphic_conf.ui" line="236"/>
|
||||
<source>Color:</source>
|
||||
<translation>Цвет:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="154"/>
|
||||
<location filename="../graphic_conf.ui" line="250"/>
|
||||
<source>Style:</source>
|
||||
<translation>Стиль:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="164"/>
|
||||
<source>Lines width:</source>
|
||||
<translation>Толщина линий:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="184"/>
|
||||
<source>Points width:</source>
|
||||
<translation>Толщина точек:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="207"/>
|
||||
<source>Fill:</source>
|
||||
<translation>Заливка:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="227"/>
|
||||
<source>Grid</source>
|
||||
<translation>Сетка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="260"/>
|
||||
<source>Width:</source>
|
||||
<translation>Толщина:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="274"/>
|
||||
<source>Step X:</source>
|
||||
<translation>Шаг X:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="281"/>
|
||||
<source>Step Y:</source>
|
||||
<translation>Шаг Y:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="288"/>
|
||||
<source>Auto X</source>
|
||||
<translation>Авто X</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="298"/>
|
||||
<source>Auto Y</source>
|
||||
<translation>Авто Y</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="308"/>
|
||||
<location filename="../graphic_conf.ui" line="311"/>
|
||||
<source>30</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="321"/>
|
||||
<location filename="../graphic_conf.ui" line="324"/>
|
||||
<source>50</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Auto step</source>
|
||||
<translation type="obsolete">Автоматический шаг</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="357"/>
|
||||
<source>Margins</source>
|
||||
<translation>Поля</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="363"/>
|
||||
<location filename="../graphic_conf.ui" line="373"/>
|
||||
<location filename="../graphic_conf.ui" line="393"/>
|
||||
<location filename="../graphic_conf.ui" line="433"/>
|
||||
<location filename="../graphic_conf.ui" line="453"/>
|
||||
<source> px</source>
|
||||
<translation> пикс</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="383"/>
|
||||
<source>All:</source>
|
||||
<translation>Все:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="403"/>
|
||||
<source>Right:</source>
|
||||
<translation>Правое:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="413"/>
|
||||
<source>Left:</source>
|
||||
<translation>Левое:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="423"/>
|
||||
<source>Bottom:</source>
|
||||
<translation>Нижнее:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.ui" line="443"/>
|
||||
<source>Top:</source>
|
||||
<translation>Верхнее:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.cpp" line="13"/>
|
||||
<source>NoPen</source>
|
||||
<translation>НетЛинии</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.cpp" line="13"/>
|
||||
<source>Solid</source>
|
||||
<translation>Сплошная</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.cpp" line="13"/>
|
||||
<source>Dash</source>
|
||||
<translation>Штриховая</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.cpp" line="14"/>
|
||||
<source>Dot</source>
|
||||
<translation>Пунктирная</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.cpp" line="14"/>
|
||||
<source>Dash-Dot</source>
|
||||
<translation>ШтрихПунктирная</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../graphic_conf.cpp" line="14"/>
|
||||
<source>Dash-Dot-Dot</source>
|
||||
<translation>ШтрихПунктирПунктирная</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="14"/>
|
||||
<source>QPICalculator</source>
|
||||
<translation>Калькулятор</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="29"/>
|
||||
<source>Calculator</source>
|
||||
<translation>Калькулятор</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="60"/>
|
||||
<source>Expression</source>
|
||||
<translation>Выражение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="65"/>
|
||||
<source>Result</source>
|
||||
<translation>Результат</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="76"/>
|
||||
<source>Correct</source>
|
||||
<translation>Корректно</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="83"/>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="100"/>
|
||||
<source>0</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="111"/>
|
||||
<source>Variables</source>
|
||||
<translation>Переменные</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="139"/>
|
||||
<source>Name</source>
|
||||
<translation>Имя</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="144"/>
|
||||
<source>Value</source>
|
||||
<translation>Значение</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="169"/>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="290"/>
|
||||
<source>Del</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="219"/>
|
||||
<source>Graphics</source>
|
||||
<translation>Графики</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="260"/>
|
||||
<source>On</source>
|
||||
<translation>Вкл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../qpicalculator/mainwindow.ui" line="265"/>
|
||||
<source>Function</source>
|
||||
<translation>Функция</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
2
libs/graphic/lang/update.bat
Normal file
2
libs/graphic/lang/update.bat
Normal file
@@ -0,0 +1,2 @@
|
||||
lupdate ../ -ts qad_graphic_ru.ts
|
||||
lupdate ../ -ts qad_graphic_en.ts
|
||||
1
libs/graphic/plugin/CMakeLists.txt
Normal file
1
libs/graphic/plugin/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
qad_plugin(graphic "Gui;Widgets;OpenGL" "")
|
||||
69
libs/graphic/plugin/graphicplugin.cpp
Normal file
69
libs/graphic/plugin/graphicplugin.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#include "graphic.h"
|
||||
#include "graphicplugin.h"
|
||||
#include <QtCore/QtPlugin>
|
||||
|
||||
|
||||
GraphicPlugin::GraphicPlugin(QObject * parent): QObject(parent) {
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
|
||||
void GraphicPlugin::initialize(QDesignerFormEditorInterface * /* core */) {
|
||||
if (m_initialized)
|
||||
return;
|
||||
|
||||
// Add extension registrations, etc. here
|
||||
|
||||
m_initialized = true;
|
||||
}
|
||||
|
||||
|
||||
bool GraphicPlugin::isInitialized() const {
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
|
||||
QWidget * GraphicPlugin::createWidget(QWidget * parent) {
|
||||
return new Graphic(parent);
|
||||
}
|
||||
|
||||
|
||||
QString GraphicPlugin::name() const {
|
||||
return QLatin1String("Graphic");
|
||||
}
|
||||
|
||||
|
||||
QString GraphicPlugin::group() const {
|
||||
return QLatin1String("Display Widgets");
|
||||
}
|
||||
|
||||
|
||||
QIcon GraphicPlugin::icon() const {
|
||||
return QIcon(":/icons/graphic.png");
|
||||
}
|
||||
|
||||
|
||||
QString GraphicPlugin::toolTip() const {
|
||||
return QLatin1String("");//QLatin1String("Widget for display any math graphics with grid and navigation");
|
||||
}
|
||||
|
||||
|
||||
QString GraphicPlugin::whatsThis() const {
|
||||
return QLatin1String("");
|
||||
}
|
||||
|
||||
|
||||
bool GraphicPlugin::isContainer() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QString GraphicPlugin::domXml() const {
|
||||
return QLatin1String("<widget class=\"Graphic\" name=\"graphic\">\n</widget>\n");
|
||||
}
|
||||
|
||||
|
||||
QString GraphicPlugin::includeFile() const {
|
||||
return QLatin1String("graphic.h");
|
||||
}
|
||||
|
||||
36
libs/graphic/plugin/graphicplugin.h
Normal file
36
libs/graphic/plugin/graphicplugin.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef GRAPHICPLUGIN_H
|
||||
#define GRAPHICPLUGIN_H
|
||||
|
||||
#include <QObject>
|
||||
#if QT_VERSION >= 0x050000
|
||||
# include <QtUiPlugin/QDesignerCustomWidgetInterface>
|
||||
#else
|
||||
# include <QDesignerCustomWidgetInterface>
|
||||
#endif
|
||||
|
||||
class GraphicPlugin: public QObject, public QDesignerCustomWidgetInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetInterface)
|
||||
|
||||
public:
|
||||
GraphicPlugin(QObject * parent = 0);
|
||||
|
||||
bool isContainer() const;
|
||||
bool isInitialized() const;
|
||||
QIcon icon() const;
|
||||
QString domXml() const;
|
||||
QString group() const;
|
||||
QString includeFile() const;
|
||||
QString name() const;
|
||||
QString toolTip() const;
|
||||
QString whatsThis() const;
|
||||
QWidget * createWidget(QWidget * parent);
|
||||
void initialize(QDesignerFormEditorInterface * core);
|
||||
|
||||
private:
|
||||
bool m_initialized;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
17
libs/graphic/plugin/qad_graphic.cpp
Normal file
17
libs/graphic/plugin/qad_graphic.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "qad_graphic.h"
|
||||
#include "graphicplugin.h"
|
||||
|
||||
QADGraphic::QADGraphic(QObject * parent): QObject(parent)
|
||||
{
|
||||
m_widgets.append(new GraphicPlugin(this));
|
||||
}
|
||||
|
||||
|
||||
QList<QDesignerCustomWidgetInterface * > QADGraphic::customWidgets() const {
|
||||
return m_widgets;
|
||||
}
|
||||
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
Q_EXPORT_PLUGIN2(qad_graphic_plugin, QADGraphic)
|
||||
#endif
|
||||
23
libs/graphic/plugin/qad_graphic.h
Normal file
23
libs/graphic/plugin/qad_graphic.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef QAD_GRAPHIC_H
|
||||
#define QAD_GRAPHIC_H
|
||||
|
||||
#include <QtDesigner/QtDesigner>
|
||||
#include <QtCore/qplugin.h>
|
||||
|
||||
class QADGraphic: public QObject, public QDesignerCustomWidgetCollectionInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(QDesignerCustomWidgetCollectionInterface)
|
||||
#if QT_VERSION >= 0x050000
|
||||
Q_PLUGIN_METADATA(IID "qad.graphic")
|
||||
#endif
|
||||
public:
|
||||
explicit QADGraphic(QObject * parent = 0);
|
||||
virtual QList<QDesignerCustomWidgetInterface * > customWidgets() const;
|
||||
|
||||
private:
|
||||
QList<QDesignerCustomWidgetInterface * > m_widgets;
|
||||
|
||||
};
|
||||
|
||||
#endif // QAD_GRAPHIC_H
|
||||
28
libs/graphic/qad_graphic.qrc
Normal file
28
libs/graphic/qad_graphic.qrc
Normal file
@@ -0,0 +1,28 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>../../icons/media-playback-pause.png</file>
|
||||
<file>../../icons/dialog-close.png</file>
|
||||
<file>../../icons/edit-clear.png</file>
|
||||
<file>../../icons/edit-guides.png</file>
|
||||
<file>../../icons/view-grid.png</file>
|
||||
<file>../../icons/view-autofit.png</file>
|
||||
<file>../../icons/configure.png</file>
|
||||
<file>../../icons/document-save.png</file>
|
||||
<file>../../icons/edit-clear-locationbar-rtl.png</file>
|
||||
<file>../../icons/edit-find.png</file>
|
||||
<file>../../icons/list-add.png</file>
|
||||
<file>../../icons/edit-delete.png</file>
|
||||
<file>../../icons/edit-copy.png</file>
|
||||
<file>../../icons/edit-paste.png</file>
|
||||
<file>../../icons/expand_s_x.png</file>
|
||||
<file>../../icons/expand_s_y.png</file>
|
||||
<file>../../icons/expand_x.png</file>
|
||||
<file>../../icons/expand_y.png</file>
|
||||
<file>../../icons/border-line.png</file>
|
||||
<file>../../icons/legend.png</file>
|
||||
<file>../../icons/graphic.png</file>
|
||||
<file>../../icons/view-fullscreen.png</file>
|
||||
<file>../../icons/pause-back.png</file>
|
||||
<file>../../icons/pause-front.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
69
libs/graphic/uglwidget.h
Normal file
69
libs/graphic/uglwidget.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#ifndef UGLWIDGET_H
|
||||
#define UGLWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDebug>
|
||||
#if QT_VERSION >= 0x050400
|
||||
# include <QOpenGLWidget>
|
||||
typedef QOpenGLWidget __GLWidget__;
|
||||
#else
|
||||
# include <QGLWidget>
|
||||
typedef QGLWidget __GLWidget__;
|
||||
# ifndef GL_MULTISAMPLE
|
||||
# define GL_MULTISAMPLE 0x809D
|
||||
# endif
|
||||
#endif
|
||||
#include "qad_graphic_export.h"
|
||||
|
||||
|
||||
class QAD_GRAPHIC_EXPORT UGLWidget: public __GLWidget__
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
#if QT_VERSION >= 0x050400
|
||||
UGLWidget(QWidget * parent = 0): __GLWidget__(parent) {QSurfaceFormat sf = format(); sf.setSamples(8); setFormat(sf);}
|
||||
#else
|
||||
UGLWidget(QWidget * parent = 0): __GLWidget__(QGLFormat(QGL::DoubleBuffer | QGL::AlphaChannel | QGL::DirectRendering | QGL::SampleBuffers), parent) {}
|
||||
#endif
|
||||
//UGLWidget(QGLContext * context, QWidget * parent = 0): __GLWidget__(context, parent) {}
|
||||
|
||||
#if QT_VERSION >= 0x050400
|
||||
QImage grabFrameBuffer() {return grabFramebuffer();}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
#if QT_VERSION >= 0x050400
|
||||
virtual void paintGL() {emit paintSignal();}
|
||||
#else
|
||||
virtual void paintEvent(QPaintEvent * ) {emit paintSignal();}
|
||||
#endif
|
||||
virtual void resizeEvent(QResizeEvent * e) {
|
||||
__GLWidget__::resizeEvent(e);
|
||||
emit resizeSignal();
|
||||
}
|
||||
|
||||
|
||||
signals:
|
||||
void closeEvent(QCloseEvent * e);
|
||||
void dragEnterEvent(QDragEnterEvent * e);
|
||||
void dragLeaveEvent(QDragLeaveEvent * e);
|
||||
void dragMoveEvent(QDragMoveEvent * e);
|
||||
void dropEvent(QDropEvent * e);
|
||||
void enterEvent(QEvent * e);
|
||||
void hideEvent(QHideEvent * e);
|
||||
void keyPressEvent(QKeyEvent * e);
|
||||
void keyReleaseEvent(QKeyEvent * e);
|
||||
void leaveEvent(QEvent * e);
|
||||
void mouseDoubleClickEvent(QMouseEvent * e);
|
||||
void mouseMoveEvent(QMouseEvent * e);
|
||||
void mousePressEvent(QMouseEvent * e);
|
||||
void mouseReleaseEvent(QMouseEvent * e);
|
||||
void moveEvent(QMoveEvent * e);
|
||||
void showEvent(QShowEvent * e);
|
||||
void wheelEvent(QWheelEvent * e);
|
||||
void resizeSignal();
|
||||
void paintSignal();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
53
libs/graphic/uwidget.h
Normal file
53
libs/graphic/uwidget.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef UWIDGET_H
|
||||
#define UWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPainter>
|
||||
#include <QStyle>
|
||||
#include <QStyleOption>
|
||||
#include <QEvent>
|
||||
#include "qad_graphic_export.h"
|
||||
|
||||
|
||||
class QAD_GRAPHIC_EXPORT UWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
UWidget(QWidget * parent = 0): QWidget(parent) {}
|
||||
|
||||
private:
|
||||
virtual bool event(QEvent * e) {
|
||||
if (e->type() != QEvent::Paint) return QWidget::event(e);
|
||||
e->accept();
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
emit paintEvent((QPaintEvent * )e);
|
||||
return true;
|
||||
}
|
||||
|
||||
signals:
|
||||
void closeEvent(QCloseEvent * e);
|
||||
void dragEnterEvent(QDragEnterEvent * e);
|
||||
void dragLeaveEvent(QDragLeaveEvent * e);
|
||||
void dragMoveEvent(QDragMoveEvent * e);
|
||||
void dropEvent(QDropEvent * e);
|
||||
void enterEvent(QEvent * e);
|
||||
void hideEvent(QHideEvent * e);
|
||||
void keyPressEvent(QKeyEvent * e);
|
||||
void keyReleaseEvent(QKeyEvent * e);
|
||||
void leaveEvent(QEvent * e);
|
||||
void mouseDoubleClickEvent(QMouseEvent * e);
|
||||
void mouseMoveEvent(QMouseEvent * e);
|
||||
void mousePressEvent(QMouseEvent * e);
|
||||
void mouseReleaseEvent(QMouseEvent * e);
|
||||
void moveEvent(QMoveEvent * e);
|
||||
void resizeEvent(QResizeEvent * e);
|
||||
void showEvent(QShowEvent * e);
|
||||
void wheelEvent(QWheelEvent * e);
|
||||
void paintEvent(QPaintEvent * e);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
1
libs/piqt/CMakeLists.txt
Normal file
1
libs/piqt/CMakeLists.txt
Normal file
@@ -0,0 +1 @@
|
||||
piqt_library(piqt "Gui;Positioning" "qad_utils;qad_widgets")
|
||||
141
libs/piqt/piqt.cpp
Normal file
141
libs/piqt/piqt.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
#include "piqt.h"
|
||||
#include "qvariantedit.h"
|
||||
#if QT_VERSION >= 0x050200
|
||||
# include <QGeoCoordinate>
|
||||
#endif
|
||||
|
||||
|
||||
const QAD::Enum PI2QADEnum(const PIVariantTypes::Enum & el) {
|
||||
QAD::Enum ret;
|
||||
piForeachC (PIVariantTypes::Enumerator & e, el.enum_list)
|
||||
ret << QAD::Enumerator(e.value, PI2QString(e.name));
|
||||
ret.selectValue(el.selectedValue());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const PIVariantTypes::Enum QAD2PIEnum(const QAD::Enum & el) {
|
||||
PIVariantTypes::Enum ret;
|
||||
foreach (const QAD::Enumerator & e, el.enum_list)
|
||||
ret << PIVariantTypes::Enumerator(e.value, Q2PIString(e.name));
|
||||
ret.selectValue(el.selectedValue());
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
const QVariant PI2QVariant(const PIVariant & v) {
|
||||
switch (v.type()) {
|
||||
case PIVariant::pivBool: return QVariant(v.toBool());
|
||||
case PIVariant::pivChar:
|
||||
case PIVariant::pivUChar:
|
||||
case PIVariant::pivShort:
|
||||
case PIVariant::pivUShort:
|
||||
case PIVariant::pivInt: return QVariant(v.toInt());
|
||||
case PIVariant::pivUInt: return QVariant(uint(v.toInt()));
|
||||
case PIVariant::pivLLong: return QVariant(v.toLLong());
|
||||
case PIVariant::pivULLong: return QVariant(ullong(v.toLLong()));
|
||||
case PIVariant::pivFloat: return QVariant(v.toFloat());
|
||||
case PIVariant::pivDouble: return QVariant(v.toDouble());
|
||||
case PIVariant::pivLDouble: return QVariant(v.toDouble());
|
||||
case PIVariant::pivByteArray: return QVariant(PI2QByteArray(v.toByteArray()));
|
||||
case PIVariant::pivString: return QVariant(PI2QString(v.toString()));
|
||||
case PIVariant::pivStringList: return QVariant(PI2QStringList(v.toStringList()));
|
||||
case PIVariant::pivTime: return QVariant(PI2QTime(v.toTime()));
|
||||
case PIVariant::pivDate: return QVariant(PI2QDate(v.toDate()));
|
||||
case PIVariant::pivDateTime: return QVariant(PI2QDateTime(v.toDateTime()));
|
||||
case PIVariant::pivEnum: return QVariant::fromValue(PI2QADEnum(v.toEnum()));
|
||||
case PIVariant::pivFile: return QVariant::fromValue(PI2QADFile(v.toFile()));
|
||||
case PIVariant::pivDir: return QVariant::fromValue(PI2QADDir(v.toDir()));
|
||||
case PIVariant::pivColor: return QVariant::fromValue(PI2QColor(v.toColor()));
|
||||
case PIVariant::pivPoint: return QVariant(PI2QPoint(v.toPoint()));
|
||||
case PIVariant::pivRect: return QVariant(PI2QRect(v.toRect()));
|
||||
case PIVariant::pivIODevice: return QVariant::fromValue(PI2QADIODevice(v.toIODevice()));
|
||||
case PIVariant::pivMathVector: return QVariant::fromValue(PI2QMathVector(v.toMathVector()));
|
||||
case PIVariant::pivMathMatrix: return QVariant::fromValue(PI2QMathMatrix(v.toMathMatrix()));
|
||||
//case PIVariant::pivSystemTime: return QVariant(v.to());
|
||||
default: return QVariant();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
const PIVariant Q2PIVariant(const QVariant & v) {
|
||||
switch (v.type()) {
|
||||
case QVariant::Bool: return PIVariant(v.toBool());
|
||||
case QVariant::Int: return PIVariant(v.toInt());
|
||||
case QVariant::UInt: return PIVariant(v.toUInt());
|
||||
case QVariant::LongLong: return PIVariant(v.toLongLong());
|
||||
case QVariant::ULongLong: return PIVariant(v.toULongLong());
|
||||
case QVariant::Double: return PIVariant(v.toDouble());
|
||||
case QVariant::ByteArray: return PIVariant(Q2PIByteArray(v.toByteArray()));
|
||||
case QVariant::String: return PIVariant(Q2PIString(v.toString()));
|
||||
case QVariant::StringList: return PIVariant(Q2PIStringList(v.toStringList()));
|
||||
case QVariant::Time: return PIVariant(Q2PITime(v.toTime()));
|
||||
case QVariant::Date: return PIVariant(Q2PIDate(v.toDate()));
|
||||
case QVariant::DateTime: return PIVariant(Q2PIDateTime(v.toDateTime()));
|
||||
case QVariant::Color: return PIVariant(Q2PIColor(v.value<QColor>()));
|
||||
case QVariant::Point:
|
||||
case QVariant::PointF: return PIVariant(Q2PIPoint(v.toPointF()));
|
||||
case QVariant::Rect:
|
||||
case QVariant::RectF: return PIVariant(Q2PIRect(v.toRectF()));
|
||||
default: break;
|
||||
}
|
||||
if (v.canConvert<QAD::Enum>()) return PIVariant(QAD2PIEnum(v.value<QAD::Enum>()));
|
||||
if (v.canConvert<QAD::File>()) return PIVariant(QAD2PIFile(v.value<QAD::File>()));
|
||||
if (v.canConvert<QAD::Dir>()) return PIVariant(QAD2PIDir(v.value<QAD::Dir>()));
|
||||
if (v.canConvert<QAD::IODevice>()) return PIVariant(QAD2PIIODevice(v.value<QAD::IODevice>()));
|
||||
if (v.canConvert<QAD::MathVector>()) return PIVariant(Q2PIMathVector(v.value<QAD::MathVector>()));
|
||||
if (v.canConvert<QAD::MathMatrix>()) return PIVariant(Q2PIMathMatrix(v.value<QAD::MathMatrix>()));
|
||||
return PIVariant();
|
||||
}
|
||||
|
||||
|
||||
const PIVariantTypes::IODevice QAD2PIIODevice(const QAD::IODevice & v) {
|
||||
PIVariantTypes::IODevice d;
|
||||
d.set(Q2PIPropertyStorage(v.props));
|
||||
d.prefix = Q2PIString(v.prefix);
|
||||
d.mode = v.mode;
|
||||
d.options = v.options;
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
const QAD::IODevice PI2QADIODevice(const PIVariantTypes::IODevice & v) {
|
||||
return QAD::IODevice(PI2QString(v.prefix), PI2QPropertyStorage(v.get()), v.mode, v.options);
|
||||
}
|
||||
|
||||
|
||||
const QAD::File PI2QADFile(const PIVariantTypes::File & v) {
|
||||
return QAD::File(PI2QString(v.file), PI2QString(v.filter), v.is_abs, v.is_save);
|
||||
}
|
||||
|
||||
|
||||
const QAD::Dir PI2QADDir(const PIVariantTypes::Dir & v) {
|
||||
return QAD::Dir(PI2QString(v.dir), v.is_abs);
|
||||
}
|
||||
|
||||
|
||||
const PIVariantTypes::File QAD2PIFile(const QAD::File & v) {
|
||||
return PIVariantTypes::File(Q2PIString(v.file), Q2PIString(v.filter), v.is_abs, v.is_save);
|
||||
}
|
||||
|
||||
|
||||
const PIVariantTypes::Dir QAD2PIDir(const QAD::Dir & v) {
|
||||
return PIVariantTypes::Dir(Q2PIString(v.dir), v.is_abs);
|
||||
}
|
||||
|
||||
|
||||
#if QT_VERSION >= 0x050200
|
||||
const QGeoCoordinate PI2QGeoPosition(const PIGeoPosition & v) {
|
||||
PIGeoPosition p(v);
|
||||
p.transformTo(PIGeoPosition::Cartesian);
|
||||
p.setEllipsoidModel(PIEllipsoidModel::WGS84Ellipsoid());
|
||||
p.transformTo(PIGeoPosition::Geodetic);
|
||||
return QGeoCoordinate(p.latitudeGeodetic(), p.longitude(), p.height());
|
||||
}
|
||||
|
||||
|
||||
const PIGeoPosition Q2PIGeoPosition(const QGeoCoordinate & v) {
|
||||
return PIGeoPosition(createVectorT3d(v.latitude(), v.longitude(), v.altitude()), PIGeoPosition::Geodetic);
|
||||
}
|
||||
#endif
|
||||
169
libs/piqt/piqt.h
Normal file
169
libs/piqt/piqt.h
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
PIQt - PIP <-> Qt convertions
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef PIQT_H
|
||||
#define PIQT_H
|
||||
|
||||
#include "pimathmatrix.h"
|
||||
#include "pipropertystorage.h"
|
||||
#include "qad_types.h"
|
||||
#include <QVector3D>
|
||||
#include <QDateTime>
|
||||
#include <QColor>
|
||||
#if QT_VERSION >= 0x050200
|
||||
# include "pigeoposition.h"
|
||||
#endif
|
||||
#include "piqt_export.h"
|
||||
|
||||
|
||||
class QGeoCoordinate;
|
||||
|
||||
|
||||
PIQT_EXPORT const QVariant PI2QVariant(const PIVariant & v);
|
||||
PIQT_EXPORT const PIVariant Q2PIVariant(const QVariant & v);
|
||||
|
||||
//inline const QString PI2QString(const PIString & v) {return QString::fromLocal8Bit(v.data());}
|
||||
inline const QString PI2QString(const PIString & v) {return QString::fromUtf8(v.dataUTF8());}
|
||||
|
||||
//inline const PIString Q2PIString(const QString & v) {return PIString(v.toLocal8Bit().data());}
|
||||
inline const PIString Q2PIString(const QString & v) {return PIString::fromUTF8(v.toUtf8().data());}
|
||||
|
||||
|
||||
inline const QStringList PI2QStringList(const PIStringList & v) {QStringList ret; piForeachC (PIString & s, v) ret << PI2QString(s); return ret;}
|
||||
|
||||
inline const PIStringList Q2PIStringList(const QStringList & v) {PIStringList ret; foreach (const QString & s, v) ret << Q2PIString(s); return ret;}
|
||||
|
||||
|
||||
inline const QByteArray PI2QByteArray(const PIByteArray & v) {return QByteArray((const char *)(v.data()), v.size_s());}
|
||||
|
||||
inline const PIByteArray Q2PIByteArray(const QByteArray & v) {return PIByteArray(v.constData(), v.size());}
|
||||
|
||||
|
||||
inline const QPointF PI2QVector2(const PIMathVectorT2d & v) {return QPointF(v[0], v[1]);}
|
||||
inline const QVector3D PI2QVector3(const PIMathVectorT3d & v) {return QVector3D(v[0], v[1], v[2]);}
|
||||
|
||||
inline const PIMathVectorT2d Q2PIVector2(const QPointF & v) {return createVectorT2d(double(v.x()), double(v.y()));}
|
||||
inline const PIMathVectorT3d Q2PIVector3(const QVector3D & v) {return createVectorT3d(double(v.x()), double(v.y()), double(v.z()));}
|
||||
|
||||
inline const QPointF PI2QPoint(const PIPointd & v) {return QPointF(v.x, v.y);}
|
||||
inline const PIPointd Q2PIPoint(const QPointF & v) {return PIPointd(v.x(), v.y());}
|
||||
|
||||
inline const QRectF PI2QRect(const PIRectd & v) {return QRectF(v.x0, v.y0, v.width(), v.height());}
|
||||
inline const PIRectd Q2PIRect(const QRectF & v) {return PIRectd(v.x(), v.y(), v.width(), v.height());}
|
||||
|
||||
inline const QAD::MathVector PI2QMathVector(const PIMathVectord & v) {
|
||||
QVector<double> q = QVector<double>(v.size());
|
||||
memcpy(q.data(), v.data(), q.size()*sizeof(double));
|
||||
return QAD::MathVector(q);
|
||||
}
|
||||
inline const PIMathVectord Q2PIMathVector(const QAD::MathVector & v) {
|
||||
PIMathVectord p = PIMathVectord(v.v.size());
|
||||
memcpy(p.data(), v.v.data(), p.size()*sizeof(double));
|
||||
return p;
|
||||
}
|
||||
|
||||
inline const QAD::MathMatrix PI2QMathMatrix(const PIMathMatrixd & v) {
|
||||
PIVector<PIVector<double> > p = v.toVectors();
|
||||
QVector<QVector<double> > q = QVector<QVector<double> >(p.size());
|
||||
for (int i = 0; i < q.size(); ++i) {
|
||||
q[i].resize(p[i].size());
|
||||
memcpy(q[i].data(), p[i].data(), q[i].size()*sizeof(double));
|
||||
}
|
||||
return QAD::MathMatrix(q);
|
||||
}
|
||||
inline const PIMathMatrixd Q2PIMathMatrix(const QAD::MathMatrix & v) {
|
||||
PIVector<PIVector<double> > p = PIVector<PIVector<double> >(v.m.size());
|
||||
for (int i = 0; i < v.m.size(); ++i) {
|
||||
p[i].resize(v.m[i].size());
|
||||
memcpy(p[i].data(), v.m[i].data(), p[i].size()*sizeof(double));
|
||||
}
|
||||
return PIMathMatrixd(p);
|
||||
}
|
||||
|
||||
|
||||
inline const QDate PI2QDate(const PIDate & v) {return QDate(v.year, v.month, v.day);}
|
||||
inline const QTime PI2QTime(const PITime & v) {return QTime(v.hours, v.minutes, v.seconds, v.milliseconds);}
|
||||
inline const QDateTime PI2QDateTime(const PIDateTime & v) {return QDateTime(PI2QDate(v.date()), PI2QTime(v.time()));}
|
||||
|
||||
inline const PIDate Q2PIDate(const QDate & v) {return PIDate(v.year(), v.month(), v.day());}
|
||||
inline const PITime Q2PITime(const QTime & v) {return PITime(v.hour(), v.minute(), v.second(), v.msec());}
|
||||
inline const PIDateTime Q2PIDateTime(const QDateTime & v) {return PIDateTime(Q2PIDate(v.date()), Q2PITime(v.time()));}
|
||||
|
||||
|
||||
inline const QColor PI2QColor(const PIVariantTypes::Color & v) {return QColor::fromRgba(v.rgba);}
|
||||
inline const PIVariantTypes::Color Q2PIColor(const QColor & v) {return PIVariantTypes::Color(v.rgba());}
|
||||
|
||||
|
||||
inline PIPropertyStorage Q2PIPropertyStorage(const PropertyStorage & props) {
|
||||
PIPropertyStorage ret;
|
||||
foreach (const PropertyStorage::Property & p, props)
|
||||
ret.addProperty(Q2PIString(p.name), Q2PIVariant(p.value), Q2PIString(p.comment), p.flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline PropertyStorage PI2QPropertyStorage(const PIPropertyStorage & props) {
|
||||
PropertyStorage ret;
|
||||
piForeachC (PIPropertyStorage::Property & p, props)
|
||||
ret.addProperty(PI2QString(p.name), PI2QVariant(p.value), PI2QString(p.comment), p.flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
PIQT_EXPORT const QAD::Enum PI2QADEnum(const PIVariantTypes::Enum & el);
|
||||
PIQT_EXPORT const QAD::File PI2QADFile(const PIVariantTypes::File & v);
|
||||
PIQT_EXPORT const QAD::Dir PI2QADDir(const PIVariantTypes::Dir & v);
|
||||
PIQT_EXPORT const QAD::IODevice PI2QADIODevice(const PIVariantTypes::IODevice & v);
|
||||
PIQT_EXPORT const PIVariantTypes::Enum QAD2PIEnum(const QAD::Enum & el);
|
||||
PIQT_EXPORT const PIVariantTypes::File QAD2PIFile(const QAD::File & v);
|
||||
PIQT_EXPORT const PIVariantTypes::Dir QAD2PIDir(const QAD::Dir & v);
|
||||
PIQT_EXPORT const PIVariantTypes::IODevice QAD2PIIODevice(const QAD::IODevice & v);
|
||||
|
||||
//inline const PIVariant QString2PIVariant(const QString & v) {return PIVariant::readFromString(QString2PIString(v));}
|
||||
|
||||
#if QT_VERSION >= 0x050200
|
||||
PIQT_EXPORT const QGeoCoordinate PI2QGeoPosition(const PIGeoPosition & v);
|
||||
PIQT_EXPORT const PIGeoPosition Q2PIGeoPosition(const QGeoCoordinate & v);
|
||||
#endif
|
||||
|
||||
template <typename From>
|
||||
class __PIQtConverter {
|
||||
public:
|
||||
__PIQtConverter(const From & v): val(v) {}
|
||||
template <typename To> operator To() {return To();}
|
||||
From val;
|
||||
};
|
||||
template<typename From> inline __PIQtConverter<From> __PIQtConvert(const From & f) {return __PIQtConverter<From>(f);}
|
||||
|
||||
#define _PIQt_CONVERT(ft, tt, ftc, tfc) \
|
||||
template<> template<> inline __PIQtConverter<ft>::operator tt() {return ftc(val);} \
|
||||
template<> template<> inline __PIQtConverter<tt>::operator ft() {return tfc(val);}
|
||||
#define _PIQt_CONVERT_S(t) _PIQt_CONVERT(PI##t, Q##t, PI2Q##t, Q2PI##t)
|
||||
|
||||
_PIQt_CONVERT_S(String)
|
||||
_PIQt_CONVERT_S(ByteArray)
|
||||
_PIQt_CONVERT_S(Time)
|
||||
_PIQt_CONVERT_S(Date)
|
||||
_PIQt_CONVERT_S(DateTime)
|
||||
_PIQt_CONVERT(PIMathVectorT2d, QPointF, PI2QVector2, Q2PIVector2)
|
||||
_PIQt_CONVERT(PIMathVectorT3d, QVector3D, PI2QVector3, Q2PIVector3)
|
||||
|
||||
#define piqt __PIQtConvert
|
||||
#define qtpi __PIQtConvert
|
||||
|
||||
#endif // PIQT_H
|
||||
30
libs/piqt/qpiconnection.cpp
Normal file
30
libs/piqt/qpiconnection.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "qpiconnection.h"
|
||||
|
||||
|
||||
QPIConnection::QPIConnection(const QString & name): QObject(), PIConnection(Q2PIString(name)) {
|
||||
setObjectName(name);
|
||||
CONNECTU(this, dataReceivedEvent, this, piDataRec);
|
||||
CONNECTU(this, packetReceivedEvent, this, piPacketRec);
|
||||
}
|
||||
|
||||
|
||||
bool QPIConnection::loadFromCMFile(const QString & file) {
|
||||
QPIConfig f(file, QIODevice::ReadOnly);
|
||||
if (!f.isOpen()) return false;
|
||||
PIString cs = Q2PIString(QString::fromLatin1(f.getValue("config").toByteArray()));
|
||||
configureFromString(&cs, Q2PIString(f.getValue("name").toString()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void QPIConnection::piDataRec(const PIString & from, const PIByteArray & data) {
|
||||
//piCout << from << PICoutManipulators::Hex << data;
|
||||
QMetaObject::invokeMethod(this, "qDataReceivedEvent", Qt::QueuedConnection,
|
||||
Q_ARG(QString, PI2QString(from)), Q_ARG(QByteArray, PI2QByteArray(data)));
|
||||
}
|
||||
|
||||
|
||||
void QPIConnection::piPacketRec(const PIString & from, const PIByteArray & data) {
|
||||
QMetaObject::invokeMethod(this, "qPacketReceivedEvent", Qt::QueuedConnection,
|
||||
Q_ARG(QString, PI2QString(from)), Q_ARG(QByteArray, PI2QByteArray(data)));
|
||||
}
|
||||
52
libs/piqt/qpiconnection.h
Normal file
52
libs/piqt/qpiconnection.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
PIQt Utils - Qt utilites for PIP
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QPICONNECTION_H
|
||||
#define QPICONNECTION_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QMetaObject>
|
||||
#include "piconnection.h"
|
||||
#include "qpiconfig.h"
|
||||
#include "piqt.h"
|
||||
#include "piqt_export.h"
|
||||
|
||||
|
||||
class PIQT_EXPORT QPIConnection: public QObject, public PIConnection {
|
||||
Q_OBJECT
|
||||
PIOBJECT_SUBCLASS(QPIConnection, PIConnection)
|
||||
public:
|
||||
QPIConnection(const QString & name = QString());
|
||||
|
||||
bool loadFromCMFile(const QString & file);
|
||||
|
||||
protected:
|
||||
void propertyChanged(const PIString & ) {setObjectName(PI2QString(name()));}
|
||||
EVENT_HANDLER2(void, piDataRec, const PIString &, from, const PIByteArray &, data);
|
||||
EVENT_HANDLER2(void, piPacketRec, const PIString &, from, const PIByteArray &, data);
|
||||
|
||||
public slots:
|
||||
|
||||
signals:
|
||||
void qDataReceivedEvent(QString from, QByteArray data);
|
||||
void qPacketReceivedEvent(QString from, QByteArray data);
|
||||
|
||||
};
|
||||
|
||||
#endif // QPICONNECTION_H
|
||||
9
libs/piqt_widgets/CMakeLists.txt
Normal file
9
libs/piqt_widgets/CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
include(PIPMacros)
|
||||
pip_code_model(CCM "${ROOT_DIR}/pip/libs/main/io_devices/piiodevice.h" "${ROOT_DIR}/pip/libs/main/io_utils/pipacketextractor.h" OPTIONS "-DPIP_EXPORT" "-Es")
|
||||
piqt_library(piqt_utils "Gui" "qad_utils;qad_widgets;qad_blockview;piqt" ${CCM})
|
||||
|
||||
foreach(_v ${_QT_VERSIONS_})
|
||||
if (LOCAL_FOUND${_v})
|
||||
add_dependencies(piqt_utils${_v} pip_cmg)
|
||||
endif()
|
||||
endforeach()
|
||||
493
libs/piqt_widgets/piqt_connection_edit.cpp
Normal file
493
libs/piqt_widgets/piqt_connection_edit.cpp
Normal file
@@ -0,0 +1,493 @@
|
||||
#include "ui_piqt_connection_edit.h"
|
||||
#include "piqt_connection_edit.h"
|
||||
#include "piqt_connection_view.h"
|
||||
#include "piqt_highlighter.h"
|
||||
#include "piqt.h"
|
||||
#include "picodeinfo.h"
|
||||
#include <QCheckBox>
|
||||
#include <QMessageBox>
|
||||
|
||||
|
||||
ConnectionEdit::ConnectionEdit(QWidget * parent): QDialog(parent) {
|
||||
ui = new Ui::ConnectionEdit();
|
||||
ui->setupUi(this);
|
||||
new ConfigHighlighter(ui->codeEdit->document());
|
||||
loading = false;
|
||||
connect(ui->blockView, SIGNAL(schemeAction(BlockItemBase::Action,QList<QGraphicsItem*>)), this, SLOT(recreateRequest()));
|
||||
connect(ui->blockView->scene(), SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
|
||||
conn = 0;
|
||||
PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceMode");
|
||||
if (ei) {
|
||||
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members)
|
||||
ui->comboMode->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
|
||||
}
|
||||
ui->comboMode->setCurrentIndex(ui->comboMode->count() - 1);
|
||||
ei = PICodeInfo::enumsInfo->value("PIIODevice::DeviceOption");
|
||||
if (ei) {
|
||||
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members) {
|
||||
QCheckBox * cb = new QCheckBox();
|
||||
cb->setText(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"));
|
||||
cb->setProperty("__value", e.value);
|
||||
ui->layoutOptions->addWidget(cb);
|
||||
}
|
||||
}
|
||||
ei = PICodeInfo::enumsInfo->value("PIPacketExtractor::SplitMode");
|
||||
if (ei) {
|
||||
piForeachC (PICodeInfo::EnumeratorInfo & e, ei->members)
|
||||
ui->comboSplit->addItem(PI2QString(e.name + " (" + PIString::fromNumber(e.value) + ")"), QVariant::fromValue<int>(e.value));
|
||||
}
|
||||
udevicenum = 0;
|
||||
}
|
||||
|
||||
|
||||
ConnectionEdit::~ConnectionEdit() {
|
||||
if (conn) {
|
||||
conn->stop();
|
||||
delete conn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::accept() {
|
||||
//bool ok = false;
|
||||
QList<BlockItem * > bl = ui->blockView->allDevices();
|
||||
foreach (BlockItem * i, bl)
|
||||
foreach (BlockItem * j, bl)
|
||||
if (i != j)
|
||||
if (((DeviceItem*)i)->name() == ((DeviceItem*)j)->name()) {
|
||||
QMessageBox::critical(this, windowTitle() + " - " + tr("error") + "!", tr("Equal devices names: \"%1\"!").arg(((DeviceItem*)i)->name()));
|
||||
return;
|
||||
}
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
|
||||
QString ConnectionEdit::configuration() const {
|
||||
if (!conn) return QString();
|
||||
return PI2QString(conn->makeConfig());
|
||||
}
|
||||
|
||||
|
||||
QByteArray ConnectionEdit::model() const {
|
||||
QByteArray ret;
|
||||
QDataStream s(&ret, QIODevice::ReadWrite);
|
||||
QString cn = PI2QString(conn ? conn->name() : PIString());
|
||||
s << cn;
|
||||
QList<BlockBusItem*> busl = ui->blockView->buses();
|
||||
s << busl.size();
|
||||
foreach (BlockBusItem * b, busl)
|
||||
s << b->save();
|
||||
QList<BlockItem*> blockl = ui->blockView->blocks();
|
||||
s << blockl.size();
|
||||
foreach (BlockItem * b, blockl) {
|
||||
int type = b->propertyByName("__type").value.toInt();
|
||||
s << type;
|
||||
switch (type) {
|
||||
case __CV_Device:
|
||||
case __CV_Filter:
|
||||
case __CV_Sender:
|
||||
s << b->save();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QString ConnectionEdit::name() const {
|
||||
if (!conn) return QString();
|
||||
return PI2QString(conn->name());
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::setName(const QString & name) {
|
||||
ui->lineName->setText(name);
|
||||
recreateConnection();
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::addDevice(const QString & name, const QString & path) {
|
||||
ui->blockView->addDevice(name, path);
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::setModel(const QByteArray & m) {
|
||||
loading = true;
|
||||
ui->blockView->removeAll();
|
||||
QDataStream s(m);
|
||||
QString cn;
|
||||
s >> cn;
|
||||
if (conn) delete conn;
|
||||
conn = new PIConnection(Q2PIString(cn));
|
||||
ui->lineName->setText(cn);
|
||||
int sz;
|
||||
s >> sz;
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
BlockBusItem * b = new BlockBusItem();
|
||||
QByteArray ba; s >> ba; b->load(ba);
|
||||
ui->blockView->addItem(b);
|
||||
}
|
||||
s >> sz;
|
||||
for (int i = 0; i < sz; ++i) {
|
||||
int type(0);
|
||||
BlockItem * b(0);
|
||||
QByteArray ba;
|
||||
s >> type;
|
||||
switch (type) {
|
||||
case __CV_Device:
|
||||
b = new DeviceItem();
|
||||
s >> ba; b->load(ba);
|
||||
if (!b->isPropertyExists("bufferSize"))
|
||||
((DeviceItem*)b)->setBufferSize(4096);
|
||||
((DeviceItem*)b)->rename();
|
||||
break;
|
||||
case __CV_Filter:
|
||||
b = new FilterItem();
|
||||
s >> ba; b->load(ba);
|
||||
if (!b->isPropertyExists("bufferSize"))
|
||||
((FilterItem*)b)->setBufferSize(65536);
|
||||
((FilterItem*)b)->rename();
|
||||
break;
|
||||
case __CV_Sender:
|
||||
b = new SenderItem();
|
||||
s >> ba; b->load(ba);
|
||||
((SenderItem*)b)->rename();
|
||||
break;
|
||||
}
|
||||
if (b)
|
||||
ui->blockView->addItem(b);
|
||||
}
|
||||
ui->blockView->reconnectAll();
|
||||
loading = false;
|
||||
recreateConnection();
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::selectionChanged() {
|
||||
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
|
||||
ui->buttonRemove->setEnabled(!si.isEmpty());
|
||||
ui->buttonDeviceModify->setEnabled(false);
|
||||
ui->buttonFilterModify->setEnabled(false);
|
||||
ui->buttonSenderModify->setEnabled(false);
|
||||
if (si.size() != 1) return;
|
||||
BlockItem * b = qgraphicsitem_cast<BlockItem*>(si[0]);
|
||||
if (!b) return;
|
||||
int type = b->propertyByName("__type").value.toInt();
|
||||
if (type == __CV_Device) {
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
DeviceItem * di = (DeviceItem*)b;
|
||||
ui->buttonDeviceModify->setEnabled(true);
|
||||
for (int i = 0; i < ui->comboMode->count(); ++i)
|
||||
if (ui->comboMode->itemData(i).toInt() == di->mode()) {
|
||||
ui->comboMode->setCurrentIndex(i);
|
||||
break;
|
||||
}
|
||||
ui->lineDevice->setText(di->name());
|
||||
ui->linePath->setEditText(di->path());
|
||||
ui->spinDeviceDT->setValue(di->disconnectTimeout());
|
||||
ui->spinDeviceBS->setValue(di->bufferSize());
|
||||
setOptions(di->options());
|
||||
}
|
||||
if (type == __CV_Filter) {
|
||||
ui->tabWidget->setCurrentIndex(1);
|
||||
FilterItem * fi = (FilterItem*)b;
|
||||
ui->buttonFilterModify->setEnabled(true);
|
||||
for (int i = 0; i < ui->comboSplit->count(); ++i)
|
||||
if (ui->comboSplit->itemData(i).toInt() == fi->mode()) {
|
||||
ui->comboSplit->setCurrentIndex(i);
|
||||
break;
|
||||
}
|
||||
ui->lineFilter->setText(fi->name());
|
||||
ui->lineHeader->setText(fi->header());
|
||||
ui->lineFooter->setText(fi->footer());
|
||||
ui->spinTimeout->setValue(fi->timeout());
|
||||
ui->spinSize->setValue(fi->packetSize());
|
||||
ui->spinFilterDT->setValue(fi->disconnectTimeout());
|
||||
ui->spinFilterBS->setValue(fi->bufferSize());
|
||||
}
|
||||
if (type == __CV_Sender) {
|
||||
ui->tabWidget->setCurrentIndex(2);
|
||||
SenderItem * si = (SenderItem*)b;
|
||||
ui->buttonSenderModify->setEnabled(true);
|
||||
ui->lineSender->setText(si->name());
|
||||
ui->lineData->setText(si->data());
|
||||
ui->spinFrequency->setValue(si->frequency());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::applyFilter(FilterItem * b) {
|
||||
b->setName(ui->lineFilter->text());
|
||||
b->setMode(PIPacketExtractor::SplitMode(ui->comboSplit->itemData(ui->comboSplit->currentIndex()).toInt()));
|
||||
b->setHeader(ui->lineHeader->text());
|
||||
b->setFooter(ui->lineFooter->text());
|
||||
b->setTimeout(ui->spinTimeout->value());
|
||||
b->setPacketSize(ui->spinSize->value());
|
||||
b->setDisconnectTimeout(ui->spinFilterDT->value());
|
||||
b->setBufferSize(ui->spinFilterBS->value());
|
||||
recreateConnection();
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::applyDevice(DeviceItem * b) {
|
||||
QString n = ui->lineDevice->text();
|
||||
if (n.isEmpty()) {
|
||||
n = "device" + QString::number(udevicenum);
|
||||
}
|
||||
b->setName(n);
|
||||
b->setMode(PIIODevice::DeviceMode(ui->comboMode->itemData(ui->comboMode->currentIndex()).toInt()));
|
||||
b->setOptions(PIIODevice::DeviceOptions(getOptions()));
|
||||
b->setPath(ui->linePath->currentText());
|
||||
b->setDisconnectTimeout(ui->spinDeviceDT->value());
|
||||
b->setBufferSize(ui->spinDeviceBS->value());
|
||||
recreateConnection();
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::applySender(SenderItem * b) {
|
||||
b->setName(ui->lineSender->text());
|
||||
b->setData(ui->lineData->text());
|
||||
b->setFrequency(ui->spinFrequency->value());
|
||||
recreateConnection();
|
||||
}
|
||||
|
||||
|
||||
int ConnectionEdit::getOptions() const {
|
||||
int ret(0);
|
||||
for (int i = 0; i < ui->layoutOptions->count(); ++i) {
|
||||
QCheckBox * cb = qobject_cast<QCheckBox*>(ui->layoutOptions->itemAt(i)->widget());
|
||||
if (!cb) continue;
|
||||
if (cb->isChecked())
|
||||
ret |= cb->property("__value").toInt();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::setOptions(int o) {
|
||||
for (int i = 0; i < ui->layoutOptions->count(); ++i) {
|
||||
QCheckBox * cb = qobject_cast<QCheckBox*>(ui->layoutOptions->itemAt(i)->widget());
|
||||
if (!cb) continue;
|
||||
int cbf = cb->property("__value").toInt();
|
||||
//qDebug() << cbf;
|
||||
cb->setChecked((o & cbf) == cbf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::recreateConnection() {
|
||||
//qDebug() << "recreate";
|
||||
if (loading) return;
|
||||
ui->blockView->reconnectAll();
|
||||
if (conn) delete conn;
|
||||
PIString cn = Q2PIString(ui->lineName->text());
|
||||
if (cn.isEmpty()) conn = new PIConnection();
|
||||
else conn = new PIConnection(cn);
|
||||
QList<BlockItem*> devs = ui->blockView->allDevices();
|
||||
foreach (BlockItem * b, devs) {
|
||||
DeviceItem * di = (DeviceItem*)b;
|
||||
//qDebug() << di->path();
|
||||
PIIODevice * dev = conn->addDevice(Q2PIString(di->path()), di->mode());
|
||||
if (!dev) continue;
|
||||
dev->setOptions(di->options());
|
||||
dev->setThreadedReadBufferSize(di->bufferSize());
|
||||
conn->setDeviceName(dev, Q2PIString(di->name()));
|
||||
PIDiagnostics * diag = conn->diagnostic(dev);
|
||||
if (diag) diag->setDisconnectTimeout(di->disconnectTimeout());
|
||||
}
|
||||
foreach (BlockItem * b, devs) {
|
||||
DeviceItem * di = (DeviceItem*)b;
|
||||
PIIODevice * dev = conn->deviceByName(Q2PIString(di->name()));
|
||||
if (!dev) continue;
|
||||
BlockItemPin * p = b->pinByText("read");
|
||||
if (!p) continue;
|
||||
QList<BlockBusItem*> buses = p->connectedBuses(), nbuses;
|
||||
QSet<BlockBusItem*> pbuses;
|
||||
while (!buses.isEmpty()) {
|
||||
nbuses.clear();
|
||||
foreach (BlockBusItem * bus, buses) {
|
||||
QList<BlockItem*> cb = bus->connectedBlocks();
|
||||
if (cb.size() != 2) continue;
|
||||
FilterItem * fi_t(0);
|
||||
BlockItem * bi_f(0);
|
||||
if (cb[0]->pinAtBus(bus)->text() == "in") {
|
||||
fi_t = (FilterItem*)(cb[0]);
|
||||
bi_f = (cb[1]);
|
||||
} else if (cb[1]->pinAtBus(bus)->text() == "in") {
|
||||
fi_t = (FilterItem*)(cb[1]);
|
||||
bi_f = (cb[0]);
|
||||
}
|
||||
if (!fi_t || !bi_f) continue;
|
||||
PIString name_from;
|
||||
int type = bi_f->propertyByName("__type").value.toInt();
|
||||
if (type == __CV_Device) name_from = Q2PIString(((DeviceItem*)bi_f)->name());
|
||||
if (type == __CV_Filter) name_from = Q2PIString(((FilterItem*)bi_f)->name());
|
||||
if (name_from.isEmpty()) continue;
|
||||
PIPacketExtractor * pe = conn->addFilter(Q2PIString(fi_t->name()),conn->deviceByName(name_from), fi_t->mode());
|
||||
if (!pe) continue;
|
||||
pe->setBufferSize(fi_t->bufferSize());
|
||||
pe->setHeader(PIByteArray::fromUserInput(Q2PIString(fi_t->header())));
|
||||
pe->setFooter(PIByteArray::fromUserInput(Q2PIString(fi_t->footer())));
|
||||
pe->setTimeout(fi_t->timeout());
|
||||
pe->setPacketSize(fi_t->packetSize());
|
||||
pe->setPayloadSize(fi_t->packetSize());
|
||||
PIDiagnostics * diag = conn->diagnostic(pe);
|
||||
if (diag) diag->setDisconnectTimeout(fi_t->disconnectTimeout());
|
||||
QList<BlockBusItem*> nb = fi_t->pinByText("out")->connectedBuses();
|
||||
foreach (BlockBusItem * b_, nb)
|
||||
if (!pbuses.contains(b_)) {
|
||||
pbuses << b_;
|
||||
nbuses << b_;
|
||||
}
|
||||
}
|
||||
buses = nbuses;
|
||||
}
|
||||
}
|
||||
foreach (BlockItem * b, devs) {
|
||||
BlockItemPin * p = b->pinByText("write");
|
||||
if (!p) continue;
|
||||
QList<BlockBusItem*> buses = p->connectedBuses();
|
||||
foreach (BlockBusItem * bus, buses) {
|
||||
QList<BlockItem*> cb = bus->connectedBlocks();
|
||||
if (cb.size() != 2) continue;
|
||||
BlockItem * bi_f(0);
|
||||
DeviceItem * di_t(0);
|
||||
if (cb[0]->pinAtBus(bus)->text() == "write") {
|
||||
di_t = (DeviceItem*)(cb[0]);
|
||||
bi_f = (cb[1]);
|
||||
} else if (cb[1]->pinAtBus(bus)->text() == "write") {
|
||||
di_t = (DeviceItem*)(cb[1]);
|
||||
bi_f = (cb[0]);
|
||||
}
|
||||
if (!bi_f || !di_t) continue;
|
||||
QString name_from;
|
||||
int type = bi_f->propertyByName("__type").value.toInt();
|
||||
if (type == __CV_Sender) {
|
||||
SenderItem * si = ((SenderItem*)bi_f);
|
||||
si->name();
|
||||
conn->addSender(Q2PIString(si->name()), Q2PIString(di_t->path()), si->frequency());
|
||||
if (!si->data().isEmpty())
|
||||
conn->setSenderFixedData(Q2PIString(si->name()), PIByteArray::fromUserInput(Q2PIString(si->data())));
|
||||
} else {
|
||||
if (type == __CV_Device) name_from = ((DeviceItem*)bi_f)->name();
|
||||
if (type == __CV_Filter) name_from = ((FilterItem*)bi_f)->name();
|
||||
if (name_from.isEmpty()) continue;
|
||||
conn->addChannel(Q2PIString(name_from), Q2PIString(di_t->name()));
|
||||
}
|
||||
}
|
||||
}
|
||||
ui->codeEdit->setText(PI2QString(conn->makeConfig()));
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::on_buttonRemove_clicked() {
|
||||
ui->blockView->removeSelected();
|
||||
recreateConnection();
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::on_buttonClear_clicked() {
|
||||
ui->blockView->removeAll();
|
||||
recreateConnection();
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::on_buttonFilterAdd_clicked() {
|
||||
if (!conn) return;
|
||||
applyFilter(ui->blockView->addFilter(ui->lineFilter->text()));
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::on_buttonFilterModify_clicked() {
|
||||
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
|
||||
if (si.isEmpty()) return;
|
||||
if (!qgraphicsitem_cast<BlockItem*>(si[0])) return;
|
||||
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Filter)
|
||||
return;
|
||||
applyFilter(qgraphicsitem_cast<FilterItem*>(si[0]));
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::on_buttonDeviceAdd_clicked() {
|
||||
if (!conn) return;
|
||||
QString n = ui->lineDevice->text();
|
||||
if (n.isEmpty()) {
|
||||
udevicenum++;
|
||||
n = "device" + QString::number(udevicenum);
|
||||
}
|
||||
QString p = ui->linePath->currentText();
|
||||
if (ui->linePath->findText(p) < 0) ui->linePath->addItem(p);
|
||||
qDebug() << "add:" << n;
|
||||
applyDevice(ui->blockView->addDevice(n, ui->linePath->currentText()));
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::on_buttonDeviceModify_clicked() {
|
||||
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
|
||||
if (si.isEmpty()) return;
|
||||
if (!qgraphicsitem_cast<BlockItem*>(si[0])) return;
|
||||
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Device)
|
||||
return;
|
||||
applyDevice(qgraphicsitem_cast<DeviceItem*>(si[0]));
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::on_buttonSenderAdd_clicked() {
|
||||
if (!conn) return;
|
||||
applySender(ui->blockView->addSender(ui->lineSender->text()));
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::on_buttonSenderModify_clicked() {
|
||||
QList<QGraphicsItem*> si = ui->blockView->scene()->selectedItems();
|
||||
if (si.isEmpty()) return;
|
||||
if (!qgraphicsitem_cast<BlockItem*>(si[0])) return;
|
||||
if (qgraphicsitem_cast<BlockItem*>(si[0])->propertyByName("__type").value.toInt() != __CV_Sender)
|
||||
return;
|
||||
applySender(qgraphicsitem_cast<SenderItem*>(si[0]));
|
||||
}
|
||||
|
||||
|
||||
void ConnectionEdit::on_comboSplit_currentIndexChanged(int index) {
|
||||
int mode = ui->comboSplit->itemData(index).toInt();
|
||||
switch (mode) {
|
||||
case PIPacketExtractor::None:
|
||||
ui->widgetHeader->setEnabled(false);
|
||||
ui->widgetFooter->setEnabled(false);
|
||||
ui->widgetTimeout->setEnabled(false);
|
||||
ui->widgetSize->setEnabled(false);
|
||||
break;
|
||||
case PIPacketExtractor::Header:
|
||||
ui->widgetHeader->setEnabled(true);
|
||||
ui->widgetFooter->setEnabled(false);
|
||||
ui->widgetTimeout->setEnabled(false);
|
||||
ui->widgetSize->setEnabled(true);
|
||||
break;
|
||||
case PIPacketExtractor::Footer:
|
||||
ui->widgetHeader->setEnabled(false);
|
||||
ui->widgetFooter->setEnabled(true);
|
||||
ui->widgetTimeout->setEnabled(false);
|
||||
ui->widgetSize->setEnabled(true);
|
||||
break;
|
||||
case PIPacketExtractor::HeaderAndFooter:
|
||||
ui->widgetHeader->setEnabled(true);
|
||||
ui->widgetFooter->setEnabled(true);
|
||||
ui->widgetTimeout->setEnabled(false);
|
||||
ui->widgetSize->setEnabled(false);
|
||||
break;
|
||||
case PIPacketExtractor::Timeout:
|
||||
ui->widgetHeader->setEnabled(false);
|
||||
ui->widgetFooter->setEnabled(false);
|
||||
ui->widgetTimeout->setEnabled(true);
|
||||
ui->widgetSize->setEnabled(false);
|
||||
break;
|
||||
case PIPacketExtractor::Size:
|
||||
ui->widgetHeader->setEnabled(false);
|
||||
ui->widgetFooter->setEnabled(false);
|
||||
ui->widgetTimeout->setEnabled(false);
|
||||
ui->widgetSize->setEnabled(true);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
82
libs/piqt_widgets/piqt_connection_edit.h
Normal file
82
libs/piqt_widgets/piqt_connection_edit.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
PIQt Utils - Qt utilites for PIP
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONNECTION_EDIT_H
|
||||
#define CONNECTION_EDIT_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "piconnection.h"
|
||||
#include "piqt_utils_export.h"
|
||||
|
||||
|
||||
namespace Ui {
|
||||
class ConnectionEdit;
|
||||
}
|
||||
|
||||
class FilterItem;
|
||||
class DeviceItem;
|
||||
class SenderItem;
|
||||
|
||||
class PIQT_UTILS_EXPORT ConnectionEdit: public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ConnectionEdit(QWidget * parent = 0);
|
||||
~ConnectionEdit();
|
||||
|
||||
QString configuration() const;
|
||||
QByteArray model() const;
|
||||
QString name() const;
|
||||
|
||||
void setName(const QString & name);
|
||||
void addDevice(const QString & name, const QString & path);
|
||||
void setModel(const QByteArray & m);
|
||||
|
||||
private:
|
||||
void accept();
|
||||
void keyPressEvent(QKeyEvent *) {}
|
||||
void applyFilter(FilterItem * b);
|
||||
void applyDevice(DeviceItem * b);
|
||||
void applySender(SenderItem * b);
|
||||
int getOptions() const;
|
||||
void setOptions(int o);
|
||||
|
||||
Ui::ConnectionEdit * ui;
|
||||
PIConnection * conn;
|
||||
bool loading;
|
||||
int udevicenum;
|
||||
|
||||
private slots:
|
||||
void recreateRequest() {if (!loading) QMetaObject::invokeMethod(this, "recreateConnection", Qt::QueuedConnection);}
|
||||
void on_buttonRemove_clicked();
|
||||
void on_buttonClear_clicked();
|
||||
void on_buttonFilterAdd_clicked();
|
||||
void on_buttonFilterModify_clicked();
|
||||
void on_buttonDeviceAdd_clicked();
|
||||
void on_buttonDeviceModify_clicked();
|
||||
void on_buttonSenderAdd_clicked();
|
||||
void on_buttonSenderModify_clicked();
|
||||
void on_comboSplit_currentIndexChanged(int index);
|
||||
void selectionChanged();
|
||||
|
||||
public slots:
|
||||
void recreateConnection();
|
||||
|
||||
};
|
||||
|
||||
#endif // CONNECTION_EDIT_H
|
||||
942
libs/piqt_widgets/piqt_connection_edit.ui
Normal file
942
libs/piqt_widgets/piqt_connection_edit.ui
Normal file
@@ -0,0 +1,942 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ConnectionEdit</class>
|
||||
<widget class="QDialog" name="ConnectionEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>794</width>
|
||||
<height>799</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Connection editor</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineName"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab">
|
||||
<attribute name="title">
|
||||
<string>Device</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="labelAlignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelFilter_4">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="CLineEdit" name="lineDevice"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelFilter_11">
|
||||
<property name="text">
|
||||
<string>Path:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="EComboBox" name="linePath">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>eth://UDP:127.0.0.1:12345:127.0.0.1:12346</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>eth://TCP:127.0.0.1:16666</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>eth://UDP:192.168.0.5:16666:192.168.0.6:16667:mcast:234.0.2.1:mcast:234.0.2.2</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>file://./text.txt</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>binlog://./logs/:mylog_:1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>ser:///dev/ttyUSB0:9600:8:N:1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>ser://COM32:115200:8:N:1</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>usb://0bb4:0c86:1:1:2</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelFilter_12">
|
||||
<property name="text">
|
||||
<string>Mode:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="comboMode"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="labelFilter_14">
|
||||
<property name="text">
|
||||
<string>Options:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QVBoxLayout" name="layoutOptions">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_14">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFilter_13">
|
||||
<property name="text">
|
||||
<string>Disconnect timeout:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinDeviceDT">
|
||||
<property name="suffix">
|
||||
<string> ms</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9999.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>3.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFilter_15">
|
||||
<property name="text">
|
||||
<string>Buffer size:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinDeviceBS">
|
||||
<property name="suffix">
|
||||
<string> b</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_18">
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonDeviceAdd">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../qad/libs/application/qad_application.qrc">
|
||||
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonDeviceModify">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Modify</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../qad/libs/application/qad_application.qrc">
|
||||
<normaloff>:/icons/document-save.png</normaloff>:/icons/document-save.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Filter</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFilter">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="CLineEdit" name="lineFilter"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="comboSplit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Parameters</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetHeader" native="true">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFilter_2">
|
||||
<property name="text">
|
||||
<string>Header:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="CLineEdit" name="lineHeader"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetFooter" native="true">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFilter_3">
|
||||
<property name="text">
|
||||
<string>Footer:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="CLineEdit" name="lineFooter"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetTimeout" native="true">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFilter_7">
|
||||
<property name="text">
|
||||
<string>Timeout:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinTimeout">
|
||||
<property name="suffix">
|
||||
<string> ms</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>99999.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetSize" native="true">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFilter_8">
|
||||
<property name="text">
|
||||
<string>Size:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinSize">
|
||||
<property name="maximum">
|
||||
<number>999999999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>8</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetDT" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFilter_9">
|
||||
<property name="text">
|
||||
<string>Disconnect timeout:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDoubleSpinBox" name="spinFilterDT">
|
||||
<property name="suffix">
|
||||
<string> ms</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9999.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>3.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widgetSize_2" native="true">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_13">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>17</width>
|
||||
<height>17</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="labelFilter_17">
|
||||
<property name="text">
|
||||
<string>Buffer size:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spinFilterBS">
|
||||
<property name="suffix">
|
||||
<string> b</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>999999999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>65536</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Expanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>1</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonFilterAdd">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../qad/libs/application/qad_application.qrc">
|
||||
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonFilterModify">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Modify</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/icons/document-save-.png</normaloff>:/icons/document-save-.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>Sender</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="labelFilter_5">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="CLineEdit" name="lineSender"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelFilter_16">
|
||||
<property name="text">
|
||||
<string>Frequency:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="spinFrequency">
|
||||
<property name="suffix">
|
||||
<string> Hz</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9999.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>10.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="labelFilter_6">
|
||||
<property name="text">
|
||||
<string>Data:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="CLineEdit" name="lineData"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>77</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_19">
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonSenderAdd">
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../qad/libs/application/qad_application.qrc">
|
||||
<normaloff>:/icons/list-add.png</normaloff>:/icons/list-add.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonSenderModify">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Modify</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/icons/document-save-.png</normaloff>:/icons/document-save-.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonRemove">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../qad/libs/application/qad_application.qrc">
|
||||
<normaloff>:/icons/edit-delete.png</normaloff>:/icons/edit-delete.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonClear">
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../qad/libs/application/qad_application.qrc">
|
||||
<normaloff>:/icons/edit-clear.png</normaloff>:/icons/edit-clear.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ConnectionView" name="blockView">
|
||||
<property name="traceConsiderBuses">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="pinMulticonnect" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="miniMap" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QCodeEdit" name="codeEdit"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>BlockView</class>
|
||||
<extends>QGraphicsView</extends>
|
||||
<header>blockview.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>CLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>clineedit.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>EComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>ecombobox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QCodeEdit</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>qcodeedit.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ConnectionView</class>
|
||||
<extends>BlockView</extends>
|
||||
<header>piqt_connection_view.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../../qad/libs/application/qad_application.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>ConnectionEdit</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>442</x>
|
||||
<y>738</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>413</x>
|
||||
<y>426</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>ConnectionEdit</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>669</x>
|
||||
<y>738</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>643</x>
|
||||
<y>428</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<slots>
|
||||
<slot>recreateConnection()</slot>
|
||||
</slots>
|
||||
</ui>
|
||||
204
libs/piqt_widgets/piqt_connection_view.cpp
Normal file
204
libs/piqt_widgets/piqt_connection_view.cpp
Normal file
@@ -0,0 +1,204 @@
|
||||
#include "piqt_connection_view.h"
|
||||
#include "picodeinfo.h"
|
||||
#include "piqt.h"
|
||||
#include <alignedtextitem.h>
|
||||
|
||||
|
||||
DeviceItem::DeviceItem(): BlockItem() {
|
||||
addProperty(BlockItem::Property("__type", "", __CV_Device));
|
||||
addProperty(BlockItem::Property("bufferSize", "", 4096));
|
||||
setSize(200, 80);
|
||||
setColor(QColor(192, 192, 255));
|
||||
text_name = new AlignedTextItem();
|
||||
text_path = new AlignedTextItem();
|
||||
QFont fnt(text_name->font()); fnt.setBold(true);
|
||||
text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
||||
text_name->setFont(fnt);
|
||||
text_name->setPos(0., -size().height() / 2.);
|
||||
addDecor(text_name);
|
||||
fnt.setBold(false);
|
||||
fnt.setPointSizeF(fnt.pointSizeF() - 2.);
|
||||
text_path->setFont(fnt);
|
||||
text_path->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
||||
text_path->setPos(0., -size().height() / 2. + 20);
|
||||
addDecor(text_path);
|
||||
addPin(Qt::AlignLeft, 0, "write", "");
|
||||
addPin(Qt::AlignRight, 0, "read", "");
|
||||
}
|
||||
|
||||
|
||||
void DeviceItem::rename() {
|
||||
QString ms;
|
||||
BlockItemPin * pr = pinByText("read"), * pw = pinByText("write");
|
||||
switch (mode()) {
|
||||
case PIIODevice::ReadOnly: ms = "ro"; pr->show(); pw->hide(); break;
|
||||
case PIIODevice::WriteOnly: ms = "wo"; pr->hide(); pw->show(); break;
|
||||
case PIIODevice::ReadWrite: ms = "rw"; pr->show(); pw->show(); break;
|
||||
}
|
||||
text_name->setText(name() + " (" + ms + ")");
|
||||
text_path->setText(path());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
FilterItem::FilterItem(): BlockItem() {
|
||||
addProperty(BlockItem::Property("__type", "", __CV_Filter));
|
||||
addProperty(BlockItem::Property("bufferSize", "", 65536));
|
||||
setSize(140, 80);
|
||||
setPos(200, 0);
|
||||
setColor(QColor(192, 255, 192));
|
||||
text_name = new AlignedTextItem();
|
||||
text_mode = new AlignedTextItem();
|
||||
QFont fnt(text_name->font()); fnt.setBold(true);
|
||||
text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
||||
text_name->setFont(fnt);
|
||||
text_name->setPos(0., -size().height() / 2.);
|
||||
addDecor(text_name);
|
||||
fnt.setBold(false);
|
||||
fnt.setPointSizeF(fnt.pointSizeF() - 2.);
|
||||
text_mode->setFont(fnt);
|
||||
text_mode->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
||||
text_mode->setPos(0., -size().height() / 2. + 20);
|
||||
addDecor(text_mode);
|
||||
addPin(Qt::AlignLeft, 0, "in", "");
|
||||
addPin(Qt::AlignRight, 0, "out", "");
|
||||
}
|
||||
|
||||
|
||||
void FilterItem::rename() {
|
||||
text_name->setText(name());
|
||||
QString ms;
|
||||
PICodeInfo::EnumInfo * ei = PICodeInfo::enumsInfo->value("PIPacketExtractor::SplitMode", 0);
|
||||
if (ei) {
|
||||
piForeachC (PICodeInfo::EnumeratorInfo & i, ei->members)
|
||||
if (i.value == mode()) {
|
||||
ms = PI2QString(i.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
text_mode->setText(ms);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
SenderItem::SenderItem(): BlockItem() {
|
||||
addProperty(BlockItem::Property("__type", "", __CV_Sender));
|
||||
setSize(140, 80);
|
||||
setPos(-200, 0);
|
||||
setColor(QColor(255, 192, 192));
|
||||
text_name = new AlignedTextItem();
|
||||
text_frequency = new AlignedTextItem();
|
||||
QFont fnt(text_name->font()); fnt.setBold(true);
|
||||
text_name->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
||||
text_name->setFont(fnt);
|
||||
text_name->setPos(0., -size().height() / 2.);
|
||||
addDecor(text_name);
|
||||
fnt.setBold(false);
|
||||
fnt.setPointSizeF(fnt.pointSizeF() - 2.);
|
||||
text_frequency->setFont(fnt);
|
||||
text_frequency->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
||||
text_frequency->setPos(0., -size().height() / 2. + 20);
|
||||
addDecor(text_frequency);
|
||||
addPin(Qt::AlignRight, 0, "out", "");
|
||||
}
|
||||
|
||||
|
||||
void SenderItem::rename() {
|
||||
text_name->setText(name());
|
||||
text_frequency->setText(QString::number(frequency()) + " Hz");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ConnectionView::ConnectionView(QWidget * parent): BlockView(parent) {
|
||||
}
|
||||
|
||||
|
||||
ConnectionView::~ConnectionView() {
|
||||
}
|
||||
|
||||
|
||||
DeviceItem * ConnectionView::addDevice(const QString & name, const QString & path) {
|
||||
DeviceItem * ret = findDevice(name);
|
||||
if (ret) return ret;
|
||||
ret = new DeviceItem();
|
||||
PIString dp;
|
||||
PIIODevice::DeviceMode dm;
|
||||
PIIODevice::splitFullPath(Q2PIString(path), &dp, &dm);
|
||||
ret->setPos(0, 0);
|
||||
ret->setName(name);
|
||||
ret->setPath(PI2QString(dp));
|
||||
ret->setMode(dm);
|
||||
ret->setDisconnectTimeout(3.);
|
||||
ret->setBufferSize(4096);
|
||||
placeBlock(ret, allDevices());
|
||||
addItem(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
FilterItem * ConnectionView::addFilter(const QString & name) {
|
||||
FilterItem * ret = new FilterItem();
|
||||
ret->setDisconnectTimeout(3.);
|
||||
ret->setBufferSize(65536);
|
||||
ret->setName(name);
|
||||
placeBlock(ret, allFilters());
|
||||
addItem(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
SenderItem * ConnectionView::addSender(const QString & name) {
|
||||
SenderItem * ret = new SenderItem();
|
||||
ret->setName(name);
|
||||
placeBlock(ret, allSenders());
|
||||
addItem(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
DeviceItem * ConnectionView::findDevice(const QString & name) const {
|
||||
QList<BlockItem*> blockl = blocks();
|
||||
foreach (BlockItem * b, blockl)
|
||||
if ((b->propertyByName("name").value == name) && (b->propertyByName("__type").value.toInt() == __CV_Device))
|
||||
return (DeviceItem*)b;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void ConnectionView::loadBus(BlockBusItem * bus) {
|
||||
bus->setEndpointsNumber(2);
|
||||
}
|
||||
|
||||
|
||||
void ConnectionView::placeBlock(BlockItem * b, QList<BlockItem * > coll) {
|
||||
if (coll.isEmpty()) return;
|
||||
QList<QRectF> collr;
|
||||
foreach (BlockItem * i, coll)
|
||||
collr << i->sceneBoundingRect();
|
||||
while (true) {
|
||||
QRectF br = b->sceneBoundingRect();
|
||||
bool ok = true;
|
||||
for (int i = 0; i < collr.size(); ++i)
|
||||
if (br.intersects(collr[i])) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
if (ok) break;
|
||||
b->moveBy(0., grid_step);
|
||||
}
|
||||
b->moveBy(0., grid_step * 2.);
|
||||
}
|
||||
|
||||
|
||||
QList<BlockItem * > ConnectionView::allByType(int type_) const {
|
||||
QList<BlockItem*> blockl = blocks(), ret;
|
||||
foreach (BlockItem * b, blockl)
|
||||
if (b->propertyByName("__type").value.toInt() == type_)
|
||||
ret << b;
|
||||
return ret;
|
||||
}
|
||||
133
libs/piqt_widgets/piqt_connection_view.h
Normal file
133
libs/piqt_widgets/piqt_connection_view.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
PIQt Utils - Qt utilites for PIP
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONNECTION_VIEW_H
|
||||
#define CONNECTION_VIEW_H
|
||||
|
||||
#include "blockview.h"
|
||||
#include "piconnection.h"
|
||||
#include "piqt_utils_export.h"
|
||||
|
||||
const int __CV_Device = 1;
|
||||
const int __CV_Filter = 2;
|
||||
const int __CV_Sender = 3;
|
||||
|
||||
|
||||
class PIQT_UTILS_EXPORT DeviceItem: public BlockItem {
|
||||
public:
|
||||
DeviceItem();
|
||||
|
||||
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); rename();}
|
||||
void setPath(const QString & p) {addProperty(BlockItem::Property("device", "", p)); rename();}
|
||||
void setMode(PIIODevice::DeviceMode m) {addProperty(BlockItem::Property("mode", "", int(m))); rename();}
|
||||
void setOptions(PIIODevice::DeviceOptions o) {addProperty(BlockItem::Property("options", "", int(o))); rename();}
|
||||
void setDisconnectTimeout(double v) {addProperty(BlockItem::Property("disconnectTimeout", "", v)); rename();}
|
||||
void setBufferSize(int v) {addProperty(BlockItem::Property("bufferSize", "", v)); rename();}
|
||||
|
||||
QString name() const {return propertyByName("name").value.toString();}
|
||||
QString path() const {return propertyByName("device").value.toString();}
|
||||
PIIODevice::DeviceMode mode() const {return PIIODevice::DeviceMode(propertyByName("mode").value.toInt());}
|
||||
PIIODevice::DeviceOptions options() const {return PIIODevice::DeviceOptions(propertyByName("options").value.toInt());}
|
||||
double disconnectTimeout() const {return propertyByName("disconnectTimeout").value.toDouble();}
|
||||
int bufferSize() const {return propertyByName("bufferSize").value.toInt();}
|
||||
|
||||
void rename();
|
||||
|
||||
protected:
|
||||
AlignedTextItem * text_name, * text_path;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class PIQT_UTILS_EXPORT FilterItem: public BlockItem {
|
||||
public:
|
||||
FilterItem();
|
||||
|
||||
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); rename();}
|
||||
void setMode(PIPacketExtractor::SplitMode m) {addProperty(BlockItem::Property("mode", "", int(m))); rename();}
|
||||
void setHeader(const QString & v) {addProperty(BlockItem::Property("header", "", v)); rename();}
|
||||
void setFooter(const QString & v) {addProperty(BlockItem::Property("footer", "", v)); rename();}
|
||||
void setTimeout(double v) {addProperty(BlockItem::Property("timeout", "", v)); rename();}
|
||||
void setPacketSize(int v) {addProperty(BlockItem::Property("size", "", v)); rename();}
|
||||
void setDisconnectTimeout(double v) {addProperty(BlockItem::Property("disconnectTimeout", "", v)); rename();}
|
||||
void setBufferSize(int v) {addProperty(BlockItem::Property("bufferSize", "", v)); rename();}
|
||||
|
||||
QString name() const {return propertyByName("name").value.toString();}
|
||||
PIPacketExtractor::SplitMode mode() const {return PIPacketExtractor::SplitMode(propertyByName("mode").value.toInt());}
|
||||
QString header() const {return propertyByName("header").value.toString();}
|
||||
QString footer() const {return propertyByName("footer").value.toString();}
|
||||
double timeout() const {return propertyByName("timeout").value.toDouble();}
|
||||
int packetSize() const {return propertyByName("size").value.toInt();}
|
||||
double disconnectTimeout() const {return propertyByName("disconnectTimeout").value.toDouble();}
|
||||
int bufferSize() const {return propertyByName("bufferSize").value.toInt();}
|
||||
|
||||
void rename();
|
||||
|
||||
protected:
|
||||
AlignedTextItem * text_name, * text_mode;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class PIQT_UTILS_EXPORT SenderItem: public BlockItem {
|
||||
public:
|
||||
SenderItem();
|
||||
|
||||
void setName(const QString & n) {addProperty(BlockItem::Property("name", "", n)); rename();}
|
||||
void setData(const QString & p) {addProperty(BlockItem::Property("data", "", p)); rename();}
|
||||
void setFrequency(double m) {addProperty(BlockItem::Property("frequency", "", m)); rename();}
|
||||
|
||||
QString name() const {return propertyByName("name").value.toString();}
|
||||
QString data() const {return propertyByName("data").value.toString();}
|
||||
double frequency() const {return propertyByName("frequency").value.toDouble();}
|
||||
|
||||
void rename();
|
||||
|
||||
protected:
|
||||
AlignedTextItem * text_name, * text_frequency;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class PIQT_UTILS_EXPORT ConnectionView: public BlockView {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ConnectionView(QWidget * parent = 0);
|
||||
~ConnectionView();
|
||||
|
||||
DeviceItem * addDevice(const QString & name, const QString & path);
|
||||
FilterItem * addFilter(const QString & name);
|
||||
SenderItem * addSender(const QString & name);
|
||||
DeviceItem * findDevice(const QString & name) const;
|
||||
QList<BlockItem * > allDevices() const {return allByType(__CV_Device);}
|
||||
QList<BlockItem * > allFilters() const {return allByType(__CV_Filter);}
|
||||
QList<BlockItem * > allSenders() const {return allByType(__CV_Sender);}
|
||||
|
||||
private:
|
||||
QSize sizeHint() const {return QSize(800, 600);}
|
||||
void loadBus(BlockBusItem * bus);
|
||||
void placeBlock(BlockItem * b, QList<BlockItem*> coll);
|
||||
|
||||
QList<BlockItem * > allByType(int type_) const;
|
||||
|
||||
private slots:
|
||||
|
||||
};
|
||||
|
||||
#endif // CONNECTION_VIEW_H
|
||||
70
libs/piqt_widgets/piqt_highlighter.cpp
Normal file
70
libs/piqt_widgets/piqt_highlighter.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#include "piqt_highlighter.h"
|
||||
|
||||
|
||||
ConfigHighlighter::ConfigHighlighter(QTextDocument * parent): QSyntaxHighlighter(parent) {
|
||||
HighlightingRule rule;
|
||||
|
||||
valueNameFormat.setForeground(QColor(0, 64, 154));
|
||||
rule.pattern = QRegExp("[^=]"); //"\\b[A-Za-z0-9_]+(?=\\()");
|
||||
rule.format = valueNameFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
valueFormat.setForeground(QColor(192, 0, 0));
|
||||
rule.pattern = QRegExp("=[^\n]*");
|
||||
rule.format = valueFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
equalFormat.setFontWeight(QFont::Bold);
|
||||
equalFormat.setForeground(QColor(96, 126, 0));
|
||||
rule.pattern = QRegExp("=");
|
||||
rule.format = equalFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
sectionFormat.setFontWeight(QFont::Bold);
|
||||
sectionFormat.setForeground(QColor(0, 32, 64));
|
||||
rule.pattern = QRegExp("\\[.*\\]");
|
||||
rule.format = sectionFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
//substFormat.setFontWeight(QFont::Bold);
|
||||
substFormat.setForeground(QColor(192, 0, 192));
|
||||
rule.pattern = QRegExp("\\$\\{.*\\}+");
|
||||
rule.pattern.setMinimal(true);
|
||||
rule.format = substFormat;
|
||||
highlightingRules.append(rule);
|
||||
rule.pattern = QRegExp("\\$\\{[^\\{]*\\}+");
|
||||
highlightingRules.append(rule);
|
||||
|
||||
singleLineCommentFormat.setFontItalic(true);
|
||||
singleLineCommentFormat.setForeground(QColor(128, 128, 128));
|
||||
rule.pattern = QRegExp("#[^\n]*");
|
||||
rule.format = singleLineCommentFormat;
|
||||
highlightingRules.append(rule);
|
||||
|
||||
spaceFormat.setForeground(QColor(210, 210, 210));
|
||||
|
||||
//commentStartExpression = QRegExp("/\\*");
|
||||
//commentEndExpression = QRegExp("\\*/");
|
||||
}
|
||||
|
||||
|
||||
void ConfigHighlighter::highlightBlock(const QString & text) {
|
||||
foreach (const HighlightingRule &rule, highlightingRules) {
|
||||
QRegExp expression(rule.pattern);
|
||||
int index = expression.indexIn(text);
|
||||
while (index >= 0) {
|
||||
int length = expression.matchedLength();
|
||||
setFormat(index, length, rule.format);
|
||||
index = expression.indexIn(text, index + length);
|
||||
}
|
||||
}
|
||||
setCurrentBlockState(0);
|
||||
|
||||
QRegExp expression = QRegExp("[ |\t]");
|
||||
int index = expression.indexIn(text);
|
||||
while (index >= 0) {
|
||||
int length = expression.matchedLength();
|
||||
setFormat(index, length, spaceFormat);
|
||||
index = expression.indexIn(text, index + length);
|
||||
}
|
||||
}
|
||||
51
libs/piqt_widgets/piqt_highlighter.h
Normal file
51
libs/piqt_widgets/piqt_highlighter.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
PIQt Utils - Qt utilites for PIP
|
||||
|
||||
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONF_HIGHLIGHTER_H
|
||||
#define CONF_HIGHLIGHTER_H
|
||||
|
||||
#include <QSyntaxHighlighter>
|
||||
#include <QTextCursor>
|
||||
#include <QTextCharFormat>
|
||||
#include "piqt_utils_export.h"
|
||||
|
||||
class QTextDocument;
|
||||
|
||||
class PIQT_UTILS_EXPORT ConfigHighlighter : public QSyntaxHighlighter
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ConfigHighlighter(QTextDocument *parent = 0);
|
||||
|
||||
QTextCursor cursor;
|
||||
|
||||
private:
|
||||
void highlightBlock(const QString &text);
|
||||
|
||||
struct PIQT_UTILS_EXPORT HighlightingRule {
|
||||
QRegExp pattern;
|
||||
QTextCharFormat format;
|
||||
};
|
||||
|
||||
QVector<HighlightingRule> highlightingRules;
|
||||
QRegExp commentStartExpression, commentEndExpression;
|
||||
QTextCharFormat singleLineCommentFormat, valueNameFormat, valueFormat, equalFormat, sectionFormat, spaceFormat, substFormat;
|
||||
};
|
||||
|
||||
#endif // CONF_HIGHTLIGHTER_H
|
||||
92
libs/piqt_widgets/piqt_iodevice_edit.cpp
Normal file
92
libs/piqt_widgets/piqt_iodevice_edit.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
#include "piqt_iodevice_edit.h"
|
||||
#include "piqt_iodevice_edit_dialog.h"
|
||||
#include "qvariantedit_custom.h"
|
||||
#include <QLineEdit>
|
||||
#include <QToolButton>
|
||||
#include <QBoxLayout>
|
||||
#include <piqt.h>
|
||||
#include <piiodevice.h>
|
||||
|
||||
|
||||
IODeviceEdit::IODeviceEdit(QWidget * parent): QWidget(parent) {
|
||||
dlg = new IODeviceEditDialog();
|
||||
line = new QLineEdit();
|
||||
btn = new QToolButton();
|
||||
setLayout(new QBoxLayout(QBoxLayout::LeftToRight));
|
||||
layout()->setContentsMargins(0, 0, 0, 0);
|
||||
layout()->addWidget(line);
|
||||
layout()->addWidget(btn);
|
||||
connect(btn, SIGNAL(clicked(bool)), this, SLOT(buttonDlg_clicked()));
|
||||
line->setReadOnly(true);
|
||||
btn->setText(QString());
|
||||
btn->setIcon(QIcon(":/icons/configure.png"));
|
||||
btn->setToolTip(tr("Edit ..."));
|
||||
}
|
||||
|
||||
|
||||
IODeviceEdit::~IODeviceEdit() {
|
||||
delete dlg;
|
||||
}
|
||||
|
||||
|
||||
QVariant IODeviceEdit::value() const {
|
||||
return QVariant::fromValue(dev);
|
||||
}
|
||||
|
||||
|
||||
bool IODeviceEdit::isReadOnly() const {
|
||||
return btn->isHidden();
|
||||
}
|
||||
|
||||
|
||||
void IODeviceEdit::setDevice(const QAD::IODevice & d) {
|
||||
if (dev.toString() == d.toString()) return;
|
||||
dev = d;
|
||||
line->setText(dev.toString());
|
||||
line->setCursorPosition(0);
|
||||
emit valueChanged();
|
||||
}
|
||||
|
||||
|
||||
void IODeviceEdit::setValue(const QVariant & v) {
|
||||
setDevice(v.value<QAD::IODevice>());
|
||||
}
|
||||
|
||||
|
||||
void IODeviceEdit::setReadOnly(bool yes) {
|
||||
btn->setHidden(yes);
|
||||
}
|
||||
|
||||
|
||||
void IODeviceEdit::buttonDlg_clicked() {
|
||||
QAD::IODevice d = dlg->getIODevice(dev);
|
||||
if (!d.isValid()) return;
|
||||
setDevice(d);
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Factory: public QVariantEditorFactoryBase {
|
||||
public:
|
||||
Factory() {}
|
||||
virtual QWidget * createEditor() {return new IODeviceEdit();}
|
||||
};
|
||||
|
||||
|
||||
__IODeviceEditRegistrator__::__IODeviceEditRegistrator__() {
|
||||
QVariantEditorFactories::registerEditorFactory(qMetaTypeId<QAD::IODevice>(), new Factory());
|
||||
__QADTypesRegistrator__::instance()->toString_funcs.insert(qMetaTypeId<QAD::IODevice>(), &QAD_IODevice_toString);
|
||||
}
|
||||
|
||||
|
||||
void QAD_IODevice_toString(const QVariant & v, QString & r) {
|
||||
PIVariantTypes::IODevice sd = Q2PIVariant(v).toIODevice();
|
||||
// piCout << sd;
|
||||
PIIODevice * rd = PIIODevice::createFromVariant(sd);
|
||||
if (rd) {
|
||||
PIString ps = rd->constructFullPath();
|
||||
r = PI2QString(ps);
|
||||
} else {
|
||||
piCout << "error in " << sd;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user