1 /***************************************************************************
2           MessageBox.cpp -  threasafe wrapper for KMessageBox
3 			     -------------------
4     begin                : Sun Apr 13 2008
5     copyright            : (C) 2008 by Thomas Eschenbacher
6     email                : Thomas.Eschenbacher@gmx.de
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 "config.h"
19 
20 #include <new>
21 
22 #include <QApplication>
23 #include <QThread>
24 #include <QWidget>
25 
26 #include <KMessageBox>
27 
28 #include "libkwave/MessageBox.h"
29 
30 //***************************************************************************
MessageBox(KMessageBox::DialogType mode,QWidget * parent,QString message,QString caption,const QString & button1,const QString & button2,const QString & dontAskAgainName)31 Kwave::MessageBox::MessageBox(KMessageBox::DialogType mode, QWidget *parent,
32     QString message, QString caption,
33     const QString &button1, const QString &button2,
34     const QString &dontAskAgainName)
35     :QObject(Q_NULLPTR), m_semaphore(0), m_retval(-1),
36      m_mode(mode), m_parent(parent), m_message(message), m_caption(caption),
37      m_button1(button1), m_button2(button2),
38      m_dont_ask_again_name(dontAskAgainName)
39 {
40     if (QThread::currentThread() == QApplication::instance()->thread()) {
41 	// we are already in the GUI thread -> direct call
42 	show();
43     } else {
44 	// schedule execution in the GUI thread ...
45 	Trigger *trigger = new(std::nothrow) Trigger(*this);
46 	Q_ASSERT(trigger);
47 	if (!trigger) return;
48 	trigger->deleteLater();
49 
50 	// ... and wait
51 	m_semaphore.acquire();
52     }
53 }
54 
55 //***************************************************************************
retval() const56 int Kwave::MessageBox::retval() const
57 {
58     return m_retval;
59 }
60 
61 //***************************************************************************
~MessageBox()62 Kwave::MessageBox::~MessageBox()
63 {
64 }
65 
66 //***************************************************************************
questionYesNo(QWidget * parent,QString message,QString caption,const QString buttonYes,const QString buttonNo,const QString & dontAskAgainName)67 int Kwave::MessageBox::questionYesNo(QWidget *parent,
68     QString message, QString caption,
69     const QString buttonYes, const QString buttonNo,
70     const QString &dontAskAgainName)
71 {
72     return Kwave::MessageBox::exec(KMessageBox::QuestionYesNo,
73 	parent, message, caption, buttonYes, buttonNo,
74 	dontAskAgainName);
75 }
76 
77 //***************************************************************************
questionYesNoCancel(QWidget * parent,QString message,QString caption,const QString buttonYes,const QString buttonNo,const QString & dontAskAgainName)78 int Kwave::MessageBox::questionYesNoCancel(QWidget *parent,
79     QString message, QString caption,
80     const QString buttonYes, const QString buttonNo,
81     const QString &dontAskAgainName)
82 {
83     return Kwave::MessageBox::exec(KMessageBox::QuestionYesNoCancel,
84 	parent, message, caption, buttonYes, buttonNo,
85 	dontAskAgainName);
86 }
87 
88 //***************************************************************************
sorry(QWidget * parent,QString message,QString caption)89 int Kwave::MessageBox::sorry(QWidget *parent,
90     QString message, QString caption)
91 {
92     return Kwave::MessageBox::exec(KMessageBox::Sorry,
93 	parent, message, caption);
94 }
95 
96 //***************************************************************************
warningYesNo(QWidget * parent,QString message,QString caption,const QString buttonYes,const QString buttonNo,const QString & dontAskAgainName)97 int Kwave::MessageBox::warningYesNo(QWidget *parent,
98     QString message, QString caption,
99     const QString buttonYes, const QString buttonNo,
100     const QString &dontAskAgainName)
101 {
102     return Kwave::MessageBox::exec(KMessageBox::WarningYesNo,
103 	parent, message, caption, buttonYes, buttonNo,
104 	dontAskAgainName);
105 }
106 
107 //***************************************************************************
warningYesNoCancel(QWidget * parent,QString message,QString caption,const QString buttonYes,const QString buttonNo,const QString & dontAskAgainName)108 int Kwave::MessageBox::warningYesNoCancel(QWidget *parent,
109     QString message, QString caption,
110     const QString buttonYes, const QString buttonNo,
111     const QString &dontAskAgainName)
112 {
113     return Kwave::MessageBox::exec(KMessageBox::WarningYesNoCancel,
114 	parent, message, caption, buttonYes, buttonNo,
115 	dontAskAgainName);
116 }
117 
118 //***************************************************************************
warningContinueCancel(QWidget * parent,QString message,QString caption,const QString buttonContinue,const QString buttonCancel,const QString & dontAskAgainName)119 int Kwave::MessageBox::warningContinueCancel(QWidget *parent,
120     QString message, QString caption,
121     const QString buttonContinue, const QString buttonCancel,
122     const QString &dontAskAgainName)
123 {
124     return Kwave::MessageBox::exec(KMessageBox::WarningContinueCancel,
125 	parent, message, caption, buttonContinue, buttonCancel,
126 	dontAskAgainName);
127 }
128 
129 //***************************************************************************
error(QWidget * parent,QString message,QString caption)130 int Kwave::MessageBox::error(QWidget *parent,
131     QString message, QString caption)
132 {
133     return Kwave::MessageBox::exec(KMessageBox::Error,
134 	parent, message, caption);
135 }
136 
137 //***************************************************************************
exec(KMessageBox::DialogType mode,QWidget * parent,QString message,QString caption,const QString & button1,const QString & button2,const QString & dontAskAgainName)138 int Kwave::MessageBox::exec(KMessageBox::DialogType mode, QWidget *parent,
139     QString message, QString caption,
140     const QString &button1, const QString &button2,
141     const QString &dontAskAgainName)
142 {
143     Kwave::MessageBox box(
144 	mode, parent, message, caption,
145 	button1, button2,
146 	dontAskAgainName
147     );
148     return box.retval();
149 }
150 
151 //***************************************************************************
show()152 void Kwave::MessageBox::show()
153 {
154     switch (m_mode) {
155 	// QuestionYesNo
156 	case KMessageBox::QuestionYesNo:
157 	    m_retval = KMessageBox::questionYesNo(m_parent,
158 		m_message, m_caption,
159 		(!m_button1.isEmpty()) ? KGuiItem(m_button1) :
160 		                         KStandardGuiItem::yes(),
161 		(!m_button2.isEmpty()) ? KGuiItem(m_button2) :
162 		                         KStandardGuiItem::no(),
163 		m_dont_ask_again_name);
164 	    break;
165 	// QuestionYesNoCancel
166 	case KMessageBox::QuestionYesNoCancel:
167 	    m_retval = KMessageBox::questionYesNoCancel(m_parent,
168 		m_message, m_caption,
169 		(!m_button1.isEmpty()) ? KGuiItem(m_button1) :
170 		                         KStandardGuiItem::yes(),
171 		(!m_button2.isEmpty()) ? KGuiItem(m_button2) :
172 		                         KStandardGuiItem::no(),
173 		KStandardGuiItem::cancel(),
174 		m_dont_ask_again_name);
175 	    break;
176 	// Sorry
177 	case KMessageBox::Sorry:
178 	    KMessageBox::sorry(m_parent, m_message, m_caption);
179 	    break;
180 	// WarningYesNoCancel
181 	case KMessageBox::WarningYesNoCancel:
182 	    m_retval = KMessageBox::warningYesNoCancel(m_parent,
183 		m_message, m_caption,
184 		(!m_button1.isEmpty()) ? KGuiItem(m_button1) :
185 		                         KStandardGuiItem::yes(),
186 		(!m_button2.isEmpty()) ? KGuiItem(m_button2) :
187 		                         KStandardGuiItem::no(),
188 		KStandardGuiItem::cancel(),
189 		m_dont_ask_again_name);
190 	    break;
191 	// WarningYesNo
192 	case KMessageBox::WarningYesNo:
193 	    m_retval = KMessageBox::warningYesNo(m_parent,
194 		m_message, m_caption,
195 		(!m_button1.isEmpty()) ? KGuiItem(m_button1) :
196 		                         KStandardGuiItem::yes(),
197 		(!m_button2.isEmpty()) ? KGuiItem(m_button2) :
198 		                         KStandardGuiItem::no(),
199 		m_dont_ask_again_name);
200 	    break;
201 	// WarningContinueCancel
202 	case KMessageBox::WarningContinueCancel:
203 	    m_retval = KMessageBox::warningContinueCancel(m_parent,
204 		m_message, m_caption,
205 		(!m_button1.isEmpty()) ? KGuiItem(m_button1) :
206 		                         KStandardGuiItem::cont(),
207 		(!m_button2.isEmpty()) ? KGuiItem(m_button2) :
208 		                         KStandardGuiItem::cancel(),
209 		m_dont_ask_again_name);
210 	    break;
211 	// Error
212 	case KMessageBox::Error:
213 	    KMessageBox::error(m_parent, m_message, m_caption);
214 	    break;
215 	case KMessageBox::Information:
216 	    KMessageBox::information(m_parent, m_message, m_caption,
217 	                             m_dont_ask_again_name);
218 	    break;
219 	default:
220 	    qWarning("unsupported messagebox mode");
221 	    Q_ASSERT(0);
222     }
223 
224     m_semaphore.release();
225 }
226 
227 //***************************************************************************
Trigger(Kwave::MessageBox & box)228 Kwave::MessageBox::Trigger::Trigger(Kwave::MessageBox &box)
229     :QObject(Q_NULLPTR), m_box(box)
230 {
231     moveToThread(QApplication::instance()->thread());
232 }
233 
234 //***************************************************************************
~Trigger()235 Kwave::MessageBox::Trigger::~Trigger()
236 {
237     m_box.show();
238 }
239 
240 //***************************************************************************
241 //***************************************************************************
242