7698bf60a7
G_(UN)?LIKELY() should be only used on whole conditional expressions, and only if the branching is very highly predictable, not if it is only more probable. These macros should be used with care because a wrong prediction may be a lot worst than what a good prediction can give. git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@5625 ea778897-0a13-0410-b9d1-a72fbfd435f5
2410 lines
60 KiB
C
2410 lines
60 KiB
C
/*
|
|
* callbacks.c - this file is part of Geany, a fast and lightweight IDE
|
|
*
|
|
* Copyright 2005-2011 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
|
|
* Copyright 2006-2011 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* Callbacks used by Glade. These are mainly in response to menu item and button events in the
|
|
* main window. Callbacks not used by Glade should go elsewhere.
|
|
*/
|
|
|
|
#include "geany.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <gdk/gdkkeysyms.h>
|
|
#include <glib/gstdio.h>
|
|
#include <time.h>
|
|
|
|
#include "callbacks.h"
|
|
#include "support.h"
|
|
|
|
#include "keyfile.h"
|
|
#include "document.h"
|
|
#include "documentprivate.h"
|
|
#include "filetypes.h"
|
|
#include "sciwrappers.h"
|
|
#include "editor.h"
|
|
#include "ui_utils.h"
|
|
#include "utils.h"
|
|
#include "dialogs.h"
|
|
#include "about.h"
|
|
#include "msgwindow.h"
|
|
#include "build.h"
|
|
#include "prefs.h"
|
|
#include "templates.h"
|
|
#include "sidebar.h"
|
|
#include "keybindings.h"
|
|
#include "encodings.h"
|
|
#include "search.h"
|
|
#include "main.h"
|
|
#include "symbols.h"
|
|
#include "tools.h"
|
|
#include "project.h"
|
|
#include "navqueue.h"
|
|
#include "printing.h"
|
|
#include "plugins.h"
|
|
#include "log.h"
|
|
#include "toolbar.h"
|
|
#include "pluginutils.h"
|
|
|
|
|
|
#ifdef HAVE_VTE
|
|
# include "vte.h"
|
|
#endif
|
|
|
|
#ifdef HAVE_SOCKET
|
|
# include "socket.h"
|
|
#endif
|
|
|
|
|
|
|
|
/* flag to indicate that an insert callback was triggered from the file menu,
|
|
* so we need to store the current cursor position in editor_info.click_pos. */
|
|
static gboolean insert_callback_from_menu = FALSE;
|
|
|
|
/* represents the state at switching a notebook page(in the left treeviews widget), to not emit
|
|
* the selection-changed signal from tv.tree_openfiles */
|
|
/*static gboolean switch_tv_notebook_page = FALSE; */
|
|
|
|
|
|
static gboolean check_no_unsaved(void)
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < documents_array->len; i++)
|
|
{
|
|
if (documents[i]->is_valid && documents[i]->changed)
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE; /* no unsaved edits */
|
|
}
|
|
|
|
|
|
/* set editor_info.click_pos to the current cursor position if insert_callback_from_menu is TRUE
|
|
* to prevent invalid cursor positions which can cause segfaults */
|
|
static void verify_click_pos(GeanyDocument *doc)
|
|
{
|
|
if (insert_callback_from_menu)
|
|
{
|
|
editor_info.click_pos = sci_get_current_position(doc->editor->sci);
|
|
insert_callback_from_menu = FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
/* should only be called from on_exit_clicked */
|
|
static void quit_app(void)
|
|
{
|
|
configuration_save();
|
|
|
|
if (app->project != NULL)
|
|
project_close(FALSE); /* save project session files */
|
|
|
|
document_close_all();
|
|
|
|
main_status.quitting = TRUE;
|
|
|
|
main_quit();
|
|
}
|
|
|
|
|
|
/* wrapper function to abort exit process if cancel button is pressed */
|
|
gboolean
|
|
on_exit_clicked (GtkWidget *widget, gpointer gdata)
|
|
{
|
|
main_status.quitting = TRUE;
|
|
|
|
if (! check_no_unsaved())
|
|
{
|
|
if (document_account_for_unsaved())
|
|
{
|
|
quit_app();
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
if (! prefs.confirm_exit ||
|
|
dialogs_show_question_full(NULL, GTK_STOCK_QUIT, GTK_STOCK_CANCEL, NULL,
|
|
_("Do you really want to quit?")))
|
|
{
|
|
quit_app();
|
|
return FALSE;
|
|
}
|
|
|
|
main_status.quitting = FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*
|
|
* GUI callbacks
|
|
*/
|
|
|
|
void
|
|
on_new1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
document_new_file(NULL, NULL, NULL);
|
|
}
|
|
|
|
|
|
void
|
|
on_save1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(main_widgets.notebook));
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
if (doc != NULL && cur_page >= 0)
|
|
{
|
|
if (document_need_save_as(doc))
|
|
dialogs_show_save_as();
|
|
else
|
|
document_save_file(doc, FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_save_as1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
dialogs_show_save_as();
|
|
}
|
|
|
|
|
|
void
|
|
on_save_all1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint i, max = gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.notebook));
|
|
GeanyDocument *doc, *cur_doc = document_get_current();
|
|
gint count = 0;
|
|
|
|
for (i = 0; i < max; i++)
|
|
{
|
|
doc = document_get_from_page(i);
|
|
if (! doc->changed)
|
|
continue;
|
|
if (document_need_save_as(doc))
|
|
{
|
|
/* display unnamed document */
|
|
gtk_notebook_set_current_page(GTK_NOTEBOOK(main_widgets.notebook),
|
|
document_get_notebook_page(doc));
|
|
if (dialogs_show_save_as())
|
|
count++;
|
|
}
|
|
else
|
|
{
|
|
if (document_save_file(doc, FALSE))
|
|
count++;
|
|
}
|
|
}
|
|
if (!count)
|
|
return;
|
|
|
|
ui_set_statusbar(FALSE, ngettext("%d file saved.", "%d files saved.", count), count);
|
|
/* saving may have changed window title, sidebar for another doc, so update */
|
|
sidebar_update_tag_list(cur_doc, TRUE);
|
|
ui_set_window_title(cur_doc);
|
|
}
|
|
|
|
|
|
void
|
|
on_close_all1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
document_close_all();
|
|
}
|
|
|
|
|
|
void
|
|
on_close1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
document_close(doc);
|
|
}
|
|
|
|
|
|
void
|
|
on_quit1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
on_exit_clicked(NULL, NULL);
|
|
}
|
|
|
|
|
|
void
|
|
on_file1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gtk_widget_set_sensitive(ui_widgets.recent_files_menuitem,
|
|
g_queue_get_length(ui_prefs.recent_queue) > 0);
|
|
#if GTK_CHECK_VERSION(2, 10, 0)
|
|
/* hide Page setup when GTK printing is not used
|
|
* (on GTK < 2.10 the menu item is hidden completely) */
|
|
ui_widget_show_hide(ui_widgets.print_page_setup,
|
|
printing_prefs.use_gtk_printing || gtk_check_version(2, 10, 0) != NULL);
|
|
#endif
|
|
}
|
|
|
|
|
|
/* edit actions, c&p & co, from menu bar and from popup menu */
|
|
void
|
|
on_edit1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GtkWidget *item;
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
ui_update_menu_copy_items(doc);
|
|
ui_update_insert_include_item(doc, 1);
|
|
|
|
item = ui_lookup_widget(main_widgets.window, "plugin_preferences1");
|
|
#ifndef HAVE_PLUGINS
|
|
gtk_widget_hide(item);
|
|
#else
|
|
gtk_widget_set_sensitive(item, plugins_have_preferences());
|
|
#endif
|
|
}
|
|
|
|
|
|
void
|
|
on_undo1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
if (document_can_undo(doc))
|
|
{
|
|
sci_cancel(doc->editor->sci);
|
|
document_undo(doc);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_redo1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
if (document_can_redo(doc))
|
|
{
|
|
sci_cancel(doc->editor->sci);
|
|
document_redo(doc);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_cut1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window));
|
|
|
|
if (GTK_IS_EDITABLE(focusw))
|
|
gtk_editable_cut_clipboard(GTK_EDITABLE(focusw));
|
|
else
|
|
if (IS_SCINTILLA(focusw) && doc != NULL)
|
|
sci_cut(doc->editor->sci);
|
|
else
|
|
if (GTK_IS_TEXT_VIEW(focusw))
|
|
{
|
|
GtkTextBuffer *buffer = gtk_text_view_get_buffer(
|
|
GTK_TEXT_VIEW(focusw));
|
|
gtk_text_buffer_cut_clipboard(buffer, gtk_clipboard_get(GDK_NONE), TRUE);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_copy1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window));
|
|
|
|
if (GTK_IS_EDITABLE(focusw))
|
|
gtk_editable_copy_clipboard(GTK_EDITABLE(focusw));
|
|
else
|
|
if (IS_SCINTILLA(focusw) && doc != NULL)
|
|
sci_copy(doc->editor->sci);
|
|
else
|
|
if (GTK_IS_TEXT_VIEW(focusw))
|
|
{
|
|
GtkTextBuffer *buffer = gtk_text_view_get_buffer(
|
|
GTK_TEXT_VIEW(focusw));
|
|
gtk_text_buffer_copy_clipboard(buffer, gtk_clipboard_get(GDK_NONE));
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_paste1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window));
|
|
|
|
if (GTK_IS_EDITABLE(focusw))
|
|
gtk_editable_paste_clipboard(GTK_EDITABLE(focusw));
|
|
else
|
|
if (IS_SCINTILLA(focusw) && doc != NULL)
|
|
{
|
|
sci_paste(doc->editor->sci);
|
|
}
|
|
else
|
|
if (GTK_IS_TEXT_VIEW(focusw))
|
|
{
|
|
GtkTextBuffer *buffer = gtk_text_view_get_buffer(
|
|
GTK_TEXT_VIEW(focusw));
|
|
gtk_text_buffer_paste_clipboard(buffer, gtk_clipboard_get(GDK_NONE), NULL,
|
|
TRUE);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_delete1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(main_widgets.window));
|
|
|
|
if (GTK_IS_EDITABLE(focusw))
|
|
gtk_editable_delete_selection(GTK_EDITABLE(focusw));
|
|
else
|
|
if (IS_SCINTILLA(focusw) && doc != NULL && sci_has_selection(doc->editor->sci))
|
|
sci_clear(doc->editor->sci);
|
|
else
|
|
if (GTK_IS_TEXT_VIEW(focusw))
|
|
{
|
|
GtkTextBuffer *buffer = gtk_text_view_get_buffer(
|
|
GTK_TEXT_VIEW(focusw));
|
|
gtk_text_buffer_delete_selection(buffer, TRUE, TRUE);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_preferences1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
prefs_show_dialog();
|
|
}
|
|
|
|
|
|
/* about menu item */
|
|
void
|
|
on_info1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
about_dialog_show();
|
|
}
|
|
|
|
|
|
/* open file */
|
|
void
|
|
on_open1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
dialogs_show_open_file();
|
|
}
|
|
|
|
|
|
/* quit toolbar button */
|
|
void
|
|
on_toolbutton_quit_clicked (GtkAction *action,
|
|
gpointer user_data)
|
|
{
|
|
on_exit_clicked(NULL, NULL);
|
|
}
|
|
|
|
|
|
/* reload file */
|
|
void
|
|
on_toolbutton_reload_clicked (GtkAction *action,
|
|
gpointer user_data)
|
|
{
|
|
on_reload_as_activate(NULL, GINT_TO_POINTER(-1));
|
|
}
|
|
|
|
|
|
/* also used for reloading when user_data is -1 */
|
|
void
|
|
on_reload_as_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
gchar *base_name;
|
|
gint i = GPOINTER_TO_INT(user_data);
|
|
const gchar *charset = NULL;
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
g_return_if_fail(doc->file_name != NULL);
|
|
|
|
if (i >= 0)
|
|
{
|
|
if (i >= GEANY_ENCODINGS_MAX || encodings[i].charset == NULL)
|
|
return;
|
|
charset = encodings[i].charset;
|
|
}
|
|
else
|
|
charset = doc->encoding;
|
|
|
|
base_name = g_path_get_basename(doc->file_name);
|
|
/* don't prompt if file hasn't been edited at all */
|
|
if ((!doc->changed && !document_can_undo(doc) && !document_can_redo(doc)) ||
|
|
dialogs_show_question_full(NULL, _("_Reload"), GTK_STOCK_CANCEL,
|
|
_("Any unsaved changes will be lost."),
|
|
_("Are you sure you want to reload '%s'?"), base_name))
|
|
{
|
|
document_reload_file(doc, charset);
|
|
if (charset != NULL)
|
|
ui_update_statusbar(doc, -1);
|
|
}
|
|
g_free(base_name);
|
|
}
|
|
|
|
|
|
void
|
|
on_change_font1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
dialogs_show_open_font();
|
|
}
|
|
|
|
|
|
/* new file */
|
|
void
|
|
on_toolbutton_new_clicked (GtkAction *action,
|
|
gpointer user_data)
|
|
{
|
|
document_new_file(NULL, NULL, NULL);
|
|
}
|
|
|
|
|
|
/* open file */
|
|
void
|
|
on_toolbutton_open_clicked (GtkAction *action,
|
|
gpointer user_data)
|
|
{
|
|
dialogs_show_open_file();
|
|
}
|
|
|
|
|
|
/* save file */
|
|
void
|
|
on_toolbutton_save_clicked (GtkAction *action,
|
|
gpointer user_data)
|
|
{
|
|
on_save1_activate(NULL, user_data);
|
|
}
|
|
|
|
|
|
/* store text, clear search flags so we can use Search->Find Next/Previous */
|
|
static void setup_find(const gchar *text, gboolean backwards)
|
|
{
|
|
setptr(search_data.text, g_strdup(text));
|
|
search_data.flags = 0;
|
|
search_data.backwards = backwards;
|
|
search_data.search_bar = TRUE;
|
|
}
|
|
|
|
|
|
static void do_toolbar_search(const gchar *text, gboolean incremental, gboolean backwards)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
gboolean result;
|
|
|
|
setup_find(text, backwards);
|
|
result = document_search_bar_find(doc, search_data.text, 0, incremental, backwards);
|
|
if (search_data.search_bar)
|
|
ui_set_search_entry_background(toolbar_get_widget_child_by_name("SearchEntry"), result);
|
|
}
|
|
|
|
|
|
/* search text */
|
|
void
|
|
on_toolbar_search_entry_changed(GtkAction *action, const gchar *text, gpointer user_data)
|
|
{
|
|
do_toolbar_search(text, TRUE, FALSE);
|
|
}
|
|
|
|
|
|
/* search text */
|
|
void
|
|
on_toolbar_search_entry_activate(GtkAction *action, const gchar *text, gpointer user_data)
|
|
{
|
|
do_toolbar_search(text, FALSE, GPOINTER_TO_INT(user_data));
|
|
}
|
|
|
|
|
|
/* search text */
|
|
void
|
|
on_toolbutton_search_clicked (GtkAction *action,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
gboolean result;
|
|
GtkWidget *entry = toolbar_get_widget_child_by_name("SearchEntry");
|
|
|
|
if (entry != NULL)
|
|
{
|
|
const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry));
|
|
|
|
setup_find(text, FALSE);
|
|
result = document_search_bar_find(doc, search_data.text, 0, FALSE, FALSE);
|
|
if (search_data.search_bar)
|
|
ui_set_search_entry_background(entry, result);
|
|
}
|
|
else
|
|
on_find1_activate(NULL, NULL);
|
|
}
|
|
|
|
|
|
/* hides toolbar from toolbar popup menu */
|
|
void
|
|
on_hide_toolbar1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GtkWidget *tool_item = ui_lookup_widget(GTK_WIDGET(main_widgets.window), "menu_show_toolbar1");
|
|
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(tool_item), FALSE);
|
|
}
|
|
|
|
|
|
/* zoom in from menu bar and popup menu */
|
|
void
|
|
on_zoom_in1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
static gint done = 1;
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
if (done++ % 3 == 0)
|
|
sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin,
|
|
(sci_get_zoom(doc->editor->sci) / 2));
|
|
sci_zoom_in(doc->editor->sci);
|
|
}
|
|
|
|
|
|
/* zoom out from menu bar and popup menu */
|
|
void
|
|
on_zoom_out1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
if (sci_get_zoom(doc->editor->sci) == 0)
|
|
sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin, 0);
|
|
sci_zoom_out(doc->editor->sci);
|
|
}
|
|
|
|
|
|
void
|
|
on_normal_size1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
sci_zoom_off(doc->editor->sci);
|
|
sci_set_line_numbers(doc->editor->sci, editor_prefs.show_linenumber_margin, 0);
|
|
}
|
|
|
|
|
|
/* close tab */
|
|
void
|
|
on_toolbutton_close_clicked (GtkAction *action,
|
|
gpointer user_data)
|
|
{
|
|
on_close1_activate(NULL, NULL);
|
|
}
|
|
|
|
|
|
void
|
|
on_toolbutton_close_all_clicked (GtkAction *action,
|
|
gpointer user_data)
|
|
{
|
|
on_close_all1_activate(NULL, NULL);
|
|
}
|
|
|
|
|
|
void
|
|
on_toolbutton_preferences_clicked (GtkAction *action,
|
|
gpointer user_data)
|
|
{
|
|
on_preferences1_activate(NULL, NULL);
|
|
}
|
|
|
|
|
|
static gboolean delayed_check_disk_status(gpointer data)
|
|
{
|
|
document_check_disk_status(data, FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/* Changes window-title after switching tabs and lots of other things.
|
|
* note: using 'after' makes Scintilla redraw before the UI, appearing more responsive */
|
|
void
|
|
on_notebook1_switch_page_after (GtkNotebook *notebook,
|
|
GtkNotebookPage *page,
|
|
guint page_num,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc;
|
|
|
|
if (G_UNLIKELY(main_status.opening_session_files || main_status.closing_all))
|
|
return;
|
|
|
|
if (page_num == (guint) -1 && page != NULL)
|
|
doc = document_find_by_sci(SCINTILLA(page));
|
|
else
|
|
doc = document_get_from_page(page_num);
|
|
|
|
if (doc != NULL)
|
|
{
|
|
sidebar_select_openfiles_item(doc);
|
|
ui_save_buttons_toggle(doc->changed);
|
|
ui_set_window_title(doc);
|
|
ui_update_statusbar(doc, -1);
|
|
ui_update_popup_reundo_items(doc);
|
|
ui_document_show_hide(doc); /* update the document menu */
|
|
build_menu_update(doc);
|
|
sidebar_update_tag_list(doc, FALSE);
|
|
|
|
/* We delay the check to avoid weird fast, unintended switching of notebook pages when
|
|
* the 'file has changed' dialog is shown while the switch event is not yet completely
|
|
* finished. So, we check after the switch has been performed to be safe. */
|
|
g_idle_add(delayed_check_disk_status, doc);
|
|
|
|
#ifdef HAVE_VTE
|
|
vte_cwd((doc->real_path != NULL) ? doc->real_path : doc->file_name, FALSE);
|
|
#endif
|
|
|
|
g_signal_emit_by_name(geany_object, "document-activate", doc);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_tv_notebook_switch_page (GtkNotebook *notebook,
|
|
GtkNotebookPage *page,
|
|
guint page_num,
|
|
gpointer user_data)
|
|
{
|
|
/* suppress selection changed signal when switching to the open files list */
|
|
ignore_callback = TRUE;
|
|
}
|
|
|
|
|
|
void
|
|
on_tv_notebook_switch_page_after (GtkNotebook *notebook,
|
|
GtkNotebookPage *page,
|
|
guint page_num,
|
|
gpointer user_data)
|
|
{
|
|
ignore_callback = FALSE;
|
|
}
|
|
|
|
|
|
static void convert_eol(gint mode)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
sci_convert_eols(doc->editor->sci, mode);
|
|
sci_set_eol_mode(doc->editor->sci, mode);
|
|
ui_update_statusbar(doc, -1);
|
|
}
|
|
|
|
|
|
void
|
|
on_crlf_activate (GtkCheckMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_callback || ! gtk_check_menu_item_get_active(menuitem))
|
|
return;
|
|
|
|
convert_eol(SC_EOL_CRLF);
|
|
}
|
|
|
|
|
|
void
|
|
on_lf_activate (GtkCheckMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_callback || ! gtk_check_menu_item_get_active(menuitem))
|
|
return;
|
|
|
|
convert_eol(SC_EOL_LF);
|
|
}
|
|
|
|
|
|
void
|
|
on_cr_activate (GtkCheckMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_callback || ! gtk_check_menu_item_get_active(menuitem))
|
|
return;
|
|
|
|
convert_eol(SC_EOL_CR);
|
|
}
|
|
|
|
|
|
void
|
|
on_replace_tabs_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
editor_replace_tabs(doc->editor);
|
|
}
|
|
|
|
|
|
gboolean
|
|
toolbar_popup_menu (GtkWidget *widget,
|
|
GdkEventButton *event,
|
|
gpointer user_data)
|
|
{
|
|
if (event->button == 3)
|
|
{
|
|
gtk_menu_popup(GTK_MENU(ui_widgets.toolbar_menu), NULL, NULL, NULL, NULL, event->button, event->time);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void on_toggle_case1_activate(GtkMenuItem *menuitem, gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
ScintillaObject *sci;
|
|
gchar *text;
|
|
gboolean keep_sel = TRUE;
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
sci = doc->editor->sci;
|
|
if (! sci_has_selection(sci))
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_SELECT, GEANY_KEYS_SELECT_WORD);
|
|
keep_sel = FALSE;
|
|
}
|
|
else
|
|
{
|
|
gchar *result = NULL;
|
|
gint cmd = SCI_LOWERCASE;
|
|
gint text_len = sci_get_selected_text_length(sci);
|
|
gboolean rectsel = scintilla_send_message(sci, SCI_SELECTIONISRECTANGLE, 0, 0);
|
|
|
|
text = g_malloc(text_len + 1);
|
|
sci_get_selected_text(sci, text);
|
|
|
|
if (utils_str_has_upper(text))
|
|
{
|
|
if (rectsel)
|
|
cmd = SCI_LOWERCASE;
|
|
else
|
|
result = g_utf8_strdown(text, -1);
|
|
|
|
}
|
|
else
|
|
{
|
|
if (rectsel)
|
|
cmd = SCI_UPPERCASE;
|
|
else
|
|
result = g_utf8_strup(text, -1);
|
|
|
|
}
|
|
|
|
if (result != NULL)
|
|
{
|
|
sci_replace_sel(sci, result);
|
|
g_free(result);
|
|
if (keep_sel)
|
|
sci_set_selection_start(sci, sci_get_current_position(sci) - text_len + 1);
|
|
}
|
|
else
|
|
sci_send_command(sci, cmd);
|
|
|
|
g_free(text);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_show_toolbar1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_callback) return;
|
|
|
|
toolbar_prefs.visible = (toolbar_prefs.visible) ? FALSE : TRUE;;
|
|
ui_widget_show_hide(GTK_WIDGET(main_widgets.toolbar), toolbar_prefs.visible);
|
|
}
|
|
|
|
|
|
void
|
|
on_fullscreen1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_callback)
|
|
return;
|
|
|
|
ui_prefs.fullscreen = (ui_prefs.fullscreen) ? FALSE : TRUE;
|
|
ui_set_fullscreen();
|
|
}
|
|
|
|
|
|
void
|
|
on_show_messages_window1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_callback)
|
|
return;
|
|
|
|
ui_prefs.msgwindow_visible = (ui_prefs.msgwindow_visible) ? FALSE : TRUE;
|
|
msgwin_show_hide(ui_prefs.msgwindow_visible);
|
|
}
|
|
|
|
|
|
void
|
|
on_markers_margin1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_callback)
|
|
return;
|
|
|
|
editor_prefs.show_markers_margin = ! editor_prefs.show_markers_margin;
|
|
ui_toggle_editor_features(GEANY_EDITOR_SHOW_MARKERS_MARGIN);
|
|
}
|
|
|
|
|
|
void
|
|
on_show_line_numbers1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_callback)
|
|
return;
|
|
|
|
editor_prefs.show_linenumber_margin = ! editor_prefs.show_linenumber_margin;
|
|
ui_toggle_editor_features(GEANY_EDITOR_SHOW_LINE_NUMBERS);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_show_white_space1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_callback)
|
|
return;
|
|
|
|
editor_prefs.show_white_space = ! editor_prefs.show_white_space;
|
|
ui_toggle_editor_features(GEANY_EDITOR_SHOW_WHITE_SPACE);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_show_line_endings1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_callback)
|
|
return;
|
|
|
|
editor_prefs.show_line_endings = ! editor_prefs.show_line_endings;
|
|
ui_toggle_editor_features(GEANY_EDITOR_SHOW_LINE_ENDINGS);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_show_indentation_guides1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_callback)
|
|
return;
|
|
|
|
editor_prefs.show_indent_guide = ! editor_prefs.show_indent_guide;
|
|
ui_toggle_editor_features(GEANY_EDITOR_SHOW_INDENTATION_GUIDES);
|
|
}
|
|
|
|
|
|
void
|
|
on_line_wrapping1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (! ignore_callback)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
editor_set_line_wrapping(doc->editor, ! doc->editor->line_wrapping);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_set_file_readonly1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (! ignore_callback)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
doc->readonly = ! doc->readonly;
|
|
sci_set_readonly(doc->editor->sci, doc->readonly);
|
|
ui_update_tab_status(doc);
|
|
ui_update_statusbar(doc, -1);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_use_auto_indentation1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (! ignore_callback)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
doc->editor->auto_indent = ! doc->editor->auto_indent;
|
|
}
|
|
}
|
|
|
|
|
|
static void find_usage(gboolean in_session)
|
|
{
|
|
gint flags;
|
|
gchar *search_text;
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
if (sci_has_selection(doc->editor->sci))
|
|
{ /* take selected text if there is a selection */
|
|
search_text = g_malloc(sci_get_selected_text_length(doc->editor->sci) + 1);
|
|
sci_get_selected_text(doc->editor->sci, search_text);
|
|
flags = SCFIND_MATCHCASE;
|
|
}
|
|
else
|
|
{
|
|
editor_find_current_word(doc->editor, -1,
|
|
editor_info.current_word, GEANY_MAX_WORD_LENGTH, NULL);
|
|
search_text = g_strdup(editor_info.current_word);
|
|
flags = SCFIND_MATCHCASE | SCFIND_WHOLEWORD;
|
|
}
|
|
|
|
search_find_usage(search_text, flags, in_session);
|
|
g_free(search_text);
|
|
}
|
|
|
|
|
|
void
|
|
on_find_document_usage1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
find_usage(FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
on_find_usage1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
find_usage(TRUE);
|
|
}
|
|
|
|
|
|
static void goto_tag(gboolean definition)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
/* update cursor pos for navigating back afterwards */
|
|
if (!sci_has_selection(doc->editor->sci))
|
|
sci_set_current_position(doc->editor->sci, editor_info.click_pos, FALSE);
|
|
|
|
/* use the keybinding callback as it checks for selections as well as current word */
|
|
if (definition)
|
|
keybindings_send_command(GEANY_KEY_GROUP_GOTO, GEANY_KEYS_GOTO_TAGDEFINITION);
|
|
else
|
|
keybindings_send_command(GEANY_KEY_GROUP_GOTO, GEANY_KEYS_GOTO_TAGDECLARATION);
|
|
}
|
|
|
|
|
|
void
|
|
on_goto_tag_definition1 (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
goto_tag(TRUE);
|
|
}
|
|
|
|
|
|
void
|
|
on_goto_tag_declaration1 (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
goto_tag(FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
on_count_words1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
tools_word_count();
|
|
}
|
|
|
|
|
|
void
|
|
on_show_color_chooser1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gchar colour[9];
|
|
GeanyDocument *doc = document_get_current();
|
|
gint pos;
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
pos = sci_get_current_position(doc->editor->sci);
|
|
editor_find_current_word(doc->editor, pos, colour, sizeof colour, GEANY_WORDCHARS"#");
|
|
tools_color_chooser(colour);
|
|
}
|
|
|
|
|
|
void
|
|
on_toolbutton_compile_clicked (GtkAction *action,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_BUILD, GEANY_KEYS_BUILD_COMPILE);
|
|
}
|
|
|
|
|
|
void
|
|
on_find1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
search_show_find_dialog();
|
|
}
|
|
|
|
|
|
void
|
|
on_find_next1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
search_find_again(FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
on_find_previous1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (search_data.flags & SCFIND_REGEXP)
|
|
/* Can't reverse search order for a regex (find next ignores search backwards) */
|
|
utils_beep();
|
|
else
|
|
search_find_again(TRUE);
|
|
}
|
|
|
|
|
|
void
|
|
on_find_nextsel1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
search_find_selection(document_get_current(), FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
on_find_prevsel1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
search_find_selection(document_get_current(), TRUE);
|
|
}
|
|
|
|
|
|
void
|
|
on_replace1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
search_show_replace_dialog();
|
|
}
|
|
|
|
|
|
void
|
|
on_find_in_files1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
search_show_find_in_files_dialog(NULL);
|
|
}
|
|
|
|
|
|
static void get_line_and_offset_from_text(const gchar *text, gint *line_no, gint *offset)
|
|
{
|
|
if (*text == '+' || *text == '-')
|
|
{
|
|
*line_no = atoi(text + 1);
|
|
*offset = (*text == '+') ? 1 : -1;
|
|
}
|
|
else
|
|
{
|
|
*line_no = atoi(text) - 1;
|
|
*offset = 0;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_go_to_line_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
static gchar value[16] = "";
|
|
gchar *result;
|
|
|
|
result = dialogs_show_input_goto_line(
|
|
_("Go to Line"), GTK_WINDOW(main_widgets.window),
|
|
_("Enter the line you want to go to:"), value);
|
|
if (result != NULL)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
gint offset;
|
|
gint line_no;
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
get_line_and_offset_from_text(result, &line_no, &offset);
|
|
if (! editor_goto_line(doc->editor, line_no, offset))
|
|
utils_beep();
|
|
/* remember value for future calls */
|
|
g_snprintf(value, sizeof(value), "%s", result);
|
|
|
|
g_free(result);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_toolbutton_goto_entry_activate(GtkAction *action, const gchar *text, gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
gint offset;
|
|
gint line_no;
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
get_line_and_offset_from_text(text, &line_no, &offset);
|
|
if (! editor_goto_line(doc->editor, line_no, offset))
|
|
utils_beep();
|
|
else
|
|
keybindings_send_command(GEANY_KEY_GROUP_FOCUS, GEANY_KEYS_FOCUS_EDITOR);
|
|
}
|
|
|
|
|
|
void
|
|
on_toolbutton_goto_clicked (GtkAction *action,
|
|
gpointer user_data)
|
|
{
|
|
GtkWidget *entry = toolbar_get_widget_child_by_name("GotoEntry");
|
|
|
|
if (entry != NULL)
|
|
{
|
|
const gchar *text = gtk_entry_get_text(GTK_ENTRY(entry));
|
|
|
|
on_toolbutton_goto_entry_activate(NULL, text, NULL);
|
|
}
|
|
else
|
|
on_go_to_line_activate(NULL, NULL);
|
|
}
|
|
|
|
|
|
void
|
|
on_help1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gchar *uri;
|
|
|
|
uri = utils_get_help_url(NULL);
|
|
utils_open_browser(uri);
|
|
g_free(uri);
|
|
}
|
|
|
|
|
|
void
|
|
on_help_shortcuts1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_show_shortcuts();
|
|
}
|
|
|
|
|
|
void
|
|
on_website1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
utils_open_browser(GEANY_HOMEPAGE);
|
|
}
|
|
|
|
|
|
void
|
|
on_comments_function_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
gchar *text;
|
|
const gchar *cur_tag = NULL;
|
|
gint line = -1, pos = 0;
|
|
|
|
if (doc == NULL || doc->file_type == NULL)
|
|
{
|
|
ui_set_statusbar(FALSE,
|
|
_("Please set the filetype for the current file before using this function."));
|
|
return;
|
|
}
|
|
|
|
/* symbols_get_current_function returns -1 on failure, so sci_get_position_from_line
|
|
* returns the current position, so it should be safe */
|
|
line = symbols_get_current_function(doc, &cur_tag);
|
|
pos = sci_get_position_from_line(doc->editor->sci, line - 1);
|
|
|
|
text = templates_get_template_function(doc, cur_tag);
|
|
|
|
sci_start_undo_action(doc->editor->sci);
|
|
sci_insert_text(doc->editor->sci, pos, text);
|
|
sci_end_undo_action(doc->editor->sci);
|
|
g_free(text);
|
|
}
|
|
|
|
|
|
void
|
|
on_comments_multiline_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
if (doc == NULL || doc->file_type == NULL)
|
|
{
|
|
ui_set_statusbar(FALSE,
|
|
_("Please set the filetype for the current file before using this function."));
|
|
return;
|
|
}
|
|
|
|
verify_click_pos(doc); /* make sure that the click_pos is valid */
|
|
|
|
if (doc->file_type->comment_open || doc->file_type->comment_single)
|
|
editor_insert_multiline_comment(doc->editor);
|
|
else
|
|
utils_beep();
|
|
}
|
|
|
|
|
|
void
|
|
on_comments_gpl_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
gchar *text;
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
text = templates_get_template_licence(doc, GEANY_TEMPLATE_GPL);
|
|
|
|
verify_click_pos(doc); /* make sure that the click_pos is valid */
|
|
|
|
sci_start_undo_action(doc->editor->sci);
|
|
sci_insert_text(doc->editor->sci, editor_info.click_pos, text);
|
|
sci_end_undo_action(doc->editor->sci);
|
|
g_free(text);
|
|
}
|
|
|
|
|
|
void
|
|
on_comments_bsd_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
|
|
GeanyDocument *doc = document_get_current();
|
|
gchar *text;
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
text = templates_get_template_licence(doc, GEANY_TEMPLATE_BSD);
|
|
|
|
verify_click_pos(doc); /* make sure that the click_pos is valid */
|
|
|
|
sci_start_undo_action(doc->editor->sci);
|
|
sci_insert_text(doc->editor->sci, editor_info.click_pos, text);
|
|
sci_end_undo_action(doc->editor->sci);
|
|
g_free(text);
|
|
|
|
}
|
|
|
|
|
|
void
|
|
on_comments_changelog_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
gchar *text;
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
text = templates_get_template_changelog(doc);
|
|
sci_start_undo_action(doc->editor->sci);
|
|
sci_insert_text(doc->editor->sci, 0, text);
|
|
/* sets the cursor to the right position to type the changelog text,
|
|
* the template has 21 chars + length of name and email */
|
|
sci_goto_pos(doc->editor->sci, 21 + strlen(template_prefs.developer) + strlen(template_prefs.mail), TRUE);
|
|
sci_end_undo_action(doc->editor->sci);
|
|
|
|
g_free(text);
|
|
}
|
|
|
|
|
|
void
|
|
on_comments_fileheader_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
gchar *text;
|
|
const gchar *fname;
|
|
GeanyFiletype *ft;
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
ft = doc->file_type;
|
|
fname = doc->file_name;
|
|
text = templates_get_template_fileheader(FILETYPE_ID(ft), fname);
|
|
|
|
sci_start_undo_action(doc->editor->sci);
|
|
sci_insert_text(doc->editor->sci, 0, text);
|
|
sci_goto_pos(doc->editor->sci, 0, FALSE);
|
|
sci_end_undo_action(doc->editor->sci);
|
|
g_free(text);
|
|
}
|
|
|
|
|
|
void
|
|
on_insert_date_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
const gchar *format = NULL;
|
|
gchar *time_str;
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
/* set default value */
|
|
if (utils_str_equal("", ui_prefs.custom_date_format))
|
|
{
|
|
g_free(ui_prefs.custom_date_format);
|
|
ui_prefs.custom_date_format = g_strdup("%d.%m.%Y");
|
|
}
|
|
|
|
if (utils_str_equal(_("dd.mm.yyyy"), (gchar*) user_data))
|
|
format = "%d.%m.%Y";
|
|
else if (utils_str_equal(_("mm.dd.yyyy"), (gchar*) user_data))
|
|
format = "%m.%d.%Y";
|
|
else if (utils_str_equal(_("yyyy/mm/dd"), (gchar*) user_data))
|
|
format = "%Y/%m/%d";
|
|
else if (utils_str_equal(_("dd.mm.yyyy hh:mm:ss"), (gchar*) user_data))
|
|
format = "%d.%m.%Y %H:%M:%S";
|
|
else if (utils_str_equal(_("mm.dd.yyyy hh:mm:ss"), (gchar*) user_data))
|
|
format = "%m.%d.%Y %H:%M:%S";
|
|
else if (utils_str_equal(_("yyyy/mm/dd hh:mm:ss"), (gchar*) user_data))
|
|
format = "%Y/%m/%d %H:%M:%S";
|
|
else if (utils_str_equal(_("_Use Custom Date Format"), (gchar*) user_data))
|
|
format = ui_prefs.custom_date_format;
|
|
else
|
|
{
|
|
gchar *str = dialogs_show_input(_("Custom Date Format"), GTK_WINDOW(main_widgets.window),
|
|
_("Enter here a custom date and time format. "
|
|
"You can use any conversion specifiers which can be used with the ANSI C strftime function."),
|
|
ui_prefs.custom_date_format);
|
|
if (str)
|
|
setptr(ui_prefs.custom_date_format, str);
|
|
return;
|
|
}
|
|
|
|
time_str = utils_get_date_time(format, NULL);
|
|
if (time_str != NULL)
|
|
{
|
|
verify_click_pos(doc); /* make sure that the click_pos is valid */
|
|
|
|
sci_start_undo_action(doc->editor->sci);
|
|
sci_insert_text(doc->editor->sci, editor_info.click_pos, time_str);
|
|
sci_goto_pos(doc->editor->sci, editor_info.click_pos + strlen(time_str), FALSE);
|
|
sci_end_undo_action(doc->editor->sci);
|
|
g_free(time_str);
|
|
}
|
|
else
|
|
{
|
|
utils_beep();
|
|
ui_set_statusbar(TRUE,
|
|
_("Date format string could not be converted (possibly too long)."));
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_insert_include_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
gint pos = -1;
|
|
gchar *text;
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
g_return_if_fail(user_data != NULL);
|
|
|
|
verify_click_pos(doc); /* make sure that the click_pos is valid */
|
|
|
|
if (utils_str_equal(user_data, "blank"))
|
|
{
|
|
text = g_strdup("#include \"\"\n");
|
|
pos = editor_info.click_pos + 10;
|
|
}
|
|
else
|
|
{
|
|
text = g_strconcat("#include <", user_data, ">\n", NULL);
|
|
}
|
|
|
|
sci_start_undo_action(doc->editor->sci);
|
|
sci_insert_text(doc->editor->sci, editor_info.click_pos, text);
|
|
sci_end_undo_action(doc->editor->sci);
|
|
g_free(text);
|
|
if (pos >= 0)
|
|
sci_goto_pos(doc->editor->sci, pos, FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
on_file_properties_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
dialogs_show_file_properties(doc);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_fold_all1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
editor_fold_all(doc->editor);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_unfold_all1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
editor_unfold_all(doc->editor);
|
|
}
|
|
|
|
|
|
void
|
|
on_toolbutton_run_clicked (GtkAction *action,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_BUILD, GEANY_KEYS_BUILD_RUN);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_remove_indicators1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
editor_indicator_clear(doc->editor, GEANY_INDICATOR_ERROR);
|
|
}
|
|
|
|
|
|
void
|
|
on_print1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
printing_print_doc(doc);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_select_all1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
sci_select_all(doc->editor->sci);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_show_sidebar1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_callback)
|
|
return;
|
|
|
|
ui_prefs.sidebar_visible = ! ui_prefs.sidebar_visible;
|
|
|
|
/* show built-in tabs if no tabs visible */
|
|
if (ui_prefs.sidebar_visible &&
|
|
! interface_prefs.sidebar_openfiles_visible && ! interface_prefs.sidebar_symbol_visible &&
|
|
gtk_notebook_get_n_pages(GTK_NOTEBOOK(main_widgets.sidebar_notebook)) <= 2)
|
|
{
|
|
interface_prefs.sidebar_openfiles_visible = TRUE;
|
|
interface_prefs.sidebar_symbol_visible = TRUE;
|
|
}
|
|
|
|
#if GTK_CHECK_VERSION(2, 14, 0)
|
|
/* if window has input focus, set it back to the editor before toggling off */
|
|
if (! ui_prefs.sidebar_visible &&
|
|
gtk_container_get_focus_child(GTK_CONTAINER(main_widgets.sidebar_notebook)) != NULL)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_FOCUS, GEANY_KEYS_FOCUS_EDITOR);
|
|
}
|
|
#endif
|
|
|
|
ui_sidebar_show_hide();
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_write_unicode_bom1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (! ignore_callback)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
if (doc->readonly)
|
|
{
|
|
utils_beep();
|
|
return;
|
|
}
|
|
|
|
document_undo_add(doc, UNDO_BOM, GINT_TO_POINTER(doc->has_bom));
|
|
|
|
doc->has_bom = ! doc->has_bom;
|
|
|
|
ui_update_statusbar(doc, -1);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_comment_line1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
editor_do_comment(doc->editor, -1, FALSE, FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_uncomment_line1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
editor_do_uncomment(doc->editor, -1, FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_toggle_line_commentation1_activate
|
|
(GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
editor_do_comment_toggle(doc->editor);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_increase_indent1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
editor_indent(doc->editor, TRUE);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_decrease_indent1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
editor_indent(doc->editor, FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
on_next_message1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (! ui_tree_view_find_next(GTK_TREE_VIEW(msgwindow.tree_msg),
|
|
msgwin_goto_messages_file_line))
|
|
ui_set_statusbar(FALSE, _("No more message items."));
|
|
}
|
|
|
|
|
|
void
|
|
on_previous_message1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (! ui_tree_view_find_previous(GTK_TREE_VIEW(msgwindow.tree_msg),
|
|
msgwin_goto_messages_file_line))
|
|
ui_set_statusbar(FALSE, _("No more message items."));
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_comments_multiline_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
insert_callback_from_menu = TRUE;
|
|
on_comments_multiline_activate(menuitem, user_data);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_comments_gpl_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
insert_callback_from_menu = TRUE;
|
|
on_comments_gpl_activate(menuitem, user_data);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_comments_bsd_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
insert_callback_from_menu = TRUE;
|
|
on_comments_bsd_activate(menuitem, user_data);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_insert_include_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
insert_callback_from_menu = TRUE;
|
|
on_insert_include_activate(menuitem, user_data);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_insert_date_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
insert_callback_from_menu = TRUE;
|
|
on_insert_date_activate(menuitem, user_data);
|
|
}
|
|
|
|
|
|
void
|
|
on_project_new1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
project_new();
|
|
}
|
|
|
|
|
|
void
|
|
on_project_open1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
project_open();
|
|
}
|
|
|
|
|
|
void
|
|
on_project_close1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
project_close(TRUE);
|
|
}
|
|
|
|
|
|
void
|
|
on_project_properties1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
project_properties();
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_project1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
static GtkWidget *item_close = NULL;
|
|
static GtkWidget *item_properties = NULL;
|
|
|
|
if (item_close == NULL)
|
|
{
|
|
item_close = ui_lookup_widget(main_widgets.window, "project_close1");
|
|
item_properties = ui_lookup_widget(main_widgets.window, "project_properties1");
|
|
}
|
|
|
|
gtk_widget_set_sensitive(item_close, (app->project != NULL));
|
|
gtk_widget_set_sensitive(item_properties, (app->project != NULL));
|
|
gtk_widget_set_sensitive(ui_widgets.recent_projects_menuitem,
|
|
g_queue_get_length(ui_prefs.recent_projects_queue) > 0);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_open_selected_file1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
gchar *sel = NULL;
|
|
const gchar *wc;
|
|
|
|
#ifdef G_OS_WIN32
|
|
wc = GEANY_WORDCHARS "./-" "\\";
|
|
#else
|
|
wc = GEANY_WORDCHARS "./-";
|
|
#endif
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
sel = editor_get_default_selection(doc->editor, TRUE, wc);
|
|
|
|
if (sel != NULL)
|
|
{
|
|
gchar *locale_filename, *filename = NULL;
|
|
|
|
if (g_path_is_absolute(sel))
|
|
filename = g_strdup(sel);
|
|
else
|
|
{ /* relative filename, add the path of the current file */
|
|
gchar *path;
|
|
|
|
path = utils_get_current_file_dir_utf8();
|
|
if (!path)
|
|
path = g_get_current_dir();
|
|
|
|
filename = g_build_path(G_DIR_SEPARATOR_S, path, sel, NULL);
|
|
|
|
if (! g_file_test(filename, G_FILE_TEST_EXISTS) &&
|
|
app->project != NULL && NZV(app->project->base_path))
|
|
{
|
|
/* try the project's base path */
|
|
setptr(path, project_get_base_path());
|
|
setptr(filename, g_build_path(G_DIR_SEPARATOR_S, path, sel, NULL));
|
|
}
|
|
g_free(path);
|
|
}
|
|
|
|
locale_filename = utils_get_locale_from_utf8(filename);
|
|
document_open_file(locale_filename, FALSE, NULL, NULL);
|
|
|
|
g_free(filename);
|
|
g_free(locale_filename);
|
|
g_free(sel);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_remove_markers1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
sci_marker_delete_all(doc->editor->sci, 0); /* delete the yellow tag marker */
|
|
sci_marker_delete_all(doc->editor->sci, 1); /* delete user markers */
|
|
editor_indicator_clear(doc->editor, GEANY_INDICATOR_SEARCH);
|
|
}
|
|
|
|
|
|
void
|
|
on_load_tags1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
symbols_show_load_tags_dialog();
|
|
}
|
|
|
|
|
|
void
|
|
on_context_action1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gchar *word, *command;
|
|
GError *error = NULL;
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
if (sci_has_selection(doc->editor->sci))
|
|
{ /* take selected text if there is a selection */
|
|
word = g_malloc(sci_get_selected_text_length(doc->editor->sci) + 1);
|
|
sci_get_selected_text(doc->editor->sci, word);
|
|
}
|
|
else
|
|
{
|
|
word = g_strdup(editor_info.current_word);
|
|
}
|
|
|
|
/* use the filetype specific command if available, fallback to global command otherwise */
|
|
if (doc->file_type != NULL &&
|
|
NZV(doc->file_type->context_action_cmd))
|
|
{
|
|
command = g_strdup(doc->file_type->context_action_cmd);
|
|
}
|
|
else
|
|
{
|
|
command = g_strdup(tool_prefs.context_action_cmd);
|
|
}
|
|
|
|
/* substitute the wildcard %s and run the command if it is non empty */
|
|
if (G_LIKELY(NZV(command)))
|
|
{
|
|
utils_str_replace_all(&command, "%s", word);
|
|
|
|
if (! g_spawn_command_line_async(command, &error))
|
|
{
|
|
ui_set_statusbar(TRUE, "Context action command failed: %s", error->message);
|
|
g_error_free(error);
|
|
}
|
|
}
|
|
g_free(word);
|
|
g_free(command);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_toggle_all_additional_widgets1_activate
|
|
(GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
static gint hide_all = -1;
|
|
GtkCheckMenuItem *msgw = GTK_CHECK_MENU_ITEM(
|
|
ui_lookup_widget(main_widgets.window, "menu_show_messages_window1"));
|
|
GtkCheckMenuItem *toolbari = GTK_CHECK_MENU_ITEM(
|
|
ui_lookup_widget(main_widgets.window, "menu_show_toolbar1"));
|
|
|
|
/* get the initial state (necessary if Geany was closed with hide_all = TRUE) */
|
|
if (G_UNLIKELY(hide_all == -1))
|
|
{
|
|
if (! gtk_check_menu_item_get_active(msgw) &&
|
|
! interface_prefs.show_notebook_tabs &&
|
|
! gtk_check_menu_item_get_active(toolbari))
|
|
{
|
|
hide_all = TRUE;
|
|
}
|
|
else
|
|
hide_all = FALSE;
|
|
}
|
|
|
|
hide_all = ! hide_all; /* toggle */
|
|
|
|
if (hide_all)
|
|
{
|
|
if (gtk_check_menu_item_get_active(msgw))
|
|
gtk_check_menu_item_set_active(msgw, ! gtk_check_menu_item_get_active(msgw));
|
|
|
|
interface_prefs.show_notebook_tabs = FALSE;
|
|
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.show_notebook_tabs);
|
|
|
|
ui_statusbar_showhide(FALSE);
|
|
|
|
if (gtk_check_menu_item_get_active(toolbari))
|
|
gtk_check_menu_item_set_active(toolbari, ! gtk_check_menu_item_get_active(toolbari));
|
|
}
|
|
else
|
|
{
|
|
|
|
if (! gtk_check_menu_item_get_active(msgw))
|
|
gtk_check_menu_item_set_active(msgw, ! gtk_check_menu_item_get_active(msgw));
|
|
|
|
interface_prefs.show_notebook_tabs = TRUE;
|
|
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.show_notebook_tabs);
|
|
|
|
ui_statusbar_showhide(TRUE);
|
|
|
|
if (! gtk_check_menu_item_get_active(toolbari))
|
|
gtk_check_menu_item_set_active(toolbari, ! gtk_check_menu_item_get_active(toolbari));
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_forward_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
navqueue_go_forward();
|
|
}
|
|
|
|
|
|
void
|
|
on_back_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
navqueue_go_back();
|
|
}
|
|
|
|
|
|
gboolean on_motion_event(GtkWidget *widget, GdkEventMotion *event, gpointer user_data)
|
|
{
|
|
if (prefs.auto_focus && ! GTK_WIDGET_HAS_FOCUS(widget))
|
|
gtk_widget_grab_focus(widget);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
static void set_indent_type(GtkCheckMenuItem *menuitem, GeanyIndentType type)
|
|
{
|
|
GeanyDocument *doc;
|
|
|
|
if (ignore_callback || ! gtk_check_menu_item_get_active(menuitem))
|
|
return;
|
|
|
|
doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
editor_set_indent(doc->editor, type, doc->editor->indent_width);
|
|
ui_update_statusbar(doc, -1);
|
|
}
|
|
|
|
|
|
void
|
|
on_tabs1_activate (GtkCheckMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
set_indent_type(menuitem, GEANY_INDENT_TYPE_TABS);
|
|
}
|
|
|
|
|
|
void
|
|
on_spaces1_activate (GtkCheckMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
set_indent_type(menuitem, GEANY_INDENT_TYPE_SPACES);
|
|
}
|
|
|
|
|
|
void
|
|
on_tabs_and_spaces1_activate (GtkCheckMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
set_indent_type(menuitem, GEANY_INDENT_TYPE_BOTH);
|
|
}
|
|
|
|
|
|
void
|
|
on_strip_trailing_spaces1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc;
|
|
|
|
if (ignore_callback)
|
|
return;
|
|
|
|
doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
editor_strip_trailing_spaces(doc->editor);
|
|
}
|
|
|
|
|
|
void
|
|
on_page_setup1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
#if GTK_CHECK_VERSION(2, 10, 0)
|
|
printing_page_setup_gtk();
|
|
#endif
|
|
}
|
|
|
|
|
|
gboolean
|
|
on_escape_key_press_event (GtkWidget *widget,
|
|
GdkEventKey *event,
|
|
gpointer user_data)
|
|
{
|
|
guint state = event->state & gtk_accelerator_get_default_mod_mask();
|
|
|
|
/* make pressing escape in the sidebar and toolbar focus the editor */
|
|
if (event->keyval == GDK_Escape && state == 0)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_FOCUS, GEANY_KEYS_FOCUS_EDITOR);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void
|
|
on_line_breaking1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc;
|
|
|
|
if (ignore_callback)
|
|
return;
|
|
|
|
doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
doc->editor->line_breaking = !doc->editor->line_breaking;
|
|
}
|
|
|
|
|
|
void
|
|
on_replace_spaces_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GeanyDocument *doc = document_get_current();
|
|
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
editor_replace_spaces(doc->editor);
|
|
}
|
|
|
|
|
|
void
|
|
on_search1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GtkWidget *next_message = ui_lookup_widget(main_widgets.window, "next_message1");
|
|
GtkWidget *previous_message = ui_lookup_widget(main_widgets.window, "previous_message1");
|
|
gboolean have_messages;
|
|
|
|
/* enable commands if the messages window has any items */
|
|
have_messages = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(msgwindow.store_msg),
|
|
NULL) > 0;
|
|
|
|
gtk_widget_set_sensitive(next_message, have_messages);
|
|
gtk_widget_set_sensitive(previous_message, have_messages);
|
|
}
|
|
|
|
|
|
/* simple implementation (vs. close all which doesn't close documents if cancelled) */
|
|
void
|
|
on_close_other_documents1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
guint i;
|
|
GeanyDocument *doc, *cur_doc = document_get_current();
|
|
|
|
for (i = 0; i < documents_array->len; i++)
|
|
{
|
|
doc = documents[i];
|
|
|
|
if (doc == cur_doc || ! doc->is_valid)
|
|
continue;
|
|
|
|
if (! document_close(doc))
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_reload_configuration1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
main_reload_configuration();
|
|
}
|
|
|
|
|
|
void
|
|
on_debug_messages1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
log_show_debug_messages_dialog();
|
|
}
|
|
|
|
|
|
void
|
|
on_send_selection_to_vte1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
#ifdef HAVE_VTE
|
|
if (vte_info.have_vte)
|
|
vte_send_selection_to_vte();
|
|
#endif
|
|
}
|
|
|
|
|
|
gboolean on_window_state_event (GtkWidget *widget,
|
|
GdkEventWindowState *event,
|
|
gpointer user_data)
|
|
{
|
|
|
|
if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
|
|
{
|
|
static GtkWidget *menuitem = NULL;
|
|
|
|
if (menuitem == NULL)
|
|
menuitem = ui_lookup_widget(widget, "menu_fullscreen1");
|
|
|
|
ignore_callback = TRUE;
|
|
|
|
ui_prefs.fullscreen = (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ? TRUE : FALSE;
|
|
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), ui_prefs.fullscreen);
|
|
|
|
ignore_callback = FALSE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void
|
|
on_customize_toolbar1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GtkWidget *widget;
|
|
GtkNotebook *notebook;
|
|
|
|
prefs_show_dialog();
|
|
|
|
/* select the KB page */
|
|
widget = ui_lookup_widget(ui_widgets.prefs_dialog, "vbox15");
|
|
notebook = GTK_NOTEBOOK(ui_lookup_widget(ui_widgets.prefs_dialog, "notebook2"));
|
|
|
|
if (notebook != NULL && widget != NULL)
|
|
gtk_notebook_set_current_page(notebook, gtk_notebook_page_num(notebook, widget));
|
|
}
|
|
|
|
|
|
void
|
|
on_button_customize_toolbar_clicked (GtkButton *button,
|
|
gpointer user_data)
|
|
{
|
|
toolbar_configure(GTK_WINDOW(ui_widgets.prefs_dialog));
|
|
}
|
|
|
|
|
|
void
|
|
on_cut_current_line_s_1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_CLIPBOARD, GEANY_KEYS_CLIPBOARD_CUTLINE);
|
|
}
|
|
|
|
|
|
void
|
|
on_copy_current_line_s_1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_CLIPBOARD, GEANY_KEYS_CLIPBOARD_COPYLINE);
|
|
}
|
|
|
|
|
|
void
|
|
on_delete_current_line_s_1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_EDITOR, GEANY_KEYS_EDITOR_DELETELINE);
|
|
}
|
|
|
|
|
|
void
|
|
on_duplicate_line_or_selection1_activate
|
|
(GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_EDITOR, GEANY_KEYS_EDITOR_DUPLICATELINE);
|
|
}
|
|
|
|
|
|
void
|
|
on_select_current_line_s_1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_SELECT, GEANY_KEYS_SELECT_LINE);
|
|
}
|
|
|
|
|
|
void
|
|
on_select_current_paragraph1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_SELECT, GEANY_KEYS_SELECT_PARAGRAPH);
|
|
}
|
|
|
|
|
|
void
|
|
on_insert_alternative_white_space1_activate
|
|
(GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_INSERT, GEANY_KEYS_INSERT_ALTWHITESPACE);
|
|
}
|
|
|
|
|
|
void
|
|
on_go_to_next_marker1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_GOTO, GEANY_KEYS_GOTO_NEXTMARKER);
|
|
}
|
|
|
|
|
|
void
|
|
on_go_to_previous_marker1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_GOTO, GEANY_KEYS_GOTO_PREVIOUSMARKER);
|
|
}
|
|
|
|
|
|
void
|
|
on_reflow_lines_block1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_FORMAT, GEANY_KEYS_FORMAT_REFLOWPARAGRAPH);
|
|
}
|
|
|
|
|
|
void
|
|
on_transpose_current_line1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_EDITOR, GEANY_KEYS_EDITOR_TRANSPOSELINE);
|
|
}
|
|
|
|
|
|
void
|
|
on_smart_line_indent1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_FORMAT, GEANY_KEYS_FORMAT_AUTOINDENT);
|
|
}
|
|
|
|
|
|
void
|
|
on_plugin_preferences1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
#ifdef HAVE_PLUGINS
|
|
plugin_show_configure(NULL);
|
|
#endif
|
|
}
|
|
|
|
|
|
static void set_indent_width(guint width)
|
|
{
|
|
GeanyDocument *doc;
|
|
|
|
if (ignore_callback)
|
|
return;
|
|
|
|
doc = document_get_current();
|
|
g_return_if_fail(doc != NULL);
|
|
|
|
editor_set_indent(doc->editor, doc->editor->indent_type, width);
|
|
}
|
|
|
|
|
|
void
|
|
on_indent_width_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gchar *label = ui_menu_item_get_text(menuitem);
|
|
gint width = atoi(label);
|
|
|
|
g_free(label);
|
|
if (width)
|
|
set_indent_width(width);
|
|
}
|
|
|
|
|
|
void
|
|
on_reset_indentation1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
guint i;
|
|
|
|
foreach_document(i)
|
|
document_apply_indent_settings(documents[i]);
|
|
|
|
ui_update_statusbar(NULL, -1);
|
|
ui_document_show_hide(NULL);
|
|
}
|
|
|
|
|
|
void
|
|
on_mark_all1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_send_command(GEANY_KEY_GROUP_SEARCH, GEANY_KEYS_SEARCH_MARKALL);
|
|
}
|
|
|