More UI work

This commit is contained in:
jaseg 2020-08-17 00:56:17 +02:00
parent 2deadc6cfb
commit c6713d0876
15 changed files with 352 additions and 75 deletions

134
TagEditDialog.ui Normal file
View file

@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TagEditDialog</class>
<widget class="QDialog" name="TagEditDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Name</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="tagNameEdit"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Tag ID</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="tagIdLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QTableView" name="tagPropertiesView"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Properties</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_4">
<property name="text">
<string>Location</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="tagLocationLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>TagEditDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>TagEditDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -8,11 +8,13 @@ Numberator::Numberator(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
, ui(new Ui::Numberator) , ui(new Ui::Numberator)
, tagsDockUi(new Ui::TagListDock) , tagsDockUi(new Ui::TagListDock)
, tagEditUi(new Ui::TagEditDialog)
, settings("jaseg.de", "Numberator") , settings("jaseg.de", "Numberator")
, loadImageDialog(this) , loadImageDialog(this)
, proj() , proj()
, tagListModel(proj) , tagListModel(proj)
, tagPropTableModel(proj) , tagPropTableModel(&proj)
, dialogTagPropTableModel(nullptr, false)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -22,16 +24,75 @@ Numberator::Numberator(QWidget *parent)
QMessageBox::critical(this, errorName, description); QMessageBox::critical(this, errorName, description);
}); });
QDialog *tagEditDialog = new QDialog(this);
tagEditUi->setupUi(tagEditDialog);
tagEditUi->tagPropertiesView->setModel(&dialogTagPropTableModel);
connect(tagEditUi->buttonBox, &QDialogButtonBox::accepted, [=]() {
Tag newTag(m_tagBeingEdited);
newTag.name = tagEditUi->tagNameEdit->text();
newTag.metadata = dialogTagPropTableModel.metadata();
proj.updateTag(newTag);
tagEditDialog->hide();
});
connect(tagEditUi->buttonBox, &QDialogButtonBox::rejected, tagEditDialog, &QDialog::hide);
connect(ui->graphicsView->scene(), &TagScene::selectionChanged, [=](){
auto dbg = qDebug() << "tag view selection changed";
auto items = ui->graphicsView->scene()->selectedItems();
if (items.isEmpty()) {
dbg << "<empty>";
return;
}
QGraphicsItem *first = items.first();
TagItem *it = qgraphicsitem_cast<TagItem *>(first);
dbg << first << it << first->type() << TagItem::Type;
if (!it) {
dbg << "<no tagitem>";
return;
}
dbg << it->tag().id << it->tag().name;
QSignalBlocker(tagsDockUi->tagList->selectionModel());
tagsDockUi->tagList->selectionModel()->select(tagListModel.indexOf(it->tag()), QItemSelectionModel::ClearAndSelect);
tagPropTableModel.showTag(it->tag());
});
/*
m_tagBeingEdited = it->tag();
tagEditUi->tagNameEdit->setText(m_tagBeingEdited.name);
tagEditUi->tagIdLabel->setText(QString::number(m_tagBeingEdited.id));
tagEditUi->tagLocationLabel->setText(m_tagBeingEdited.humanReadableAnchor());
dialogTagPropTableModel.showTag(m_tagBeingEdited);
*/
QDockWidget *dock = new QDockWidget(this); QDockWidget *dock = new QDockWidget(this);
tagsDockUi->setupUi(dock); tagsDockUi->setupUi(dock);
addDockWidget(Qt::LeftDockWidgetArea, dock); addDockWidget(Qt::LeftDockWidgetArea, dock);
tagsDockUi->tagList->setModel(&tagListModel);
qDebug() << "connecting up model" << tagsDockUi->tagList->selectionModel();
connect(tagsDockUi->tagList->selectionModel(), &QItemSelectionModel::selectionChanged,
[=](const QItemSelection &selected, const QItemSelection &deselected) {
Q_UNUSED(deselected);
auto dbg = qDebug() << "tagList...selectionChanged";
if (selected.indexes().isEmpty()) {
dbg << "<empty>";
ui->graphicsView->scene()->clearSelection();
tagPropTableModel.showTag(Tag());
} else {
Tag tag(tagListModel.getTag(selected.indexes().first()));
qDebug() << tag.id << tag.name;
tagPropTableModel.showTag(tag);
QSignalBlocker(ui->graphicsView->scene());
ui->graphicsView->scene()->selectTag(tag);
}
});
ui->menuView->addAction(dock->toggleViewAction()); ui->menuView->addAction(dock->toggleViewAction());
connect(ui->actionReload_Image, &QAction::triggered, connect(ui->actionReload_Image, &QAction::triggered, &proj, &SQLiteSaveFile::reloadImageFromDisk);
&proj, &SQLiteSaveFile::reloadImageFromDisk);
ui->graphicsView->setProject(&proj); ui->graphicsView->setProject(&proj);
tagsDockUi->tagList->setModel(&tagListModel);
tagsDockUi->propertyTable->setModel(&tagPropTableModel); tagsDockUi->propertyTable->setModel(&tagPropTableModel);
loadImageDialog.setWindowModality(Qt::ApplicationModal); loadImageDialog.setWindowModality(Qt::ApplicationModal);
@ -80,12 +141,6 @@ Numberator::Numberator(QWidget *parent)
}); });
connect(ui->actionAbout, &QAction::triggered, &aboutDialog, &AboutDialog::open); connect(ui->actionAbout, &QAction::triggered, &aboutDialog, &AboutDialog::open);
connect(tagsDockUi->tagList->selectionModel(), &QItemSelectionModel::selectionChanged,
[=](const QItemSelection &selected, const QItemSelection &deselected) {
Q_UNUSED(deselected);
tagPropTableModel.showTag(tagListModel.getTag(selected.indexes().first()));
});
connect(ui->actionZoom_to_fit, &QAction::triggered, ui->graphicsView, &TagView::zoomToFit); connect(ui->actionZoom_to_fit, &QAction::triggered, ui->graphicsView, &TagView::zoomToFit);
connect(ui->actionZoom_in, &QAction::triggered, ui->graphicsView, &TagView::zoomIn); connect(ui->actionZoom_in, &QAction::triggered, ui->graphicsView, &TagView::zoomIn);
connect(ui->actionZoom_out, &QAction::triggered, ui->graphicsView, &TagView::zoomOut); connect(ui->actionZoom_out, &QAction::triggered, ui->graphicsView, &TagView::zoomOut);

