1 /** @file
2 * @brief A dialog that displays log messages
3 */
4 /* Authors:
5 * Bob Jamison
6 * Other dudes from The Inkscape Organization
7 *
8 * Copyright (C) 2004 The Inkscape Organization
9 * Released under GNU GPL, read the file 'COPYING' for more information
10 */
11 #ifdef HAVE_CONFIG_H
12 # include <config.h>
13 #endif
15 #include <glibmm/i18n.h>
16 #include <gtkmm/box.h>
17 #include <gtkmm/dialog.h>
18 #include <gtkmm/textview.h>
19 #include <gtkmm/button.h>
20 #include <gtkmm/menubar.h>
21 #include <gtkmm/scrolledwindow.h>
23 #include "debug.h"
25 namespace Inkscape {
26 namespace UI {
27 namespace Dialog {
29 /**
30 * @brief A very simple dialog for displaying Inkscape messages - implementation
31 */
32 class DebugDialogImpl : public DebugDialog, public Gtk::Dialog
33 {
34 public:
35 DebugDialogImpl();
36 ~DebugDialogImpl();
38 void show();
39 void hide();
40 void clear();
41 void message(char const *msg);
42 void captureLogMessages();
43 void releaseLogMessages();
45 private:
46 Gtk::MenuBar menuBar;
47 Gtk::Menu fileMenu;
48 Gtk::ScrolledWindow textScroll;
49 Gtk::TextView messageText;
51 //Handler ID's
52 guint handlerDefault;
53 guint handlerGlibmm;
54 guint handlerAtkmm;
55 guint handlerPangomm;
56 guint handlerGdkmm;
57 guint handlerGtkmm;
58 };
60 void DebugDialogImpl::clear()
61 {
62 Glib::RefPtr<Gtk::TextBuffer> buffer = messageText.get_buffer();
63 buffer->erase(buffer->begin(), buffer->end());
64 }
66 DebugDialogImpl::DebugDialogImpl()
67 {
68 set_title(_("Messages"));
69 set_size_request(300, 400);
71 Gtk::VBox *mainVBox = get_vbox();
73 //## Add a menu for clear()
74 menuBar.items().push_back( Gtk::Menu_Helpers::MenuElem(_("_File"), fileMenu) );
75 fileMenu.items().push_back( Gtk::Menu_Helpers::MenuElem(_("_Clear"),
76 sigc::mem_fun(*this, &DebugDialogImpl::clear) ) );
77 fileMenu.items().push_back( Gtk::Menu_Helpers::MenuElem(_("Capture log messages"),
78 sigc::mem_fun(*this, &DebugDialogImpl::captureLogMessages) ) );
79 fileMenu.items().push_back( Gtk::Menu_Helpers::MenuElem(_("Release log messages"),
80 sigc::mem_fun(*this, &DebugDialogImpl::releaseLogMessages) ) );
81 mainVBox->pack_start(menuBar, Gtk::PACK_SHRINK);
84 //### Set up the text widget
85 messageText.set_editable(false);
86 textScroll.add(messageText);
87 textScroll.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS);
88 mainVBox->pack_start(textScroll);
90 show_all_children();
92 message("ready.");
93 message("enable log display by setting ");
94 message("dialogs.debug 'redirect' attribute to 1 in preferences.xml");
96 handlerDefault = 0;
97 handlerGlibmm = 0;
98 handlerAtkmm = 0;
99 handlerPangomm = 0;
100 handlerGdkmm = 0;
101 handlerGtkmm = 0;
102 }
105 DebugDialog *DebugDialog::create()
106 {
107 DebugDialog *dialog = new DebugDialogImpl();
108 return dialog;
109 }
111 DebugDialogImpl::~DebugDialogImpl()
112 {
113 }
115 void DebugDialogImpl::show()
116 {
117 //call super()
118 Gtk::Dialog::show();
119 //sp_transientize((GtkWidget *)gobj()); //Make transient
120 raise();
121 Gtk::Dialog::present();
122 }
124 void DebugDialogImpl::hide()
125 {
126 // call super
127 Gtk::Dialog::hide();
128 }
130 void DebugDialogImpl::message(char const *msg)
131 {
132 Glib::RefPtr<Gtk::TextBuffer> buffer = messageText.get_buffer();
133 Glib::ustring uMsg = msg;
134 if (uMsg[uMsg.length()-1] != '\n')
135 uMsg += '\n';
136 buffer->insert (buffer->end(), uMsg);
137 }
139 /* static instance, to reduce dependencies */
140 static DebugDialog *debugDialogInstance = NULL;
142 DebugDialog *DebugDialog::getInstance()
143 {
144 if (!debugDialogInstance) {
145 debugDialogInstance = new DebugDialogImpl();
146 }
147 return debugDialogInstance;
148 }
152 void DebugDialog::showInstance()
153 {
154 DebugDialog *debugDialog = getInstance();
155 debugDialog->show();
156 }
161 /*##### THIS IS THE IMPORTANT PART ##### */
162 void dialogLoggingFunction(const gchar */*log_domain*/,
163 GLogLevelFlags /*log_level*/,
164 const gchar *messageText,
165 gpointer user_data)
166 {
167 DebugDialogImpl *dlg = (DebugDialogImpl *)user_data;
168 dlg->message(messageText);
169 }
172 void DebugDialogImpl::captureLogMessages()
173 {
174 /*
175 This might likely need more code, to capture Gtkmm
176 and Glibmm warnings, or maybe just simply grab stdout/stderr
177 */
178 GLogLevelFlags flags = (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL |
179 G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE |
180 G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG);
181 if ( !handlerDefault ) {
182 handlerDefault = g_log_set_handler(NULL, flags,
183 dialogLoggingFunction, (gpointer)this);
184 }
185 if ( !handlerGlibmm ) {
186 handlerGlibmm = g_log_set_handler("glibmm", flags,
187 dialogLoggingFunction, (gpointer)this);
188 }
189 if ( !handlerAtkmm ) {
190 handlerAtkmm = g_log_set_handler("atkmm", flags,
191 dialogLoggingFunction, (gpointer)this);
192 }
193 if ( !handlerPangomm ) {
194 handlerPangomm = g_log_set_handler("pangomm", flags,
195 dialogLoggingFunction, (gpointer)this);
196 }
197 if ( !handlerGdkmm ) {
198 handlerGdkmm = g_log_set_handler("gdkmm", flags,
199 dialogLoggingFunction, (gpointer)this);
200 }
201 if ( !handlerGtkmm ) {
202 handlerGtkmm = g_log_set_handler("gtkmm", flags,
203 dialogLoggingFunction, (gpointer)this);
204 }
205 message("log capture started");
206 }
208 void DebugDialogImpl::releaseLogMessages()
209 {
210 if ( handlerDefault ) {
211 g_log_remove_handler(NULL, handlerDefault);
212 handlerDefault = 0;
213 }
214 if ( handlerGlibmm ) {
215 g_log_remove_handler("glibmm", handlerGlibmm);
216 handlerGlibmm = 0;
217 }
218 if ( handlerAtkmm ) {
219 g_log_remove_handler("atkmm", handlerAtkmm);
220 handlerAtkmm = 0;
221 }
222 if ( handlerPangomm ) {
223 g_log_remove_handler("pangomm", handlerPangomm);
224 handlerPangomm = 0;
225 }
226 if ( handlerGdkmm ) {
227 g_log_remove_handler("gdkmm", handlerGdkmm);
228 handlerGdkmm = 0;
229 }
230 if ( handlerGtkmm ) {
231 g_log_remove_handler("gtkmm", handlerGtkmm);
232 handlerGtkmm = 0;
233 }
234 message("log capture discontinued");
235 }
239 } //namespace Dialogs
240 } //namespace UI
241 } //namespace Inkscape
243 /*
244 Local Variables:
245 mode:c++
246 c-file-style:"stroustrup"
247 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
248 indent-tabs-mode:nil
249 fill-column:99
250 End:
251 */
252 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :