1 /***************************************************************************
2 qgsmessagebaritem.h - description
3 -------------------
4 begin : August 2013
5 copyright : (C) 2013 by Denis Rouzaud
6 email : denis.rouzaud@gmail.com
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 "qgsapplication.h"
19 #include "qgsmessagebaritem.h"
20 #include "qgsmessagebar.h"
21 #include "qgsgui.h"
22 #include "qgsnative.h"
23 #include <QHBoxLayout>
24 #include <QLabel>
25 #include <QTextBrowser>
26 #include <QDesktopServices>
27 #include <QFileInfo>
28
QgsMessageBarItem(const QString & text,Qgis::MessageLevel level,int duration,QWidget * parent)29 QgsMessageBarItem::QgsMessageBarItem( const QString &text, Qgis::MessageLevel level, int duration, QWidget *parent )
30 : QWidget( parent )
31 , mText( text )
32 , mLevel( level )
33 , mDuration( duration )
34 {
35 writeContent();
36 }
37
QgsMessageBarItem(const QString & title,const QString & text,Qgis::MessageLevel level,int duration,QWidget * parent)38 QgsMessageBarItem::QgsMessageBarItem( const QString &title, const QString &text, Qgis::MessageLevel level, int duration, QWidget *parent )
39 : QWidget( parent )
40 , mTitle( title )
41 , mText( text )
42 , mLevel( level )
43 , mDuration( duration )
44 {
45 writeContent();
46 }
47
QgsMessageBarItem(const QString & title,const QString & text,QWidget * widget,Qgis::MessageLevel level,int duration,QWidget * parent)48 QgsMessageBarItem::QgsMessageBarItem( const QString &title, const QString &text, QWidget *widget, Qgis::MessageLevel level, int duration, QWidget *parent )
49 : QWidget( parent )
50 , mTitle( title )
51 , mText( text )
52 , mLevel( level )
53 , mDuration( duration )
54 , mWidget( widget )
55 , mUserIcon( QIcon() )
56
57 {
58 writeContent();
59 }
60
QgsMessageBarItem(QWidget * widget,Qgis::MessageLevel level,int duration,QWidget * parent)61 QgsMessageBarItem::QgsMessageBarItem( QWidget *widget, Qgis::MessageLevel level, int duration, QWidget *parent )
62 : QWidget( parent )
63 , mLevel( level )
64 , mDuration( duration )
65 , mWidget( widget )
66 , mUserIcon( QIcon() )
67
68 {
69 writeContent();
70 }
71
writeContent()72 void QgsMessageBarItem::writeContent()
73 {
74 if ( !mLayout )
75 {
76 mLayout = new QHBoxLayout( this );
77 mLayout->setContentsMargins( 0, 0, 0, 0 );
78 mTextBrowser = nullptr;
79 mLblIcon = nullptr;
80 }
81
82 // ICON
83 if ( !mLblIcon )
84 {
85 mLblIcon = new QLabel( this );
86 mLayout->addWidget( mLblIcon );
87 }
88 QIcon icon;
89 if ( !mUserIcon.isNull() )
90 {
91 icon = mUserIcon;
92 }
93 else
94 {
95 QString msgIcon( QStringLiteral( "/mIconInfo.svg" ) );
96 switch ( mLevel )
97 {
98 case Qgis::Critical:
99 msgIcon = QStringLiteral( "/mIconCritical.svg" );
100 break;
101 case Qgis::Warning:
102 msgIcon = QStringLiteral( "/mIconWarning.svg" );
103 break;
104 case Qgis::Success:
105 msgIcon = QStringLiteral( "/mIconSuccess.svg" );
106 break;
107 default:
108 break;
109 }
110 icon = QgsApplication::getThemeIcon( msgIcon );
111 }
112 const int iconSize = std::max( 24.0, fontMetrics().height() * 1.2 );
113 mLblIcon->setPixmap( icon.pixmap( iconSize ) );
114
115
116 // STYLESHEETS
117 QString contentStyleSheet;
118 if ( mLevel == Qgis::Success )
119 {
120 mStyleSheet = QStringLiteral( "QgsMessageBar { background-color: #dff0d8; border: 1px solid #8e998a; } "
121 "QLabel,QTextEdit { color: black; } " );
122 contentStyleSheet = QStringLiteral( "<style> a, a:visited, a:hover { color:#268300; } </style>" );
123 }
124 else if ( mLevel == Qgis::Critical )
125 {
126 mStyleSheet = QStringLiteral( "QgsMessageBar { background-color: #d65253; border: 1px solid #9b3d3d; } "
127 "QLabel,QTextEdit { color: white; } " );
128 contentStyleSheet = QStringLiteral( "<style>a, a:visited, a:hover { color:#4e0001; }</style>" );
129 }
130 else if ( mLevel == Qgis::Warning )
131 {
132 mStyleSheet = QStringLiteral( "QgsMessageBar { background-color: #ffc800; border: 1px solid #e0aa00; } "
133 "QLabel,QTextEdit { color: black; } " );
134 contentStyleSheet = QStringLiteral( "<style>a, a:visited, a:hover { color:#945a00; }</style>" );
135 }
136 else if ( mLevel == Qgis::Info )
137 {
138 mStyleSheet = QStringLiteral( "QgsMessageBar { background-color: #e7f5fe; border: 1px solid #b9cfe4; } "
139 "QLabel,QTextEdit { color: #2554a1; } " );
140 contentStyleSheet = QStringLiteral( "<style>a, a:visited, a:hover { color:#3bb2fe; }</style>" );
141 }
142 mStyleSheet += QLatin1String( "QLabel#mItemCount { font-style: italic; }" );
143
144 // TITLE AND TEXT
145 if ( mTitle.isEmpty() && mText.isEmpty() )
146 {
147 if ( mTextBrowser )
148 {
149 delete mTextBrowser;
150 mTextBrowser = nullptr;
151 }
152 }
153 else
154 {
155 if ( !mTextBrowser )
156 {
157 mTextBrowser = new QTextBrowser( this );
158 mTextBrowser->setObjectName( QStringLiteral( "textEdit" ) );
159 mTextBrowser->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Maximum );
160 mTextBrowser->setReadOnly( true );
161 mTextBrowser->setOpenLinks( false );
162 connect( mTextBrowser, &QTextBrowser::anchorClicked, this, &QgsMessageBarItem::urlClicked );
163
164 mTextBrowser->setFrameShape( QFrame::NoFrame );
165 // stylesheet set here so Qt-style substitued scrollbar arrows can show within limited height
166 // adjusts to height of font set in app options
167 mTextBrowser->setStyleSheet( "QTextEdit { background-color: rgba(0,0,0,0); margin-top: 0.25em; max-height: 1.75em; min-height: 1.75em; } "
168 "QScrollBar { background-color: rgba(0,0,0,0); } "
169 "QScrollBar::add-page,QScrollBar::sub-page,QScrollBar::handle { background-color: rgba(0,0,0,0); color: rgba(0,0,0,0); } "
170 "QScrollBar::up-arrow,QScrollBar::down-arrow { color: rgb(0,0,0); } " );
171 mLayout->addWidget( mTextBrowser );
172 }
173 QString content = mText;
174 if ( !mTitle.isEmpty() )
175 {
176 // add ':' to end of title
177 QString t = mTitle.trimmed();
178 if ( !content.isEmpty() && !t.endsWith( ':' ) && !t.endsWith( QLatin1String( ": " ) ) )
179 t += QLatin1String( ": " );
180 content.prepend( QStringLiteral( "<b>" ) + t + " </b>" );
181 }
182 content.prepend( contentStyleSheet );
183 mTextBrowser->setText( content );
184 }
185
186 // WIDGET
187 if ( mWidget )
188 {
189 QLayoutItem *item = mLayout->itemAt( 2 );
190 if ( !item || item->widget() != mWidget )
191 {
192 mLayout->addWidget( mWidget );
193 }
194 }
195 }
196
setText(const QString & text)197 QgsMessageBarItem *QgsMessageBarItem::setText( const QString &text )
198 {
199 mText = text;
200 writeContent();
201 return this;
202 }
203
text() const204 QString QgsMessageBarItem::text() const
205 {
206 return mText;
207 }
208
setTitle(const QString & title)209 QgsMessageBarItem *QgsMessageBarItem::setTitle( const QString &title )
210 {
211 mTitle = title;
212 writeContent();
213 return this;
214 }
215
title() const216 QString QgsMessageBarItem::title() const
217 {
218 return mTitle;
219 }
220
setLevel(Qgis::MessageLevel level)221 QgsMessageBarItem *QgsMessageBarItem::setLevel( Qgis::MessageLevel level )
222 {
223 if ( level != mLevel )
224 {
225 mLevel = level;
226 writeContent();
227 emit styleChanged( mStyleSheet );
228 }
229
230 return this;
231 }
232
level() const233 Qgis::MessageLevel QgsMessageBarItem::level() const
234 {
235 return mLevel;
236 }
237
setWidget(QWidget * widget)238 QgsMessageBarItem *QgsMessageBarItem::setWidget( QWidget *widget )
239 {
240 if ( mWidget )
241 {
242 QLayoutItem *item = nullptr;
243 item = mLayout->itemAt( 2 );
244 if ( item->widget() == mWidget )
245 {
246 delete item->widget();
247 }
248 }
249 mWidget = widget;
250 writeContent();
251 return this;
252 }
253
widget() const254 QWidget *QgsMessageBarItem::widget() const
255 {
256 return mWidget;
257 }
258
setIcon(const QIcon & icon)259 QgsMessageBarItem *QgsMessageBarItem::setIcon( const QIcon &icon )
260 {
261 mUserIcon = icon;
262 return this;
263 }
264
icon() const265 QIcon QgsMessageBarItem::icon() const
266 {
267 return mUserIcon;
268 }
269
270
setDuration(int duration)271 QgsMessageBarItem *QgsMessageBarItem::setDuration( int duration )
272 {
273 mDuration = duration;
274 return this;
275 }
276
dismiss()277 void QgsMessageBarItem::dismiss()
278 {
279 if ( !mMessageBar )
280 return;
281
282 mMessageBar->popWidget( this );
283 }
284
urlClicked(const QUrl & url)285 void QgsMessageBarItem::urlClicked( const QUrl &url )
286 {
287 QFileInfo file( url.toLocalFile() );
288 if ( file.exists() && !file.isDir() )
289 QgsGui::instance()->nativePlatformInterface()->openFileExplorerAndSelectFile( url.toLocalFile() );
290 else
291 QDesktopServices::openUrl( url );
292 dismiss();
293 }
294