View file

@ -9,6 +9,7 @@
#include <QFileDialog> #include <QFileDialog>
#include <QMainWindow> #include <QMainWindow>
#include <ui_TagEditDialog.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace Ui { namespace Ui {
@ -33,6 +34,7 @@ public slots:
private: private:
Ui::Numberator *ui; Ui::Numberator *ui;
Ui::TagListDock *tagsDockUi; Ui::TagListDock *tagsDockUi;
Ui::TagEditDialog *tagEditUi;
QSettings settings; QSettings settings;
QFileDialog loadImageDialog, QFileDialog loadImageDialog,
@ -41,7 +43,7 @@ private:
SQLiteSaveFile proj; SQLiteSaveFile proj;
TagListModel tagListModel; TagListModel tagListModel;
TagPropTableModel tagPropTableModel; TagPropTableModel tagPropTableModel, dialogTagPropTableModel;
TagView m_tagView; Tag m_tagBeingEdited;
}; };
#endif // NUMBERATOR_H #endif // NUMBERATOR_H

View file

@ -37,6 +37,7 @@ HEADERS += \
tagscene.h tagscene.h
FORMS += \ FORMS += \
TagEditDialog.ui \
TagEditor.ui \ TagEditor.ui \
TagListDock.ui \ TagListDock.ui \
aboutdialog.ui \ aboutdialog.ui \

View file

