Beispiel #1
0
/*
 * key pressed event
 */
static gboolean on_key_pressed(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
	guint keyval = ((GdkEventKey*)event)->keyval;
	GtkTreeSelection *selection;
	GList *rows;

	/* do not process event is page is readonly (debug is running) */
	if (readonly)
		return FALSE;

	/* get selected rows */
	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree));
	rows = gtk_tree_selection_get_selected_rows(selection, &model);
	rows = g_list_sort(rows, (GCompareFunc)gtk_tree_path_compare);

	if (keyval == GDK_Delete && rows && g_list_length(rows))
	{
		GList *breaks, *iter;
		GtkTreeRowReference *new_selection = NULL;
		GtkTreePath *first_path = (GtkTreePath*)rows->data;

		/* "delete selected rows" */

		/* get new selection */
		if (gtk_tree_path_get_depth(first_path) > 1)
		{
			new_selection = get_unselected_sibling(first_path);
		}
		if (!new_selection)
		{
			GtkTreePath *file_path = gtk_tree_path_copy(first_path);
			if (gtk_tree_path_get_depth(file_path) > 1)
			{
				gtk_tree_path_up(file_path);
			}
			new_selection = get_unselected_sibling(file_path);
			gtk_tree_path_free(file_path);
		}
		
		/* collect GList of breakpoints to remove
		if file row is met - add all unselected breaks to the list as well */
		breaks = NULL;
		for (iter = rows; iter; iter = iter->next)
		{
			GtkTreePath *path = (GtkTreePath*)iter->data;
			GtkTreeIter titer;
			
			gtk_tree_model_get_iter(model, &titer, path);
			
			if (1 == gtk_tree_path_get_depth(path))
			{
				GtkTreeIter citer;
				gtk_tree_model_iter_children(model, &citer, &titer);
				
				do
				{
					if (!gtk_tree_selection_iter_is_selected(selection, &citer))
					{
						gchar *file = NULL;
						gint line;
						breakpoint *bp;

						gtk_tree_model_get(model, &titer, FILEPATH, &file, -1);
						gtk_tree_model_get(model, &citer, LINE, &line, -1);

						bp = breaks_lookup_breakpoint(file, line);
						
						breaks = g_list_append(breaks, bp);
						
						g_free(file);
					}
				}
				while(gtk_tree_model_iter_next(model, &citer));
			}
			else
			{
				GtkTreeIter piter;
				gchar *file = NULL;
				gint line;
				breakpoint *bp;

				gtk_tree_model_iter_parent(model, &piter, &titer);
				
				gtk_tree_model_get(model, &piter, FILEPATH, &file, -1);

				gtk_tree_model_get(model, &titer, LINE, &line, -1);

				bp = breaks_lookup_breakpoint(file, line);
				
				breaks = g_list_append(breaks, bp);
				
				g_free(file);
			}
		}
		
		if (1 == g_list_length(breaks))
		{
			breakpoint *bp = (breakpoint*)breaks->data;
			g_list_free(breaks);
			breaks_remove(bp->file, bp->line);
		}
		else
		{
			breaks_remove_list(breaks);
		}

		if (new_selection)
		{
			/* get path to select */
			GtkTreePath *path = NULL;
			path = gtk_tree_row_reference_get_path(new_selection);

			gtk_tree_selection_select_path(selection, path);
			gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(widget), path, NULL, TRUE, 0.5, 0.5);
			gtk_tree_path_free(path);

			gtk_tree_row_reference_free(new_selection);
		}
	}

	/* free rows list */
	g_list_foreach (rows, (GFunc)gtk_tree_path_free, NULL);
	g_list_free (rows);

	return FALSE;
}
Beispiel #2
0
/*
 * 	Occures on notify from editor.
 * 	Handles margin click to set/remove breakpoint 
 */
