Add Draw-figures Tab

master
addi 2016-12-14 10:00:35 +01:00
parent 7b801e5755
commit 145bf8c688
33 changed files with 2332 additions and 313 deletions

View File

@ -16,17 +16,26 @@ TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
colorlineedit.cpp \
geometry.cpp \
geometrywidget.cpp \
configdialog.cpp \
colorstxtassistant.cpp \
makecolors.cpp
makecolors.cpp \
drawmapfigure.cpp \
drawmapfiguretablemodel.cpp \
figuredelegate.cpp
HEADERS += mainwindow.h \
colorlineedit.h \
geometry.h \
geometrywidget.h \
configdialog.h \
colorstxtassistant.h \
makecolors.h
makecolors.h \
drawmapfigure.h \
drawmapfiguretablemodel.h \
figuredelegate.h
FORMS += mainwindow.ui \
geometrywidget.ui \

104
doc/drawfigure.html Normal file
View File

@ -0,0 +1,104 @@
<h1 id="figure"><code>--draw[map]&lt;figure&gt; &quot;&lt;geometry&gt; &lt;color&gt; [&lt;text&gt;]&quot;</code></h1>
<blockquote>
<p>Draw a figure on the map, with the given geometry and color.</p>
<p>Possible figures are:</p>
<ul>
<li>circle</li>
<li>ellipse (which is a synonym for circle)</li>
<li>line</li>
<li>arrow</li>
<li>point (which uses simple coordinates (x,y) instead of a geometry)</li>
<li>rectangle</li>
<li>text (which uses simple coordinates (x,y) instead of a geometry)</li>
</ul>
<p>If <code>--draw&lt;figure&gt;</code> is used, the geometry specifies world coordinates; if <code>--drawmap&lt;figure&gt;</code> is used, the geometry specifies map (i.e. image) coordinates, where 0,0 is the top-left corner of the map-part of
the image, and coordinates increase to the right and down. Any points in the left and top scale area (if present)
have negative coordinates.</p>
<p>Note that the combination of geometry and color (and text if applicable) must be a single argument. This means that they
<em>must</em> be enclosed in quotes together on the command-line, else they will be misinterpreted as two or more
command-line arguments.</p>
<p>Example:</p>
<pre><code>minetestmapper --drawcircle &quot;10,10:6x6 red&quot;</code></pre>
<p>For the color of figures, an alpha value can be specified. Note that due to a bug in the drawing library, this has not
the expected effect when drawing circles and ellipses.</p>
<p>See also Geometry Syntax_ and Color Syntax_.</p>
<p><strong>Interaction of figure geometry and map scaling</strong></p>
<p>If the map is scaled, figures could either keep the same size in pixels, or the same size relative to the world, which
would make them appear smaller like the entire map. Whether they scale of not depends on how they are drawn:</p>
<blockquote>
<ul>
<li>Figures which are drawn using map (i.e. image) coordinates are never scaled. It is assumed that it was the intention
to draw them on the image to begin with, and not in the world.</li>
</ul>
</blockquote>
<p>At the moment, figures which are drawn using world coordinates may or may not scale with the world.</p>
<ul>
<li>If the geometry of a figure is specified using 2 corners, then the distance between the coordinates obviously scales
with the world, and the resulting figure will be visually smaller as well.</li>
<li>If the geometry of a figure is specified using a corner or the center and dimensions, then the corner or center is
obviously also interpreted as world-coordinates, but the dimensions will be interpreted relative to the image.
I.e. they won't scale with the map.</li>
<li>If the geometry is specified using an angle and length, and if the length is specified in nodes (e.g. '20n'), the
size will scale. If the length is specified in pixels (e.g. '20p') or if no unit is specified, then the size
will not scale.</li>
</ul>
<p>In practise this means that two identically-sized figures in a full-scale map, may have different sizes after scaling,
depending on how their geometry was specified. The jury is still out as to whether this is a bug or a feature.</p>
</blockquote>
<h1 id="drawmapcircle"><code>--draw[map]circle &quot;&lt;geometry&gt; &lt;color&gt;&quot;</code></h1>
<blockquote>
<p>Draw a circle on the map, with the given geometry and color.</p>
<p>If the geometry does not specify equal horizontal and vertical dimensions, then an ellipse will be drawn.</p>
<p>See <a href="#figure">--draw[map]</a> for details.</p>
<p>An example circle:</p>
<p><img src=":/images/drawcircle.png" alt="image" /></p>
</blockquote>
<h1 id="drawmapellipse"><code>--draw[map]ellipse &quot;&lt;geometry&gt; &lt;color&gt;&quot;</code></h1>
<blockquote>
<p>Draw an ellipse on the map. This is a synonym for <code>--draw[map]circle</code>.</p>
<p>See <a href="#figure">--draw[map]</a> for details.</p>
</blockquote>
<h1 id="drawmapline"><code>--draw[map]line &quot;&lt;geometry&gt; &lt;color&gt;&quot;</code></h1>
<blockquote>
<p>Draw a line on the map, with the given geometry and color.</p>
<p>See <a href="#figure">--draw[map]</a> for details.</p>
<p>An example line:</p>
<p><img src=":/images/drawline.png" alt="image" /></p>
</blockquote>
<h1 id="drawmaparrow"><code>--draw[map]arrow &quot;&lt;geometry&gt; &lt;color&gt;&quot;</code></h1>
<blockquote>
<p>Draw an arrow on the map, with the given geometry and color.</p>
<p>See <a href="#figure">--draw[map]</a> for details.</p>
<p>An example arrow:</p>
<p><img src=":/images/drawarrow.png" alt="image" /></p>
</blockquote>
<h1 id="drawmappoint"><code>--draw[map]point &quot;&lt;x&gt;,&lt;y&gt; &lt;color&gt;&quot;</code></h1>
<blockquote>
<p>Draw a point on the map, at the given location, using the given color.</p>
<p>See <a href="#figure">--draw[map]</a> for details.</p>
<p>An example point (red, in te white area):</p>
<p><img src=":/images/drawpoint.png" alt="image" /></p>
</blockquote>
<h1 id="drawmaprectangle"><code>--draw[map]rectangle &quot;&lt;geometry&gt; &lt;color&gt;&quot;</code></h1>
<blockquote>
<p>Draw a reactangle on the map, with the given geometry and color.</p>
<p>See <a href="#figure">--draw[map]</a> for details.</p>
<p>An example rectangle:</p>
<p><img src=":/images/drawrectangle.png" alt="image" /></p>
</blockquote>
<h1 id="drawmaptext"><code>--draw[map]text &quot;&lt;x&gt;,&lt;y&gt; &lt;color&gt; &lt;text&gt;&quot;</code></h1>
<blockquote>
<p>Write text on the map, at the specified location, using the given color.</p>
<p>The text can consist of any number of words. Be careful when using characters that the command shell may interpret, like
'<code>&quot;</code>', '<code>$</code>', etc. On unix-like systems, use single quotes to avoid interpretation of
most characters (except for <code>'</code> itself).</p>
<p>Due to a limitation of the drawing library, currently only text that can be represented in (i.e. converted to) the ISO8859-2
character set is supported. Text that uses non-compatible characters will not be rendered correctly.</p>
<p>Note that the combination of geometry, color and text should be a single argument. This means that they must be enclosed
in quotes together on the command-line, else they will be misinterpreted as three command-line arguments.</p>
<p>Example:</p>
<pre><code>minetestmapper --drawtext &quot;20,-10 red This text will be on the map&quot;</code></pre>
<p>See also <a href="#figure">--draw[map]</a> for more details.</p>
<p>Example text:</p>
<p><img src=":/images/drawtext.png" alt="image" /></p>
</blockquote>

227
drawmapfigure.cpp Normal file
View File

@ -0,0 +1,227 @@
#include "drawmapfigure.h"
DrawMapFigure::DrawMapFigure(QObject *parent) :
QObject(parent)
{
geometry = new Geometry();
}
DrawMapFigure::DrawMapFigure(const QString &str, QObject *parent) :
QObject(parent)
{
const QRegularExpression parser = QRegularExpression("^--draw(?<map>map)?(?<type>\\w+) \"(?<params>.+)*\"$");
QRegularExpressionMatch match = parser.match(str);
QStringList xy;
if(match.hasMatch()){
useImageCoordinates = (match.captured("map")=="map");
QString params = match.captured("params");
color.setNamedColor(params.section(' ', 1, 1));
bool ok;
figure = getFigure(match.captured("type"));
if(color.isValid() && ok){
switch (figure) {
case Text:
//parse text and fall through for point
text = params.section(' ', 2);// everything after the 3rd whitespace
case Point:
//parse point and color
xy = params.section(' ', 0, 0).split(',');
point.setX(xy[0].toInt());
point.setY(xy[1].toInt());
break;
case Circle:
case Arrow:
case Line:
case Rectangle:
case Ellipse:
//parse geometry
geometry = new Geometry(params.section(' ', 0, 0));
break;
default:
figure = Unknown;
geometry = new Geometry();
break;
}
}
else{
geometry = new Geometry();
figure = Unknown;
}
}
else{
geometry = new Geometry();
figure = Unknown;
}
}
bool DrawMapFigure::requiresPoint() const
{
return (figure == Text || figure == Point);
}
bool DrawMapFigure::requiresGeometry() const
{
return (figure != Text && figure != Point);
}
bool DrawMapFigure::requiresText() const
{
return (figure == Text);
}
QString DrawMapFigure::getString() const
{
QStringList splitted = getSplittedString();
return QString("%1 \"%2\"").arg(splitted.at(0)).arg(splitted.at(1));
}
QStringList DrawMapFigure::getSplittedString() const
{
QString param;
QString argument;
param = "--draw";
if(useImageCoordinates)
param += "map";
param += QString(metaFigure.key(figure)).toLower();
if(requiresGeometry())
argument += geometry->getString();
if(requiresPoint())
argument += QString("%1,%2").arg(point.x()).arg(point.y());
argument += ' '+ color.name();
if(requiresText())
argument += ' '+text;
return QStringList()<<param<<argument;
}
bool DrawMapFigure::getUseImageCoordinates() const
{
return useImageCoordinates;
}
DrawMapFigure::Figure DrawMapFigure::getFigure() const
{
return figure;
}
DrawMapFigure::Figure DrawMapFigure::getFigure(const QString &str) const
{
const QString temp = str.left(1).toUpper()+str.mid(1);
return static_cast<Figure>(metaFigure.keyToValue(temp.toUtf8().constData()));
}
int DrawMapFigure::getFigureIndex() const
{
QMetaEnum metaEnum = QMetaEnum::fromType<Figure>();
return metaEnum.value(figure);
}
QPoint DrawMapFigure::getPoint() const
{
return point;
}
QString DrawMapFigure::getText() const
{
return text;
}
QColor DrawMapFigure::getColor() const
{
return color;
}
QStringList DrawMapFigure::getFigureList()
{
QMetaEnum metaEnum = QMetaEnum::fromType<Figure>();
QStringList list;
for(int i =0; i<metaEnum.keyCount();i++){
list << metaEnum.key(i);
}
return list;
}
void DrawMapFigure::setFigure(const Figure &value)
{
figure = value;
}
void DrawMapFigure::setFigure(int value)
{
figure = static_cast<Figure>(value);
}
void DrawMapFigure::setText(const QString &value)
{
text = value;
}
void DrawMapFigure::setColor(const QColor &value)
{
color = value;
}
Geometry *DrawMapFigure::getGeometry()
{
return this->geometry;
}
void DrawMapFigure::setGeometry(Geometry *value)
{
geometry = value;
}
void DrawMapFigure::setUseImageCoordinates(bool value)
{
useImageCoordinates = value;
}
void DrawMapFigure::setPoint(const QPoint &value)
{
point = value;
}
void DrawMapFigure::setPoint(const QVariant &value)
{
point = value.toPoint();
}
void DrawMapFigure::setPoint(const QString &value)
{
static const QRegularExpression regex("(\\-?\\d+)[ |,](\\-?\\d+)");
QRegularExpressionMatch match = regex.match(value);
if(match.hasMatch()){
point = QPoint(match.captured(1).toInt(), match.captured(2).toInt());
}
else{
qDebug() <<"Could not match point from String "<<value;
point = QPoint();
}
}
QIcon DrawMapFigure::getIcon() const
{
return getIcon(figure);
}
QIcon DrawMapFigure::getIcon(DrawMapFigure::Figure figure)
{
const char* a = QMetaEnum::fromType<Figure>().key(figure);
return QIcon(QString(":/images/draw-%1").arg(a).toLower());
}

106
drawmapfigure.h Normal file
View File

@ -0,0 +1,106 @@
#ifndef DRAWMAPFIGURE_H
#define DRAWMAPFIGURE_H
#include <QObject>
#include <QPoint>
#include <QColor>
#include <QMetaEnum>
#include <QIcon>
#include "geometry.h"
class DrawMapFigure : public QObject
{
Q_OBJECT
public:
enum Figure{
Unknown,
Arrow,
Circle,
Ellipse,
Line,
Point,
Rectangle,
Text
};
Q_ENUM(Figure)
explicit DrawMapFigure(QObject *parent = 0);
/**
* @brief DrawMapFigure
* @param str QString to convert to DrawMapFigure
* @param parent
*/
explicit DrawMapFigure(const QString &str, QObject *parent = 0);
explicit DrawMapFigure(QColor color, QObject *parent = 0) :
color(color), QObject(parent) { }
explicit DrawMapFigure(QPoint point, QColor color, QObject *parent = 0) :
point(point), color(color), QObject(parent) {}
explicit DrawMapFigure(Geometry *geometry, QColor color, QObject *parent = 0) :
geometry(geometry), color(color), QObject(parent) { }
//DrawMapFigure(const DrawMapFigure &f) {}
bool requiresPoint(void) const;
bool requiresGeometry(void) const;
bool requiresText(void) const;
QString getString(void) const;
QStringList getSplittedString(void) const;
bool getUseImageCoordinates() const;
int getFigureIndex() const;
QPoint getPoint() const;
QString getText() const;
/**
* @brief getColor
* @return
*/
QColor getColor() const;
static QStringList getFigureList();
void setFigure(const Figure &value);
void setFigure(int value);
void setText(const QString &value);
void setColor(const QColor &value);
Geometry* getGeometry();
void setGeometry(Geometry *value);
void setUseImageCoordinates(bool value);
void setPoint(const QString &value);
void setPoint(const QPoint &value);
QIcon getIcon() const;
static QIcon getIcon(Figure figure);
void setPoint(const QVariant &value);
Figure getFigure() const;
Figure getFigure(const QString &str) const;
signals:
public slots:
protected:
bool useImageCoordinates;
Figure figure = Unknown;
QPoint point;
Geometry *geometry;
QString text;
QColor color;
QMetaEnum metaFigure = QMetaEnum::fromType<Figure>();
private:
};
#endif // DRAWMAPFIGURE_H

248
drawmapfiguretablemodel.cpp Normal file
View File

@ -0,0 +1,248 @@
#include "drawmapfiguretablemodel.h"
#include <QBrush>
DrawMapFigureTableModel::DrawMapFigureTableModel(QObject *parent)
: QAbstractTableModel(parent)
{
list = new QList<DrawMapFigure *>;
header <<"Figure"<<"Use image coordinates"<<"Point"<<"Geometry"<<"Color"<<"Text";
}
DrawMapFigureTableModel::DrawMapFigureTableModel(QList<DrawMapFigure *> *list, QObject *parent)
: QAbstractTableModel(parent)
{
this->list = list;
header <<"Figure"<<"Use image coordinates"<<"Point"<<"Geometry"<<"Color"<<"Text";
}
QVariant DrawMapFigureTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole && orientation == Qt::Horizontal && section <= header.size())
{
return header[section];
}
else if(role == Qt::DisplayRole && orientation == Qt::Vertical){
return section+1;
}
return QVariant();
}
bool DrawMapFigureTableModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
{
if (value != headerData(section, orientation, role) && role == Qt::DisplayRole && orientation == Qt::Horizontal)
{
header[section] = value.toString();
emit headerDataChanged(orientation, section, section);
return true;
}
return false;
}
int DrawMapFigureTableModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
if (parent.isValid())
return 0;
return list->size();
}
int DrawMapFigureTableModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
if (parent.isValid())
return 0;
return header.size();
// FIXME: Implement me!
}
QVariant DrawMapFigureTableModel::data(const QModelIndex &index, int role) const
{
if (index.isValid()){
int row = index.row();
int col = index.column();
DrawMapFigure *item = list->at(row);
QPoint p = item->getPoint();
QMetaEnum metaEnum = QMetaEnum::fromType<DrawMapFigure::Figure>();
if(role == Qt::DecorationRole && col ==0)
{
return item->getIcon();
}
else if(role == Qt::BackgroundRole)
{
if(item->getFigure()==DrawMapFigure::Unknown){
return QBrush(Qt::red);
}
else if(col == 2 && !item->requiresPoint()){
return QBrush(Qt::lightGray);
}
else if (col == 3 && !item->requiresGeometry()){
return QBrush(Qt::lightGray);
}
else if(col == 5 && !item->requiresText()){
return QBrush(Qt::lightGray);
}
}
else if(role == Qt::EditRole ||role == Qt::DisplayRole){
switch(col){
case 0:
return (role == Qt::EditRole) ? QVariant(item->getFigure()) : QString(metaEnum.key(item->getFigure()));
break;
case 1:
return item->getUseImageCoordinates();
break;
case 2:
return (item->requiresPoint()) ? QString("(%1,%2)").arg(p.x()).arg(p.y()) : QVariant();
break;
case 3:
return item->requiresGeometry() ? item->getGeometry()->getString() : QVariant();
break;
case 4:
return item->getColor();
break;
case 5:
return item->getText();
break;
default:
return QVariant();
}
// FIXME: Implement me!
return QVariant();
}
else if(role == Qt::DecorationRole && col==4){
return item->getColor();
}
}
return QVariant();
}
bool DrawMapFigureTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.isValid() && role == Qt::EditRole && data(index, role) != value) {
int row = index.row();
int col = index.column();
DrawMapFigure *item = list->at(row);
switch(col){
case 0:
item->setFigure(value.toInt());
break;
case 1:
item->setUseImageCoordinates(value.toBool());
break;
case 2:
item->setPoint(value.toString());
break;
case 3:
item->getGeometry()->set(value.toString());
break;
case 4:
item->setColor(QColor(value.toString()));
break;
case 5:
item->setText(value.toString());
default:
break;
}
// FIXME: Implement me!
emit dataChanged(index, index, QVector<int>() << role);
return true;
}
return false;
}
Qt::ItemFlags DrawMapFigureTableModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::NoItemFlags;
Qt::ItemFlags flag = QAbstractItemModel::flags(index);
int col = index.column();
DrawMapFigure *item = list->at(index.row());
if(col == 0)
flag |= Qt::ItemIsEnabled|Qt::ItemIsEditable;
else if(col == 1)
flag |= Qt::ItemIsEditable;
else if (col == 2 && item->requiresPoint())
flag |= Qt::ItemIsEditable;
else if (col == 3 && item->requiresGeometry())
flag |= Qt::ItemIsEditable;
else if (col == 4)
flag |= Qt::ItemIsEditable;
else if(col == 5 && item->requiresText())
flag |= Qt::ItemIsEditable;
return flag;
}
bool DrawMapFigureTableModel::insertRows(int position, int count, const QModelIndex &parent)
{
beginInsertRows(parent, position, position + count - 1);
for (int row = 0; row < count; ++row) {
list->insert(position, new DrawMapFigure());
}
endInsertRows();
return true;
}
bool DrawMapFigureTableModel::insertColumns(int column, int count, const QModelIndex &parent)
{
beginInsertColumns(parent, column, column + count - 1);
// FIXME: Implement me!
endInsertColumns();
return false;
}
bool DrawMapFigureTableModel::removeRows(int position, int count, const QModelIndex &parent)
{
beginRemoveRows(parent, position, position + count - 1);
for (int row = 0; row < count; ++row) {
list->removeAt(position);
}
endRemoveRows();
return true;
}
bool DrawMapFigureTableModel::removeColumns(int column, int count, const QModelIndex &parent)
{
beginRemoveColumns(parent, column, column + count - 1);
// FIXME: Implement me!
endRemoveColumns();
return false;
}
QStringList DrawMapFigureTableModel::getStringList() const
{
QStringList retval;
for (int i = 0; i < list->size(); ++i)
retval << list->at(i)->getString();
return retval;
}
QStringList DrawMapFigureTableModel::getArguments() const
{
QStringList retval;
for (int i = 0; i < list->size(); ++i)
retval << list->at(i)->getSplittedString();
return retval;
}
void DrawMapFigureTableModel::insertStringList(const QStringList &other)
{
if(other.length() > 0){
int leng = other.length();
beginInsertRows(QModelIndex() , list->length(), list->length()+leng - 1);
//insertRows(0, other.length(),QModelIndex());
for(int i = 0; i < leng; ++i){
list->append(new DrawMapFigure(other.at(i)));
}
endInsertRows();
}
}

View File

@ -0,0 +1,248 @@
#include "drawmapfiguretablemodel.h"
#include <QBrush>
DrawMapFigureTableModel::DrawMapFigureTableModel(QObject *parent)
: QAbstractTableModel(parent)
{
list = new QList<DrawMapFigure *>;
header <<"Figure"<<"Use image coordinates"<<"Point"<<"Geometry"<<"Color"<<"Text";
}
DrawMapFigureTableModel::DrawMapFigureTableModel(QList<DrawMapFigure *> *list, QObject *parent)
: QAbstractTableModel(parent)
{
this->list = list;
header <<"Figure"<<"Use image coordinates"<<"Point"<<"Geometry"<<"Color"<<"Text";
}
QVariant DrawMapFigureTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole && orientation == Qt::Horizontal && section <= header.size())
{
return header[section];
}
else if(role == Qt::DisplayRole && orientation == Qt::Vertical){
return section+1;
}
return QVariant();
}
bool DrawMapFigureTableModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
{
if (value != headerData(section, orientation, role) && role == Qt::DisplayRole && orientation == Qt::Horizontal)
{
header[section] = value.toString();
emit headerDataChanged(orientation, section, section);
return true;
}
return false;
}
int DrawMapFigureTableModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
if (parent.isValid())
return 0;
return list->size();
}
int DrawMapFigureTableModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
if (parent.isValid())
return 0;
return header.size();
// FIXME: Implement me!
}
QVariant DrawMapFigureTableModel::data(const QModelIndex &index, int role) const
{
if (index.isValid()){
int row = index.row();
int col = index.column();
DrawMapFigure *item = list->at(row);
QPoint p = item->getPoint();
QMetaEnum metaEnum = QMetaEnum::fromType<DrawMapFigure::Figure>();
if(role == Qt::DecorationRole && col ==0)
{
return item->getIcon();
}
else if(role == Qt::BackgroundRole)
{
if(item->getFigure()==DrawMapFigure::Unknown){
return QBrush(Qt::red);
}
else if(col == 2 && !item->requiresPoint()){
return QBrush(Qt::lightGray);
}
else if (col == 3 && !item->requiresGeometry()){
return QBrush(Qt::lightGray);
}
else if(col == 5 && !item->requiresText()){
return QBrush(Qt::lightGray);
}
}
else if(role == Qt::EditRole ||role == Qt::DisplayRole){
switch(col){
case 0:
return (role == Qt::EditRole) ? QVariant(item->getFigure()) : QString(metaEnum.key(item->getFigure()));
break;
case 1:
return item->getUseImageCoordinates();
break;
case 2:
return (item->requiresPoint()) ? QString("(%1,%2)").arg(p.x()).arg(p.y()) : QVariant();
break;
case 3:
return item->requiresGeometry() ? item->getGeometry()->getString() : QVariant();
break;
case 4:
return item->getColor();
break;
case 5:
return item->getText();
break;
default:
return QVariant();
}
// FIXME: Implement me!
return QVariant();
}
else if(role == Qt::DecorationRole && col==4){
return item->getColor();
}
}
return QVariant();
}
bool DrawMapFigureTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.isValid() && role == Qt::EditRole && data(index, role) != value) {
int row = index.row();
int col = index.column();
DrawMapFigure *item = list->at(row);
switch(col){
case 0:
item->setFigure(value.toInt());
break;
case 1:
item->setUseImageCoordinates(value.toBool());
break;
case 2:
item->setPoint(value.toString());
break;
case 3:
item->getGeometry()->set(value.toString());
break;
case 4:
item->setColor(QColor(value.toString()));
break;
case 5:
item->setText(value.toString());
default:
break;
}
// FIXME: Implement me!
emit dataChanged(index, index, QVector<int>() << role);
return true;
}
return false;
}
Qt::ItemFlags DrawMapFigureTableModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::NoItemFlags;
Qt::ItemFlags flag = QAbstractItemModel::flags(index);
int col = index.column();
DrawMapFigure *item = list->at(index.row());
if(col == 0)
flag |= Qt::ItemIsEnabled|Qt::ItemIsEditable;
else if(col == 1)
flag |= Qt::ItemIsEditable;
else if (col == 2 && item->requiresPoint())
flag |= Qt::ItemIsEditable;
else if (col == 3 && item->requiresGeometry())
flag |= Qt::ItemIsEditable;
else if (col == 4)
flag |= Qt::ItemIsEditable;
else if(col == 5 && item->requiresText())
flag |= Qt::ItemIsEditable;
return flag;
}
bool DrawMapFigureTableModel::insertRows(int position, int count, const QModelIndex &parent)
{
beginInsertRows(parent, position, position + count - 1);
for (int row = 0; row < count; ++row) {
list->insert(position, new DrawMapFigure());
}
endInsertRows();
return true;
}
bool DrawMapFigureTableModel::insertColumns(int column, int count, const QModelIndex &parent)
{
beginInsertColumns(parent, column, column + count - 1);
// FIXME: Implement me!
endInsertColumns();
return false;
}
bool DrawMapFigureTableModel::removeRows(int position, int count, const QModelIndex &parent)
{
beginRemoveRows(parent, position, position + count - 1);
for (int row = 0; row < count; ++row) {
list->removeAt(position);
}
endRemoveRows();
return true;
}
bool DrawMapFigureTableModel::removeColumns(int column, int count, const QModelIndex &parent)
{
beginRemoveColumns(parent, column, column + count - 1);
// FIXME: Implement me!
endRemoveColumns();
return false;
}
QStringList DrawMapFigureTableModel::getStringList() const
{
QStringList retval;
for (int i = 0; i < list->size(); ++i)
retval << list->at(i)->getString();
return retval;
}
QStringList DrawMapFigureTableModel::getArguments() const
{
QStringList retval;
for (int i = 0; i < list->size(); ++i)
retval << list->at(i)->getSplittedString();
return retval;
}
void DrawMapFigureTableModel::insertStringList(const QStringList &other)
{
if(other.length() > 0){
int leng = other.length();
beginInsertRows(QModelIndex() , list->length(), list->length()+leng - 1);
//insertRows(0, other.length(),QModelIndex());
for(int i = 0; i < leng; ++i){
list->append(new DrawMapFigure(other.at(i)));
}
endInsertRows();
}
}

51
drawmapfiguretablemodel.h Normal file
View File

@ -0,0 +1,51 @@
#ifndef DRAWMAPFIGURETABLEMODEL_H
#define DRAWMAPFIGURETABLEMODEL_H
#include <QAbstractTableModel>
#include <QPixmap>
#include "drawmapfigure.h"
#include "geometry.h"
class DrawMapFigureTableModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit DrawMapFigureTableModel(QObject *parent = 0);
explicit DrawMapFigureTableModel(QList<DrawMapFigure *> *list, QObject *parent = 0);
// Header:
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole) override;
// Basic functionality:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
// Editable:
bool setData(const QModelIndex &index, const QVariant &value,
int role = Qt::EditRole) override;
Qt::ItemFlags flags(const QModelIndex& index) const override;
// Add data:
bool insertRows(int position, int count, const QModelIndex &parent = QModelIndex()) override;
bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override;
// Remove data:
bool removeRows(int position, int count, const QModelIndex &parent = QModelIndex()) override;
bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex()) override;
QStringList getStringList(void) const;
QStringList getArguments(void) const;
void insertStringList(const QStringList &other);
private:
QList<DrawMapFigure *> *list;
QStringList header;
};
#endif // DRAWMAPFIGURETABLEMODEL_H

55
figuredelegate.cpp Normal file
View File

