Skip to content

Commit

Permalink
Add html annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
NathanW2 committed Sep 2, 2012
1 parent cbdafbc commit 7298e73
Show file tree
Hide file tree
Showing 12 changed files with 625 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -30,6 +30,7 @@ SET(QGIS_APP_SRCS
qgsdecorationgriddialog.cpp
qgsembedlayerdialog.cpp
qgsformannotationdialog.cpp
qgshtmlannotationdialog.cpp
qgsdelattrdialog.cpp
qgsdisplayangle.cpp
qgsfieldcalculator.cpp
Expand All @@ -55,6 +56,7 @@ SET(QGIS_APP_SRCS
qgsmaptooledit.cpp
qgsmaptoolfeatureaction.cpp
qgsmaptoolformannotation.cpp
qgsmaptoolhtmlannotation.cpp
qgsmaptoolpinlabels.cpp
qgsmaptoolshowhidelabels.cpp
qgsmaptoolidentify.cpp
Expand Down Expand Up @@ -188,6 +190,7 @@ SET (QGIS_APP_MOC_HDRS
qgsfeatureaction.h
qgsfieldcalculator.h
qgsformannotationdialog.h
qgshtmlannotationdialog.h
qgsgraduatedsymboldialog.h
qgsidentifyresults.h
qgslabeldialog.h
Expand Down
23 changes: 23 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -124,6 +124,7 @@
#include "qgsexception.h"
#include "qgsfeature.h"
#include "qgsformannotationitem.h"
#include "qgshtmlannotationitem.h"
#include "qgsgenericprojectionselector.h"
#include "qgsgpsinformationwidget.h"
#include "qgslabelinggui.h"
Expand Down Expand Up @@ -217,6 +218,7 @@
#include "qgsmaptooldeletevertex.h"
#include "qgsmaptoolfeatureaction.h"
#include "qgsmaptoolformannotation.h"
#include "qgsmaptoolhtmlannotation.h"
#include "qgsmaptoolidentify.h"
#include "qgsmaptoolmeasureangle.h"
#include "qgsmaptoolmovefeature.h"
Expand Down Expand Up @@ -728,6 +730,7 @@ QgisApp::~QgisApp()
delete mMapTools.mMeasureAngle;
delete mMapTools.mTextAnnotation;
delete mMapTools.mFormAnnotation;
delete mMapTools.mHtmlAnnotation;
delete mMapTools.mAnnotation;
delete mMapTools.mAddFeature;
delete mMapTools.mMoveFeature;
Expand Down Expand Up @@ -931,6 +934,7 @@ void QgisApp::createActions()
connect( mActionDraw, SIGNAL( triggered() ), this, SLOT( refreshMapCanvas() ) );
connect( mActionTextAnnotation, SIGNAL( triggered() ), this, SLOT( addTextAnnotation() ) );
connect( mActionFormAnnotation, SIGNAL( triggered() ), this, SLOT( addFormAnnotation() ) );
connect( mActionHtmlAnnotation, SIGNAL( triggered() ), this, SLOT( addHtmlAnnotation() ) );
connect( mActionAnnotation, SIGNAL( triggered() ), this, SLOT( modifyAnnotation() ) );
connect( mActionLabeling, SIGNAL( triggered() ), this, SLOT( labeling() ) );

Expand Down Expand Up @@ -1354,6 +1358,7 @@ void QgisApp::createToolBars()
bt->setPopupMode( QToolButton::MenuButtonPopup );
bt->addAction( mActionTextAnnotation );
bt->addAction( mActionFormAnnotation );
bt->addAction( mActionHtmlAnnotation );
bt->addAction( mActionAnnotation );

QAction* defAnnotationAction = mActionTextAnnotation;
Expand All @@ -1362,6 +1367,7 @@ void QgisApp::createToolBars()
case 0: defAnnotationAction = mActionTextAnnotation; break;
case 1: defAnnotationAction = mActionFormAnnotation; break;
case 2: defAnnotationAction = mActionAnnotation; break;
case 3: defAnnotationAction = mActionHtmlAnnotation; break;
}
bt->setDefaultAction( defAnnotationAction );
QAction* annotationAction = mAttributesToolBar->addWidget( bt );
Expand Down Expand Up @@ -1665,6 +1671,7 @@ void QgisApp::setTheme( QString theThemeName )
mActionAddToOverview->setIcon( QgsApplication::getThemeIcon( "/mActionInOverview.png" ) );
mActionAnnotation->setIcon( QgsApplication::getThemeIcon( "/mActionAnnotation.png" ) );
mActionFormAnnotation->setIcon( QgsApplication::getThemeIcon( "/mActionFormAnnotation.png" ) );
mActionHtmlAnnotation->setIcon( QgsApplication::getThemeIcon( "/mActionFormAnnotation.png" ) );
mActionTextAnnotation->setIcon( QgsApplication::getThemeIcon( "/mActionTextAnnotation.png" ) );
mActionLabeling->setIcon( QgsApplication::getThemeIcon( "/mActionLabeling.png" ) );
mActionShowPinnedLabels->setIcon( QgsApplication::getThemeIcon( "/mActionShowPinnedLabels.svg" ) );
Expand Down Expand Up @@ -1793,6 +1800,8 @@ void QgisApp::createCanvasTools()
mMapTools.mTextAnnotation->setAction( mActionTextAnnotation );
mMapTools.mFormAnnotation = new QgsMapToolFormAnnotation( mMapCanvas );
mMapTools.mFormAnnotation->setAction( mActionFormAnnotation );
mMapTools.mHtmlAnnotation = new QgsMapToolHtmlAnnotation( mMapCanvas );
mMapTools.mHtmlAnnotation->setAction( mActionHtmlAnnotation );
mMapTools.mAnnotation = new QgsMapToolAnnotation( mMapCanvas );
mMapTools.mAnnotation->setAction( mActionAnnotation );
mMapTools.mAddFeature = new QgsMapToolAddFeature( mMapCanvas );
Expand Down Expand Up @@ -3904,6 +3913,11 @@ void QgisApp::addFormAnnotation()
mMapCanvas->setMapTool( mMapTools.mFormAnnotation );
}

void QgisApp::addHtmlAnnotation()
{
mMapCanvas->setMapTool( mMapTools.mHtmlAnnotation );
}

void QgisApp::addTextAnnotation()
{
mMapCanvas->setMapTool( mMapTools.mTextAnnotation );
Expand Down Expand Up @@ -4431,6 +4445,13 @@ bool QgisApp::loadAnnotationItemsFromProject( const QDomDocument& doc )
QgsFormAnnotationItem* newFormItem = new QgsFormAnnotationItem( mMapCanvas );
newFormItem->readXML( doc, formItemList.at( i ).toElement() );
}

QDomNodeList htmlItemList = doc.elementsByTagName( "HtmlAnnotationItem" );
for ( int i = 0; i < htmlItemList.size(); ++i )
{
QgsHtmlAnnotationItem* newHtmlItem = new QgsHtmlAnnotationItem( mMapCanvas );
newHtmlItem->readXML( doc, htmlItemList.at( i ).toElement() );
}
return true;
}

