diff options
author | Arno <am@disconnect.de> | 2012-03-24 08:40:23 +0100 |
---|---|---|
committer | Arno <am@disconnect.de> | 2012-03-24 08:40:23 +0100 |
commit | f30d07e5acb83dd74bc6e6dc75b8b1c9e39e6e01 (patch) | |
tree | a5a7f348cea349330d230d96d59e79ec8adf7ead | |
parent | e788be03472f1617a05274dac6d7f8939ca85f46 (diff) | |
download | SheMov-f30d07e5acb83dd74bc6e6dc75b8b1c9e39e6e01.tar.gz SheMov-f30d07e5acb83dd74bc6e6dc75b8b1c9e39e6e01.tar.bz2 SheMov-f30d07e5acb83dd74bc6e6dc75b8b1c9e39e6e01.zip |
Show mappings in PictureViewer2
Hell, this was one heck of a bitch. Lots of changes just to show the
mapping tree in PictureViewer2. Did I mention that I hate recursion?
Added a function for fetching a SmTreeItem * from MappingTreeModel for
paths, just to turn it into a QTextDocument in PictureViewer2. Of course
everything is recursive. Did I say that I hate recursion?
Well, as said in the comments, one recursion function seems fishy, but
it works (tm).
-rw-r--r-- | mappingtreemodel.cpp | 45 | ||||
-rw-r--r-- | mappingtreemodel.h | 6 | ||||
-rw-r--r-- | pictureviewer2.cpp | 110 | ||||
-rw-r--r-- | pictureviewer2.h | 20 | ||||
-rw-r--r-- | smtreeitem.cpp | 2 | ||||
-rw-r--r-- | smtreeitem.h | 2 |
6 files changed, 171 insertions, 14 deletions
diff --git a/mappingtreemodel.cpp b/mappingtreemodel.cpp index 42c1380..ce96ff4 100644 --- a/mappingtreemodel.cpp +++ b/mappingtreemodel.cpp @@ -7,6 +7,7 @@ #include <QSqlDatabase> #include <QSqlQuery> +#include <QHash> #include <algorithm> @@ -43,6 +44,8 @@ MappingTreeModel::MappingTreeModel(QStringList &headers, QObject *parent) : SmTr mUpdateParentQ->prepare("UPDATE mappings_parents SET iparent_id = :pid WHERE imapping_id = :id"); mDeleteMappingParentQ = new QSqlQuery(mDb); mDeleteMappingParentQ->prepare("DELETE FROM mappings_parents WHERE imapping_id = :id"); + mMappingsForFileIdQ = new QSqlQuery(mDb); + mMappingsForFileIdQ->prepare("SELECT DISTINCT(imapping_id) FROM pics_mappings WHERE ipics_id = :pid"); } MappingTreeModel::~MappingTreeModel(){ @@ -57,6 +60,7 @@ MappingTreeModel::~MappingTreeModel(){ delete mAddParentQ; delete mDeleteChildQ; delete mUpdateParentQ; + delete mMappingsForFileIdQ; mDb = QSqlDatabase(); } @@ -87,6 +91,36 @@ QString MappingTreeModel::mappingTypeNameFromId(int id) const{ return QString(); } +//caller has ownership of this item! +SmTreeItem *MappingTreeModel::treeFromPaths(const QStringList &paths){ + if(paths.isEmpty()){ + return 0; + } + QHash<QString, SmTreeItem*> partsHash; + SmTreeItem *root = new SmTreeItem(1); + partsHash.insert(QString(), root); + SmTreeItem *pItem = root; + + // create tree + for(int i = 0; i < paths.count(); ++i){ + //split the paths + QStringList parts = paths.at(i).split(forbidden()); + //process path items + for(int j = 0; j < parts.count(); ++j){ + if(partsHash.contains(parts.at(j))){ + pItem = partsHash.value(parts.at(j)); //we've already seen this item, set it as new parent + }else{ + //create a new item, save old root + SmTreeItem *oldRoot = pItem; + pItem = new SmTreeItem(QList<QVariant>() << parts.at(j), oldRoot); + oldRoot->appendChild(pItem); + partsHash.insert(parts.at(j), pItem); + } + } + } + return root; +} + QVariant MappingTreeModel::data(const QModelIndex &index, int role) const{ if(!index.isValid()){ return QVariant(); @@ -118,6 +152,17 @@ QList<QVariant> MappingTreeModel::childList(const QVariant &value, int column) c return QList<QVariant>() << value; } +QList<QVariant> MappingTreeModel::mappingsForFile(const QVariant &fileId) const{ + QList<QVariant> retval; + mMappingsForFileIdQ->addBindValue(fileId); + if(mMappingsForFileIdQ->exec()){ + while(mMappingsForFileIdQ->next()){ + retval << mMappingsForFileIdQ->value(0); + } + } + return retval; +} + QModelIndex MappingTreeModel::indexFromPath(const QString &path, int column) const{ QStringList items = path.split("/"); if(items.isEmpty() || column >= NumFields){ diff --git a/mappingtreemodel.h b/mappingtreemodel.h index c1b6248..396484a 100644 --- a/mappingtreemodel.h +++ b/mappingtreemodel.h @@ -32,9 +32,14 @@ class MappingTreeModel : public SmTreeModel { int mappingTypeIdFromName(const QVariant &name) const; QString mappingTypeNameFromId(int id) const; + //static convenience funcs + //the caller is responsible for deleting the result! + SmTreeItem *treeFromPaths(const QStringList &paths); + //data QVariant data(const QModelIndex &index, int role) const; QList<QVariant> childList(const QVariant &value, int column = 0) const; + QList<QVariant> mappingsForFile(const QVariant &fileId) const; QModelIndex indexFromPath(const QString &path, int column = 0) const; bool setData(const QModelIndex &index, const QVariant &value, int role); void move(const QModelIndex &source, const QModelIndex &dest); @@ -80,6 +85,7 @@ class MappingTreeModel : public SmTreeModel { QSqlQuery *mDeleteChildQ; QSqlQuery *mUpdateParentQ; QSqlQuery *mDeleteMappingParentQ; + QSqlQuery *mMappingsForFileIdQ; QList<mappingType> mMappingTypes; QList<MappingData> mValidMappings; QList<SmTreeItem*> mSelectedMappings; diff --git a/pictureviewer2.cpp b/pictureviewer2.cpp index a5f250b..8c6d831 100644 --- a/pictureviewer2.cpp +++ b/pictureviewer2.cpp @@ -18,11 +18,17 @@ #include <QStyleOptionGraphicsItem> #include <QDate> #include <QSettings> +#include <QTextDocument> +#include <QTextCursor> +#include <QTextList> #include "pictureviewer2.h" #include "pictureswidget.h" +#include "smglobals.h" +#include "mappingtreemodel.h" +#include "smtreeitem.h" -PictureViewer2::PictureViewer2(QWidget *parent) : QGraphicsView(parent), mCur(0), mCurPos(0), mDefaultFile(":/picgone.png"), mFnItem(0) { +PictureViewer2::PictureViewer2(QWidget *parent) : QGraphicsView(parent), mCur(0), mCurPos(0), mDefaultFile(":/picgone.png"), mFnItem(0), mMappingItem(0) { //behave like QDialog, but don't be one... setWindowFlags(QFlags<Qt::WindowType>(0x1|0x2|0x1000|0x2000|0x10000|0x8000000)); @@ -201,6 +207,7 @@ void PictureViewer2::showFile(const PicData &file){ setWindowTitle(constructWindowTitle()); //TODO: configure! constructInfoItem(file, pixmap.size()); + constructMappingItem(file); } void PictureViewer2::constructInfoItem(const PicData &data, QSize picSize){ @@ -209,11 +216,37 @@ void PictureViewer2::constructInfoItem(const PicData &data, QSize picSize){ mScene->removeItem(mFnItem); delete mFnItem; } - mFnItem = new PictureViewer2FileinfoItem(data, mFiles.size(), picSize); + mFnItem = new PictureViewer2Item(data, mFiles.size(), picSize); mFnItem->setPos(mInfoPos); mScene->addItem(mFnItem); } +void PictureViewer2::constructMappingItem(const PicData &file){ + MappingTreeModel *mappingModel = static_cast<MappingTreeModel*>(SmGlobals::instance()->model("MappingTree")); + QList<QVariant> mappings = mappingModel->mappingsForFile(file.at(PicFilesModel::Id)); + QStringList mappingPaths; + foreach(QVariant mId, mappings){ + mappingPaths << mappingModel->mappingDataFromId(mId.toInt()).path.join("/"); + } + SmTreeItem *mappingTree = mappingModel->treeFromPaths(mappingPaths); + if(mappingTree){ + if(mMappingItem){ + mMappingPos = mMappingItem->scenePos(); + mScene->removeItem(mMappingItem); + delete mMappingItem; + } + QTextDocument *mapString = treeToString(mappingTree); + mMappingItem = new PictureViewer2Item(mapString); + if(mFnItem){ + QPointF fnRect = mFnItem->scenePos(); + QPointF myPos = QPointF(fnRect.x(), fnRect.y() + mFnItem->boundingRect().height() + 10); + mMappingItem->setPos(myPos); + } + mScene->addItem(mMappingItem); + } + delete mappingTree; +} + void PictureViewer2::setGradient(const QPixmap &pic){ QPoint val1 = QPoint(qrand() % pic.width(), qrand() % pic.height()); QPoint val2 = QPoint(qrand() % pic.width(), qrand() % pic.height()); @@ -226,12 +259,54 @@ void PictureViewer2::setGradient(const QPixmap &pic){ setBackgroundBrush(QBrush(g)); } +QTextDocument *PictureViewer2::treeToString(const SmTreeItem *root) const{ + QTextDocument *retval = new QTextDocument; + retval->setIndentWidth(1); + retval->setDocumentMargin(8); + QTextCursor *cursor = new QTextCursor(retval); + QTextListFormat listFormat; + listFormat.setStyle(QTextListFormat::ListDisc); + listFormat.setIndent(10); + for(int i = 0 ; i < root->childCount(); ++i){ + cursor->createList(listFormat); + cursor->insertText(root->child(i)->data(0).toString()); + treeToStringRecursive(root->child(i), cursor); + } + return retval; +} + +void PictureViewer2::treeToStringRecursive(const SmTreeItem *parent, QTextCursor *cursor) const{ + //hell, this kinda does what it's supposed to, but it seems fishy... + //don't like the break and checking the parent... + for(int i = 0 ; i < parent->childCount(); ++i){ + QTextListFormat listFormat; + listFormat.setStyle(QTextListFormat::ListDisc); + listFormat.setIndent(cursor->currentList()->format().indent() + 5); + if(parent->child(i)->childCount()){ + cursor->insertList(listFormat); + cursor->insertText(parent->child(i)->data(0).toString()); + treeToStringRecursive(parent->child(i), cursor); + return; + }else{ + const SmTreeItem *p = parent; + cursor->insertList(listFormat); + for(int j = 0; j < p->childCount(); ++j){ + if(j != 0){ + cursor->insertBlock(); + } + cursor->insertText(p->child(j)->data(0).toString()); + } + break; + } + } +} + QString PictureViewer2::constructWindowTitle() const { QString retval = QString(tr("PicViewer 2 - [%1]")).arg(mFiles.at(mCurPos).at(PicFilesModel::FileName).toString()); return retval; } -PictureViewer2FileinfoItem::PictureViewer2FileinfoItem(const PicData &data, const int numSelected, const QSize &picSize, QGraphicsItem *parent) : QGraphicsItem(parent){ +PictureViewer2Item::PictureViewer2Item(const PicData &data, const int numSelected, const QSize &picSize, QGraphicsItem *parent) : QGraphicsItem(parent), mDoc(0){ QStringList textList; //prevent QStaticText from wrapping filesnames with spaces //we shouldn't allow this in the first place @@ -244,18 +319,32 @@ PictureViewer2FileinfoItem::PictureViewer2FileinfoItem(const PicData &data, cons textList << QString(QObject::tr("%1 files selected")).arg(QString::number(numSelected)); mText = QStaticText(textList.join("<br/>")); setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable); + setZValue(1); +} + +PictureViewer2Item::PictureViewer2Item(QTextDocument *doc, QGraphicsItem *parent) : QGraphicsItem(parent), mDoc(doc){ + setZValue(1); +} + +PictureViewer2Item::~PictureViewer2Item(){ + delete mDoc; } -QRectF PictureViewer2FileinfoItem::boundingRect() const { - QSizeF size = mText.size(); - size += QSize(10, 10); +QRectF PictureViewer2Item::boundingRect() const { + QSizeF size; + if(mDoc){ + size = mDoc->size(); + }else{ + size = mText.size(); + size += QSize(10, 10); + } QRectF retval; retval.setWidth(size.width()); retval.setHeight(size.height()); return retval; } -void PictureViewer2FileinfoItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){ +void PictureViewer2Item::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){ Q_UNUSED(option); Q_UNUSED(widget); painter->save(); @@ -269,6 +358,11 @@ void PictureViewer2FileinfoItem::paint(QPainter *painter, const QStyleOptionGrap painter->setBrush(brush); painter->drawRoundedRect(boundingRect(), 15.0, 15.0); painter->setPen(QPen(fgColor)); - painter->drawStaticText(5, 5, mText); + if(mDoc){ + mDoc->drawContents(painter); + }else{ + painter->drawStaticText(5, 5, mText); + } painter->restore(); } + diff --git a/pictureviewer2.h b/pictureviewer2.h index e18fc18..d31780e 100644 --- a/pictureviewer2.h +++ b/pictureviewer2.h @@ -19,7 +19,11 @@ class QGraphicsPixmapItem; class QWheelEvent; class QContextMenuEvent; class QTimer; -class PictureViewer2FileinfoItem; +class QTextDocument; +class QTextCursor; +class PictureViewer2Item; +class SmTreeItem; +class MappingTreeModel; typedef QList<QVariant> PicData; typedef QList<QList<QVariant> > PicDataList; @@ -51,10 +55,13 @@ class PictureViewer2 : public QGraphicsView { private slots: void showFile(const PicData &data); void constructInfoItem(const PicData &file, QSize picSize); + void constructMappingItem(const PicData &file); private: void setupDialog(); void setGradient(const QPixmap &pic); + QTextDocument *treeToString(const SmTreeItem *root) const; + void treeToStringRecursive(const SmTreeItem *parent, QTextCursor *cursor) const; QString constructWindowTitle() const; PicDataList mFiles; QGraphicsScene *mScene; @@ -63,22 +70,27 @@ class PictureViewer2 : public QGraphicsView { int mCurPos; QTimer *mSlideTimer; const QString mDefaultFile; - PictureViewer2FileinfoItem *mFnItem; + PictureViewer2Item *mFnItem; + PictureViewer2Item *mMappingItem; bool mUseGradient; QColor mBgColor; QPointF mInfoPos; + QPointF mMappingPos; QAction *mSlideA; QAction *mHideA; }; -class PictureViewer2FileinfoItem : public QGraphicsItem { +class PictureViewer2Item : public QGraphicsItem { public: - explicit PictureViewer2FileinfoItem(const PicData &data, const int numSelected, const QSize &picSize = QSize(), QGraphicsItem *parent = 0); + explicit PictureViewer2Item(const PicData &data, const int numSelected, const QSize &picSize = QSize(), QGraphicsItem *parent = 0); + explicit PictureViewer2Item(QTextDocument *doc, QGraphicsItem *parent = 0); + ~PictureViewer2Item(); QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); private: QStaticText mText; + QTextDocument *mDoc; }; #endif // PICTUREVIEWER2_H diff --git a/smtreeitem.cpp b/smtreeitem.cpp index 56d9b6e..ed9f73e 100644 --- a/smtreeitem.cpp +++ b/smtreeitem.cpp @@ -57,7 +57,7 @@ int SmTreeItem::row() const{ return 0; } -SmTreeItem *SmTreeItem::parent(){ +SmTreeItem *SmTreeItem::parent() const{ return mParent; } diff --git a/smtreeitem.h b/smtreeitem.h index 28ab77a..b0b9ca7 100644 --- a/smtreeitem.h +++ b/smtreeitem.h @@ -22,7 +22,7 @@ class SmTreeItem { int childCount() const; int columnCount() const; int row() const; - SmTreeItem *parent(); + SmTreeItem *parent() const; void setParent(SmTreeItem *parent); QVariant data(int column) const; void setData(int column, const QVariant &data); |