@ -0,0 +1,55 @@
#include "figuredelegate.h"
#include <QComboBox>
FigureDelegate::FigureDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
list = DrawMapFigure::getFigureList();
}
QWidget *FigureDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &/* option */,
const QModelIndex &/* index */) const
{
QComboBox *editor = new QComboBox(parent);
editor->setFrame(false);
QMetaEnum figureEnum = QMetaEnum::fromType<DrawMapFigure::Figure>();
for(int i = 0; i<list.length(); i++){
DrawMapFigure::Figure f = static_cast<DrawMapFigure::Figure>(figureEnum.value(i));
editor->addItem(DrawMapFigure::getIcon(f), list.at(i), f);
}
return editor;
}
void FigureDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
int value = index.model()->data(index, Qt::EditRole).toInt();
QComboBox *comboBox = static_cast<QComboBox*>(editor);
comboBox->setCurrentIndex(value);
}
void FigureDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
QComboBox *comboBox = static_cast<QComboBox*>(editor);
model->setData(index, comboBox->currentData(), Qt::EditRole);
}
void FigureDelegate::updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &/* index */) const
{
editor->setGeometry(option.rect);
}
/*void FigureDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyle* style = QApplication::style();
QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &option);
painter->drawText(textRect, option.displayAlignment, list.at(index.data().toInt()));
QStyledItemDelegate::paint(painter, option, index);
}*/

35
figuredelegate.h Normal file
View File

@ -0,0 +1,35 @@
#ifndef FIGUREDELEGATE_H
#define FIGUREDELEGATE_H
#include <QApplication>
#include <QObject>
#include <QPainter>
#include <QSpinBox>
#include <QStyledItemDelegate>
#include <QWidget>
#include "drawmapfigure.h"
class FigureDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
FigureDelegate(QObject *parent = 0);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const Q_DECL_OVERRIDE;
void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE;
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const Q_DECL_OVERRIDE;
void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
//void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE ;
private:
QStringList list;
};
#endif // FIGUREDELEGATE_H

256
geometry.cpp Normal file
View File

@ -0,0 +1,256 @@
#include "geometry.h"
QMap<Geometry::Format, QString> Geometry::geometryIdNameMap;
QMap<QString, Geometry::Format> Geometry::geometryNameIdMap;
const Geometry::InitStatics initStatics;
Geometry::InitStatics::InitStatics()
{
Geometry::geometryIdNameMap[Geometry::FormatUnknown] = "unknown";
Geometry::geometryIdNameMap[Geometry::FormatNone] = "none";
Geometry::geometryIdNameMap[Geometry::CenterDimensions] = "center-dimensions";
Geometry::geometryIdNameMap[Geometry::CornerDimensions] = "corner-dimensions";
Geometry::geometryIdNameMap[Geometry::Corners] = "corners";
Geometry::geometryIdNameMap[Geometry::FormatCustom] = "custom";
for (int i = Geometry::FormatNone; i < Geometry::FormatMax; i++)
Geometry::geometryNameIdMap[Geometry::geometryIdNameMap[static_cast<Format>(i)]] = static_cast<Format>(i);
}
const QString &Geometry::formatName(Geometry::Format id)
{
if (id < Geometry::FormatNone || id >= Geometry::FormatMax)
id = Geometry::FormatUnknown;
return geometryIdNameMap[id];
}
Geometry::Format Geometry::formatId(const QString &name)
{
if (geometryNameIdMap.find(name) == geometryNameIdMap.end())
return Geometry::FormatUnknown;
else
return geometryNameIdMap[name];
}
Geometry::Format Geometry::set(QString str)
{
qDebug()<<"Trying to detect format of "<<str;
QRegularExpressionMatch match;
if(str.isEmpty()){
qDebug()<<"format is FormatNone";
return FormatNone;
}
else if((match =corners.match(str)).hasMatch()) {
qDebug()<<"format is Corners";
corner[0][0] = match.captured(1).toInt();
corner[0][1] = match.captured(2).toInt();
corner[1][0] = match.captured(3).toInt();
corner[1][1] = match.captured(4).toInt();
adjustCorners();
// Order is important here!
computeDimensions();
computeCenter();
return Geometry::Corners;
}
else if((match =centerDimension.match(str)).hasMatch()){
qDebug()<<"format is CenterDimensions";
center[0] = match.captured(1).toInt();
center[1] = match.captured(2).toInt();
dimension[0] = match.captured(3).toInt();
dimension[1] = match.captured(4).toInt();
computeCorner0();
computeCorner1();
if (adjustCorners()) {
// Order is important here!
computeDimensions();
computeCenter();
}
return Geometry::CenterDimensions;
}
else if((match = cornerDimension.match(str)).hasMatch()){
qDebug()<<"format is CornerDimensions";
corner[0][0] = match.captured(1).toInt();
corner[0][1] = match.captured(2).toInt();
dimension[0] = match.captured(3).toInt();
dimension[1] = match.captured(4).toInt();
computeCenter();
computeCorner1();
if (adjustCorners()) {
// Order is important here!
computeDimensions();
computeCenter();
}
return Geometry::CornerDimensions;
}
else if((match = cornerDimensionAlternate.match(str)).hasMatch()){
qDebug() << "format is <width>x<height>[<+|-xoffset><+|-yoffset>]";
if(match.lastCapturedIndex() ==2){
qDebug() << "format is CenterDimensions with center =0,0";
center[0] = 0;
center[1] = 0;
dimension[0] = match.captured(1).toInt();
dimension[1] = match.captured(2).toInt();
computeCorner0();
computeCorner1();
if (adjustCorners()) {
// Order is important here!
computeDimensions();
computeCenter();
}
return Geometry::CenterDimensions;
}
else if(match.lastCapturedIndex() ==4){
qDebug() << "format is CornerDimensions";
corner[0][0] = match.captured(3).toInt();
corner[0][1] = match.captured(4).toInt();
dimension[0] = match.captured(1).toInt();
dimension[1] = match.captured(2).toInt();
computeCenter();
computeCorner1();
if (adjustCorners()) {
// Order is important here!
computeDimensions();
computeCenter();
}
return Geometry::CornerDimensions;
}
else return Geometry::FormatCustom;
}
else {
qDebug()<<"Warning: Could not parse format of string: "<<str;
return Geometry::FormatCustom;
}
}
void Geometry::setMax(void)
{
for (int i=0; i<2; i++) {
center[i] = 0;
dimension[i] = 65536;
}
computeCorner0();
computeCorner1();
}
bool Geometry::adjustCorners(void)
{
bool adjusted = false;
for (int j = 0; j < 2; j++) {
for (int i = 0; i < 2; i++) {
if (corner[j][i] < -32768) {
corner[j][i] = -32768;
adjusted = true;
}
if (corner[j][i] > 32767) {
corner[j][i] = 32767;
adjusted = true;
}
}
}
return adjusted;
}
void Geometry::setCenterDimensions(int cx, int cy, int dx, int dy)
{
center[0] = cx;
center[1] = cy;
dimension[0] = dx;
dimension[1] = dy;
computeCorner0();
computeCorner1();
}
void Geometry::setCornerDimensions(int cx, int cy, int dx, int dy)
{
corner[0][0] = cx;
corner[0][1] = cy;
dimension[0] = dx;
dimension[1] = dy;
computeCenter();
computeCorner1();
}
void Geometry::setCorners(int c0x, int c0y, int c1x, int c1y)
{
corner[0][0] = c0x;
corner[0][1] = c0y;
corner[1][0] = c1x;
corner[1][1] = c1y;
computeDimensions();
computeCenter();
}
QString Geometry::getString(Geometry::Format format)
{
switch (format) {
case CenterDimensions:
if(center[0]==0 && center[1] ==0)
return QString("%1x%2")
.arg(dimension[0])
.arg(dimension[1]);
return QString("%1,%2:%3x%4")
.arg(center[0])
.arg(center[1])
.arg(dimension[0])
.arg(dimension[1]);
break;
case CornerDimensions:
return QString("%1,%2+%3+%4")
.arg(corner[0][0])
.arg(corner[0][1])
.arg(dimension[0])
.arg(dimension[1]);
break;
case Corners:
default:
return QString("%1,%2:%3,%4")
.arg(corner[0][0])
.arg(corner[0][1])
.arg(corner[1][0])
.arg(corner[1][1]);
break;
}
}
void Geometry::computeCorner0(void)
{
for (int i = 0; i < 2; i++) {
if (dimension[i] < 0)
corner[0][i] = center[i] + (-dimension[i]) / 2;
else
corner[0][i] = center[i] - dimension[i] / 2;
}
}
void Geometry::computeCorner1(void)
{
for (int i = 0; i < 2; i++) {
if (dimension[i] < 0)
corner[1][i] = corner[0][i] + dimension[i] + 1;
else
corner[1][i] = corner[0][i] + dimension[i] - 1;
}
}
void Geometry::computeCenter(void)
{
for (int i = 0; i < 2; i++) {
if (corner[0][i] > corner[1][i])
center[i] = corner[0][i] - (-dimension[i]) / 2;
else
center[i] = corner[0][i] + dimension[i] / 2;
}
}
void Geometry::computeDimensions(void)
{
for (int i = 0; i < 2; i++) {
if (corner[0][i] > corner[1][i])
dimension[i] = corner[1][i] - corner[0][i] - 1;
else
dimension[i] = corner[1][i] - corner[0][i] + 1;
}
}