@ -258,7 +258,6 @@ QString SQLiteSaveFile::getNextAutoTagName()
bool ok = false; bool ok = false;
int numericSuffix = res.captured(2).toInt(&ok); int numericSuffix = res.captured(2).toInt(&ok);
QString stringPrefix = res.captured(1); QString stringPrefix = res.captured(1);
qDebug() << "Name has match" << stringPrefix << numericSuffix;
if (ok) { if (ok) {
do { do {

View file

@ -21,7 +21,10 @@ public:
Tag(long long int id, const Tag &other); Tag(long long int id, const Tag &other);
Tag(QString name, const QPointF &anchor, const QVariantMap metadata=QVariantMap()); Tag(QString name, const QPointF &anchor, const QVariantMap metadata=QVariantMap());
bool isValid() { return valid; } bool operator==(const Tag &t2) const { return id == t2.id; }
bool isValid() const { return valid; }
QString humanReadableAnchor() { return QString("%1, %2").arg(anchor.x()).arg(anchor.y()); }
long long int id; long long int id;
QString name; QString name;

View file

@ -1,18 +1,22 @@
#include "tagitem.h" #include "tagitem.h"
#include "tagscene.h"
#include <QPainter> #include <QPainter>
#include <QGuiApplication> #include <QGuiApplication>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
TagItem::TagItem(const Tag &tag) TagItem::TagItem(const Tag &tag)
: valid(true) : valid(true)
, m_margins(2, 2, 2, 2)
{ {
setFlags(QGraphicsItem::ItemIsMovable setFlags(QGraphicsItem::ItemIsSelectable
| QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable
| QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsFocusable
| QGraphicsItem::ItemIgnoresTransformations | QGraphicsItem::ItemIgnoresTransformations
| QGraphicsItem::ItemSendsGeometryChanges); | QGraphicsItem::ItemSendsGeometryChanges);
QFont font(QGuiApplication::font()); QFont font(QGuiApplication::font());
font.setPointSize(18); font.setPointSize(12);
setFont(font); setFont(font);
tagUpdated(tag); tagUpdated(tag);
} }
@ -29,7 +33,7 @@ QRectF TagItem::boundingRect() const
{ {
QRectF parentRect(QGraphicsSimpleTextItem::boundingRect()); QRectF parentRect(QGraphicsSimpleTextItem::boundingRect());
parentRect.translate(-(parentRect.bottomRight() - parentRect.topLeft()) * 0.5); parentRect.translate(-(parentRect.bottomRight() - parentRect.topLeft()) * 0.5);
return parentRect.marginsAdded(QMargins(5, 5, 5, 5)); return parentRect.marginsAdded(m_margins);
} }
/* For some reason this is not exposed through the public API so we have to copy-paste it here m( */ /* For some reason this is not exposed through the public API so we have to copy-paste it here m( */
@ -56,7 +60,11 @@ static void paintSelectionHighlightBorder(QPainter *painter, const QStyleOptionG
void TagItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) void TagItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{ {
painter->setBrush(Qt::white); bool selectionHighlight = option->state & (QStyle::State_Selected | QStyle::State_HasFocus);
if (selectionHighlight)
painter->setBrush(QColor("#80aaaaff"));
else
painter->setBrush(QColor("#80ffffff"));
painter->drawRect(boundingRect()); painter->drawRect(boundingRect());
QRectF parentRect(QGraphicsSimpleTextItem::boundingRect()); QRectF parentRect(QGraphicsSimpleTextItem::boundingRect());
@ -68,7 +76,7 @@ void TagItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q
QGraphicsSimpleTextItem::paint(painter, &newOption, widget); QGraphicsSimpleTextItem::paint(painter, &newOption, widget);
painter->translate(pos); painter->translate(pos);
if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus)) if (selectionHighlight)
paintSelectionHighlightBorder(painter, option, this); paintSelectionHighlightBorder(painter, option, this);
} }
@ -80,13 +88,40 @@ QPainterPath TagItem::shape() const
QVariant TagItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) QVariant TagItem::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{ {
qDebug() << "itemChange" << m_tag.name << this->boundingRect() << change; //qDebug() << "itemChange" << m_tag.name << this->boundingRect() << change;
if (change == ItemPositionChange) { if (change == ItemSceneChange) {
assert(qvariant_cast<TagScene *>(value)); /* TagItems must only be used in TagScene. */
} else if (change == ItemPositionChange) {
/* https://gist.github.com/csukuangfj/c2a06416062bec9ed99eddd705c21275#file-qgraphicsscenetest-cpp-L90 /* https://gist.github.com/csukuangfj/c2a06416062bec9ed99eddd705c21275#file-qgraphicsscenetest-cpp-L90
* *
*/ */
/* FIXME */ /* FIXME */
} }
return QGraphicsItem::itemChange(change, value); return QGraphicsItem::itemChange(change, value);
} }
void TagItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) {
QPoint delta = event->screenPos() - event->buttonDownScreenPos(Qt::LeftButton);
int pixelThreshold = 10;
if (QPoint::dotProduct(delta, delta) > pixelThreshold*pixelThreshold)
dragAboveThreshold = true;
if (!dragAboveThreshold) {
// patch up event to prevent small movements
event->setPos(event->buttonDownPos(Qt::LeftButton));
event->setScenePos(event->buttonDownScenePos(Qt::LeftButton));
event->setScreenPos(event->buttonDownScreenPos(Qt::LeftButton));
}
}
QGraphicsItem::mouseMoveEvent(event);
}
void TagItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
Q_UNUSED(event);
dragAboveThreshold = false;
QGraphicsItem::mouseReleaseEvent(event);
}

