QGIS API Documentation  2.14.11-Essen
qgsphotowidgetwrapper.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsphotowidgetwrapper.cpp
3  --------------------------------------
4  Date : 5.1.2014
5  Copyright : (C) 2014 Matthias Kuhn
6  Email : matthias at opengis dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsphotowidgetwrapper.h"
17 #include "qgspixmaplabel.h"
18 #include "qgsproject.h"
19 
20 #include <QGridLayout>
21 #include <QFileDialog>
22 #include <QSettings>
23 #include <QUrl>
24 
25 #include "qgsfilterlineedit.h"
26 
28  : QgsEditorWidgetWrapper( vl, fieldIdx, editor, parent )
29  , mPhotoLabel( nullptr )
30  , mPhotoPixmapLabel( nullptr )
31  , mLineEdit( nullptr )
32  , mButton( nullptr )
33 {
34 #ifdef WITH_QTWEBKIT
35  mWebView = nullptr;
36 #endif
37 }
38 
39 void QgsPhotoWidgetWrapper::selectFileName()
40 {
41  if ( !mLineEdit )
42  return;
43 
44  QString fileName = QFileDialog::getOpenFileName( nullptr, tr( "Select a picture" ), QFileInfo( mLineEdit->text() ).absolutePath() );
45 
46  if ( fileName.isNull() )
47  return;
48 
49  QString projPath = QDir::toNativeSeparators( QDir::cleanPath( QgsProject::instance()->fileInfo().absolutePath() ) );
50  QString filePath = QDir::toNativeSeparators( QDir::cleanPath( QFileInfo( fileName ).absoluteFilePath() ) );
51 
52  if ( filePath.startsWith( projPath ) )
53  filePath = QDir( projPath ).relativeFilePath( filePath );
54 
55  mLineEdit->setText( filePath );
56 }
57 
58 void QgsPhotoWidgetWrapper::loadPixmap( const QString& fileName )
59 {
60  if ( fileName.isEmpty() )
61  {
62 #ifdef WITH_QTWEBKIT
63  if ( mWebView )
64  {
65  mWebView->setUrl( QString() );
66  }
67 #endif
68  clearPicture();
69  return;
70  }
71 
72  QString filePath = fileName;
73 
74  if ( QUrl( fileName ).isRelative() )
75  filePath = QDir( QgsProject::instance()->fileInfo().absolutePath() ).filePath( fileName );
76 
77 #ifdef WITH_QTWEBKIT
78  if ( mWebView )
79  {
80  mWebView->setUrl( filePath );
81  }
82 #endif
83 
84  QPixmap pm( filePath );
85  if ( !pm.isNull() && mPhotoLabel )
86  {
87  QSize size( config( "Width" ).toInt(), config( "Height" ).toInt() );
88  if ( size.width() == 0 && size.height() > 0 )
89  {
90  size.setWidth( size.height() * pm.size().width() / pm.size().height() );
91  }
92  else if ( size.width() > 0 && size.height() == 0 )
93  {
94  size.setHeight( size.width() * pm.size().height() / pm.size().width() );
95  }
96 
97  if ( mPhotoPixmapLabel )
98  {
99  mPhotoPixmapLabel->setPixmap( pm );
100 
101  if ( size.width() != 0 || size.height() != 0 )
102  {
103  mPhotoPixmapLabel->setMinimumSize( size );
104  mPhotoPixmapLabel->setMaximumSize( size );
105  }
106  }
107  else // mPhotoLabel is checked in the outer if branch
108  {
109  mPhotoLabel->setMinimumSize( size );
110  pm = pm.scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
111  mPhotoLabel->setPixmap( pm );
112  }
113  }
114  else
115  {
116  clearPicture();
117  }
118 }
119 
120 void QgsPhotoWidgetWrapper::clearPicture()
121 {
122  if ( mPhotoLabel )
123  {
124  mPhotoLabel->clear();
125  mPhotoLabel->setMinimumSize( QSize( 0, 0 ) );
126 
127  if ( mPhotoPixmapLabel )
128  mPhotoPixmapLabel->setPixmap( QPixmap() );
129  else
130  mPhotoLabel->setPixmap( QPixmap() );
131  }
132 }
133 
135 {
136  QVariant v;
137 
138  if ( mLineEdit )
139  {
140  if ( mLineEdit->text() == QSettings().value( "qgis/nullValue", "NULL" ).toString() )
141  v = QVariant( QVariant::String );
142  else
143  v = mLineEdit->text();
144  }
145 
146  return v;
147 }
148 
150 {
151  QWidget* container = new QWidget( parent );
152  QGridLayout* layout = new QGridLayout( container );
153  QgsFilterLineEdit* le = new QgsFilterLineEdit( container );
154  QgsPixmapLabel* label = new QgsPixmapLabel( parent );
155  label->setObjectName( "PhotoLabel" );
156  QPushButton* pb = new QPushButton( tr( "..." ), container );
157  pb->setObjectName( "FileChooserButton" );
158 
159  layout->addWidget( label, 0, 0, 1, 2 );
160  layout->addWidget( le, 1, 0 );
161  layout->addWidget( pb, 1, 1 );
162  layout->setMargin( 0 );
163  layout->setContentsMargins( 0, 0, 0, 0 );
164 
165  container->setLayout( layout );
166 
167  return container;
168 }
169 
171 {
172  QWidget* container;
173 
174  mLineEdit = qobject_cast<QLineEdit*>( editor );
175 #ifdef WITH_QTWEBKIT
176  mWebView = qobject_cast<QWebView*>( editor );
177 #endif
178 
179  if ( mLineEdit )
180  {
181  container = mLineEdit->parentWidget();
182  }
183 #ifdef WITH_QTWEBKIT
184  else if ( mWebView )
185  {
186  container = mWebView->parentWidget();
187  mLineEdit = container->findChild<QLineEdit*>();
188  }
189 #endif
190  else
191  {
192  container = editor;
193  mLineEdit = container->findChild<QLineEdit*>();
194  }
195 
196  mButton = container->findChild<QPushButton*>( "FileChooserButton" );
197  if ( !mButton )
198  mButton = container->findChild<QPushButton*>();
199 
200  mPhotoLabel = container->findChild<QLabel*>( "PhotoLabel" );
201  if ( !mPhotoLabel )
202  mPhotoLabel = container->findChild<QLabel*>();
203 
204  mPhotoPixmapLabel = qobject_cast<QgsPixmapLabel*>( mPhotoLabel );
205  if ( mButton )
206  connect( mButton, SIGNAL( clicked() ), this, SLOT( selectFileName() ) );
207 
208  if ( mLineEdit )
209  {
210 
211  QgsFilterLineEdit *fle = qobject_cast<QgsFilterLineEdit*>( mLineEdit );
212  if ( fle )
213  {
214  fle->setNullValue( QSettings().value( "qgis/nullValue", "NULL" ).toString() );
215  }
216 
217  connect( mLineEdit, SIGNAL( textChanged( QString ) ), this, SLOT( valueChanged( QString ) ) );
218  connect( mLineEdit, SIGNAL( textChanged( QString ) ), this, SLOT( loadPixmap( QString ) ) );
219  }
220 }
221 
223 {
224 #ifdef WITH_QTWEBKIT
225  return mPhotoLabel || mLineEdit || mButton || mWebView;
226 #else
227  return mPhotoLabel || mLineEdit || mButton;
228 #endif
229 }
230 
232 {
233  if ( mLineEdit )
234  {
235  if ( value.isNull() )
236  {
237  mLineEdit->blockSignals( true );
238  mLineEdit->setText( QSettings().value( "qgis/nullValue", "NULL" ).toString() );
239  mLineEdit->blockSignals( false );
240  clearPicture();
241  }
242  else
243  mLineEdit->setText( value.toString() );
244  }
245  else
246  {
247  loadPixmap( value.toString() );
248  }
249 }
250 
252 {
253  if ( mLineEdit )
254  mLineEdit->setEnabled( enabled );
255 
256  if ( mButton )
257  mButton->setEnabled( enabled );
258 }
QSize size() const
QString toNativeSeparators(const QString &pathName)
void setHeight(int height)
QString relativeFilePath(const QString &fileName) const
void setContentsMargins(int left, int top, int right, int bottom)
void setPixmap(const QPixmap &)
int width() const
void valueChanged()
Will call the value() method to determine the emitted value.
QVariant value() const override
Will be used to access the widget&#39;s value.
void addWidget(QWidget *widget, int row, int column, QFlags< Qt::AlignmentFlag > alignment)
Manages an editor widget Widget and wrapper share the same parent.
void setPixmap(const QPixmap &)
QString filePath(const QString &fileName) const
void clear()
QString tr(const char *sourceText, const char *disambiguation, int n)
bool isNull() const
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
QgsPhotoWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *editor=nullptr, QWidget *parent=nullptr)
void setMinimumSize(const QSize &)
void setEnabled(bool)
void setLayout(QLayout *layout)
bool isNull() const
void setWidth(int width)
void setObjectName(const QString &name)
bool isEmpty() const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
Lineedit with builtin clear button.
QPixmap scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const
void setMargin(int margin)
bool blockSignals(bool block)
void setEnabled(bool enabled) override
bool isNull() const
void setMaximumSize(const QSize &)
bool valid() const override
Return true if the widget has been properly initialized.
QString cleanPath(const QString &path)
QVariant value(const QString &key, const QVariant &defaultValue) const
QWidget * parentWidget() const
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:381
int height() const
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFlags< QFileDialog::Option > options)
QgsEditorWidgetConfig config() const
Returns the whole config.
void setNullValue(const QString &nullValue)
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void setValue(const QVariant &value) override
QObject * parent() const
Represents a vector layer which manages a vector based data sets.
QString toString() const
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
The QgsPixmapLabel class shows a pixmap and adjusts its size to the space given to the widget by the ...
T findChild(const QString &name) const