57
geometry.h Normal file
View File

@ -0,0 +1,57 @@
#ifndef GEOMETRY_H
#define GEOMETRY_H
#include <QMap>
#include <QRegularExpression>
#include <QDebug>
class Geometry
{
public:
enum Format {
FormatKeep = -2, // Special value used when setting geometry: don't change current format.
FormatUnknown = -1,
FormatNone = 0,
CenterDimensions = 1,
CornerDimensions = 2,
Corners = 3,
FormatCustom,
FormatMax
};
static QMap<Geometry::Format, QString> geometryIdNameMap;
static QMap<QString, Geometry::Format> geometryNameIdMap;
static const QString &formatName(Geometry::Format id);
static Geometry::Format formatId(const QString &name);
struct InitStatics { InitStatics(void); };
static const InitStatics initStatics;
friend struct InitStatics;
int center[2];
int dimension[2];
int corner[2][2];
Geometry(void) { setMax(); }
Geometry(const char *s) { set(s); }
Geometry(const QString &s) { set(s); }
//Geometry(const Geometry &g);
Geometry::Format set(QString str);
void setMax(void);
void setCenterDimensions(int cx, int cy, int dx, int dy);
void setCornerDimensions(int cx, int cy, int dx, int dy);
void setCorners(int c0x, int c0y, int c1x, int c1y);
QString getString(Geometry::Format format = Geometry::FormatNone);
private:
const QRegularExpression corners = QRegularExpression("(-?\\d*),(-?\\d*):(-?\\d*),(-?\\d*)");
const QRegularExpression centerDimension = QRegularExpression("(-?\\d*),(-?\\d*):(-?\\d*)x(-?\\d*)");
const QRegularExpression cornerDimension = QRegularExpression("(-?\\d*)[,:](-?\\d*)[+-](-?\\d*)[+-](-?\\d*)");
const QRegularExpression cornerDimensionAlternate = QRegularExpression("(\\d*)x(\\d*)[+]?(-?\\d+)?[+]?(-?\\d+)?");
bool adjustCorners(void);
void computeCorner0(void);
void computeCorner1(void);
void computeCenter(void); // Depends dimensions to be correct !
void computeDimensions(void);
};
#endif // GEOMETRY_H

View File

