1 /*
2 * A very simple dialog for displaying Inkscape messages. Messages
3 * sent to g_log(), g_warning(), g_message(), ets, are routed here,
4 * in order to avoid messing with the startup console.
5 *
6 * Authors:
7 * Bob Jamison
8 * Other dudes from The Inkscape Organization
9 *
10 * Copyright (C) 2004 The Inkscape Organization
11 *
12 * Released under GNU GPL, read the file 'COPYING' for more information
13 */
14 #ifdef HAVE_CONFIG_H
15 # include <config.h>
16 #endif
18 #include <glibmm/i18n.h>
19 #include <gtkmm/box.h>
20 #include <gtkmm/dialog.h>
21 #include <gtkmm/textview.h>
22 #include <gtkmm/button.h>
23 #include <gtkmm/menubar.h>
24 #include <gtkmm/scrolledwindow.h>
26 #include "debugdialog.h"
28 namespace Inkscape {
29 namespace UI {
30 namespace Dialogs {
33 //#########################################################################
34 //## I M P L E M E N T A T I O N
35 //#########################################################################
37 /**
38 * A dialog that displays log messages
39 */
40 class DebugDialogImpl : public DebugDialog, public Gtk::Dialog
41 {
43 public:
46 /**
47 * Constructor
48 */
49 DebugDialogImpl();
51 /**
52 * Destructor
53 */
54 ~DebugDialogImpl();
57 /**
58 * Show the dialog
59 */
60 void show();
62 /**
63 * Do not show the dialog
64 */
65 void hide();
67 /**
68 * Clear all information from the dialog
69 */
70 void clear();
72 /**
73 * Display a message
74 */
75 void message(char const *msg);
77 /**
78 * Redirect g_log() messages to this widget
79 */
80 void captureLogMessages();
82 /**
83 * Return g_log() messages to normal handling
84 */
85 void releaseLogMessages();
89 private:
92 Gtk::MenuBar menuBar;
94 Gtk::Menu fileMenu;
96 Gtk::ScrolledWindow textScroll;
98 Gtk::TextView messageText;
100 //Handler ID's
101 guint handlerDefault;
102 guint handlerGlibmm;
103 guint handlerAtkmm;
104 guint handlerPangomm;
105 guint handlerGdkmm;
106 guint handlerGtkmm;
108 };
113 //#########################################################################
114 //## E V E N T S
115 //#########################################################################
117 /**
118 * Also a public method. Remove all text from the dialog
119 */
120 void DebugDialogImpl::clear()
121 {
122 Glib::RefPtr<Gtk::TextBuffer> buffer = messageText.get_buffer();
123 buffer->erase(buffer->begin(), buffer->end());
124 }
127 //#########################################################################
128 //## C O N S T R U C T O R / D E S T R U C T O R
129 //#########################################################################
130 /**
131 * Constructor
132 */
133 DebugDialogImpl::DebugDialogImpl()
134 {
135 set_title(_("Messages"));
136 set_size_request(300, 400);
138 Gtk::VBox *mainVBox = get_vbox();
140 //## Add a menu for clear()
141 menuBar.items().push_back( Gtk::Menu_Helpers::MenuElem(_("_File"), fileMenu) );
142 fileMenu.items().push_back( Gtk::Menu_Helpers::MenuElem(_("_Clear"),
143 sigc::mem_fun(*this, &DebugDialogImpl::clear) ) );
144 fileMenu.items().push_back( Gtk::Menu_Helpers::MenuElem(_("Capture log messages"),
145 sigc::mem_fun(*this, &DebugDialogImpl::captureLogMessages) ) );
146 fileMenu.items().push_back( Gtk::Menu_Helpers::MenuElem(_("Release log messages"),
147 sigc::mem_fun(*this, &DebugDialogImpl::releaseLogMessages) ) );
148 mainVBox->pack_start(menuBar, Gtk::PACK_SHRINK);
151 //### Set up the text widget
152 messageText.set_editable(false);
153 textScroll.add(messageText);
154 textScroll.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
155 mainVBox->pack_start(textScroll);
157 show_all_children();
159 message("ready.");
160 message("enable log display by setting ");
161 message("dialogs.debug 'redirect' attribute to 1 in preferences.xml");
163 handlerDefault = 0;
164 handlerGlibmm = 0;
165 handlerAtkmm = 0;
166 handlerPangomm = 0;
167 handlerGdkmm = 0;
168 handlerGtkmm = 0;
169 }
171 /**
172 * Factory method. Use this to create a new DebugDialog
173 */
174 DebugDialog *DebugDialog::create()
175 {
176 DebugDialog *dialog = new DebugDialogImpl();
177 return dialog;
178 }
181 /**
182 * Constructor
183 */
184 DebugDialogImpl::~DebugDialogImpl()
185 {
188 }
191 //#########################################################################
192 //## M E T H O D S
193 //#########################################################################
195 void DebugDialogImpl::show()
196 {
197 //call super()
198 Gtk::Dialog::show();
199 //sp_transientize((GtkWidget *)gobj()); //Make transient
200 raise();
201 Gtk::Dialog::present();
202 }
206 void DebugDialogImpl::hide()
207 {
208 //call super()
209 Gtk::Dialog::hide();
210 }
214 void DebugDialogImpl::message(char const *msg)
215 {
216 Glib::RefPtr<Gtk::TextBuffer> buffer = messageText.get_buffer();
217 Glib::ustring uMsg = msg;
218 if (uMsg[uMsg.length()-1] != '\n')
219 uMsg += '\n';
220 buffer->insert (buffer->end(), uMsg);
221 }
224 /* static instance, to reduce dependencies */
225 static DebugDialog *debugDialogInstance = NULL;
227 DebugDialog *DebugDialog::getInstance()
228 {
229 if ( !debugDialogInstance )
230 {
231 debugDialogInstance = new DebugDialogImpl();
232 }
233 return debugDialogInstance;
234 }
238 void DebugDialog::showInstance()
239 {
240 DebugDialog *debugDialog = getInstance();
241 debugDialog->show();
242 }
247 /*##### THIS IS THE IMPORTANT PART ##### */
248 void dialogLoggingFunction(const gchar *log_domain,
249 GLogLevelFlags log_level,
250 const gchar *messageText,
251 gpointer user_data)
252 {
253 DebugDialogImpl *dlg = (DebugDialogImpl *)user_data;
255 dlg->message(messageText);
257 }
260 void DebugDialogImpl::captureLogMessages()
261 {
262 /*
263 This might likely need more code, to capture Gtkmm
264 and Glibmm warnings, or maybe just simply grab stdout/stderr
265 */
266 GLogLevelFlags flags = (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL |
267 G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE |
268 G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG);
269 if ( !handlerDefault )
270 {
271 handlerDefault = g_log_set_handler(NULL, flags,
272 dialogLoggingFunction, (gpointer)this);
273 }
274 if ( !handlerGlibmm )
275 {
276 handlerGlibmm = g_log_set_handler("glibmm", flags,
277 dialogLoggingFunction, (gpointer)this);
278 }
279 if ( !handlerAtkmm )
280 {
281 handlerAtkmm = g_log_set_handler("atkmm", flags,
282 dialogLoggingFunction, (gpointer)this);
283 }
284 if ( !handlerPangomm )
285 {
286 handlerPangomm = g_log_set_handler("pangomm", flags,
287 dialogLoggingFunction, (gpointer)this);
288 }
289 if ( !handlerGdkmm )
290 {
291 handlerGdkmm = g_log_set_handler("gdkmm", flags,
292 dialogLoggingFunction, (gpointer)this);
293 }
294 if ( !handlerGtkmm )
295 {
296 handlerGtkmm = g_log_set_handler("gtkmm", flags,
297 dialogLoggingFunction, (gpointer)this);
298 }
299 message("log capture started");
300 }
302 void DebugDialogImpl::releaseLogMessages()
303 {
304 if ( handlerDefault )
305 {
306 g_log_remove_handler(NULL, handlerDefault);
307 handlerDefault = 0;
308 }
309 if ( handlerGlibmm )
310 {
311 g_log_remove_handler("glibmm", handlerGlibmm);
312 handlerGlibmm = 0;
313 }
314 if ( handlerAtkmm )
315 {
316 g_log_remove_handler("atkmm", handlerAtkmm);
317 handlerAtkmm = 0;
318 }
319 if ( handlerPangomm )
320 {
321 g_log_remove_handler("pangomm", handlerPangomm);
322 handlerPangomm = 0;
323 }
324 if ( handlerGdkmm )
325 {
326 g_log_remove_handler("gdkmm", handlerGdkmm);
327 handlerGdkmm = 0;
328 }
329 if ( handlerGtkmm )
330 {
331 g_log_remove_handler("gtkmm", handlerGtkmm);
332 handlerGtkmm = 0;
333 }
334 message("log capture discontinued");
335 }
339 } //namespace Dialogs
340 } //namespace UI
341 } //namespace Inkscape
343 //#########################################################################
344 //## E N D O F F I L E
345 //#########################################################################