QGIS API Documentation
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 
24 #include "qgsfilterlineedit.h"
25 
27  : QgsEditorWidgetWrapper( vl, fieldIdx, editor, parent )
28  , mPhotoLabel( nullptr )
29  , mPhotoPixmapLabel( nullptr )
30  , mLineEdit( nullptr )
31  , mButton( nullptr )
32 {
33 #ifdef WITH_QTWEBKIT
34  mWebView = nullptr;
35 #endif
36 }
37 
38 void QgsPhotoWidgetWrapper::selectFileName()
39 {
40  if ( !mLineEdit )
41  return;
42 
43  QString fileName = QFileDialog::getOpenFileName( nullptr, tr( "Select a picture" ), QFileInfo( mLineEdit->text() ).absolutePath() );
44 
45  if ( fileName.isNull() )
46  return;
47 
48  QString projPath = QDir::toNativeSeparators( QDir::cleanPath( QgsProject::instance()->fileInfo().absolutePath() ) );
49  QString filePath = QDir::toNativeSeparators( QDir::cleanPath( QFileInfo( fileName ).absoluteFilePath() ) );
50 
51  if ( filePath.startsWith( projPath ) )
52  filePath = QDir( projPath ).relativeFilePath( filePath );
53 
54  mLineEdit->setText( filePath );
55 }
56 
57 void QgsPhotoWidgetWrapper::loadPixmap( const QString& fileName )
58 {
59  if ( fileName.isEmpty() )
60  {
61 #ifdef WITH_QTWEBKIT
62  if ( mWebView )
63  {
64  mWebView->setUrl( QString() );
65  }
66 #endif
67  clearPicture();
68  return;
69  }
70 
71  QString filePath = fileName;
72 
73  if ( QUrl( fileName ).isRelative() )
74  filePath = QDir( QgsProject::instance()->fileInfo().absolutePath() ).filePath( fileName );
75 
76 #ifdef WITH_QTWEBKIT
77  if ( mWebView )
78  {
79  mWebView->setUrl( filePath );
80  }
81 #endif
82 
83  QPixmap pm( filePath );
84  if ( !pm.isNull() && mPhotoLabel )
85  {
86  QSize size( config( "Width" ).toInt(), config( "Height" ).toInt() );
87  if ( size.width() == 0 && size.height() > 0 )
88  {
89  size.setWidth( size.height() * pm.size().width() / pm.size().height() );
90  }
91  else if ( size.width() > 0 && size.height() == 0 )
92  {
93  size.setHeight( size.width() * pm.size().height() / pm.size().width() );
94  }
95 
96  if ( mPhotoPixmapLabel )
97  {
98  mPhotoPixmapLabel->setPixmap( pm );
99 
100  if ( size.width() != 0 || size.height() != 0 )
101  {
102  mPhotoPixmapLabel->setMinimumSize( size );
103  mPhotoPixmapLabel->setMaximumSize( size );
104  }
105  }
106  else // mPhotoLabel is checked in the outer if branch
107  {
108  mPhotoLabel->setMinimumSize( size );
109  pm = pm.scaled( size, Qt::KeepAspectRatio, Qt::SmoothTransformation );
110  mPhotoLabel->setPixmap( pm );
111  }
112  }
113  else
114  {
115  clearPicture();
116  }
117 }
118 
119 void QgsPhotoWidgetWrapper::clearPicture()
120 {
121  if ( mPhotoLabel )
122  {
123  mPhotoLabel->clear();
124  mPhotoLabel->setMinimumSize( QSize( 0, 0 ) );
125 
126  if ( mPhotoPixmapLabel )
127  mPhotoPixmapLabel->setPixmap( QPixmap() );
128  else
129  mPhotoLabel->setPixmap( QPixmap() );
130  }
131 }
132 
134 {
135  QVariant v;
136 
137  if ( mLineEdit )
138  {
139  if ( mLineEdit->text() == QSettings().value( "qgis/nullValue", "NULL" ).toString() )
140  v = QVariant( QVariant::String );
141  else
142  v = mLineEdit->text();
143  }
144 
145  return v;
146 }
147 
149 {
150  if ( mLineEdit )
151  {
152  whileBlocking( mLineEdit )->clear();
153  }
154  if ( mPhotoLabel )
155  mPhotoLabel->clear();
156  if ( mPhotoPixmapLabel )
157  mPhotoPixmapLabel->clear();
158 }
159 
161 {
162  QWidget* container = new QWidget( parent );
163  QGridLayout* layout = new QGridLayout();
165  QgsPixmapLabel* label = new QgsPixmapLabel();
166  label->setObjectName( "PhotoLabel" );
167  QPushButton* pb = new QPushButton( tr( "..." ) );
168  pb->setObjectName( "FileChooserButton" );
169 
170  layout->addWidget( label, 0, 0, 1, 2 );
171  layout->addWidget( le, 1, 0 );
172  layout->addWidget( pb, 1, 1 );
173  layout->setMargin( 0 );
174  layout->setContentsMargins( 0, 0, 0, 0 );
175 
176  container->setLayout( layout );
177 
178  return container;
179 }
180 
182 {
183  QWidget* container;
184 
185  mLineEdit = qobject_cast<QLineEdit*>( editor );
186 #ifdef WITH_QTWEBKIT
187  mWebView = qobject_cast<QWebView*>( editor );
188 #endif
189 
190  if ( mLineEdit )
191  {
192  container = mLineEdit->parentWidget();
193  }
194 #ifdef WITH_QTWEBKIT
195  else if ( mWebView )
196  {
197  container = mWebView->parentWidget();
198  mLineEdit = container->findChild<QLineEdit*>();
199  }
200 #endif
201  else
202  {
203  container = editor;
204  mLineEdit = container->findChild<QLineEdit*>();
205  }
206 
207  mButton = container->findChild<QPushButton*>( "FileChooserButton" );
208  if ( !mButton )
209  mButton = container->findChild<QPushButton*>();
210 
211  mPhotoLabel = container->findChild<QLabel*>( "PhotoLabel" );
212  if ( !mPhotoLabel )
213  mPhotoLabel = container->findChild<QLabel*>();
214 
215  mPhotoPixmapLabel = qobject_cast<QgsPixmapLabel*>( mPhotoLabel );
216  if ( mButton )
217  connect( mButton, SIGNAL( clicked() ), this, SLOT( selectFileName() ) );
218 
219  if ( mLineEdit )
220  {
221 
222  QgsFilterLineEdit *fle = qobject_cast<QgsFilterLineEdit*>( mLineEdit );
223  if ( fle )
224  {
225  fle->setNullValue( QSettings().value( "qgis/nullValue", "NULL" ).toString() );
226  }
227 
228  connect( mLineEdit, SIGNAL( textChanged( QString ) ), this, SLOT( valueChanged( QString ) ) );
229  connect( mLineEdit, SIGNAL( textChanged( QString ) ), this, SLOT( loadPixmap( QString ) ) );
230  }
231 }
232 
234 {
235 #ifdef WITH_QTWEBKIT
236  return mPhotoLabel || mLineEdit || mButton || mWebView;
237 #else
238  return mPhotoLabel || mLineEdit || mButton;
239 #endif
240 }
241 
243 {
244  if ( mLineEdit )
245  {
246  if ( value.isNull() )
247  {
248  whileBlocking( mLineEdit )->setText( QSettings().value( "qgis/nullValue", "NULL" ).toString() );
249  clearPicture();
250  }
251  else
252  mLineEdit->setText( value.toString() );
253  }
254  else
255  {
256  loadPixmap( value.toString() );
257  }
258 }
259 
261 {
262  if ( mLineEdit )
263  mLineEdit->setEnabled( enabled );
264 
265  if ( mButton )
266  mButton->setEnabled( enabled );
267 }
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)
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
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:328
void showIndeterminateState() override
Sets the widget to display in an indeterminate "mixed value" state.
QWidget * parentWidget() const
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:388
int height() const
QgsEditorWidgetConfig config() const
Returns the whole config.
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFlags< QFileDialog::Option > options)
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