QGIS API Documentation  2.99.0-Master (0a63d1f)
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() == QgsApplication::nullRepresentation() )
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  {
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( QgsApplication::nullRepresentation() );
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.
QVariantMap config() const
Returns the whole config.
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...
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
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:173
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:350
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 ...