1 /*
2 Copyright (C) 2002 Kai Sterker <kai.sterker@gmail.com>
3 Part of the Adonthell Project <http://adonthell.nongnu.org>
4
5 Dlgedit is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 Dlgedit is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with Dlgedit. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /**
20 * @file gui_error.cc
21 *
22 * @author Kai Sterker
23 * @brief The error console
24 */
25
26 #include <pango/pango-font.h>
27 #include "gui_dlgedit.h"
28 #include "gui_error.h"
29
30 // callback for selecting an item from the list
on_list_select_child(GtkTreeSelection * selection,gpointer user_data)31 static void on_list_select_child (GtkTreeSelection *selection, gpointer user_data)
32 {
33 GtkTreeModel *model;
34 GtkTreeIter iter;
35
36 // anything selected at all?
37 if (gtk_tree_selection_get_selected (selection, &model, &iter))
38 {
39 // don't show selection
40 gtk_tree_selection_unselect_iter (selection, &iter);
41
42 // ignore edit command if in preview mode
43 if (GuiDlgedit::window->mode () == L10N_PREVIEW) return;
44
45 DlgNode* node;
46 gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 1, &node, -1);
47
48 GuiGraph *graph = GuiDlgedit::window->graph ();
49
50 // select the node where the error occurred
51 graph->deselectNode ();
52 graph->selectNode (node);
53
54 // center the view on it
55 graph->centerNode ();
56
57 // open the edit dialog
58 if (graph->editNode ())
59 {
60 // dialog closed with okay -> assume the error is fixed
61 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
62
63 // close error console if no items remain in the list
64 if (gtk_tree_model_iter_n_children (model, NULL) == 0)
65 gtk_widget_hide (GTK_WIDGET (user_data));
66 }
67 }
68 }
69
70 // callback for closing the window
on_close_clicked(GtkButton * button,gpointer user_data)71 static void on_close_clicked (GtkButton *button, gpointer user_data)
72 {
73 // only hide the window
74 gtk_widget_hide (GTK_WIDGET (user_data));
75 }
76
77 // callback when the window is deleted
on_delete_window(GtkWidget * window)78 static void on_delete_window (GtkWidget *window)
79 {
80 gtk_widget_destroy (window);
81
82 if (GuiError::console)
83 delete GuiError::console;
84 }
85
86 // global pointer to the error console
87 GuiError *GuiError::console = NULL;
88
89 // constructor
GuiError()90 GuiError::GuiError ()
91 {
92 GtkWidget *vbox;
93 GtkWidget *scrolled;
94 GtkWidget *hseparator1;
95 GtkWidget *buttonbox;
96 GtkWidget *close;
97
98 // the error console window
99 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
100 g_object_set_data (G_OBJECT (window), "window", window);
101 gtk_widget_set_size_request (window, 400, 320);
102 gtk_window_set_title (GTK_WINDOW (window), "Error Console");
103 gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
104
105 vbox = gtk_vbox_new (FALSE, 0);
106 g_object_ref (vbox);
107 g_object_set_data_full (G_OBJECT (window), "vbox", vbox, (GDestroyNotify) g_object_unref);
108 gtk_widget_show (vbox);
109 gtk_container_add (GTK_CONTAINER (window), vbox);
110 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
111
112 // vertical scrollbar for the list
113 scrolled = gtk_scrolled_window_new (NULL, NULL);
114 g_object_ref (scrolled);
115 g_object_set_data_full (G_OBJECT (window), "scrolled", scrolled, (GDestroyNotify) g_object_unref);
116 gtk_widget_show (scrolled);
117 gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
118 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
119
120 // the model
121 GtkListStore *model = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING);
122
123 // the list
124 list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
125 g_object_ref (list);
126 gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(list), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL);
127 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list), FALSE);
128 g_object_set_data_full (G_OBJECT (window), "list", list, (GDestroyNotify) g_object_unref);
129 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled), list);
130 gtk_widget_show (list);
131
132 // create the columns
133 GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
134 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW(list), 0, "Errors", renderer, "text", 0, "font", 2, "foreground", 3, NULL);
135
136 // tooltip for the list
137 gtk_widget_set_tooltip_text (window, "Click on an error to bring up the corresponding node");
138
139 hseparator1 = gtk_hseparator_new ();
140 g_object_ref (hseparator1);
141 g_object_set_data_full (G_OBJECT (window), "hseparator1", hseparator1, (GDestroyNotify) g_object_unref);
142 gtk_widget_show (hseparator1);
143 gtk_box_pack_start (GTK_BOX (vbox), hseparator1, FALSE, TRUE, 2);
144
145 buttonbox = gtk_hbutton_box_new ();
146 g_object_ref (buttonbox);
147 g_object_set_data_full (G_OBJECT (window), "buttonbox", buttonbox, (GDestroyNotify) g_object_unref);
148 gtk_widget_show (buttonbox);
149 gtk_box_pack_start (GTK_BOX (vbox), buttonbox, FALSE, TRUE, 0);
150 gtk_button_box_set_layout (GTK_BUTTON_BOX (buttonbox), GTK_BUTTONBOX_END);
151 gtk_box_set_spacing (GTK_BOX (buttonbox), 0);
152
153 // close button
154 close = gtk_button_new_with_label ("Close");
155 g_object_ref (close);
156 g_object_set_data_full (G_OBJECT (window), "close", close, (GDestroyNotify) g_object_unref);
157 gtk_widget_show (close);
158 gtk_container_add (GTK_CONTAINER (buttonbox), close);
159 gtk_container_set_border_width (GTK_CONTAINER (close), 2);
160 gtk_widget_set_can_default (close, TRUE);
161 gtk_widget_set_tooltip_text (close, "Hide the Error Console");
162
163 // selection listener
164 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(list));
165
166 g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK(on_list_select_child), window);
167 g_signal_connect (G_OBJECT (close), "clicked", G_CALLBACK (on_close_clicked), window);
168 g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (on_delete_window), window);
169
170 // give the focus to the close button
171 gtk_widget_grab_focus (close);
172 gtk_widget_grab_default (close);
173
174 // make sure that there is only one error console
175 if (console) delete console;
176 console = this;
177
178 // set transient for dialogue editor main window
179 gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (GuiDlgedit::window->getWindow ()));
180 }
181
182 // dtor
~GuiError()183 GuiError::~GuiError ()
184 {
185 console = NULL;
186 }
187
188 // empty the list
clear()189 void GuiError::clear ()
190 {
191 gtk_widget_hide (list);
192
193 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list));
194 gtk_list_store_clear (GTK_LIST_STORE(model));
195
196 gtk_widget_show (list);
197 }
198
199 // add an error message to the list
add(std::string error,DlgNode * node)200 void GuiError::add (std::string error, DlgNode *node)
201 {
202 GtkTreeIter iter;
203 GdkColor color = { 0, 27500, 0, 0 };
204 GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list));
205 gchar *font_color = gdk_color_to_string(&color);
206
207 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
208 gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0, error.c_str(), 1, node, 2, "Fixed,Monospace 10", 3, font_color, -1);
209
210 g_free(font_color);
211 }
212
213 // display all error messages
display()214 void GuiError::display ()
215 {
216 // show the console
217 gtk_widget_show (window);
218 }
219