View file

@ -12,12 +12,13 @@ public:
TagItem(const Tag &tag); TagItem(const Tag &tag);
TagItem() : valid(false) {}; TagItem() : valid(false) {};
enum { TagItemType = UserType + 1 }; enum { Type = UserType + 1 };
int type() const override { return TagItemType; } int type() const override { return Type; }
bool isValid() { return valid; } bool isValid() { return valid; }
void tagUpdated(const Tag &tag); void tagUpdated(const Tag &tag);
Tag tag() { return m_tag; } Tag tag() { return m_tag; }
virtual QRectF boundingRect() const override; virtual QRectF boundingRect() const override;
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
virtual QPainterPath shape() const override; virtual QPainterPath shape() const override;
@ -25,9 +26,14 @@ public:
protected: protected:
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override; QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
private: private:
Tag m_tag; Tag m_tag;
bool valid; bool valid;
QMargins m_margins;
bool dragAboveThreshold = false;
}; };
#endif // TAGITEM_H #endif // TAGITEM_H

View file

@ -17,10 +17,24 @@ int TagListModel::rowCount(const QModelIndex &parent) const
return cached_tags.size(); return cached_tags.size();
} }
bool collateTagNames(QString a, QString b) {
QRegularExpression name_re("^(\\d*)(.*?)(\\d*)$");
auto res_a = name_re.match(a), res_b = name_re.match(b);
if (res_a.captured(1).isEmpty() && !res_b.captured(1).isEmpty())
return true;
if (res_a.captured().toInt() < res_b.captured().toInt())
return true;
/* FIXME TODO */
}
void TagListModel::reloadTags() void TagListModel::reloadTags()
{ {
qDebug() << "TagListModel::reloadTags()";
beginResetModel(); beginResetModel();
cached_tags = backend.getAllTags(); cached_tags = backend.getAllTags();
std::sort(cached_tags.begin(), cached_tags.end(), [](const Tag &a, const Tag &b) { return collateTagNames(a.name, b.name); });
endResetModel(); endResetModel();
} }
@ -47,6 +61,11 @@ QVariant TagListModel::headerData(int section, Qt::Orientation orientation, int
return QString("Tag"); return QString("Tag");
} }
QModelIndex TagListModel::indexOf(const Tag &t) const
{
return index(cached_tags.indexOf(t));
}
Qt::ItemFlags TagListModel::flags(const QModelIndex &index) const Qt::ItemFlags TagListModel::flags(const QModelIndex &index) const
{ {
Q_UNUSED(index); Q_UNUSED(index);

View file

@ -15,6 +15,7 @@ public:
int rowCount(const QModelIndex &parent=QModelIndex()) const override; int rowCount(const QModelIndex &parent=QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override; QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override; QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override;
QModelIndex indexOf(const Tag &t) const;
Qt::ItemFlags flags(const QModelIndex &index) const override; Qt::ItemFlags flags(const QModelIndex &index) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override; bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override;

View file

@ -1,32 +1,28 @@
#include "tagproptablemodel.h" #include "tagproptablemodel.h"
TagPropTableModel::TagPropTableModel(SQLiteSaveFile &backend, const Tag tag)
: TagPropTableModel(backend, true)
{
tag_cached = tag;
tag_keys = tag_cached.metadata.keys();
tag_keys.sort();
qDebug() << "connecting TagPropTableModel" << &backend;
}
TagPropTableModel::TagPropTableModel(SQLiteSaveFile &backend, bool tagIsValid) TagPropTableModel::TagPropTableModel(SQLiteSaveFile *backend, bool showBaseData)
: backend(backend) : backend(backend)
, tagIsValid(tagIsValid) , showBaseData(showBaseData)
{ {
connect(&backend, &SQLiteSaveFile::tagChange, this, &TagPropTableModel::tagChange); if (backend) {
connect(&backend, &SQLiteSaveFile::fileReload, [=]() { connect(backend, &SQLiteSaveFile::tagChange, this, &TagPropTableModel::tagChange);
beginResetModel(); connect(backend, &SQLiteSaveFile::fileReload, [=]() {
this->tagIsValid = false; showTag(Tag());
endResetModel(); });
}); }
} }
int TagPropTableModel::rowCount(const QModelIndex &parent) const int TagPropTableModel::rowCount(const QModelIndex &parent) const
{ {
Q_UNUSED(parent); Q_UNUSED(parent);
if (!tagIsValid) if (!tag_cached.isValid())
return 0; return 0;
return 3 + tag_cached.metadata.size();
if (showBaseData)
return 3 + tag_cached.metadata.size();
else
return tag_cached.metadata.size();
} }
int TagPropTableModel::columnCount(const QModelIndex &parent) const int TagPropTableModel::columnCount(const QModelIndex &parent) const
@ -43,16 +39,20 @@ QVariant TagPropTableModel::data(const QModelIndex &index, int role) const
if (role != Qt::DisplayRole && role != Qt::EditRole) if (role != Qt::DisplayRole && role != Qt::EditRole)
return QVariant(); return QVariant();
int row = index.row();
bool label = index.column() == 0; bool label = index.column() == 0;
if (showBaseData) {
switch (index.row()) { switch (row) {
case 0: return label ? QVariant("Database ID") : tag_cached.id; break; case 0: return label ? QVariant("Database ID") : tag_cached.id; break;
case 1: return label ? QVariant("Label") : tag_cached.name; break; case 1: return label ? QVariant("Label") : tag_cached.name; break;
case 2: return label ? QVariant("Anchor") : QString("%1, %2").arg(tag_cached.anchor.x()).arg(tag_cached.anchor.y()); break; case 2: return label ? QVariant("Anchor") : QString("%1, %2").arg(tag_cached.anchor.x()).arg(tag_cached.anchor.y()); break;
}
row -= 3;
} }
int idx = index.row() - 3; return label ? tag_keys[row] : tag_cached.metadata[tag_keys[row]];
return label ? tag_keys[idx] : tag_cached.metadata[tag_keys[idx]];
} }
QVariant TagPropTableModel::headerData(int section, Qt::Orientation orientation, int role) const QVariant TagPropTableModel::headerData(int section, Qt::Orientation orientation, int role) const
@ -75,17 +75,19 @@ Qt::ItemFlags TagPropTableModel::flags(const QModelIndex &index) const
return Qt::NoItemFlags; return Qt::NoItemFlags;
if (index.column() == 0) { if (index.column() == 0) {
if (index.row() < 3) if (showBaseData && index.row() < 3)
return Qt::ItemIsEnabled; return Qt::ItemIsEnabled;
return Qt::ItemIsEnabled | Qt::ItemIsEditable; return Qt::ItemIsEnabled | Qt::ItemIsEditable;
} }
if (index.row() == 1) if (showBaseData) {
return Qt::ItemIsEnabled | Qt::ItemIsEditable; if (index.row() == 1)
return Qt::ItemIsEnabled | Qt::ItemIsEditable;
if (index.row() == 2) /* anchor */ if (index.row() == 2) /* anchor */
return Qt::ItemIsEnabled; return Qt::ItemIsEnabled;
}
return Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled; return Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled;
} }
@ -98,22 +100,32 @@ bool TagPropTableModel::setData(const QModelIndex &index, const QVariant &value,
if (role != Qt::EditRole) if (role != Qt::EditRole)
return false; return false;
if (index.row() == 1) { int row = index.row();
tag_cached.name = value.toString(); if (showBaseData) {
} else if (index.row() < 3) { if (row == 1) {
return false; tag_cached.name = value.toString();
} else {
int idx = index.row() - 3; if (backend)
if (index.column() == 0) { /* key changed */ backend->updateTag(tag_cached);
/* move value to new key and delete old key */ return true;
tag_cached.metadata[value.toString()] = tag_cached.metadata[tag_keys[idx]];
tag_cached.metadata.remove(tag_keys[idx]); } else if (row < 3) {
return false;
} else { } else {
tag_cached.metadata[tag_keys[idx]] = value.toString(); row -= 3;
} }
} }
backend.updateTag(tag_cached); if (index.column() == 0) { /* key changed */
/* move value to new key and delete old key */
tag_cached.metadata[value.toString()] = tag_cached.metadata[tag_keys[row]];
tag_cached.metadata.remove(tag_keys[row]);
} else {
tag_cached.metadata[tag_keys[row]] = value.toString();
}
if (backend)
backend->updateTag(tag_cached);
return true; return true;
} }
@ -130,9 +142,7 @@ void TagPropTableModel::tagChange(TagChange change, const Tag &tag)
} else if (change == TagChange::DELETED) { } else if (change == TagChange::DELETED) {
dbg << "deleted"; dbg << "deleted";
beginResetModel(); showTag(Tag());
tagIsValid = false;
endResetModel();
} }
} }
@ -143,6 +153,5 @@ void TagPropTableModel::showTag(const Tag &tag)
tag_cached = tag; tag_cached = tag;
tag_keys = tag_cached.metadata.keys(); tag_keys = tag_cached.metadata.keys();
tag_keys.sort(); tag_keys.sort();
tagIsValid = true;
endResetModel(); endResetModel();
} }

