
* viewer/Makefile.am, * viewer/README, * viewer/browser_widget.cc, * viewer/browser_widget.hh, * viewer/common.hh, * viewer/domitem.cc, * viewer/domitem.hh, * viewer/dommodel.cc, * viewer/dommodel.hh, * viewer/help_dialog.cc, * viewer/help_dialog.hh, * viewer/image_region.cc, * viewer/image_region.hh, * viewer/image_region.hxx, * viewer/image_scene.cc, * viewer/image_scene.hh, * viewer/image_view.cc, * viewer/image_view.hh, * viewer/image_widget.cc, * viewer/image_widget.hh, * viewer/key_widget.cc, * viewer/key_widget.hh, * viewer/main.cc, * viewer/property_widget.cc, * viewer/property_widget.hh, * viewer/viewer.cc, * viewer/viewer.hh, * viewer/viewer.hxx, * viewer/xml_widget.cc, * viewer/xml_widget.hh: New. --- viewer/Makefile.am | 67 ++++++++++ viewer/README | 33 +++++ viewer/browser_widget.cc | 63 ++++++++++ viewer/browser_widget.hh | 41 ++++++ viewer/common.hh | 36 ++++++ viewer/domitem.cc | 98 +++++++++++++++ viewer/domitem.hh | 75 +++++++++++ viewer/dommodel.cc | 198 +++++++++++++++++++++++++++++ viewer/dommodel.hh | 85 +++++++++++++ viewer/help_dialog.cc | 53 ++++++++ viewer/help_dialog.hh | 32 +++++ viewer/image_region.cc | 87 +++++++++++++ viewer/image_region.hh | 74 +++++++++++ viewer/image_region.hxx | 114 +++++++++++++++++ viewer/image_scene.cc | 62 +++++++++ viewer/image_scene.hh | 42 +++++++ viewer/image_view.cc | 48 +++++++ viewer/image_view.hh | 32 +++++ viewer/image_widget.cc | 44 +++++++ viewer/image_widget.hh | 38 ++++++ viewer/key_widget.cc | 65 ++++++++++ viewer/key_widget.hh | 44 +++++++ viewer/main.cc | 26 ++++ viewer/property_widget.cc | 73 +++++++++++ viewer/property_widget.hh | 41 ++++++ viewer/viewer.cc | 300 +++++++++++++++++++++++++++++++++++++++++++++ viewer/viewer.hh | 79 ++++++++++++ viewer/viewer.hxx | 31 +++++ viewer/xml_widget.cc | 53 ++++++++ viewer/xml_widget.hh | 41 ++++++ 30 files changed, 2075 insertions(+), 0 deletions(-) create mode 100644 viewer/Makefile.am create mode 100644 viewer/README create mode 100644 viewer/browser_widget.cc create mode 100644 viewer/browser_widget.hh create mode 100644 viewer/common.hh create mode 100644 viewer/domitem.cc create mode 100644 viewer/domitem.hh create mode 100644 viewer/dommodel.cc create mode 100644 viewer/dommodel.hh create mode 100644 viewer/help_dialog.cc create mode 100644 viewer/help_dialog.hh create mode 100644 viewer/image_region.cc create mode 100644 viewer/image_region.hh create mode 100644 viewer/image_region.hxx create mode 100644 viewer/image_scene.cc create mode 100644 viewer/image_scene.hh create mode 100644 viewer/image_view.cc create mode 100644 viewer/image_view.hh create mode 100644 viewer/image_widget.cc create mode 100644 viewer/image_widget.hh create mode 100644 viewer/key_widget.cc create mode 100644 viewer/key_widget.hh create mode 100644 viewer/main.cc create mode 100644 viewer/property_widget.cc create mode 100644 viewer/property_widget.hh create mode 100644 viewer/viewer.cc create mode 100644 viewer/viewer.hh create mode 100644 viewer/viewer.hxx create mode 100644 viewer/xml_widget.cc create mode 100644 viewer/xml_widget.hh diff --git a/viewer/Makefile.am b/viewer/Makefile.am new file mode 100644 index 0000000..0a6213a --- /dev/null +++ b/viewer/Makefile.am @@ -0,0 +1,67 @@ +## +## Document layout viewer. +## +## Copyright (C) 2009 Florent D'Halluin. +## +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License +## as published by the Free Software Foundation; either version 2 +## of the License, or (at your option) any later version. +## +## The complete GNU General Public Licence Notice can be found as the +## `COPYING' file in the root directory. +## + +include $(top_srcdir)/build-aux/autotroll.mk + +bin_PROGRAMS = viewer +viewer_SOURCES = $(BUILT_SOURCES) \ + viewer.cc \ + main.cc \ + image_widget.cc \ + xml_widget.cc \ + key_widget.cc \ + property_widget.cc \ + browser_widget.cc \ + image_scene.cc \ + image_view.cc \ + dommodel.cc \ + domitem.cc \ + image_region.cc \ + help_dialog.cc + +viewer_CPPFLAGS = $(QT_CPPFLAGS) $(AM_CPPFLAGS) -I$(srcdir) +viewer_CXXFLAGS = $(QT_CXXFLAGS) $(AM_CXXFLAGS) -O3 +viewer_LDFLAGS = $(QT_LDFLAGS) $(LDFLAGS) +viewer_LDADD = $(QT_LIBS) $(LDADD) + +BUILT_SOURCES = viewer.moc.cc \ + image_widget.moc.cc \ + xml_widget.moc.cc \ + key_widget.moc.cc \ + property_widget.moc.cc \ + browser_widget.moc.cc \ + image_scene.moc.cc \ + image_view.moc.cc \ + dommodel.moc.cc \ + domitem.moc.cc \ + image_region.moc.cc \ + help_dialog.moc.cc + +include_HEADERS = viewer.hh \ + viewer.hxx \ + image_widget.hh \ + xml_widget.hh \ + key_widget.hh \ + property_widget.hh \ + browser_widget.hh \ + image_scene.hh \ + image_view.hh \ + dommodel.hh \ + domitem.hh \ + image_region.hh \ + image_region.hxx \ + common.hh \ + help_dialog.hh + +EXTRA_DIST = README diff --git a/viewer/README b/viewer/README new file mode 100644 index 0000000..6032a41 --- /dev/null +++ b/viewer/README @@ -0,0 +1,33 @@ + +Document layout viewer. + +Copyright (C) 2009 Florent D'Halluin. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +The complete GNU General Public Licence Notice can be found as the +`COPYING' file in the root directory. + +__________________________________________________________________ + + +Document Layout Viewer + +Purpose: +- Display layout information about image documents. + +Contact: +d-halluin@lrde.epita.fr + +Usage: +- Get XML layout descriptions (PAGE format, ICDAR2009). +- Put XML and image files in the same directory, with the same name. +- Select an image within the application. +- Click on regions to display their attributes. + +Infos: +- Everything is read-only. +- The DOM Model classes are a slightly modified Qt example. diff --git a/viewer/browser_widget.cc b/viewer/browser_widget.cc new file mode 100644 index 0000000..643cf2f --- /dev/null +++ b/viewer/browser_widget.cc @@ -0,0 +1,63 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#include "browser_widget.hh" + +BrowserWidget::BrowserWidget(QDirModel* files) + : files_(files), + view_(new QListView()), + path_(new QLabel("")) +{ + QLabel* title = new QLabel(tr("Images")); + title->setAlignment(Qt::AlignHCenter); + + QVBoxLayout* layout = new QVBoxLayout; + layout->addWidget(title); + layout->addWidget(path_); + layout->addWidget(view_); + + setLayout(layout); + + view_->setModel(files); + files->setFilter(QDir::AllDirs | QDir::Files + | QDir::Readable | QDir::Drives); + + view_->setRootIndex(files->index(QDir::currentPath())); + view_->setRowHidden(0, true); + path_->setText(files->filePath(view_->rootIndex())); + connect(view_, SIGNAL(activated(const QModelIndex&)), + this, SLOT(activate(const QModelIndex&))); + + QStringList files_filters; + files_filters << "*.png" << "*.jpg" + << "*.tif" << "*.ppm" << "*.pgm"; + files->setNameFilters(files_filters); +} + +void +BrowserWidget::activate(const QModelIndex& index) +{ + if (files_->isDir(index)) + { + view_->setRootIndex(index); + view_->setRowHidden(0, true); + path_->setText(files_->filePath(view_->rootIndex())); + return; + } + emit activated(files_->filePath(index)); +} + +BrowserWidget::~BrowserWidget() +{ +} diff --git a/viewer/browser_widget.hh b/viewer/browser_widget.hh new file mode 100644 index 0000000..954115f --- /dev/null +++ b/viewer/browser_widget.hh @@ -0,0 +1,41 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef BROWSER_WIDGET_HH_ +# define BROWSER_WIDGET_HH_ + +# include <QtGui> + +class BrowserWidget + : public QWidget +{ + Q_OBJECT + +public: + BrowserWidget(QDirModel* files); + ~BrowserWidget(); + +public slots: + void activate(const QModelIndex& index); + +signals: + void activated(QString filename); + +private: + QDirModel* files_; + QListView* view_; + QLabel* path_; +}; + +#endif /* !BROWSER_WIDGET_HH_ */ diff --git a/viewer/common.hh b/viewer/common.hh new file mode 100644 index 0000000..ba4f3b1 --- /dev/null +++ b/viewer/common.hh @@ -0,0 +1,36 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef COMMON_HH_ +# define COMMON_HH_ + +namespace region +{ + typedef QVector<QPair<QString, QColor> > KeyMap; + + enum RegionId + { + Text = 0, + Image, + Noise, + Separator, + Table, + LineDrawing, + Graphic, + Chart, + Maths + }; +}; + +#endif /* !COMMON_HH_ */ diff --git a/viewer/domitem.cc b/viewer/domitem.cc new file mode 100644 index 0000000..66e989a --- /dev/null +++ b/viewer/domitem.cc @@ -0,0 +1,98 @@ +/**************************************************************************** + ** + ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). + ** Contact: Qt Software Information (qt-info@nokia.com) + ** + ** This file is part of the example classes of the Qt Toolkit. + ** + ** Commercial Usage + ** Licensees holding valid Qt Commercial licenses may use this file in + ** accordance with the Qt Commercial License Agreement provided with the + ** Software or, alternatively, in accordance with the terms contained in + ** a written agreement between you and Nokia. + ** + ** + ** GNU General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU + ** General Public License versions 2.0 or 3.0 as published by the Free + ** Software Foundation and appearing in the file LICENSE.GPL included in + ** the packaging of this file. Please review the following information + ** to ensure GNU General Public Licensing requirements will be met: + ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and + ** http://www.gnu.org/copyleft/gpl.html. In addition, as a special + ** exception, Nokia gives you certain additional rights. These rights + ** are described in the Nokia Qt GPL Exception version 1.3, included in + ** the file GPL_EXCEPTION.txt in this package. + ** + ** Qt for Windows(R) Licensees + ** As a special exception, Nokia, as the sole copyright holder for Qt + ** Designer, grants users of the Qt/Eclipse Integration plug-in the + ** right for the Qt/Eclipse Integration to link to functionality + ** provided by Qt Designer and its related libraries. + ** + ** If you are unsure which license is appropriate for your use, please + ** contact the sales department at qt-sales@nokia.com. + ** + ****************************************************************************/ + +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#include <QtXml> + +#include "domitem.hh" + +DomItem::DomItem(QDomNode &node, int row, DomItem *parent) +{ + domNode = node; + // Record the item's location within its parent. + rowNumber = row; + parentItem = parent; +} + +DomItem::~DomItem() +{ + QHash<int,DomItem*>::iterator it; + for (it = childItems.begin(); it != childItems.end(); ++it) + delete it.value(); +} + +QDomNode DomItem::node() const +{ + return domNode; +} + +DomItem *DomItem::parent() +{ + return parentItem; +} + +DomItem *DomItem::child(int i) +{ + if (childItems.contains(i)) + return childItems[i]; + + if (i >= 0 && i < domNode.childNodes().count()) { + QDomNode childNode = domNode.childNodes().item(i); + DomItem *childItem = new DomItem(childNode, i, this); + childItems[i] = childItem; + return childItem; + } + return 0; +} + +int DomItem::row() +{ + return rowNumber; +} diff --git a/viewer/domitem.hh b/viewer/domitem.hh new file mode 100644 index 0000000..a5c22cc --- /dev/null +++ b/viewer/domitem.hh @@ -0,0 +1,75 @@ + /**************************************************************************** + ** + ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). + ** Contact: Qt Software Information (qt-info@nokia.com) + ** + ** This file is part of the example classes of the Qt Toolkit. + ** + ** Commercial Usage + ** Licensees holding valid Qt Commercial licenses may use this file in + ** accordance with the Qt Commercial License Agreement provided with the + ** Software or, alternatively, in accordance with the terms contained in + ** a written agreement between you and Nokia. + ** + ** + ** GNU General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU + ** General Public License versions 2.0 or 3.0 as published by the Free + ** Software Foundation and appearing in the file LICENSE.GPL included in + ** the packaging of this file. Please review the following information + ** to ensure GNU General Public Licensing requirements will be met: + ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and + ** http://www.gnu.org/copyleft/gpl.html. In addition, as a special + ** exception, Nokia gives you certain additional rights. These rights + ** are described in the Nokia Qt GPL Exception version 1.3, included in + ** the file GPL_EXCEPTION.txt in this package. + ** + ** Qt for Windows(R) Licensees + ** As a special exception, Nokia, as the sole copyright holder for Qt + ** Designer, grants users of the Qt/Eclipse Integration plug-in the + ** right for the Qt/Eclipse Integration to link to functionality + ** provided by Qt Designer and its related libraries. + ** + ** If you are unsure which license is appropriate for your use, please + ** contact the sales department at qt-sales@nokia.com. + ** + ****************************************************************************/ + +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef DOMITEM_H +#define DOMITEM_H + +#include <QDomNode> +#include <QHash> + +class DomItem +{ +public: + DomItem(QDomNode &node, int row, DomItem *parent = 0); + ~DomItem(); + DomItem *child(int i); + DomItem *parent(); + QDomNode node() const; + int row(); + +private: + QDomNode domNode; + QHash<int,DomItem*> childItems; + DomItem *parentItem; + int rowNumber; +}; + +#endif diff --git a/viewer/dommodel.cc b/viewer/dommodel.cc new file mode 100644 index 0000000..baaf9a7 --- /dev/null +++ b/viewer/dommodel.cc @@ -0,0 +1,198 @@ +/**************************************************************************** + ** + ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). + ** Contact: Qt Software Information (qt-info@nokia.com) + ** + ** This file is part of the example classes of the Qt Toolkit. + ** + ** Commercial Usage + ** Licensees holding valid Qt Commercial licenses may use this file in + ** accordance with the Qt Commercial License Agreement provided with the + ** Software or, alternatively, in accordance with the terms contained in + ** a written agreement between you and Nokia. + ** + ** + ** GNU General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU + ** General Public License versions 2.0 or 3.0 as published by the Free + ** Software Foundation and appearing in the file LICENSE.GPL included in + ** the packaging of this file. Please review the following information + ** to ensure GNU General Public Licensing requirements will be met: + ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and + ** http://www.gnu.org/copyleft/gpl.html. In addition, as a special + ** exception, Nokia gives you certain additional rights. These rights + ** are described in the Nokia Qt GPL Exception version 1.3, included in + ** the file GPL_EXCEPTION.txt in this package. + ** + ** Qt for Windows(R) Licensees + ** As a special exception, Nokia, as the sole copyright holder for Qt + ** Designer, grants users of the Qt/Eclipse Integration plug-in the + ** right for the Qt/Eclipse Integration to link to functionality + ** provided by Qt Designer and its related libraries. + ** + ** If you are unsure which license is appropriate for your use, please + ** contact the sales department at qt-sales@nokia.com. + ** + ****************************************************************************/ + +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#include <QtGui> +#include <QtXml> + +#include "domitem.hh" +#include "dommodel.hh" + +DomModel::DomModel(QDomDocument document, QObject *parent) + : QAbstractItemModel(parent), domDocument(document) +{ + rootItem = new DomItem(domDocument, 0); +} + +DomModel::~DomModel() +{ + delete rootItem; +} + +int DomModel::columnCount(const QModelIndex &/*parent*/) const +{ + return 3; +} + +QVariant DomModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + DomItem *item = static_cast<DomItem*>(index.internalPointer()); + QDomNode node = item->node(); + QDomNamedNodeMap attributeMap = node.attributes(); + + if (role == Qt::DisplayRole) + { + QStringList attributes; + + switch (index.column()) + { + case 0: + return node.nodeName(); + case 1: + for (int i = 0; i < attributeMap.count(); ++i) + { + QDomNode attribute = attributeMap.item(i); + attributes << attribute.nodeName() + "=\"" + + attribute.nodeValue() + "\""; + } + return attributes.join(" "); + case 2: + return node.nodeValue().split("\n").join(" "); + default: + return QVariant(); + } + } + else if (role == Qt::UserRole) + { + QMap<QString, QVariant> attributes; + switch (index.column()) + { + case 1: + for (int i = 0; i < attributeMap.count(); ++i) + { + QDomNode attribute = attributeMap.item(i); + attributes[attribute.nodeName()] = attribute.nodeValue(); + } + return attributes; + default: + return QVariant(); + } + } + return QVariant(); +} + +Qt::ItemFlags DomModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return 0; + + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +QVariant DomModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { + switch (section) { + case 0: + return tr("Name"); + case 1: + return tr("Attributes"); + case 2: + return tr("Value"); + default: + return QVariant(); + } + } + + return QVariant(); +} + +QModelIndex DomModel::index(int row, int column, const QModelIndex &parent) + const +{ + if (!hasIndex(row, column, parent)) + return QModelIndex(); + + DomItem *parentItem; + + if (!parent.isValid()) + parentItem = rootItem; + else + parentItem = static_cast<DomItem*>(parent.internalPointer()); + + DomItem *childItem = parentItem->child(row); + if (childItem) + return createIndex(row, column, childItem); + else + return QModelIndex(); +} + +QModelIndex DomModel::parent(const QModelIndex &child) const +{ + if (!child.isValid()) + return QModelIndex(); + + DomItem *childItem = static_cast<DomItem*>(child.internalPointer()); + DomItem *parentItem = childItem->parent(); + + if (!parentItem || parentItem == rootItem) + return QModelIndex(); + + return createIndex(parentItem->row(), 0, parentItem); +} + +int DomModel::rowCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) + return 0; + + DomItem *parentItem; + + if (!parent.isValid()) + parentItem = rootItem; + else + parentItem = static_cast<DomItem*>(parent.internalPointer()); + + return parentItem->node().childNodes().count(); +} diff --git a/viewer/dommodel.hh b/viewer/dommodel.hh new file mode 100644 index 0000000..16c5a23 --- /dev/null +++ b/viewer/dommodel.hh @@ -0,0 +1,85 @@ +/**************************************************************************** + ** + ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). + ** Contact: Qt Software Information (qt-info@nokia.com) + ** + ** This file is part of the example classes of the Qt Toolkit. + ** + ** Commercial Usage + ** Licensees holding valid Qt Commercial licenses may use this file in + ** accordance with the Qt Commercial License Agreement provided with the + ** Software or, alternatively, in accordance with the terms contained in + ** a written agreement between you and Nokia. + ** + ** + ** GNU General Public License Usage + ** Alternatively, this file may be used under the terms of the GNU + ** General Public License versions 2.0 or 3.0 as published by the Free + ** Software Foundation and appearing in the file LICENSE.GPL included in + ** the packaging of this file. Please review the following information + ** to ensure GNU General Public Licensing requirements will be met: + ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and + ** http://www.gnu.org/copyleft/gpl.html. In addition, as a special + ** exception, Nokia gives you certain additional rights. These rights + ** are described in the Nokia Qt GPL Exception version 1.3, included in + ** the file GPL_EXCEPTION.txt in this package. + ** + ** Qt for Windows(R) Licensees + ** As a special exception, Nokia, as the sole copyright holder for Qt + ** Designer, grants users of the Qt/Eclipse Integration plug-in the + ** right for the Qt/Eclipse Integration to link to functionality + ** provided by Qt Designer and its related libraries. + ** + ** If you are unsure which license is appropriate for your use, please + ** contact the sales department at qt-sales@nokia.com. + ** + ****************************************************************************/ + +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef DOMMODEL_H +#define DOMMODEL_H + +#include <QAbstractItemModel> +#include <QDomDocument> +#include <QModelIndex> +#include <QVariant> + +class DomItem; + +class DomModel : public QAbstractItemModel +{ + Q_OBJECT + + public: + DomModel(QDomDocument document, QObject *parent = 0); + ~DomModel(); + + QVariant data(const QModelIndex &index, int role) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &child) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + +private: + QDomDocument domDocument; + DomItem *rootItem; +}; + +#endif diff --git a/viewer/help_dialog.cc b/viewer/help_dialog.cc new file mode 100644 index 0000000..ebdfdaa --- /dev/null +++ b/viewer/help_dialog.cc @@ -0,0 +1,53 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#include "help_dialog.hh" + +HelpDialog::HelpDialog() +{ + QPushButton *closeButton = new QPushButton(tr("Close")); + connect(closeButton, SIGNAL(clicked()), this, SLOT(close())); + + QHBoxLayout *buttonsLayout = new QHBoxLayout; + buttonsLayout->addStretch(1); + buttonsLayout->addWidget(closeButton); + + QVBoxLayout *mainLayout = new QVBoxLayout; + + QString help = tr( + "Document layout viewer:\n" + "\n" + "Usage:\n" + " - Choose an image file in the file browser\n" + " - If the document layout is present\n" + " (XML file with the same name),\n" + " select regions to display their properties.\n" + "\n" + "Contact: d-halluin@lrde.epita.fr\n" + "\n" + "Copyright Florent D'Halluin, 2009.\n"); + + QLabel* label = new QLabel(help); + + mainLayout->addWidget(label); + mainLayout->addLayout(buttonsLayout); + + setLayout(mainLayout); + setWindowTitle(tr("About")); +} + +void HelpDialog::done() +{ + emit close(); +} diff --git a/viewer/help_dialog.hh b/viewer/help_dialog.hh new file mode 100644 index 0000000..114d8f5 --- /dev/null +++ b/viewer/help_dialog.hh @@ -0,0 +1,32 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef HELP_DIALOG_HH_ +# define HELP_DIALOG_HH_ + +# include <QtGui> + +class HelpDialog + : public QDialog +{ + Q_OBJECT + +public: + HelpDialog(); + +public slots: + void done(); +}; + +#endif /* !HELP_DIALOG_HH_ */ diff --git a/viewer/image_region.cc b/viewer/image_region.cc new file mode 100644 index 0000000..bef30fc --- /dev/null +++ b/viewer/image_region.cc @@ -0,0 +1,87 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#include "image_region.hh" + +ImageRegion::ImageRegion(region::RegionId id, + QString name, + QColor color, + QModelIndex index, + const QVector<QPoint>& points, + bool outline, + bool fill, + bool precise, + bool draw) + : QGraphicsItem(0), + id_(id), + name_(name), + color_(color), + index_(index), + shape_(), + rect_(), + outline_(outline), + precise_(precise), + fill_(fill), + draw_(draw), + selected_(false), + alpha_(30) +{ + setCursor(Qt::ArrowCursor); + setZValue(1); + + if (points.size() == 0) + return; + + for (int i = 1; i < points.size(); ++i) + shape_.lineTo(points[i] - points[0]); + shape_.lineTo(QPoint(0, 0)); + + rect_ = shape_.boundingRect(); + setPos(points[0]); + + prepareGeometryChange(); +} + +ImageRegion::~ImageRegion() +{ +} + +void +ImageRegion::paint(QPainter* painter, + const QStyleOptionGraphicsItem*, + QWidget*) +{ + if (!draw_ && !selected_) + return; + + int width = 0; + if (precise_) + width = 1; + + if (outline_) + painter->setPen(QPen(QBrush(color_), width)); + else + painter->setPen(QColor(0, 0, 0, 0)); + if (selected_) + painter->setPen(QPen(QBrush(QColor("red")), width)); + + QColor brush = color_; + if (fill_) + brush.setAlpha(alpha_); + else + brush.setAlpha(0); + painter->setBrush(brush); + + painter->drawPath(shape_); +} diff --git a/viewer/image_region.hh b/viewer/image_region.hh new file mode 100644 index 0000000..7f65c02 --- /dev/null +++ b/viewer/image_region.hh @@ -0,0 +1,74 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef IMAGE_REGION_HH_ +# define IMAGE_REGION_HH_ + +# include <QtGui> +# include "common.hh" + +class ImageRegion + : public QObject, public QGraphicsItem +{ + Q_OBJECT + +public: + ImageRegion(region::RegionId id, + QString name, + QColor color, + QModelIndex index, + const QVector<QPoint>& points, + bool outline, + bool fill, + bool precise, + bool draw); + + ~ImageRegion(); + + void paint(QPainter* painter, + const QStyleOptionGraphicsItem* option, + QWidget* widget = 0); + + const QModelIndex& index() const; + QRectF boundingRect() const; + QPainterPath shape() const; + +public slots: + void setOutline(bool outline); + void setFill(bool fill); + void setFillAlpha(int alpha); + void setDraw(bool draw); + void setPrecise(bool precise); + void setDrawIfSameId(int id, bool draw); + void select(); + void deselect(); + +private: + region::RegionId id_; + QString name_; + QColor color_; + QModelIndex index_; + QPainterPath shape_; + QRectF rect_; + bool outline_; + bool precise_; + bool fill_; + bool draw_; + bool selected_; + int alpha_; +}; + +#include "image_region.hxx" + +#endif /* !IMAGE_REGION_HH_ */ diff --git a/viewer/image_region.hxx b/viewer/image_region.hxx new file mode 100644 index 0000000..35634f7 --- /dev/null +++ b/viewer/image_region.hxx @@ -0,0 +1,114 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef IMAGE_REGION_HXX_ +# define IMAGE_REGION_HXX_ + +# include "image_region.hh" + +inline +void +ImageRegion::setOutline(bool outline) +{ + outline_ = outline; + update(); +} + +inline +void +ImageRegion::setPrecise(bool precise) +{ + precise_ = precise; + update(); +} + +inline +void +ImageRegion::setFill(bool fill) +{ + fill_ = fill; + update(); +} + +inline +void +ImageRegion::setDraw(bool draw) +{ + draw_ = draw; + update(); +} + +inline +void +ImageRegion::setDrawIfSameId(int id, bool draw) +{ + if (id == id_) + draw_ = draw; + update(); +} + +inline +void +ImageRegion::setFillAlpha(int alpha) +{ + alpha_ = alpha; + update(); +} + +inline +QRectF +ImageRegion::boundingRect() const +{ + return rect_; +} + +inline +QPainterPath +ImageRegion::shape() const +{ + return shape_; +} + +inline +const QModelIndex& +ImageRegion::index() const +{ + return index_; +} + +inline +void +ImageRegion::select() +{ + if (!selected_) + { + selected_ = true; + setZValue(2); + update(); + } +} + +inline +void +ImageRegion::deselect() +{ + if (selected_) + { + selected_ = false; + setZValue(1); + update(); + } +} + +#endif /* !IMAGE_REGION_HXX_ */ diff --git a/viewer/image_scene.cc b/viewer/image_scene.cc new file mode 100644 index 0000000..14eac76 --- /dev/null +++ b/viewer/image_scene.cc @@ -0,0 +1,62 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#include "image_scene.hh" +#include "image_region.hh" + +ImageScene::ImageScene() + : selected_(0) +{ +} + +void +ImageScene::clear() +{ + selected_ = 0; + QGraphicsScene::clear(); +} + +void +ImageScene::mousePressEvent(QGraphicsSceneMouseEvent* event) +{ + QGraphicsScene::mousePressEvent(event); + ImageRegion* item = dynamic_cast<ImageRegion*>(itemAt(event->pos())); + if (item) + { + if (item != selected_) + { + if (selected_) + { + selected_->deselect(); + emit deselected(selected_->index()); + } + selected_ = item; + item->select(); + emit selected(item->index()); + } + } + else + { + if (selected_) + { + selected_->deselect(); + emit deselected(selected_->index()); + selected_ = 0; + } + } +} + +ImageScene::~ImageScene() +{ +} diff --git a/viewer/image_scene.hh b/viewer/image_scene.hh new file mode 100644 index 0000000..eb95462 --- /dev/null +++ b/viewer/image_scene.hh @@ -0,0 +1,42 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef IMAGE_SCENE_HH_ +# define IMAGE_SCENE_HH_ + +# include <QtGui> + +class ImageRegion; + +class ImageScene + : public QGraphicsScene +{ + Q_OBJECT + +public: + ImageScene(); + ~ImageScene(); + + void mousePressEvent(QGraphicsSceneMouseEvent* event); + void clear(); + +signals: + void selected(const QModelIndex& index); + void deselected(const QModelIndex& index); + +private: + ImageRegion* selected_; +}; + +#endif /* !IMAGE_SCENE_HH_ */ diff --git a/viewer/image_view.cc b/viewer/image_view.cc new file mode 100644 index 0000000..f017fe9 --- /dev/null +++ b/viewer/image_view.cc @@ -0,0 +1,48 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#include "image_view.hh" + +ImageView::ImageView(QGraphicsScene* scene) + : QGraphicsView(scene) +{ +} + +void +ImageView::wheelEvent(QWheelEvent* event) +{ + // Basic zoom code (same as yavgui) + if (event->delta() != 0) + { + qreal degrees = ((qreal) event->delta()) / 8; + qreal sc; + if (degrees > 0) + sc = 1 + degrees / 100; + else + sc = 1 / (1 - degrees / 100); + + QPointF center = mapToScene(width() / 2, height() / 2); + QPointF mouse = mapToScene(event->pos()); + + qreal dx = (mouse.x() - center.x()); + qreal dy = (mouse.y() - center.y()); + QPointF newCenter = QPointF (mouse.x() - dx / sc, + mouse.y() - dy / sc); + scale(sc, sc); + } +} + +ImageView::~ImageView() +{ +} diff --git a/viewer/image_view.hh b/viewer/image_view.hh new file mode 100644 index 0000000..d2e0058 --- /dev/null +++ b/viewer/image_view.hh @@ -0,0 +1,32 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef IMAGE_VIEW_HH_ +# define IMAGE_VIEW_HH_ + +# include <QtGui> + +class ImageView + : public QGraphicsView +{ + Q_OBJECT + +public: + ImageView(QGraphicsScene* scene); + ~ImageView(); + + void wheelEvent(QWheelEvent* event); +}; + +#endif /* !IMAGE_VIEW_HH_ */ diff --git a/viewer/image_widget.cc b/viewer/image_widget.cc new file mode 100644 index 0000000..b8ac8c2 --- /dev/null +++ b/viewer/image_widget.cc @@ -0,0 +1,44 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#include "image_widget.hh" +#include "image_view.hh" + +ImageWidget::ImageWidget(QGraphicsScene* scene) + : view_ (new ImageView(scene)) +{ + QLabel* title = new QLabel(tr("Layout")); + title->setAlignment(Qt::AlignHCenter); + + QVBoxLayout* layout = new QVBoxLayout; + layout->addWidget(title); + layout->addWidget(view_); + + view_->setDragMode (QGraphicsView::ScrollHandDrag); + view_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + view_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + view_->setTransformationAnchor(QGraphicsView::AnchorUnderMouse); + + setLayout(layout); +} + +void +ImageWidget::update() +{ + view_->fitInView(view_->sceneRect(), Qt::KeepAspectRatio); +} + +ImageWidget::~ImageWidget() +{ +} diff --git a/viewer/image_widget.hh b/viewer/image_widget.hh new file mode 100644 index 0000000..25a41a0 --- /dev/null +++ b/viewer/image_widget.hh @@ -0,0 +1,38 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef IMAGE_WIDGET_HH_ +# define IMAGE_WIDGET_HH_ + +# include <QtGui> + +class ImageView; + +class ImageWidget + : public QWidget +{ + Q_OBJECT + +public: + ImageWidget(QGraphicsScene* scene); + ~ImageWidget(); + +public slots: + void update(); + +private: + ImageView* view_; +}; + +#endif /* !IMAGE_WIDGET_HH_ */ diff --git a/viewer/key_widget.cc b/viewer/key_widget.cc new file mode 100644 index 0000000..af817b3 --- /dev/null +++ b/viewer/key_widget.cc @@ -0,0 +1,65 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#include "key_widget.hh" +#include "common.hh" + +KeyWidget::KeyWidget(const region::KeyMap& key_map) + : items_(new QListWidget()) +{ + QLabel* title = new QLabel(tr("Key")); + title->setAlignment(Qt::AlignHCenter); + + QVBoxLayout* layout = new QVBoxLayout; + layout->addWidget(title); + layout->addWidget(items_); + + for (int i = 0; i < key_map.size(); ++i) + add_item_(key_map[i].first, key_map[i].second); + + setLayout(layout); + + connect(items_, SIGNAL(itemChanged(QListWidgetItem*)), + this, SLOT(update(QListWidgetItem*))); +} + +void +KeyWidget::add_item_(QString text, QColor color) +{ + QListWidgetItem* item = new QListWidgetItem(text); + QPixmap pixmap(10, 6); + pixmap.fill(color); + item->setIcon(QIcon(pixmap)); + item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + item->setCheckState(Qt::Checked); + items_->addItem(item); +} + +bool +KeyWidget::isChecked(region::RegionId id) +{ + return items_->item(id)->checkState() == Qt::Checked; +} + +void +KeyWidget::update(QListWidgetItem* item) +{ + int id = items_->row(item); + + emit updated(id, item->checkState() == Qt::Checked); +} + +KeyWidget::~KeyWidget() +{ +} diff --git a/viewer/key_widget.hh b/viewer/key_widget.hh new file mode 100644 index 0000000..2f8a8c6 --- /dev/null +++ b/viewer/key_widget.hh @@ -0,0 +1,44 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef KEY_WIDGET_HH_ +# define KEY_WIDGET_HH_ + +# include <QtGui> +# include "common.hh" + +class KeyWidget + : public QWidget +{ + Q_OBJECT + +public: + KeyWidget(const region::KeyMap& key_map); + ~KeyWidget(); + + bool isChecked(region::RegionId id); + +signals: + void updated(int key, bool checked); + +private slots: + void update(QListWidgetItem* slot); + +private: + void add_item_(QString text, QColor color); + + QListWidget* items_; +}; + +#endif /* !KEY_WIDGET_HH_ */ diff --git a/viewer/main.cc b/viewer/main.cc new file mode 100644 index 0000000..3bcc590 --- /dev/null +++ b/viewer/main.cc @@ -0,0 +1,26 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#include <QtGui> +#include "viewer.hh" + +int main(int argc, char** argv) +{ + Viewer* viewer = Viewer::Instance(argc, argv); + + if (!viewer) + return 0; + + return viewer->exec(); +} diff --git a/viewer/property_widget.cc b/viewer/property_widget.cc new file mode 100644 index 0000000..3d2f4d5 --- /dev/null +++ b/viewer/property_widget.cc @@ -0,0 +1,73 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#include "property_widget.hh" + +#include "dommodel.hh" + +PropertyWidget::PropertyWidget() + : view_(new QTreeWidget()), + model_(0) +{ + QLabel* title = new QLabel(tr("Properties")); + title->setAlignment(Qt::AlignHCenter); + + QVBoxLayout* layout = new QVBoxLayout; + layout->addWidget(title); + layout->addWidget(view_); + + view_->setColumnCount(2); + view_->setSortingEnabled(true); + view_->setRootIsDecorated(false); + QStringList header_names; + header_names << tr("Name") << tr("Value"); + view_->setHeaderItem(new QTreeWidgetItem(header_names)); + + setLayout(layout); +} + +void +PropertyWidget::update(DomModel* model) +{ + model_ = model; +} + +void +PropertyWidget::select(const QModelIndex& index) +{ + if (!index.isValid()) + return; + + QMap<QString, QVariant> data = + model_->data(index, Qt::UserRole).toMap(); + + for (QMap<QString, QVariant>::iterator i = data.begin(); + i != data.end(); + ++i) + { + QStringList values; + values << i.key() << i.value().toString(); + view_->addTopLevelItem(new QTreeWidgetItem(values)); + } +} + +void +PropertyWidget::deselect(const QModelIndex&) +{ + view_->clear(); +} + +PropertyWidget::~PropertyWidget() +{ +} diff --git a/viewer/property_widget.hh b/viewer/property_widget.hh new file mode 100644 index 0000000..fc4c755 --- /dev/null +++ b/viewer/property_widget.hh @@ -0,0 +1,41 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef PROPERTY_WIDGET_HH_ +# define PROPERTY_WIDGET_HH_ + +# include <QtGui> + +class DomModel; + +class PropertyWidget + : public QWidget +{ + Q_OBJECT + +public: + PropertyWidget(); + ~PropertyWidget(); + +public slots: + void update(DomModel* model); + void select(const QModelIndex& index); + void deselect(const QModelIndex& index); + +private: + QTreeWidget* view_; + DomModel* model_; +}; + +#endif /* !PROPERTY_WIDGET_HH_ */ diff --git a/viewer/viewer.cc b/viewer/viewer.cc new file mode 100644 index 0000000..3b3b188 --- /dev/null +++ b/viewer/viewer.cc @@ -0,0 +1,300 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#include "viewer.hh" +#include "property_widget.hh" +#include "key_widget.hh" +#include "browser_widget.hh" +#include "image_widget.hh" +#include "xml_widget.hh" +#include "image_scene.hh" +#include "image_region.hh" +#include "help_dialog.hh" + +#include "dommodel.hh" + +#include "common.hh" + +Viewer::Viewer(int &argc, char** argv) + : app_ (new QApplication(argc, argv)), + win_ (new QMainWindow()), + image_(0), + scene_(new ImageScene()), + files_(new QDirModel()), + doc_layout_(0), + key_map_(9), + alt_cache_(false) +{ + // Key map + + key_map_[region::Text] = qMakePair(tr("Text"), QColor(0, 200, 0)); + key_map_[region::Image] = qMakePair(tr("Image"), QColor(255, 120, 0)); + key_map_[region::Noise] = qMakePair(tr("Noise"), QColor(114, 188, 144)); + key_map_[region::Separator] = qMakePair(tr("Separator"), QColor(200, 222, 0)); + key_map_[region::Table] = qMakePair(tr("Table"), QColor(0, 0, 255)); + key_map_[region::LineDrawing] = qMakePair(tr("LineDrawing"), + QColor(255, 198, 0)); + key_map_[region::Graphic] = qMakePair(tr("Graphic"), QColor(255, 0, 144)); + key_map_[region::Chart] = qMakePair(tr("Chart"), QColor(0, 204, 255)); + key_map_[region::Maths] = qMakePair(tr("Maths"), QColor(170, 0, 255)); + + // Region ids + + region_ids_["text_region"] = region::Text; + region_ids_["image_region"] = region::Image; + region_ids_["noise_region"] = region::Noise; + region_ids_["separator_region"] = region::Separator; + region_ids_["table_region"] = region::Table; + region_ids_["line_drawing_region"] = region::LineDrawing; + region_ids_["graphic_region"] = region::Graphic; + region_ids_["chart_region"] = region::Chart; + region_ids_["maths_region"] = region::Maths; + + // Layout + + win_->resize(1024, 768); + win_->statusBar(); + + QMenu* file_menu = win_->menuBar()->addMenu(tr("File")); + QAction* quit_action = new QAction(tr("Quit"), file_menu); + connect(quit_action, SIGNAL(triggered()), + app_, SLOT(quit())); + quit_action->setStatusTip(tr("Exit the program.")); + file_menu->addAction(quit_action); + + QMenu* option_menu = win_->menuBar()->addMenu(tr("Options")); + outline_action_ = new QAction(tr("Draw outline"), option_menu); + outline_action_->setStatusTip(tr("Draw region outlines.")); + outline_action_->setCheckable(true); + outline_action_->setChecked(true); + connect(outline_action_, SIGNAL(toggled(bool)), + this, SIGNAL(setOutline(bool))); + option_menu->addAction(outline_action_); + precise_action_ = new QAction(tr("Precise outline"), option_menu); + precise_action_->setStatusTip(tr("1px outline relative to the image " + "(1px relative to the view if off).")); + precise_action_->setCheckable(true); + precise_action_->setChecked(false); + connect(precise_action_, SIGNAL(toggled(bool)), + this, SIGNAL(setPrecise(bool))); + option_menu->addAction(precise_action_); + fill_action_ = new QAction(tr("Fill regions"), option_menu); + fill_action_->setStatusTip(tr("Color the inside of regions.")); + fill_action_->setCheckable(true); + fill_action_->setChecked(true); + connect(fill_action_, SIGNAL(toggled(bool)), + this, SIGNAL(setFill(bool))); + option_menu->addAction(fill_action_); + QAction* cache_action = new QAction(tr("Alternative cache mode"), + option_menu); + cache_action->setStatusTip(tr("Much faster at low zoom, " + "but unstable at high zoom.")); + cache_action->setCheckable(true); + cache_action->setChecked(false); + connect(cache_action, SIGNAL(toggled(bool)), + this, SLOT(setAltCache(bool))); + option_menu->addAction(cache_action); + + QMenu* help_menu = win_->menuBar()->addMenu(tr("Help")); + QAction* about_action = new QAction(tr("About"), help_menu); + about_action->setStatusTip(tr("About this program.")); + connect(about_action, SIGNAL(triggered()), + this, SLOT(help())); + help_menu->addAction(about_action); + + QSplitter* h_splitter = new QSplitter(); + QSplitter* v_splitter = new QSplitter(Qt::Vertical); + QSplitter* v_splitter2 = new QSplitter(Qt::Vertical); + + PropertyWidget* property_wgt = new PropertyWidget(); + XmlWidget* xml_wgt = new XmlWidget(); + BrowserWidget* browser_wgt = new BrowserWidget(files_); + ImageWidget* image_wgt = new ImageWidget(scene_); + key_wgt_ = new KeyWidget(key_map_); + + scene_->setBackgroundBrush(scene_->palette().window()); + + v_splitter->addWidget(property_wgt); + v_splitter->addWidget(key_wgt_); + v_splitter->addWidget(browser_wgt); + + v_splitter2->addWidget(image_wgt); + v_splitter2->addWidget(xml_wgt); + + h_splitter->addWidget(v_splitter); + h_splitter->addWidget(v_splitter2); + + win_->setCentralWidget(h_splitter); + + QList<int> v_sizes; + v_sizes << 300 << 200 << 500; + v_splitter->setSizes(v_sizes); + + QList<int> v_sizes2; + v_sizes2 << 500 << 100; + v_splitter2->setSizes(v_sizes2); + + QList<int> h_sizes; + h_sizes << 200 << 700; + h_splitter->setSizes(h_sizes); + + connect(browser_wgt, SIGNAL(activated(QString)), + this, SLOT(load(QString))); + connect(this, SIGNAL(updated(DomModel*)), + property_wgt, SLOT(update(DomModel*))); + connect(this, SIGNAL(updated(DomModel*)), + xml_wgt, SLOT(update(DomModel*))); + connect(this, SIGNAL(updated(DomModel*)), + image_wgt, SLOT(update())); + connect(key_wgt_, SIGNAL(updated(int, bool)), + this, SIGNAL(key_updated(int, bool))); + connect(scene_, SIGNAL(selected(QModelIndex)), + property_wgt, SLOT(select(QModelIndex))); + connect(scene_, SIGNAL(deselected(QModelIndex)), + property_wgt, SLOT(deselect(QModelIndex))); + connect(scene_, SIGNAL(selected(QModelIndex)), + xml_wgt, SLOT(select(QModelIndex))); + connect(scene_, SIGNAL(deselected(QModelIndex)), + xml_wgt, SLOT(deselect(QModelIndex))); +} + +void +Viewer::load(QString filename) +{ + app_->setOverrideCursor(QCursor(Qt::WaitCursor)); + scene_->clear(); + image_ = 0; + + // Load the image in a pixmap that is directly shown on screen. + // This is very slow when used with the normal rendering system. + // OpenGL might speed up things a bit. + image_ = new QGraphicsPixmapItem(QPixmap(filename)); + image_->setShapeMode(QGraphicsPixmapItem::BoundingRectShape); + image_->setCacheMode(QGraphicsItem::ItemCoordinateCache, QSize()); + image_->setZValue(0); + scene_->addItem(image_); + + if (doc_layout_) + { + doc_layout_->deleteLater(); + doc_layout_ = 0; + } + + // FIXME: Ugly + QString xml_file = filename; + xml_file.chop(4); + xml_file += ".xml"; + + if (QFile::exists(xml_file)) + { + QFile file(xml_file); + if (file.open(QIODevice::ReadOnly)) + { + QDomDocument document; + if (document.setContent(&file)) + { + doc_layout_ = new DomModel(document, this); + } + file.close(); + } + } + + // Add layout info to the scene. + if (doc_layout_) + { + QModelIndex pgGts = doc_layout_->index(1, 0); + QModelIndex page = doc_layout_->index(1, 0, pgGts); + QModelIndex region; + QModelIndex attributes; + QModelIndex coords; + QModelIndex point; + for (int i = 0; true; ++i) + { + region = doc_layout_->index(i, 0, page); + attributes = doc_layout_->index(i, 1, page); + QString name = doc_layout_->data(region, Qt::DisplayRole).toString(); + region::RegionId id = static_cast<region::RegionId>(region_ids_[name]); + + coords = doc_layout_->index(0, 0, region); + if (!region.isValid() || !coords.isValid()) + break; + + QVector<QPoint> points; + for (int j = 0; true; ++j) + { + // Navigate to the coordinate list + point = doc_layout_->index(j, 1, coords); + if (!point.isValid()) + break; + + QMap<QString, QVariant> data = + doc_layout_->data(point, Qt::UserRole).toMap(); + int x = data["x"].toInt(); + int y = data["y"].toInt(); + points << QPoint(x, y); + } + + // Create region + ImageRegion* r = new ImageRegion(id, + key_map_[id].first, + key_map_[id].second, + attributes, points, + outline_action_->isChecked(), + fill_action_->isChecked(), + precise_action_->isChecked(), + key_wgt_->isChecked(id)); + + connect(this, SIGNAL(key_updated(int, bool)), + r, SLOT(setDrawIfSameId(int, bool))); + connect(this, SIGNAL(setOutline(bool)), + r, SLOT(setOutline(bool))); + connect(this, SIGNAL(setPrecise(bool)), + r, SLOT(setPrecise(bool))); + connect(this, SIGNAL(setFill(bool)), + r, SLOT(setFill(bool))); + scene_->addItem(r); + } + } + + emit updated(doc_layout_); + + app_->restoreOverrideCursor(); +} + +int +Viewer::exec() +{ + win_->show(); + return app_->exec(); +} + +void +Viewer::help() +{ + HelpDialog dlg; + dlg.exec(); +} + +void +Viewer::setAltCache(bool b) +{ + alt_cache_ = b; + if (image_) + { + if (b) + image_->setCacheMode(QGraphicsItem::DeviceCoordinateCache); + else + image_->setCacheMode(QGraphicsItem::ItemCoordinateCache); + } +} diff --git a/viewer/viewer.hh b/viewer/viewer.hh new file mode 100644 index 0000000..0a76afd --- /dev/null +++ b/viewer/viewer.hh @@ -0,0 +1,79 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef VIEWER_HH_ +# define VIEWER_HH_ + +# include <QtGui> +# include "common.hh" + +class ImageScene; +class DomModel; +class KeyWidget; + +class Viewer + : public QObject +{ + Q_OBJECT + +public: + ~Viewer(); + + static Viewer* Instance(int &argc, char** argv); + + int exec(); + +public slots: + // Load the file as an image, load the layout if xml with the same + // name is found. + void load(QString filename); + void help(); + + void setAltCache(bool b); + +signals: + void updated(DomModel* model); + void key_updated(int key, bool checked); + void setOutline(bool b); + void setPrecise(bool b); + void setFill(bool b); + +private: + Viewer(int &argc, char** argv); + Viewer(); + + QApplication* app_; + QMainWindow* win_; + + QGraphicsPixmapItem* image_; + + ImageScene* scene_; + QDirModel* files_; + DomModel* doc_layout_; + + QAction* outline_action_; + QAction* fill_action_; + QAction* precise_action_; + + KeyWidget* key_wgt_; + + QMap<QString, int> region_ids_; + region::KeyMap key_map_; + + bool alt_cache_; +}; + +#include "viewer.hxx" + +#endif /* !VIEWER_HH_ */ diff --git a/viewer/viewer.hxx b/viewer/viewer.hxx new file mode 100644 index 0000000..72ee1f2 --- /dev/null +++ b/viewer/viewer.hxx @@ -0,0 +1,31 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef VIEWER_HXX_ +# define VIEWER_HXX_ + +# include "viewer.hh" + +inline Viewer* Viewer::Instance(int &argc, char** argv) +{ + static Viewer viewer(argc, argv); + + return &viewer; +} + +inline Viewer::~Viewer() +{ +} + +#endif /* !VIEWER_HXX_ */ diff --git a/viewer/xml_widget.cc b/viewer/xml_widget.cc new file mode 100644 index 0000000..fa050ec --- /dev/null +++ b/viewer/xml_widget.cc @@ -0,0 +1,53 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#include "xml_widget.hh" + +#include "dommodel.hh" + +XmlWidget::XmlWidget() + : view_(new QTreeView()), + model_(0) +{ + QLabel* title = new QLabel(tr("XML")); + title->setAlignment(Qt::AlignHCenter); + + QVBoxLayout* layout = new QVBoxLayout; + layout->addWidget(title); + layout->addWidget(view_); + + setLayout(layout); +} + +void +XmlWidget::update(DomModel* model) +{ + view_->setModel(model); + view_->resizeColumnToContents(2); +} + +void +XmlWidget::select(const QModelIndex& index) +{ + view_->setCurrentIndex(index); +} + +void +XmlWidget::deselect(const QModelIndex&) +{ +} + +XmlWidget::~XmlWidget() +{ +} diff --git a/viewer/xml_widget.hh b/viewer/xml_widget.hh new file mode 100644 index 0000000..b3de3fa --- /dev/null +++ b/viewer/xml_widget.hh @@ -0,0 +1,41 @@ +// +// Document layout viewer. +// +// Copyright (C) 2009 Florent D'Halluin. +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// The complete GNU General Public Licence Notice can be found as the +// `COPYING' file in the root directory. +// + +#ifndef XML_WIDGET_HH_ +# define XML_WIDGET_HH_ + +# include <QtGui> + +class DomModel; + +class XmlWidget + : public QWidget +{ + Q_OBJECT + +public: + XmlWidget(); + ~XmlWidget(); + +public slots: + void update(DomModel* model); + void select(const QModelIndex& index); + void deselect(const QModelIndex& index); + +private: + QTreeView* view_; + DomModel* model_; +}; + +#endif /* !XML_WIDGET_HH_ */ -- 1.5.6.5