1 /***************************************************************************
2                          qgsattributedialog.cpp  -  description
3                              -------------------
4     begin                : October 2004
5     copyright            : (C) 2004 by Marco Hugentobler
6     email                : marco.hugentobler@autoform.ch
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "qgsattributedialog.h"
19 
20 #include "qgsattributeform.h"
21 #include "qgshighlight.h"
22 #include "qgsapplication.h"
23 #include "qgssettings.h"
24 #include "qgsmessagebar.h"
25 
QgsAttributeDialog(QgsVectorLayer * vl,QgsFeature * thepFeature,bool featureOwner,QWidget * parent,bool showDialogButtons,const QgsAttributeEditorContext & context)26 QgsAttributeDialog::QgsAttributeDialog( QgsVectorLayer *vl, QgsFeature *thepFeature, bool featureOwner, QWidget *parent, bool showDialogButtons, const QgsAttributeEditorContext &context )
27   : QDialog( parent )
28   , mOwnedFeature( featureOwner ? thepFeature : nullptr )
29 {
30   init( vl, thepFeature, context, showDialogButtons );
31 }
32 
~QgsAttributeDialog()33 QgsAttributeDialog::~QgsAttributeDialog()
34 {
35   if ( mHighlight )
36   {
37     mHighlight->hide();
38     delete mHighlight;
39   }
40 
41   delete mOwnedFeature;
42 
43   saveGeometry();
44 }
45 
saveGeometry()46 void QgsAttributeDialog::saveGeometry()
47 {
48   // WARNING!!!! Don't use QgsGui::enableAutoGeometryRestore for this dialog -- the object name
49   // is dynamic and is set to match the layer/feature combination.
50   QgsSettings().setValue( QStringLiteral( "Windows/AttributeDialog/geometry" ), QDialog::saveGeometry() );
51 }
52 
restoreGeometry()53 void QgsAttributeDialog::restoreGeometry()
54 {
55   // WARNING!!!! Don't use QgsGui::enableAutoGeometryRestore for this dialog -- the object name
56   // is dynamic and is set to match the layer/feature combination.
57   QDialog::restoreGeometry( QgsSettings().value( QStringLiteral( "Windows/AttributeDialog/geometry" ) ).toByteArray() );
58 }
59 
setHighlight(QgsHighlight * h)60 void QgsAttributeDialog::setHighlight( QgsHighlight *h )
61 {
62   delete mHighlight;
63 
64   mHighlight = h;
65 }
66 
accept()67 void QgsAttributeDialog::accept()
68 {
69   QString error;
70   const bool didSave = mAttributeForm->saveWithDetails( &error );
71   if ( didSave )
72   {
73     QDialog::accept();
74   }
75   else
76   {
77     if ( error.isEmpty() )
78       error = tr( "An unknown error was encountered saving attributes" );
79 
80     mMessageBar->pushMessage( QString(),
81                               error,
82                               Qgis::MessageLevel::Critical );
83   }
84 }
85 
show()86 void QgsAttributeDialog::show()
87 {
88   QDialog::show();
89   raise();
90   activateWindow();
91 }
92 
reject()93 void QgsAttributeDialog::reject()
94 {
95   // Delete any actions on other layers that may have been triggered from this dialog
96   if ( mAttributeForm->mode() == QgsAttributeEditorContext::AddFeatureMode )
97     mTrackedVectorLayerTools.rollback();
98 
99   QDialog::reject();
100 }
101 
init(QgsVectorLayer * layer,QgsFeature * feature,const QgsAttributeEditorContext & context,bool showDialogButtons)102 void QgsAttributeDialog::init( QgsVectorLayer *layer, QgsFeature *feature, const QgsAttributeEditorContext &context, bool showDialogButtons )
103 {
104   QgsAttributeEditorContext trackedContext = context;
105   setWindowTitle( tr( "%1 - Feature Attributes" ).arg( layer->name() ) );
106   setLayout( new QGridLayout() );
107   layout()->setContentsMargins( 0, 0, 0, 0 );
108   mMessageBar = new QgsMessageBar( this );
109   mMessageBar->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
110   layout()->addWidget( mMessageBar );
111 
112   setLayout( layout() );
113 
114   mTrackedVectorLayerTools.setVectorLayerTools( trackedContext.vectorLayerTools() );
115   trackedContext.setVectorLayerTools( &mTrackedVectorLayerTools );
116   if ( showDialogButtons )
117     trackedContext.setFormMode( QgsAttributeEditorContext::StandaloneDialog );
118 
119   mAttributeForm = new QgsAttributeForm( layer, *feature, trackedContext, this );
120   mAttributeForm->disconnectButtonBox();
121   layout()->addWidget( mAttributeForm );
122   QDialogButtonBox *buttonBox = mAttributeForm->findChild<QDialogButtonBox *>();
123   connect( buttonBox, &QDialogButtonBox::rejected, this, &QgsAttributeDialog::reject );
124   connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsAttributeDialog::accept );
125   connect( layer, &QObject::destroyed, this, &QWidget::close );
126 
127   mMenu = new QgsActionMenu( layer, mAttributeForm->feature(), QStringLiteral( "Feature" ), this );
128   if ( !mMenu->menuActions().isEmpty() )
129   {
130     QMenuBar *menuBar = new QMenuBar( this );
131     menuBar->addMenu( mMenu );
132     layout()->setMenuBar( menuBar );
133   }
134 
135   restoreGeometry();
136   focusNextChild();
137 }
138 
setMode(QgsAttributeEditorContext::Mode mode)139 void QgsAttributeDialog::setMode( QgsAttributeEditorContext::Mode mode )
140 {
141   mAttributeForm->setMode( mode );
142   mMenu->setMode( mode );
143 }
144 
event(QEvent * e)145 bool QgsAttributeDialog::event( QEvent *e )
146 {
147   if ( e->type() == QEvent::WindowActivate && mHighlight )
148     mHighlight->show();
149   else if ( e->type() == QEvent::WindowDeactivate && mHighlight )
150     mHighlight->hide();
151 
152   return QDialog::event( e );
153 }
154 
setExtraContextScope(QgsExpressionContextScope * extraScope)155 void QgsAttributeDialog::setExtraContextScope( QgsExpressionContextScope *extraScope )
156 {
157   mAttributeForm->setExtraContextScope( extraScope );
158 }
159