@ -2,259 +2,6 @@
#include "ui_geometrywidget.h"
QMap<Geometry::Format, QString> Geometry::geometryIdNameMap;
QMap<QString, Geometry::Format> Geometry::geometryNameIdMap;
const Geometry::InitStatics initStatics;
Geometry::InitStatics::InitStatics()
{
Geometry::geometryIdNameMap[Geometry::FormatUnknown] = "unknown";
Geometry::geometryIdNameMap[Geometry::FormatNone] = "none";
Geometry::geometryIdNameMap[Geometry::CenterDimensions] = "center-dimensions";
Geometry::geometryIdNameMap[Geometry::CornerDimensions] = "corner-dimensions";
Geometry::geometryIdNameMap[Geometry::Corners] = "corners";
Geometry::geometryIdNameMap[Geometry::FormatCustom] = "custom";
for (int i = Geometry::FormatNone; i < Geometry::FormatMax; i++)
Geometry::geometryNameIdMap[Geometry::geometryIdNameMap[static_cast<Format>(i)]] = static_cast<Format>(i);
}
const QString &Geometry::formatName(Geometry::Format id)
{
if (id < Geometry::FormatNone || id >= Geometry::FormatMax)
id = Geometry::FormatUnknown;
return geometryIdNameMap[id];
}
Geometry::Format Geometry::formatId(const QString &name)
{
if (geometryNameIdMap.find(name) == geometryNameIdMap.end())
return Geometry::FormatUnknown;
else
return geometryNameIdMap[name];
}
Geometry::Format Geometry::set(QString str)
{
qDebug()<<"Trying to detect format of "<<str;
QRegularExpressionMatch match;
if(str.isEmpty()){
qDebug()<<"format is FormatNone";
return FormatNone;
}
else if((match =corners.match(str)).hasMatch()) {
qDebug()<<"format is Corners";
corner[0][0] = match.captured(1).toInt();
corner[0][1] = match.captured(2).toInt();
corner[1][0] = match.captured(3).toInt();
corner[1][1] = match.captured(4).toInt();
adjustCorners();
// Order is important here!
computeDimensions();
computeCenter();
return Geometry::Corners;
}
else if((match =centerDimension.match(str)).hasMatch()){
qDebug()<<"format is CenterDimensions";
center[0] = match.captured(1).toInt();
center[1] = match.captured(2).toInt();
dimension[0] = match.captured(3).toInt();
dimension[1] = match.captured(4).toInt();
computeCorner0();
computeCorner1();
if (adjustCorners()) {
// Order is important here!
computeDimensions();
computeCenter();
}
return Geometry::CenterDimensions;
}
else if((match = cornerDimension.match(str)).hasMatch()){
qDebug()<<"format is CornerDimensions";
corner[0][0] = match.captured(1).toInt();
corner[0][1] = match.captured(2).toInt();
dimension[0] = match.captured(3).toInt();
dimension[1] = match.captured(4).toInt();
computeCenter();
computeCorner1();
if (adjustCorners()) {
// Order is important here!
computeDimensions();
computeCenter();
}
return Geometry::CornerDimensions;
}
else if((match = cornerDimensionAlternate.match(str)).hasMatch()){
qDebug() << "format is <width>x<height>[<+|-xoffset><+|-yoffset>]";
if(match.lastCapturedIndex() ==2){
qDebug() << "format is CenterDimensions with center =0,0";
center[0] = 0;
center[1] = 0;
dimension[0] = match.captured(1).toInt();
dimension[1] = match.captured(2).toInt();
computeCorner0();
computeCorner1();
if (adjustCorners()) {
// Order is important here!
computeDimensions();
computeCenter();
}
return Geometry::CenterDimensions;
}
else if(match.lastCapturedIndex() ==4){
qDebug() << "format is CornerDimensions";
corner[0][0] = match.captured(3).toInt();
corner[0][1] = match.captured(4).toInt();
dimension[0] = match.captured(1).toInt();
dimension[1] = match.captured(2).toInt();
computeCenter();
computeCorner1();
if (adjustCorners()) {
// Order is important here!
computeDimensions();
computeCenter();
}
return Geometry::CornerDimensions;
}
else return Geometry::FormatCustom;
}
else {
qDebug()<<"Warning: Could not parse format of string: "<<str;
return Geometry::FormatCustom;
}
}
void Geometry::setMax(void)
{
for (int i=0; i<2; i++) {
center[i] = 0;
dimension[i] = 65536;
}
computeCorner0();
computeCorner1();
}
bool Geometry::adjustCorners(void)
{
bool adjusted = false;
for (int j = 0; j < 2; j++) {
for (int i = 0; i < 2; i++) {
if (corner[j][i] < -32768) {
corner[j][i] = -32768;
adjusted = true;
}
if (corner[j][i] > 32767) {
corner[j][i] = 32767;
adjusted = true;
}
}
}
return adjusted;
}
void Geometry::setCenterDimensions(int cx, int cy, int dx, int dy)
{
center[0] = cx;
center[1] = cy;
dimension[0] = dx;
dimension[1] = dy;
computeCorner0();
computeCorner1();
}
void Geometry::setCornerDimensions(int cx, int cy, int dx, int dy)
{
corner[0][0] = cx;
corner[0][1] = cy;
dimension[0] = dx;
dimension[1] = dy;
computeCenter();
computeCorner1();
}
void Geometry::setCorners(int c0x, int c0y, int c1x, int c1y)
{
corner[0][0] = c0x;
corner[0][1] = c0y;
corner[1][0] = c1x;
corner[1][1] = c1y;
computeDimensions();
computeCenter();
}
QString Geometry::getString(Geometry::Format format)
{
switch (format) {
case CenterDimensions:
if(center[0]==0 && center[1] ==0)
return QString("%1x%2")
.arg(dimension[0])
.arg(dimension[1]);
return QString("%1,%2:%3x%4")
.arg(center[0])
.arg(center[1])
.arg(dimension[0])
.arg(dimension[1]);
break;
case CornerDimensions:
return QString("%1,%2+%3+%4")
.arg(corner[0][0])
.arg(corner[0][1])
.arg(dimension[0])
.arg(dimension[1]);
break;
case Corners:
default:
return QString("%1,%2:%3,%4")
.arg(corner[0][0])
.arg(corner[0][1])
.arg(corner[1][0])
.arg(corner[1][1]);
break;
}
}
void Geometry::computeCorner0(void)
{
for (int i = 0; i < 2; i++) {
if (dimension[i] < 0)
corner[0][i] = center[i] + (-dimension[i]) / 2;
else
corner[0][i] = center[i] - dimension[i] / 2;
}
}
void Geometry::computeCorner1(void)
{
for (int i = 0; i < 2; i++) {
if (dimension[i] < 0)
corner[1][i] = corner[0][i] + dimension[i] + 1;
else
corner[1][i] = corner[0][i] + dimension[i] - 1;
}
}
void Geometry::computeCenter(void)
{
for (int i = 0; i < 2; i++) {
if (corner[0][i] > corner[1][i])
center[i] = corner[0][i] - (-dimension[i]) / 2;
else
center[i] = corner[0][i] + dimension[i] / 2;
}
}
void Geometry::computeDimensions(void)
{
for (int i = 0; i < 2; i++) {
if (corner[0][i] > corner[1][i])
dimension[i] = corner[1][i] - corner[0][i] - 1;
else
dimension[i] = corner[1][i] - corner[0][i] + 1;
}
}
template<class Q, class V>
static void setQWidgetValue(Q *object, V value)
@ -345,7 +92,7 @@ bool GeometryWidget::set(const QString geomStr, Geometry::Format requestedFormat
return true;
}
QString GeometryWidget::getGeometry()
QString GeometryWidget::getGeometry(void) const
{
Geometry geometry;
Geometry::Format format = getFormat();
@ -393,7 +140,7 @@ bool GeometryWidget::setFormat(Geometry::Format format)
return true;
}
Geometry::Format GeometryWidget::getFormat(void)
Geometry::Format GeometryWidget::getFormat(void) const
{
Geometry::Format format = static_cast<Geometry::Format>(ui->geometryStackedWidget->currentIndex());
// Usage of '0' instead of a symbolic value is intentional. The currentIndex() should never be less than 0.
@ -419,6 +166,7 @@ void GeometryWidget::on_geometry_CD_CenterX_editingFinished()
ui->geometry_CD_DimensionX->setValue(65536 - 2 * center);
else if (center + (dimension - 1)/2 < -32768)
ui->geometry_CD_DimensionX->setValue(65536 + 2 * (center - 1));
emit editingFinished();
}
void GeometryWidget::on_geometry_CD_CenterY_editingFinished()
@ -429,6 +177,7 @@ void GeometryWidget::on_geometry_CD_CenterY_editingFinished()
ui->geometry_CD_DimensionY->setValue(65536 - 2 * center);
else if (center + (dimension - 1)/2 < -32768)
ui->geometry_CD_DimensionY->setValue(65536 + 2 * (center - 1));
emit editingFinished();
}
void GeometryWidget::on_geometry_CD_DimensionX_editingFinished()
@ -439,6 +188,7 @@ void GeometryWidget::on_geometry_CD_DimensionX_editingFinished()
ui->geometry_CD_DimensionX->setValue(65536 - 2 * center);
else if (center + (dimension - 1)/2 < -32768)
ui->geometry_CD_DimensionX->setValue(65536 + 2 * (center - 1));
emit editingFinished();
}
void GeometryWidget::on_geometry_CD_DimensionY_editingFinished()
@ -449,6 +199,7 @@ void GeometryWidget::on_geometry_CD_DimensionY_editingFinished()
ui->geometry_CD_DimensionY->setValue(65536 - 2 * center);
else if (center + (dimension - 1)/2 < -32768)
ui->geometry_CD_DimensionY->setValue(65536 + 2 * (center - 1));
emit editingFinished();
}
void GeometryWidget::on_geometry_C0D_CornerX_editingFinished()
@ -459,6 +210,7 @@ void GeometryWidget::on_geometry_C0D_CornerX_editingFinished()
ui->geometry_C0D_DimensionX->setValue(32767 + 1 - corner);
else if (corner + dimension - 1 < -32768)
ui->geometry_C0D_DimensionX->setValue(-32768 + 1 - corner);
emit editingFinished();
}
void GeometryWidget::on_geometry_C0D_CornerY_editingFinished()
@ -469,6 +221,7 @@ void GeometryWidget::on_geometry_C0D_CornerY_editingFinished()
ui->geometry_C0D_DimensionY->setValue(32767 + 1 - corner);
else if (corner + dimension - 1 < -32768)
ui->geometry_C0D_DimensionY->setValue(-32768 + 1 - corner);
emit editingFinished();
}
void GeometryWidget::on_geometry_C0D_DimensionX_editingFinished()
@ -479,6 +232,7 @@ void GeometryWidget::on_geometry_C0D_DimensionX_editingFinished()
ui->geometry_C0D_DimensionX->setValue(32767 + 1 - corner);
else if (corner + dimension - 1 < -32768)
ui->geometry_C0D_DimensionX->setValue(-32768 + 1 - corner);
emit editingFinished();
}
void GeometryWidget::on_geometry_C0D_DimensionY_editingFinished()
@ -489,6 +243,7 @@ void GeometryWidget::on_geometry_C0D_DimensionY_editingFinished()
ui->geometry_C0D_DimensionY->setValue(32767 + 1 - corner);
else if (corner + dimension - 1 < -32768)
ui->geometry_C0D_DimensionY->setValue(-32768 + 1 - corner);
emit editingFinished();
}
void GeometryWidget::on_geometry_parse_clicked()

View File

@ -5,64 +5,19 @@
#include <QtWidgets>
#include <QRegularExpression>
class Geometry;
#include "geometry.h"
class GeometryWidget;
namespace Ui {
class GeometryWidget;
}
class Geometry
{
public:
enum Format {
FormatKeep = -2, // Special value used when setting geometry: don't change current format.
FormatUnknown = -1,
FormatNone = 0,
CenterDimensions = 1,
CornerDimensions = 2,
Corners = 3,
FormatCustom,
FormatMax
};
static QMap<Geometry::Format, QString> geometryIdNameMap;
static QMap<QString, Geometry::Format> geometryNameIdMap;
static const QString &formatName(Geometry::Format id);
static Geometry::Format formatId(const QString &name);
struct InitStatics { InitStatics(void); };
static const InitStatics initStatics;
friend struct InitStatics;
int center[2];
int dimension[2];
int corner[2][2];
Geometry(void) { setMax(); }
Geometry(const char *s) { set(s); }
Geometry(const QString &s) { set(s); }
Geometry(const Geometry &g);
Geometry::Format set(QString str);
void setMax(void);
void setCenterDimensions(int cx, int cy, int dx, int dy);
void setCornerDimensions(int cx, int cy, int dx, int dy);
void setCorners(int c0x, int c0y, int c1x, int c1y);
QString getString(Geometry::Format format = Geometry::FormatNone);
private:
const QRegularExpression corners = QRegularExpression("(-?\\d*),(-?\\d*):(-?\\d*),(-?\\d*)");
const QRegularExpression centerDimension = QRegularExpression("(-?\\d*),(-?\\d*):(-?\\d*)x(-?\\d*)");
const QRegularExpression cornerDimension = QRegularExpression("(-?\\d*)[,:](-?\\d*)[+-](-?\\d*)[+-](-?\\d*)");
const QRegularExpression cornerDimensionAlternate = QRegularExpression("(\\d*)x(\\d*)[+]?(-?\\d+)?[+]?(-?\\d+)?");
bool adjustCorners(void);
void computeCorner0(void);
void computeCorner1(void);
void computeCenter(void); // Depends dimensions to be correct !
void computeDimensions(void);
};
class GeometryWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY(QString geometry READ getGeometry WRITE set NOTIFY editingFinished USER true)
public:
explicit GeometryWidget(QWidget *parent = 0);
@ -73,9 +28,9 @@ public:
bool setFormat(int i) { return setFormat(static_cast<Geometry::Format>(i)); }
bool setFormat(Geometry::Format format);
bool setFormat(QString formatStr) { return setFormat(Geometry::formatId(formatStr)); }
Geometry::Format getFormat(void);
Geometry::Format getFormat(void) const;
QString getFormatStr(void) { return Geometry::formatName(getFormat()); }
QString getGeometry();
QString getGeometry(void) const;
private slots:
void on_geometryFormat_currentIndexChanged(int index);
@ -99,6 +54,8 @@ private:
QSpinBox *m_ui_C0D_corner[2];
QSpinBox *m_ui_C0D_dimension[2];
QSpinBox *m_ui_C01_corner[2][2];
signals:
void editingFinished(void);
};