View file

@ -12,8 +12,7 @@ class TagPropTableModel : public QAbstractTableModel
Q_OBJECT Q_OBJECT
public: public:
TagPropTableModel(SQLiteSaveFile &backend) : TagPropTableModel(backend, false) {}; TagPropTableModel(SQLiteSaveFile *backend, bool showBaseData=true);
TagPropTableModel(SQLiteSaveFile &backend, const Tag tag);
int rowCount(const QModelIndex &parent=QModelIndex()) const override; int rowCount(const QModelIndex &parent=QModelIndex()) const override;
int columnCount(const QModelIndex &parent=QModelIndex()) const override; int columnCount(const QModelIndex &parent=QModelIndex()) const override;
@ -25,16 +24,17 @@ public:
void showTag(const Tag &tag); void showTag(const Tag &tag);
QVariantMap metadata() { return tag_cached.metadata; }
private slots: private slots:
void tagChange(TagChange change, const Tag &tag); void tagChange(TagChange change, const Tag &tag);
private: private:
TagPropTableModel(SQLiteSaveFile &backend, bool tagIsValid);
SQLiteSaveFile &backend; SQLiteSaveFile *backend = nullptr;
Tag tag_cached; Tag tag_cached;
QStringList tag_keys; QStringList tag_keys;
bool tagIsValid; bool showBaseData;
}; };
#endif // TAGPROPTABLEMODEL_H #endif // TAGPROPTABLEMODEL_H

