1 /**
2  * \file messagedialog.cpp
3  * Message dialog.
4  *
5  * \b Project: Kid3
6  * \author Urs Fleisch
7  * \date 18 Aug 2011
8  *
9  * Copyright (C) 2011-2018  Urs Fleisch
10  *
11  * This file is part of Kid3.
12  *
13  * Kid3 is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * Kid3 is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25  */
26 
27 #include "messagedialog.h"
28 #include <QLabel>
29 #include <QTextEdit>
30 #include <QDialogButtonBox>
31 #include <QVBoxLayout>
32 #include <QStyle>
33 #include <QIcon>
34 #include <QPushButton>
35 
36 /**
37  * Constructor.
38  *
39  * @param parent parent widget
40  */
MessageDialog(QWidget * parent)41 MessageDialog::MessageDialog(QWidget* parent)
42   : QDialog(parent)
43 {
44   setObjectName(QLatin1String("MessageDialog"));
45   auto vlayout = new QVBoxLayout(this);
46 
47   auto hlayout = new QHBoxLayout;
48   m_iconLabel = new QLabel;
49   m_iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
50   hlayout->addWidget(m_iconLabel);
51   m_textLabel = new QLabel;
52   m_textLabel->setWordWrap(true);
53   m_textLabel->setMinimumSize(50, 50);
54   hlayout->addWidget(m_textLabel);
55   vlayout->addLayout(hlayout);
56 
57   m_textEdit = new QTextEdit;
58   m_textEdit->setFocusPolicy(Qt::NoFocus);
59   m_textEdit->setReadOnly(true);
60   m_textEdit->hide();
61   vlayout->addWidget(m_textEdit);
62 
63   m_buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
64   m_buttonBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
65   connect(m_buttonBox, &QDialogButtonBox::clicked,
66           this, &MessageDialog::buttonClicked);
67   vlayout->addWidget(m_buttonBox);
68 }
69 
70 /**
71  * Set the text to be displayed.
72  *
73  * @param text message text.
74  */
setText(const QString & text)75 void MessageDialog::setText(const QString &text)
76 {
77   m_textLabel->setText(text);
78 }
79 
80 /**
81  * Set the informative text.
82    * This text can be large and is displayed in a text edit.
83  *
84  * @param text message text.
85  */
setInformativeText(const QString & text)86 void MessageDialog::setInformativeText(const QString& text)
87 {
88   m_textEdit->setText(text);
89   const QStringList lines = text.split(QLatin1Char('\n'));
90   QFontMetrics fm(m_textEdit->fontMetrics());
91   int maxWidth = 0;
92   for (const QString& line : lines) {
93 #if QT_VERSION >= 0x050b00
94     int lineWidth = fm.horizontalAdvance(line);
95 #else
96     int lineWidth = fm.width(line);
97 #endif
98     if (maxWidth < lineWidth) {
99       maxWidth = lineWidth;
100     }
101   }
102 #if QT_VERSION >= 0x050b00
103   maxWidth += fm.horizontalAdvance(QLatin1String("WW")); // some space for the borders
104 #else
105   maxWidth += fm.width(QLatin1String("WW")); // some space for the borders
106 #endif
107 
108   if (maxWidth <= 1000) {
109     m_textEdit->setMinimumWidth(maxWidth);
110     m_textEdit->setWordWrapMode(QTextOption::NoWrap);
111   } else {
112     m_textEdit->setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
113   }
114 
115   if (text.isEmpty()) {
116     m_textEdit->hide();
117   } else {
118     m_textEdit->show();
119   }
120 }
121 
122 /**
123  * Set the message box's icon.
124  *
125  * @param icon icon to be displayed
126  */
setIcon(QMessageBox::Icon icon)127 void MessageDialog::setIcon(QMessageBox::Icon icon)
128 {
129   QStyle::StandardPixmap sp = QStyle::SP_MessageBoxQuestion;
130   bool hasIcon = true;
131   switch (icon) {
132   case QMessageBox::Question:
133     sp = QStyle::SP_MessageBoxQuestion;
134     break;
135   case QMessageBox::Information:
136     sp = QStyle::SP_MessageBoxInformation;
137     break;
138   case QMessageBox::Warning:
139     sp = QStyle::SP_MessageBoxWarning;
140     break;
141   case QMessageBox::Critical:
142     sp = QStyle::SP_MessageBoxCritical;
143     break;
144   case QMessageBox::NoIcon:
145   default:
146     hasIcon = false;
147   }
148   if (hasIcon) {
149     QStyle* widgetStyle = style();
150     int iconSize = widgetStyle->pixelMetric(
151           QStyle::PM_MessageBoxIconSize, nullptr, this);
152     m_iconLabel->setPixmap(widgetStyle->standardIcon(sp, nullptr, this)
153                            .pixmap(iconSize, iconSize));
154   } else {
155     m_iconLabel->setPixmap(QPixmap());
156   }
157 }
158 
159 /**
160  * Set buttons to be displayed.
161  *
162  * @param buttons buttons to be displayed
163  */
setStandardButtons(QMessageBox::StandardButtons buttons)164 void MessageDialog::setStandardButtons(QMessageBox::StandardButtons buttons)
165 {
166   m_buttonBox->setStandardButtons(
167         QDialogButtonBox::StandardButtons(static_cast<int>(buttons)));
168 }
169 
170 /**
171  * Set default button.
172  *
173  * @param button button which gets default focus
174  */
setDefaultButton(QMessageBox::StandardButton button)175 void MessageDialog::setDefaultButton(QMessageBox::StandardButton button)
176 {
177   m_buttonBox->button(static_cast<QDialogButtonBox::StandardButton>(button))->
178       setDefault(true);
179 }
180 
181 /**
182  * Called when a button is clicked.
183  *
184  * @param button button which was clicked
185  */
buttonClicked(QAbstractButton * button)186 void MessageDialog::buttonClicked(QAbstractButton* button)
187 {
188   done(m_buttonBox->standardButton(button));
189 }
190 
191 /**
192  * Display a modal dialog with a list of items.
193  *
194  * @param parent parent widget
195  * @param title dialog title
196  * @param text dialog text
197  * @param list list of items
198  * @param buttons buttons shown
199  *
200  * @return QMessageBox::StandardButton code of pressed button.
201  */
warningList(QWidget * parent,const QString & title,const QString & text,const QStringList & list,QMessageBox::StandardButtons buttons)202 int MessageDialog::warningList(
203   QWidget* parent, const QString& title,
204   const QString& text, const QStringList& list,
205   QMessageBox::StandardButtons buttons)
206 {
207   MessageDialog dialog(parent);
208   dialog.setWindowTitle(title);
209   dialog.setText(text);
210   dialog.setInformativeText(list.join(QLatin1String("\n")));
211   dialog.setIcon(QMessageBox::Warning);
212   dialog.setStandardButtons(buttons);
213   return dialog.exec();
214 }
215