3
images/desktop.ini Normal file
View File

@ -0,0 +1,3 @@
[LocalizedFileNames]
draw-arrow-up.png=@draw-arrow-up.png,0
draw-text-2.png=@draw-text-2.png,0

67
images/draw-arrow.svg Normal file
View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
id="svg5331"
version="1.1"
inkscape:version="0.91 r13725"
viewBox="0 0 16 16"
sodipodi:docname="draw-arrow.svg">
<defs
id="defs5333" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="22.197802"
inkscape:cx="8"
inkscape:cy="8"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1536"
inkscape:window-height="801"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid5339" />
</sodipodi:namedview>
<metadata
id="metadata5336">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 10,0.5 0,1 3.792969,0 L 0.64648438,14.646484 1.3535156,15.353516 14.5,2.2070312 14.5,6 l 1,0 c 0,-1.8333333 0,-3.6666667 0,-5.5 z"
id="path5343"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

90
images/draw-circle.svg Normal file
View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
id="svg4203"
version="1.1"
inkscape:version="0.91 r13725"
viewBox="0 0 16 16"
sodipodi:docname="draw-circle.svg">
<defs
id="defs4205">
<linearGradient
inkscape:collect="always"
id="linearGradient4763">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop4765" />
<stop
style="stop-color:#0000ff;stop-opacity:0;"
offset="1"
id="stop4767" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4763"
id="linearGradient4769"
x1="0.5"
y1="8"
x2="15.5"
y2="8"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="31.392433"
inkscape:cx="1.4741751"
inkscape:cy="8.2212389"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1536"
inkscape:window-height="801"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid4211" />
</sodipodi:namedview>
<metadata
id="metadata4208">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<circle
id="path4213"
cx="8"
cy="8"
r="7"
style="fill-opacity:1;fill:url(#linearGradient4769);stroke:#000000;stroke-opacity:1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

91
images/draw-ellipse.svg Normal file
View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
id="svg4771"
version="1.1"
inkscape:version="0.91 r13725"
viewBox="0 0 16 16"
sodipodi:docname="draw-ellipse.svg">
<defs
id="defs4773">
<linearGradient
inkscape:collect="always"
id="linearGradient5323">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop5325" />
<stop
style="stop-color:#0000ff;stop-opacity:0;"
offset="1"
id="stop5327" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5323"
id="linearGradient5329"
x1="0.5"
y1="8.5"
x2="15.5"
y2="8.5"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="31.392433"
inkscape:cx="1.9938176"
inkscape:cy="8.5872531"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1536"
inkscape:window-height="801"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid4779" />
</sodipodi:namedview>
<metadata
id="metadata4776">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<ellipse
style="fill:url(#linearGradient5329);fill-opacity:1;stroke:#000000;stroke-opacity:1"
id="path4781"
cx="8"
cy="8.5"
rx="7"
ry="3.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

66
images/draw-line.svg Normal file
View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
id="svg5331"
version="1.1"
inkscape:version="0.91 r13725"
viewBox="0 0 16 16"
sodipodi:docname="draw-line.svg">
<defs
id="defs5333" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="22.197802"
inkscape:cx="8"
inkscape:cy="8"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1536"
inkscape:window-height="801"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid5339" />
</sodipodi:namedview>
<metadata
id="metadata5336">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 1,13 15,4"
id="path5349"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

90
images/draw-point.svg Normal file
View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
id="svg5331"
version="1.1"
inkscape:version="0.91 r13725"
viewBox="0 0 16 16"
sodipodi:docname="draw-point.svg">
<defs
id="defs5333">
<linearGradient
inkscape:collect="always"
id="linearGradient5893">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop5895" />
<stop
style="stop-color:#0000ff;stop-opacity:0;"
offset="1"
id="stop5897" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5893"
id="linearGradient5899"
x1="4.5"
y1="8.5"
x2="10.5"
y2="8.5"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="22.197802"
inkscape:cx="0.65693063"
inkscape:cy="8"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1536"
inkscape:window-height="801"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid5339" />
</sodipodi:namedview>
<metadata
id="metadata5336">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<circle
style="fill:url(#linearGradient5899);fill-opacity:1;stroke:#000000;stroke-opacity:1"
id="path5351"
cx="7.5"
cy="8.5"
r="2.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

92
images/draw-rectangle.svg Normal file
View File

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
id="svg3381"
version="1.1"
inkscape:version="0.91 r13725"
viewBox="0 0 16 16"
sodipodi:docname="draw-rectangle.svg">
<defs
id="defs3383">
<linearGradient
inkscape:collect="always"
id="linearGradient4195">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop4197" />
<stop
style="stop-color:#0000ff;stop-opacity:0;"
offset="1"
id="stop4199" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4195"
id="linearGradient4201"
x1="0.5"
y1="8"
x2="15.5"
y2="8"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="31.392433"
inkscape:cx="5.0777047"
inkscape:cy="9.8448689"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:snap-grids="true"
inkscape:window-width="1536"
inkscape:window-height="801"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid3393" />
</sodipodi:namedview>
<metadata
id="metadata3386">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<rect
style="fill:url(#linearGradient4201);fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
id="rect3391"
width="14"
height="8"
x="1"
y="4" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

74
images/draw-text.svg Normal file
View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
id="svg5331"
version="1.1"
inkscape:version="0.91 r13725"
viewBox="0 0 16 16"
sodipodi:docname="draw-text.svg">
<defs
id="defs5333" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="22.197802"
inkscape:cx="1.7885208"
inkscape:cy="6.7480896"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1536"
inkscape:window-height="801"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid5339" />
</sodipodi:namedview>
<metadata
id="metadata5336">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:22.62917709px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-0.62774837"
y="16.075411"
id="text5901"
sodipodi:linespacing="125%"
transform="scale(1.0652952,0.93870693)"><tspan
sodipodi:role="line"
id="tspan5903"
x="-0.62774837"
y="16.075411"
style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Times New Roman';-inkscape-font-specification:'Times New Roman, Italic'">T </tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

67
images/draw-unknown.svg Normal file
View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
id="svg3336"
version="1.1"
inkscape:version="0.91 r13725"
viewBox="0 0 16 16"
sodipodi:docname="draw-unknown.svg">
<defs
id="defs3338" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="31.392433"
inkscape:cx="7.366444"
inkscape:cy="8.5100351"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:window-width="1536"
inkscape:window-height="801"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid3344" />
</sodipodi:namedview>
<metadata
id="metadata3341">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 2,15 2,6 8,13 12,7 5,5 10,2 10,13.980646 14,11 2,2 14,4"
id="path3346"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
images/drawarrow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
images/drawcircle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
images/drawline.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
images/drawpoint.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
images/drawrectangle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