Expand Down Expand Up @@ -7945,6 +7966,8 @@ void QgisApp::toolButtonActionTriggered( QAction *action )
settings.setValue( "/UI/annotationTool", 1 );
else if ( action == mActionAnnotation )
settings.setValue( "/UI/annotationTool", 2 );
else if ( action == mActionHtmlAnnotation )
settings.setValue( "/UI/annotationTool", 3 );

bt->setDefaultAction( action );
}
Expand Down
2 changes: 2 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -816,6 +816,7 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
//annotations
void addFormAnnotation();
void addTextAnnotation();
void addHtmlAnnotation();
void modifyAnnotation();

//! shows label settings dialog (for labeling-ng)
Expand Down Expand Up @@ -1084,6 +1085,7 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
QgsMapTool* mRotatePointSymbolsTool;
QgsMapTool* mAnnotation;
QgsMapTool* mFormAnnotation;
QgsMapTool* mHtmlAnnotation;
QgsMapTool* mTextAnnotation;
QgsMapTool* mPinLabels;
QgsMapTool* mShowHideLabels;
Expand Down
90 changes: 90 additions & 0 deletions src/app/qgshtmlannotationdialog.cpp
@@ -0,0 +1,90 @@
/***************************************************************************
QgsHTMLAnnotationDialog.cpp
---------------------
begin : March 2010
copyright : (C) 2010 by Marco Hugentobler
email : marco dot hugentobler at sourcepole dot ch
***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#include "qgshtmlannotationdialog.h"
#include "qgsannotationwidget.h"
#include "qgsvectorlayer.h"
#include <QFileDialog>
#include <QFileInfo>
#include <QGraphicsScene>

QgsHtmlAnnotationDialog::QgsHtmlAnnotationDialog( QgsHtmlAnnotationItem* item, QWidget * parent, Qt::WindowFlags f )
: QDialog( parent, f ), mItem( item ), mEmbeddedWidget( 0 )
{
setupUi( this );
mEmbeddedWidget = new QgsAnnotationWidget( mItem );
mEmbeddedWidget->show();
mStackedWidget->addWidget( mEmbeddedWidget );
mStackedWidget->setCurrentWidget( mEmbeddedWidget );

if ( item )
{
mFileLineEdit->setText( item->htmlPage() );
}

QObject::connect( mButtonBox, SIGNAL( accepted() ), this, SLOT( applySettingsToItem() ) );
QPushButton* deleteButton = new QPushButton( tr( "Delete" ) );
QObject::connect( deleteButton, SIGNAL( clicked() ), this, SLOT( deleteItem() ) );
mButtonBox->addButton( deleteButton, QDialogButtonBox::RejectRole );
}

QgsHtmlAnnotationDialog::~QgsHtmlAnnotationDialog()
{

}

void QgsHtmlAnnotationDialog::applySettingsToItem()
{
//apply settings from embedded item widget
if ( mEmbeddedWidget )
{
mEmbeddedWidget->apply();
}

if ( mItem )
{
mItem->setHTMLPage( mFileLineEdit->text() );
QgsVectorLayer* layer = mItem->vectorLayer();
if ( layer )
{
//set last used annotation form as default for the layer
//layer->setAnnotationForm( mFileLineEdit->text() );
}
mItem->update();
}
}

void QgsHtmlAnnotationDialog::on_mBrowseToolButton_clicked()
{
QString directory;
QFileInfo fi( mFileLineEdit->text() );
if ( fi.exists() )
{
directory = fi.absolutePath();
}
QString filename = QFileDialog::getOpenFileName( 0, tr( "html" ), directory, "*.html" );
mFileLineEdit->setText( filename );
}

void QgsHtmlAnnotationDialog::deleteItem()
{
QGraphicsScene* scene = mItem->scene();
if ( scene )
{
scene->removeItem( mItem );
}
delete mItem;
mItem = 0;
}

40 changes: 40 additions & 0 deletions src/app/qgshtmlannotationdialog.h
@@ -0,0 +1,40 @@
/***************************************************************************
qgsformannotationdialog.h
---------------------
begin : March 2010
copyright : (C) 2010 by Marco Hugentobler
email : marco dot hugentobler at sourcepole dot ch
***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#ifndef QgsHTMLAnnotationDialog_H
#define QgsHTMLAnnotationDialog_H

#include "ui_qgsformannotationdialogbase.h"
#include "qgshtmlannotationitem.h"

class QgsAnnotationWidget;

class QgsHtmlAnnotationDialog: public QDialog, private Ui::QgsFormAnnotationDialogBase
{
Q_OBJECT
public:
QgsHtmlAnnotationDialog( QgsHtmlAnnotationItem* item, QWidget * parent = 0, Qt::WindowFlags f = 0 );
~QgsHtmlAnnotationDialog();

private:
QgsHtmlAnnotationItem* mItem;
QgsAnnotationWidget* mEmbeddedWidget;

private slots:
void applySettingsToItem();
void on_mBrowseToolButton_clicked();
void deleteItem();
};

#endif // QgsHTMLAnnotationDialog_H
8 changes: 8 additions & 0 deletions src/app/qgsmaptoolannotation.cpp
Expand Up @@ -18,6 +18,8 @@
#include "qgsmaptoolannotation.h"
#include "qgsformannotationdialog.h"
#include "qgsformannotationitem.h"
#include "qgshtmlannotationitem.h"
#include "qgshtmlannotationdialog.h"
#include "qgslogger.h"
#include "qgsmapcanvas.h"
#include "qgstextannotationdialog.h"
Expand Down Expand Up @@ -60,6 +62,12 @@ QDialog* QgsMapToolAnnotation::createItemEditor( QgsAnnotationItem *item )
return new QgsFormAnnotationDialog( fItem );
}

QgsHtmlAnnotationItem* hItem = dynamic_cast<QgsHtmlAnnotationItem*>( item );
if ( hItem )
{
return new QgsHtmlAnnotationDialog( hItem );
}

return 0;
}

Expand Down
53 changes: 53 additions & 0 deletions src/app/qgsmaptoolhtmlannotation.cpp
@@ -0,0 +1,53 @@
/***************************************************************************
qgsmaptoolformannotation.cpp
-------------------------------
begin : February 9, 2010
copyright : (C) 2010 by Marco Hugentobler
email : marco dot hugentobler at hugis dot net
***************************************************************************/

