1 /*
2  *      btnpanel.c
3  *
4  *      Copyright 2010 Alexander Petukhov <devel(at)apetukhov.ru>
5  *
6  *      This program is free software; you can redistribute it and/or modify
7  *      it under the terms of the GNU General Public License as published by
8  *      the Free Software Foundation; either version 2 of the License, or
9  *      (at your option) any later version.
10  *
11  *      This program is distributed in the hope that it will be useful,
12  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *      GNU General Public License for more details.
15  *
16  *      You should have received a copy of the GNU General Public License
17  *      along with this program; if not, write to the Free Software
18  *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  *      MA 02110-1301, USA.
20  */
21 
22 /*
23  * 		buttons panel
24  */
25 
26 #include <sys/stat.h>
27 
28 #ifdef HAVE_CONFIG_H
29 	#include "config.h"
30 #endif
31 #include <geanyplugin.h>
32 
33 extern GeanyPlugin		*geany_plugin;
34 
35 #include "gui.h"
36 #include "breakpoints.h"
37 #include "debug.h"
38 #include "dconfig.h"
39 #include "tpage.h"
40 #include "watch_model.h"
41 #include "wtree.h"
42 #include "dpaned.h"
43 #include "btnpanel.h"
44 
45 #define CP_BUTTONS_PAD 5
46 
47 static GtkWidget *runbtn = NULL;
48 static GtkWidget *restartbtn = NULL;
49 static GtkWidget *stopbtn = NULL;
50 
51 static GtkWidget *stepoverbtn = NULL;
52 static GtkWidget *stepinbtn = NULL;
53 static GtkWidget *stepoutbtn = NULL;
54 static GtkWidget *runcursorbtn = NULL;
55 
56 static GtkWidget *tabbtn = NULL;
57 static GtkWidget *optbtn = NULL;
58 
59 /*
60  * calls settings dialog
61  */
on_settings(GtkButton * button,gpointer user_data)62 static void on_settings(GtkButton *button, gpointer user_data)
63 {
64 	plugin_show_configure(geany_plugin);
65 }
66 
67 /*
68  * gets current file and line and calls debug function
69  */
on_execute_until(GtkButton * button,gpointer user_data)70 static void on_execute_until(GtkButton *button, gpointer user_data)
71 {
72 	GeanyDocument *doc = document_get_current();
73 	if (doc)
74 	{
75 		int line = sci_get_current_line(doc->editor->sci) + 1;
76 		debug_execute_until(DOC_FILENAME(doc), line);
77 	}
78 }
79 
80 /*
81  * create and initialize buttons panel
82  */
btnpanel_create(on_toggle cb)83 GtkWidget* btnpanel_create(on_toggle cb)
84 {
85 #if GTK_CHECK_VERSION(3, 0, 0)
86 	GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, CP_BUTTONS_PAD);
87 	GtkWidget *hbutton_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, CP_BUTTONS_PAD);
88 #else
89 	GtkWidget *vbox = gtk_vbox_new(FALSE, CP_BUTTONS_PAD);
90 	GtkWidget *hbutton_box = gtk_hbox_new(FALSE, CP_BUTTONS_PAD);
91 #endif
92 
93 	runbtn = create_button("run.gif", _("Run"));
94 	g_signal_connect(G_OBJECT(runbtn), "clicked", G_CALLBACK (debug_run), (gpointer)TRUE);
95 
96 	gtk_box_pack_start(GTK_BOX(hbutton_box), runbtn, TRUE, TRUE, 0);
97 	gtk_box_pack_start(GTK_BOX(vbox), hbutton_box, FALSE, TRUE, 0);
98 
99 #if GTK_CHECK_VERSION(3, 0, 0)
100 	hbutton_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, CP_BUTTONS_PAD);
101 	gtk_box_set_homogeneous(GTK_BOX(hbutton_box), TRUE);
102 #else
103 	hbutton_box = gtk_hbox_new(TRUE, CP_BUTTONS_PAD);
104 #endif
105 
106 	restartbtn = create_button("restart.gif", _("Restart"));
107 	g_signal_connect(G_OBJECT(restartbtn), "clicked", G_CALLBACK (debug_restart), (gpointer)TRUE);
108 
109 	stopbtn = create_button("stop.gif", _("Stop"));
110 	g_signal_connect(G_OBJECT(stopbtn), "clicked", G_CALLBACK (debug_stop), (gpointer)TRUE);
111 
112 	gtk_box_pack_start(GTK_BOX(hbutton_box), restartbtn, FALSE, TRUE, 0);
113 	gtk_box_pack_start(GTK_BOX(hbutton_box), stopbtn, FALSE, TRUE, 0);
114 	gtk_box_pack_start(GTK_BOX(vbox), hbutton_box, FALSE, TRUE, 0);
115 
116 #if GTK_CHECK_VERSION(3, 0, 0)
117 	hbutton_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, CP_BUTTONS_PAD);
118 	gtk_box_set_homogeneous(GTK_BOX(hbutton_box), TRUE);
119 #else
120 	hbutton_box = gtk_hbox_new(TRUE, CP_BUTTONS_PAD);
121 #endif
122 
123 	stepoverbtn = create_button("step_over.gif", _("Step over"));
124 	g_signal_connect(G_OBJECT(stepoverbtn), "clicked", G_CALLBACK (debug_step_over), (gpointer)TRUE);
125 
126 	stepinbtn = create_button("step_in.png", _("Step into"));
127 	g_signal_connect(G_OBJECT(stepinbtn), "clicked", G_CALLBACK (debug_step_into), (gpointer)TRUE);
128 
129 	gtk_box_pack_start(GTK_BOX(hbutton_box), stepoverbtn, FALSE, TRUE, 0);
130 	gtk_box_pack_start(GTK_BOX(hbutton_box), stepinbtn, FALSE, TRUE, 0);
131 	gtk_box_pack_start(GTK_BOX(vbox), hbutton_box, FALSE, TRUE, 0);
132 
133 #if GTK_CHECK_VERSION(3, 0, 0)
134 	hbutton_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, CP_BUTTONS_PAD);
135 	gtk_box_set_homogeneous(GTK_BOX(hbutton_box), TRUE);
136 #else
137 	hbutton_box = gtk_hbox_new(TRUE, CP_BUTTONS_PAD);
138 #endif
139 
140 	stepoutbtn = create_button("step_out.gif", _("Step out"));
141 	g_signal_connect(G_OBJECT(stepoutbtn), "clicked", G_CALLBACK (debug_step_out), (gpointer)TRUE);
142 
143 	runcursorbtn = create_button("run_to_cursor.gif", _("Run to cursor"));
144 	g_signal_connect(G_OBJECT(runcursorbtn), "clicked", G_CALLBACK (on_execute_until), (gpointer)TRUE);
145 
146 	gtk_box_pack_start(GTK_BOX(hbutton_box), stepoutbtn, FALSE, TRUE, 0);
147 	gtk_box_pack_start(GTK_BOX(hbutton_box), runcursorbtn, FALSE, TRUE, 0);
148 	gtk_box_pack_start(GTK_BOX(vbox), hbutton_box, FALSE, TRUE, 0);
149 
150 #if GTK_CHECK_VERSION(3, 0, 0)
151 	optbtn = create_stock_button("preferences-system", _("Settings"));
152 #else
153 	optbtn = create_stock_button(GTK_STOCK_PREFERENCES, _("Settings"));
154 #endif
155 	g_signal_connect(G_OBJECT(optbtn), "clicked", G_CALLBACK (on_settings), NULL);
156 	gtk_box_pack_end(GTK_BOX(vbox), optbtn, FALSE, FALSE, 0);
157 
158 	tabbtn = create_toggle_button("tabs.gif", _("Two panel mode"));
159 	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tabbtn), config_get_tabbed());
160 	g_signal_connect(G_OBJECT(tabbtn), "toggled", G_CALLBACK(cb), NULL);
161 	gtk_box_pack_end(GTK_BOX(vbox), tabbtn, FALSE, FALSE, 0);
162 
163 	btnpanel_set_debug_state(DBS_IDLE);
164 
165 	return vbox;
166 }
167 
168 /*
169  * set buttons sensitive based on debugger state
170  */
btnpanel_set_debug_state(enum dbs state)171 void btnpanel_set_debug_state(enum dbs state)
172 {
173 	if (DBS_STOPPED == state)
174 	{
175 		set_button_image(runbtn, "continue.png");
176 		gtk_widget_set_tooltip_text(runbtn, _("Continue"));
177 	}
178 	else
179 	{
180 		set_button_image(runbtn, "run.gif");
181 		gtk_widget_set_tooltip_text(runbtn, _("Run"));
182 	}
183 
184 	gtk_widget_set_sensitive(runbtn, DBS_IDLE == state || DBS_STOPPED == state);
185 	gtk_widget_set_sensitive(restartbtn, DBS_STOPPED == state);
186 	gtk_widget_set_sensitive(stopbtn, DBS_IDLE != state);
187 
188 	gtk_widget_set_sensitive(stepoverbtn, DBS_STOPPED == state);
189 	gtk_widget_set_sensitive(stepinbtn, DBS_STOPPED == state);
190 	gtk_widget_set_sensitive(stepoutbtn, DBS_STOPPED == state);
191 	gtk_widget_set_sensitive(runcursorbtn, DBS_STOPPED == state);
192 }
193