gboolean on_editor_notify(
	GObject *object, GeanyEditor *editor,
	SCNotification *nt, gpointer data)
{
	if (!editor->document->real_path)
	{
		/* no other way to handle removing a file from outside of geany */
		markers_remove_all(editor->document);
	}
	
	switch (nt->nmhdr.code)
	{
		case SCN_MARGINCLICK:
		{
			char* file;
			int line;
			break_state bs;

			if (!editor->document->real_path || 1 != nt->margin)
				break;
			
			file = editor->document->file_name;
			line = sci_get_line_from_position(editor->sci, nt->position) + 1;

			bs = breaks_get_state(file, line);
			if (BS_NOT_SET == bs)
				breaks_add(file, line, NULL, TRUE, 0);
			else if (BS_ENABLED == bs)
				breaks_remove(file, line);
			else if (BS_DISABLED == bs)
				breaks_switch(file, line);
			
			scintilla_send_message(editor->sci, SCI_SETFOCUS, TRUE, 0);
			
			return TRUE;
		}
		case SCN_DWELLSTART:
		{
			GString *word;

			if (DBS_STOPPED != debug_get_state ())
				break;

			/* get a word under the cursor */
			word = get_word_at_position(editor->sci, nt->position);
			if (word->len)
			{
				gchar *calltip = debug_get_calltip_for_expression(word->str);
				if (calltip)
				{
					leave_signal = g_signal_connect(G_OBJECT(editor->sci), "leave-notify-event", G_CALLBACK(on_mouse_leave), NULL);
					scintilla_send_message (editor->sci, SCI_CALLTIPSHOW, nt->position, (long)calltip);
				}
			}
				
			g_string_free(word, TRUE);
			
			break;
		}
		case SCN_DWELLEND:
		{
			if (DBS_STOPPED != debug_get_state ())
				break;

			if (scintilla_send_message (editor->sci, SCI_CALLTIPACTIVE, 0, 0))
			{
				g_signal_handler_disconnect(G_OBJECT(editor->sci), leave_signal);
				scintilla_send_message (editor->sci, SCI_CALLTIPCANCEL, 0, 0);
			}
			break;
		}
		case SCN_MODIFYATTEMPTRO:
		{
			dialogs_show_msgbox(GTK_MESSAGE_INFO, _("To edit source files stop debugging session"));
			break;
		}
		case SCN_MODIFIED:
		{
			if(((SC_MOD_INSERTTEXT & nt->modificationType) || (SC_MOD_DELETETEXT && nt->modificationType)) && editor->document->file_name && nt->linesAdded)
			{
				int line = sci_get_line_from_position(editor->sci, nt->position) + 1;

				GList *breaks = breaks_get_for_document(editor->document->file_name);
				if (breaks)
				{
					GList *iter = breaks;
					while (iter)
					{
						breakpoint *bp = (breakpoint*)iter->data;

						if (nt->linesAdded > 0 && bp->line >= line)
						{
							breaks_move_to_line(bp->file, bp->line, bp->line + nt->linesAdded);
							bptree_update_breakpoint(bp);
						}
						else if (nt->linesAdded < 0 && bp->line >= line)
						{
							if (bp->line < line - nt->linesAdded)
							{
								breaks_remove(bp->file, bp->line);
							}
							else
							{
								breaks_move_to_line(bp->file, bp->line, bp->line + nt->linesAdded);
								bptree_update_breakpoint(bp);
							}
						}
						iter = iter->next;
					}
					
					config_set_debug_changed();

					g_list_free(breaks);
				}
			}
			break;
		}
	}

	return FALSE;
}
Beispiel #3
0
/*
 * 	Occures when key is pressed.
 * 	Handles debug Run/Stop/... and add/remove breakpoint activities  
 */
gboolean keys_callback(guint key_id)
{
	switch (key_id)
	{
		case KEY_RUN:
			debug_run();
			break;
		case KEY_STOP:
			debug_stop();
			break;
		case KEY_RESTART:
			debug_restart();
			break;
		case KEY_STEP_OVER:
			debug_step_over();
			break;
		case KEY_STEP_INTO:
			debug_step_into();
			break;
		case KEY_STEP_OUT:
			debug_step_out();
			break;
		case KEY_EXECUTE_UNTIL:
		{
			GeanyDocument *doc = document_get_current();
			if (doc)
			{
				int line = sci_get_current_line(doc->editor->sci) + 1;
				debug_execute_until(DOC_FILENAME(doc), line);
			}
			break;
		}
		case KEY_BREAKPOINT:
		{
			GeanyDocument *doc = document_get_current();
			if (doc)
			{
				int line = sci_get_current_line(doc->editor->sci) + 1;
				break_state	bs = breaks_get_state(DOC_FILENAME(doc), line);
				if (BS_NOT_SET == bs)
					breaks_add(DOC_FILENAME(doc), line, NULL, TRUE, 0);
				else if (BS_ENABLED == bs)
					breaks_remove(DOC_FILENAME(doc), line);
				else if (BS_DISABLED == bs)
					breaks_switch(DOC_FILENAME(doc), line);
				
				scintilla_send_message(doc->editor->sci, SCI_SETFOCUS, TRUE, 0);
			}
			break;
		}
		case KEY_CURRENT_INSTRUCTION:
		{
			if (DBS_STOPPED == debug_get_state() && debug_current_instruction_have_sources())
			{
				debug_jump_to_current_instruction();
				gtk_widget_set_sensitive(tab_call_stack, FALSE);
				stree_select_first_frame(FALSE);
				gtk_widget_set_sensitive(tab_call_stack, TRUE);
			}
		}
	}
	
	return TRUE;
} 
Beispiel #4
0
/*
 * function to remove a break when loading config and iterating through
 * existing breaks
 */
void removebreak(void *p)
{
	breakpoint *bp = (breakpoint*)p;
	breaks_remove(bp->file, bp->line);
}