/***************************************************************************
* *
* 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. *
* *
***************************************************************************/

#include "qgsmaptoolhtmlannotation.h"
#include "qgshtmlannotationitem.h"
#include "qgsmapcanvas.h"
#include "qgsvectorlayer.h"
#include <QMouseEvent>

QgsMapToolHtmlAnnotation::QgsMapToolHtmlAnnotation( QgsMapCanvas* canvas ): QgsMapToolAnnotation( canvas )
{

}

QgsMapToolHtmlAnnotation::~QgsMapToolHtmlAnnotation()
{

}

QgsAnnotationItem* QgsMapToolHtmlAnnotation::createItem( QMouseEvent* e )
{
//try to associate the current vector layer and a feature to the form item
QgsVectorLayer* currentVectorLayer = 0;
if ( mCanvas )
{
QgsMapLayer* mLayer = mCanvas->currentLayer();
if ( mLayer )
{
currentVectorLayer = dynamic_cast<QgsVectorLayer*>( mLayer );
}
}

QgsHtmlAnnotationItem* formItem = new QgsHtmlAnnotationItem( mCanvas, currentVectorLayer );
formItem->setMapPosition( toMapCoordinates( e->pos() ) );
formItem->setSelected( true );
formItem->setFrameSize( QSizeF( 200, 100 ) );
return formItem;
}