View file

@ -81,6 +81,15 @@ void TagScene::reloadScene()
reloadPicture(); /* calls invalidate() for us */ reloadPicture(); /* calls invalidate() for us */
} }
void TagScene::selectTag(const Tag &tag)
{
clearSelection();
TagItem *it = tags[tag.id];
if (!it)
return;
it->setSelected(true);
}
void TagScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) void TagScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{ {
QGraphicsItem *it = itemAt(event->scenePos(), QTransform()); QGraphicsItem *it = itemAt(event->scenePos(), QTransform());

View file

@ -15,11 +15,13 @@ class TagScene : public QGraphicsScene
public: public:
TagScene() {} TagScene() {}
~TagScene() { this->blockSignals(true); }
const QGraphicsPixmapItem *backgroundPixmapItem() const { return pix_it; } const QGraphicsPixmapItem *backgroundPixmapItem() const { return pix_it; }
public slots: public slots:
void reloadPicture(); void reloadPicture();
void reloadScene(); void reloadScene();
void selectTag(const Tag &tag);
void setProject(SQLiteSaveFile *proj); void setProject(SQLiteSaveFile *proj);

View file

@ -16,6 +16,8 @@ public:
TagView(QWidget *parent=nullptr); TagView(QWidget *parent=nullptr);
virtual ~TagView(); virtual ~TagView();
TagScene *scene() { return &m_scene; }
public slots: public slots:
void zoomToFit(); void zoomToFit();
void setZoom(qreal zoom); void setZoom(qreal zoom);