QGIS API Documentation  2.99.0-Master (8ec3eaf)
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 
27 QgsPhotoWidgetWrapper::QgsPhotoWidgetWrapper( QgsVectorLayer* vl, int fieldIdx, QWidget* editor, QWidget* parent )
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( QStringLiteral( "Width" ) ).toInt(), config( QStringLiteral( "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( QStringLiteral( "qgis/nullValue" ), "NULL" ).toString() )
141  v = QVariant( QVariant::String );
142  else
143  v = mLineEdit->text();
144  }
145 
146  return v;
147 }
148 
150 {
151  if ( mLineEdit )
152  {
153  whileBlocking( mLineEdit )->clear();
154  }
155  if ( mPhotoLabel )
156  mPhotoLabel->clear();
157  if ( mPhotoPixmapLabel )
158  mPhotoPixmapLabel->clear();
159 }
160 
161 QWidget* QgsPhotoWidgetWrapper::createWidget( QWidget* parent )
162 {
163  QWidget* container = new QWidget( parent );
164  QGridLayout* layout = new QGridLayout();
166  QgsPixmapLabel* label = new QgsPixmapLabel();
167  label->setObjectName( QStringLiteral( "PhotoLabel" ) );
168  QPushButton* pb = new QPushButton( tr( "..." ) );
169  pb->setObjectName( QStringLiteral( "FileChooserButton" ) );
170 
171  layout->addWidget( label, 0, 0, 1, 2 );
172  layout->addWidget( le, 1, 0 );
173  layout->addWidget( pb, 1, 1 );
174  layout->setMargin( 0 );
175  layout->setContentsMargins( 0, 0, 0, 0 );
176 
177  container->setLayout( layout );
178 
179  return container;
180 }
181 
182 void QgsPhotoWidgetWrapper::initWidget( QWidget* editor )
183 {
184  QWidget* container;
185 
186  mLineEdit = qobject_cast<QLineEdit*>( editor );
187 #ifdef WITH_QTWEBKIT
188  mWebView = qobject_cast<QWebView*>( editor );
189 #endif
190 
191  if ( mLineEdit )
192  {
193  container = mLineEdit->parentWidget();
194  }
195 #ifdef WITH_QTWEBKIT
196  else if ( mWebView )
197  {
198  container = mWebView->parentWidget();
199  mLineEdit = container->findChild<QLineEdit*>();
200  }
201 #endif
202  else
203  {
204  container = editor;
205  mLineEdit = container->findChild<QLineEdit*>();
206  }
207 
208  mButton = container->findChild<QPushButton*>( QStringLiteral( "FileChooserButton" ) );
209  if ( !mButton )
210  mButton = container->findChild<QPushButton*>();
211 
212  mPhotoLabel = container->findChild<QLabel*>( QStringLiteral( "PhotoLabel" ) );
213  if ( !mPhotoLabel )
214  mPhotoLabel = container->findChild<QLabel*>();
215 
216  mPhotoPixmapLabel = qobject_cast<QgsPixmapLabel*>( mPhotoLabel );
217  if ( mButton )
218  connect( mButton, SIGNAL( clicked() ), this, SLOT( selectFileName() ) );
219 
220  if ( mLineEdit )
221  {
222 
223  QgsFilterLineEdit *fle = qobject_cast<QgsFilterLineEdit*>( mLineEdit );
224  if ( fle )
225  {
226  fle->setNullValue( QSettings().value( QStringLiteral( "qgis/nullValue" ), "NULL" ).toString() );
227  }
228 
229  connect( mLineEdit, SIGNAL( textChanged( QString ) ), this, SLOT( valueChanged( QString ) ) );
230  connect( mLineEdit, SIGNAL( textChanged( QString ) ), this, SLOT( loadPixmap( QString ) ) );
231  }
232 }
233 
235 {
236 #ifdef WITH_QTWEBKIT
237  return mPhotoLabel || mLineEdit || mButton || mWebView;
238 #else
239  return mPhotoLabel || mLineEdit || mButton;
240 #endif
241 }
242 
243 void QgsPhotoWidgetWrapper::setValue( const QVariant& value )
244 {
245  if ( mLineEdit )
246  {
247  if ( value.isNull() )
248  {
249  whileBlocking( mLineEdit )->setText( QSettings().value( QStringLiteral( "qgis/nullValue" ), "NULL" ).toString() );
250  clearPicture();
251  }
252  else
253  mLineEdit->setText( value.toString() );
254  }
255  else
256  {
257  loadPixmap( value.toString() );
258  }
259 }
260 
262 {
263  if ( mLineEdit )
264  mLineEdit->setEnabled( enabled );
265 
266  if ( mButton )
267  mButton->setEnabled( enabled );
268 }
269 
270 void QgsPhotoWidgetWrapper::updateConstraintWidgetStatus( ConstraintResult status )
271 {
272  if ( mLineEdit )
273  {
274  switch ( status )
275  {
277  mLineEdit->setStyleSheet( QString() );
278  break;
279 
281  mLineEdit->setStyleSheet( QStringLiteral( "QgsFilterLineEdit { background-color: #dd7777; }" ) );
282  break;
283 
285  mLineEdit->setStyleSheet( QStringLiteral( "QgsFilterLineEdit { background-color: #ffd85d; }" ) );
286  break;
287  }
288  }
289 }
Widget failed at least one soft (non-enforced) constraint.
void setPixmap(const QPixmap &)
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.
Manages an editor widget Widget and wrapper share the same parent.
Widget failed at least one hard (enforced) constraint.
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)
QLineEdit subclass with built in support for clearing the widget&#39;s value and handling custom null val...
void setEnabled(bool enabled) override
bool valid() const override
Return true if the widget has been properly initialized.
Widget passed constraints successfully.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:176
ConstraintResult
Result of constraint checks.
void showIndeterminateState() override
Sets the widget to display in an indeterminate "mixed value" state.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:348
QgsEditorWidgetConfig config() const
Returns the whole config.
void setNullValue(const QString &nullValue)
Sets the string representation for null values in the widget.
void setValue(const QVariant &value) override
Represents a vector layer which manages a vector based data sets.
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 ...