33 changes: 33 additions & 0 deletions src/app/qgsmaptoolhtmlannotation.h
@@ -0,0 +1,33 @@
/***************************************************************************
QgsMapToolHtmlAnnotation.h
-----------------------------
begin : February 9, 2010
copyright : (C) 2010 by Marco Hugentobler
email : marco dot hugentobler at hugis dot net
***************************************************************************/

/***************************************************************************
* *
* 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. *
* *
***************************************************************************/

#ifndef QGSMAPTOOLHTMLANNOTATION_H
#define QGSMAPTOOLHTMLANNOTATION_H

#include "qgsmaptoolannotation.h"

class QgsMapToolHtmlAnnotation: public QgsMapToolAnnotation
{
public:
QgsMapToolHtmlAnnotation( QgsMapCanvas* canvas );
~QgsMapToolHtmlAnnotation();

protected:
QgsAnnotationItem* createItem( QMouseEvent* e );
};

#endif // QgsMapToolHtmlAnnotation_H
2 changes: 2 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -59,6 +59,7 @@ qgsencodingfiledialog.cpp
qgsfiledropedit.cpp
qgsfieldvalidator.cpp
qgsformannotationitem.cpp
qgshtmlannotationitem.cpp
qgsgenericprojectionselector.cpp
qgsmanageconnectionsdialog.cpp
qgsmapcanvas.cpp
Expand Down Expand Up @@ -156,6 +157,7 @@ qgisinterface.h
qgsencodingfiledialog.h
qgsfieldvalidator.h
qgsformannotationitem.h
qgshtmlannotationitem.h
qgsgenericprojectionselector.h
qgsmanageconnectionsdialog.h
qgsmapcanvas.h
Expand Down

5 comments on commit 7298e73

@AndrewM-
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As of the master 26 July 2013, I found the html annotation worked but did not update the field data used in expressions so show the data for the current feature record. Data for the first record in the table was being shown no matter which feature was clicked. The same html code works correctly for html tips. The test code was:

<b>[% "PhotoName" %]</b>
<img src='[% "URL" %]' height='200' width='300'/>

where URL is the file address for an image such as "c:\photos\img1.jpg". I have tried the using double quotes and single quotes to ensure that it is not just an issue with how quotes are used.

I am applying the html by double clicking an existing blank annotation and importing a html file each time I add an annotation. Is this how the tools is meant to be used, or is there some place that I should be putting the html before starting to use the tool?

@AndrewM-
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have read the source code and can't quite figure it out but it appears that a single feature ID is used to look up the DOM and get attributes. In my photographic data, which is geotagged using a time-based track log from a Garmin GPS, is it common for photos to be stacked on top of each other. Even if this was not the case, I often stand in one spot and take photos upstream, downstream and across the stream. Handling of multiple features at the same point is likely to be an issue. The only solution I can think of would be to have a preview in the dialog that has forwards and backwards butttons to allow the user to choose which of the coincident records to display.

@NathanW2
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes currently it's a limitation of the tool. I doesn't support stacked features well or at all.

This should be opened as a bug on hub.qgis.org

@AndrewM-
Copy link

@AndrewM- AndrewM- commented on 7298e73 Jul 28, 2013 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@timlinux
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi

@AndrewM- QtCreator is the defacto IDE for Qt related development and works great for QGIS. You can debug etc nicely with it (in partiular under linux).

Tim

Please sign in to comment.