BIN
images/drawtext.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@ -78,7 +78,7 @@ MainWindow::MainWindow(QWidget *parent) :
ui->setupUi(this);
finishUiInitialisation();
readSettings();
readProfile(currentProfile);
progressBar = new QProgressBar(ui->statusBar);
progressBar->setAlignment(Qt::AlignRight);
progressBar->setMaximumSize(180, 19);
@ -92,11 +92,34 @@ MainWindow::MainWindow(QWidget *parent) :
createLanguageMenu();
createProfilesMenu();
ui->figureSelect->addItems(DrawMapFigure::getFigureList());
drawMapFigureTable = new DrawMapFigureTableModel(this);
ui->figures_list->setModel(drawMapFigureTable);
ui->figures_list->setItemDelegateForColumn(0, new FigureDelegate(this));
drawMapFigureTableMapper = new QDataWidgetMapper(this);
readProfile(currentProfile);
drawMapFigureTableMapper->setModel(drawMapFigureTable);
drawMapFigureTableMapper->addMapping(ui->figureSelect, 0, "currentIndex");
drawMapFigureTableMapper->addMapping(ui->figureUseImageCoordinates,1);
drawMapFigureTableMapper->addMapping(ui->figure_point,2);
drawMapFigureTableMapper->addMapping(ui->figure_geometry, 3, "geometry");
drawMapFigureTableMapper->addMapping(ui->figure_color,4);
drawMapFigureTableMapper->addMapping(ui->figure_text,5);
connect(ui->figures_list->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
drawMapFigureTableMapper, SLOT(setCurrentModelIndex(QModelIndex)));
ui->figures_list->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->figures_list->resizeColumnsToContents();
QCompleter *completer = new QCompleter(this);
QDirModel *model =new QDirModel(completer);
model->setFilter(QDir::Dirs|QDir::NoDotAndDotDot|QDir::Drives);
completer->setModel(model);
ui->path_World->setCompleter(completer);
}
void MainWindow::finishUiInitialisation(void)
@ -428,6 +451,9 @@ void MainWindow::on_button_generate_clicked()
}
}
// Draw figures tab
arguments << drawMapFigureTable->getArguments();
ui->button_generate->setDisabled(true);
if(ui->actionExpert_Mode->isChecked()){
@ -543,6 +569,18 @@ void MainWindow::mapperFinisched(int exit)
ui->statusBar->showMessage(tr("minetestmapper terminated"));
}
else{//something was wrong
QMessageBox errBox;
errBox.setText(tr("<b>Minetest Mapper failed</b>"));
errBox.setSizeGripEnabled(true);
errBox.setMinimumSize(800,600);
errBox.resize(800,600);
errBox.setIcon(QMessageBox::Icon::Critical);
errBox.setInformativeText(tr("Exit code: %1").arg(exit));
errBox.setDetailedText(ui->statusBar->currentMessage());
errBox.setStandardButtons(QMessageBox::Close);
errBox.setDefaultButton(QMessageBox::Close);
errBox.exec();
QMessageBox::critical(this, tr("Minetest Mapper failed"),
tr("<h1>ERROR</h1> <h2>minetestmapper failed</h2>"
"Exit code: <i>%1</i> <br>"
@ -811,7 +849,10 @@ void MainWindow::writeProfile(QString strProfile)
/*
* Todo: also save and restore other tiles
*/
profile.endGroup();
profile.beginGroup("drawFigures"); //tab7 Draw Figures
profile.setValue("drawMapFigures", drawMapFigureTable->getStringList());
profile.endGroup();
}
@ -911,6 +952,10 @@ void MainWindow::readProfile(QString strProfile)
ui->tiles_coordinateX->setValue(profile.value("tiles_coordinateX",0).toInt());
ui->tiles_coordinateY->setValue(profile.value("tiles_coordinateY",0).toInt());
profile.endGroup();
profile.beginGroup("drawFigures");
drawMapFigureTable->insertStringList(profile.value("drawMapFigures",QStringList()).toStringList());
profile.endGroup();
}
void MainWindow::closeEvent(QCloseEvent *event)
@ -1187,3 +1232,29 @@ QString MainWindow::getColorsTxtFilePath(QDir *appDir, QDir *worldDir)
}
return retval;
}
void MainWindow::on_button_addFigure_clicked()
{
drawMapFigureTable->insertRow(0);
}
void MainWindow::on_figure_geometry_apply_clicked()
{
drawMapFigureTableMapper->submit();
}
void MainWindow::on_button_deleteFigure_clicked()
{
QModelIndexList indexes;
while((indexes = ui->figures_list->selectionModel()->selectedIndexes()).size()) {
drawMapFigureTable->removeRow(indexes.first().row());
}
}
void MainWindow::on_figureSelect_currentIndexChanged(int index)
{
QStringList lookup = QStringList()<<"figure"
<< "drawmaparrow" << "drawmapcircle" << "drawmapellipse"
<< "drawmapline" << "drawmappoint" << "drawmaprectangle" << "drawmaptext";
ui->figureInformation->scrollToAnchor(lookup.at(index));
}

View File

@ -13,6 +13,8 @@
#include <QInputDialog>
#include <QActionGroup>
#include <QSettings>
#include <QMessageBox>
#include <QDataWidgetMapper>
#ifdef Q_OS_WIN
#include <QWinTaskbarProgress>
#include <QWinTaskbarButton>
@ -20,6 +22,9 @@
#include "configdialog.h"
#include "colorstxtassistant.h"
#include "drawmapfigure.h"
#include "drawmapfiguretablemodel.h"
#include "figuredelegate.h"
namespace Ui {
class MainWindow;
@ -104,6 +109,14 @@ private slots:
void on_actionPreferences_triggered();
void on_button_addFigure_clicked();
void on_figure_geometry_apply_clicked();
void on_button_deleteFigure_clicked();
void on_figureSelect_currentIndexChanged(int index);
private:
bool portable;
Ui::MainWindow *ui;
@ -135,6 +148,9 @@ private:
//QSettings profile;
QSettings *settings;
QString getColorsTxtFilePath(QDir *appDir, QDir *worldDir);
DrawMapFigureTableModel *drawMapFigureTable;
QDataWidgetMapper *drawMapFigureTableMapper;
};
#endif // MAINWINDOW_H

View File

@ -894,7 +894,7 @@ Nodes higher than this level will not be drawn. This can be used to avoid floati
<rect>
<x>0</x>
<y>0</y>
<width>503</width>
<width>524</width>
<height>427</height>
</rect>
</property>
@ -2178,6 +2178,174 @@ Nodes higher than this level will not be drawn. This can be used to avoid floati
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Draw figures</string>
</attribute>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Elements</string>
</property>
<layout class="QGridLayout" name="gridLayout_16">
<item row="1" column="0">
<widget class="QPushButton" name="button_addFigure">
<property name="text">
<string>+</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="button_deleteFigure">
<property name="text">
<string>-</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QTableView" name="figures_list">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragDrop</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::MoveAction</enum>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>30</number>
</attribute>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Properties</string>
</property>
<layout class="QGridLayout" name="gridLayout_14">
<item row="3" column="2">
<widget class="QLineEdit" name="figure_point"/>
</item>
<item row="6" column="1">
<widget class="QLabel" name="label_22">
<property name="text">
<string>Information: </string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="figureSelect"/>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Figure:</string>
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="ColorLineEdit" name="figure_color">
<property name="text">
<string>red</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Color: </string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QCheckBox" name="figureUseImageCoordinates">
<property name="text">
<string>Use Image Coodinates</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QLineEdit" name="figure_text"/>
</item>
<item row="5" column="1">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Text:</string>
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<widget class="QGroupBox" name="groupBox_9">
<property name="title">
<string>Geometry</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_10">
<item>
<widget class="GeometryWidget" name="figure_geometry" native="true"/>
</item>
<item>
<widget class="QPushButton" name="figure_geometry_apply">
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_21">
<property name="text">
<string>Point</string>
</property>
</widget>
</item>
<item row="7" column="1" colspan="2">
<widget class="QTextBrowser" name="figureInformation">
<property name="acceptRichText">
<bool>false</bool>
</property>
<property name="source">
<url>
<string>qrc:/doc/drawfigure.html</string>
</url>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_output">
<attribute name="title">
<string>MinetestMapper Output</string>
@ -3092,7 +3260,7 @@ p, li { white-space: pre-wrap; }
</connection>
</connections>
<buttongroups>
<buttongroup name="geometrymode_size_group"/>
<buttongroup name="geometrymode_granularity_group"/>
<buttongroup name="geometrymode_size_group"/>
</buttongroups>
</ui>

View File

@ -173,12 +173,13 @@ bool MakeColors::writeColorsTxt(const QString file)
{
mi.next();
const QString fullNodeName = mi.key();
const QString currentMod = fullNodeName.split(':')[0];
const QString currentMod = fullNodeName.section(':',0,0,QString::SectionIncludeLeadingSep);
//write a new paragraph
if(currentMod != lastMod){
out<<endl<<"# "<<fullNodeName.split(':')[0]<<endl;
if(currentMod != lastMod)
{
lastMod = currentMod;
out<<endl<<"# "<<currentMod<<endl;
}
//read the color for texture out of requiredColors QHash
QColor color = requiredColors.value(mi.value());

View File

@ -8,5 +8,20 @@
<file alias="open">images/open.svg</file>
<file>images/icon.svg</file>
<file>images/minetest.svg</file>
<file>doc/drawfigure.html</file>
<file>images/draw-arrow.svg</file>
<file>images/draw-circle.svg</file>
<file>images/draw-ellipse.svg</file>
<file>images/draw-line.svg</file>
<file>images/draw-point.svg</file>
<file>images/draw-rectangle.svg</file>
<file>images/draw-unknown.svg</file>
<file>images/draw-text.svg</file>
<file>images/drawarrow.png</file>
<file>images/drawcircle.png</file>
<file>images/drawline.png</file>
<file>images/drawpoint.png</file>
<file>images/drawrectangle.png</file>
<file>images/drawtext.png</file>
</qresource>
</RCC>