ef1399e000
Move most GeanyApp fields into: GeanyPrefs for (most) Preferences dialog fields; UIPrefs for non-Prefs dialog visual settings; UIWidgets for less commonly used widgets such as menuitems and dialogs; GeanyStatus for various states the application can be in. Move some GeanyApp fields into EditorPrefs (and one into each of CommandLineOptions and SidebarTreeviews). Add plugin API prefs field. Move disabling build widgets on Windows to build_init(). Make build callbacks static. Add treeviews_init() to prepare popup menus and open files treeview. Replace treeviews_find_node() with treeviews_select_openfiles_item(). Make utils_isbrace() and utils_is_opening_brace() take an 'include_angles' argument (to separate from editor_prefs). Make 'Goto matching brace' keybinding include <> angle brackets. git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@1815 ea778897-0a13-0410-b9d1-a72fbfd435f5
2097 lines
54 KiB
C
2097 lines
54 KiB
C
/*
|
|
* callbacks.c - this file is part of Geany, a fast and lightweight IDE
|
|
*
|
|
* Copyright 2005-2007 Enrico Tröger <enrico.troeger@uvena.de>
|
|
* Copyright 2006-2007 Nick Treleaven <nick.treleaven@btinternet.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 "interface.h"
|
|
#include "support.h"
|
|
|
|
#include "keyfile.h"
|
|
#include "document.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 "treeviews.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"
|
|
|
|
#ifdef HAVE_VTE
|
|
# include "vte.h"
|
|
#endif
|
|
|
|
#ifdef HAVE_SOCKET
|
|
# include "socket.h"
|
|
#endif
|
|
|
|
|
|
// represents the state while closing all tabs(used to prevent notebook switch page signals)
|
|
static gboolean closing_all = FALSE;
|
|
|
|
// flag to indicate the explicit change of a toggle button of the toolbar menu and so the
|
|
// toggled callback should ignore the change since it is not triggered by the user
|
|
static gboolean ignore_toolbar_toggle = FALSE;
|
|
|
|
// 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;
|
|
|
|
CallbacksData callbacks_data = {-1};
|
|
|
|
|
|
static gboolean check_no_unsaved()
|
|
{
|
|
guint i;
|
|
|
|
for (i = 0; i < doc_array->len; i++)
|
|
{
|
|
if (doc_list[i].is_valid && doc_list[i].changed)
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE; // no unsaved edits
|
|
}
|
|
|
|
|
|
static gboolean account_for_unsaved()
|
|
{
|
|
gint p;
|
|
|
|
for (p = 0; p < gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook)); p++)
|
|
{
|
|
gint idx = document_get_n_idx(p);
|
|
|
|
if (doc_list[idx].changed)
|
|
{
|
|
if (! dialogs_show_unsaved_file(idx))
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// 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(gint idx)
|
|
{
|
|
if (insert_callback_from_menu)
|
|
{
|
|
editor_info.click_pos = sci_get_current_position(doc_list[idx].sci);
|
|
insert_callback_from_menu = FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
// should only be called from on_exit_clicked
|
|
static void quit_app()
|
|
{
|
|
guint i;
|
|
|
|
configuration_save();
|
|
|
|
// force close all tabs
|
|
for (i = 0; i < doc_array->len; i++)
|
|
{
|
|
if (doc_list[i].is_valid && doc_list[i].changed)
|
|
{
|
|
doc_list[i].changed = FALSE; // ignore changes (already asked user in on_exit_clicked)
|
|
}
|
|
}
|
|
on_close_all1_activate(NULL, NULL);
|
|
|
|
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 (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);
|
|
}
|
|
|
|
|
|
void
|
|
on_save1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(app->notebook));
|
|
gint idx = document_get_cur_idx();
|
|
|
|
if (cur_page >= 0)
|
|
{
|
|
if (doc_list[idx].file_name == NULL)
|
|
dialogs_show_save_as();
|
|
else
|
|
document_save_file(idx, 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, idx, max = gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook));
|
|
gint cur_idx = document_get_cur_idx();
|
|
for(i = 0; i < max; i++)
|
|
{
|
|
idx = document_get_n_idx(i);
|
|
if (! doc_list[idx].changed) continue;
|
|
if (doc_list[idx].file_name == NULL)
|
|
dialogs_show_save_as();
|
|
else
|
|
document_save_file(idx, FALSE);
|
|
}
|
|
treeviews_update_tag_list(cur_idx, TRUE);
|
|
ui_set_window_title(cur_idx);
|
|
}
|
|
|
|
|
|
gboolean
|
|
on_close_all1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gboolean ret = TRUE;
|
|
gint i, max = gtk_notebook_get_n_pages(GTK_NOTEBOOK(app->notebook));
|
|
|
|
closing_all = TRUE;
|
|
for(i = 0; i < max; i++)
|
|
{
|
|
if (! document_remove(0))
|
|
{
|
|
ret = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
closing_all = FALSE;
|
|
tm_workspace_update(TM_WORK_OBJECT(app->tm_workspace), TRUE, TRUE, FALSE);
|
|
// if cancel is clicked, cancel the complete exit process
|
|
return ret;
|
|
}
|
|
|
|
|
|
void
|
|
on_close1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
guint cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(app->notebook));
|
|
document_remove(cur_page);
|
|
}
|
|
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
// edit actions, c&p & co, from menu bar and from popup menu
|
|
void
|
|
on_edit1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
ui_update_menu_copy_items(idx);
|
|
ui_update_insert_include_item(idx, 1);
|
|
}
|
|
|
|
|
|
void
|
|
on_undo1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (idx == -1 || ! doc_list[idx].is_valid) return;
|
|
if (document_can_undo(idx)) document_undo(idx);
|
|
}
|
|
|
|
|
|
void
|
|
on_redo1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (idx == -1 || ! doc_list[idx].is_valid) return;
|
|
if (document_can_redo(idx)) document_redo(idx);
|
|
}
|
|
|
|
|
|
void
|
|
on_cut1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(app->window));
|
|
|
|
if (GTK_IS_EDITABLE(focusw))
|
|
gtk_editable_cut_clipboard(GTK_EDITABLE(focusw));
|
|
else
|
|
if (IS_SCINTILLA(focusw) && idx >= 0)
|
|
sci_cut(doc_list[idx].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)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(app->window));
|
|
|
|
if (GTK_IS_EDITABLE(focusw))
|
|
gtk_editable_copy_clipboard(GTK_EDITABLE(focusw));
|
|
else
|
|
if (IS_SCINTILLA(focusw) && idx >= 0)
|
|
sci_copy(doc_list[idx].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)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(app->window));
|
|
|
|
if (GTK_IS_EDITABLE(focusw))
|
|
gtk_editable_paste_clipboard(GTK_EDITABLE(focusw));
|
|
else
|
|
if (IS_SCINTILLA(focusw) && idx >= 0)
|
|
{
|
|
#ifdef G_OS_WIN32
|
|
// insert the text manually for now, because the auto conversion of EOL characters by
|
|
// by Scintilla seems to make problems
|
|
if (gtk_clipboard_wait_is_text_available(gtk_clipboard_get(GDK_NONE)))
|
|
{
|
|
gchar *content = gtk_clipboard_wait_for_text(gtk_clipboard_get(GDK_NONE));
|
|
if (content != NULL)
|
|
{
|
|
sci_replace_sel(doc_list[idx].sci, content);
|
|
g_free(content);
|
|
}
|
|
}
|
|
#else
|
|
sci_paste(doc_list[idx].sci);
|
|
#endif
|
|
}
|
|
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)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
GtkWidget *focusw = gtk_window_get_focus(GTK_WINDOW(app->window));
|
|
|
|
if (GTK_IS_EDITABLE(focusw))
|
|
gtk_editable_delete_selection(GTK_EDITABLE(focusw));
|
|
else
|
|
if (IS_SCINTILLA(focusw) && idx >= 0)
|
|
sci_clear(doc_list[idx].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_toolbutton19_clicked (GtkToolButton *toolbutton,
|
|
gpointer user_data)
|
|
{
|
|
on_exit_clicked(NULL, NULL);
|
|
}
|
|
|
|
|
|
// reload file
|
|
void
|
|
on_toolbutton23_clicked (GtkToolButton *toolbutton,
|
|
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)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
gchar *base_name;
|
|
gint i = GPOINTER_TO_INT(user_data);
|
|
gchar *charset = NULL;
|
|
|
|
if (idx < 0 || ! doc_list[idx].is_valid || doc_list[idx].file_name == NULL)
|
|
return;
|
|
if (i >= 0)
|
|
{
|
|
if (i >= GEANY_ENCODINGS_MAX || encodings[i].charset == NULL) return;
|
|
charset = encodings[i].charset;
|
|
}
|
|
|
|
base_name = g_path_get_basename(doc_list[idx].file_name);
|
|
if (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(idx, charset);
|
|
if (charset != NULL)
|
|
ui_update_statusbar(idx, -1);
|
|
}
|
|
g_free(base_name);
|
|
}
|
|
|
|
|
|
void
|
|
on_images_and_text2_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_toolbar_toggle) return;
|
|
|
|
gtk_toolbar_set_style(GTK_TOOLBAR(app->toolbar), GTK_TOOLBAR_BOTH);
|
|
prefs.toolbar_icon_style = GTK_TOOLBAR_BOTH;
|
|
}
|
|
|
|
|
|
void
|
|
on_images_only2_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_toolbar_toggle) return;
|
|
|
|
gtk_toolbar_set_style(GTK_TOOLBAR(app->toolbar), GTK_TOOLBAR_ICONS);
|
|
prefs.toolbar_icon_style = GTK_TOOLBAR_ICONS;
|
|
}
|
|
|
|
|
|
void
|
|
on_text_only2_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_toolbar_toggle) return;
|
|
|
|
gtk_toolbar_set_style(GTK_TOOLBAR(app->toolbar), GTK_TOOLBAR_TEXT);
|
|
prefs.toolbar_icon_style = GTK_TOOLBAR_TEXT;
|
|
}
|
|
|
|
|
|
void
|
|
on_change_font1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
dialogs_show_open_font();
|
|
}
|
|
|
|
|
|
// new file
|
|
void
|
|
on_toolbutton8_clicked (GtkToolButton *toolbutton,
|
|
gpointer user_data)
|
|
{
|
|
document_new_file(NULL, NULL);
|
|
}
|
|
|
|
// open file
|
|
void
|
|
on_toolbutton9_clicked (GtkToolButton *toolbutton,
|
|
gpointer user_data)
|
|
{
|
|
dialogs_show_open_file();
|
|
}
|
|
|
|
|
|
// save file
|
|
void
|
|
on_toolbutton10_clicked (GtkToolButton *toolbutton,
|
|
gpointer user_data)
|
|
{
|
|
on_save1_activate(NULL, user_data);
|
|
}
|
|
|
|
|
|
static void set_search_bar_background(gboolean success)
|
|
{
|
|
const GdkColor red = {0, 0xffff, 0x6666, 0x6666};
|
|
const GdkColor white = {0, 0xffff, 0xffff, 0xffff};
|
|
static gboolean old_value = TRUE;
|
|
GtkWidget *widget = lookup_widget(app->window, "entry1");
|
|
|
|
// only update if really needed
|
|
if (search_data.search_bar && old_value != success)
|
|
{
|
|
gtk_widget_modify_base(widget, GTK_STATE_NORMAL, success ? NULL : &red);
|
|
gtk_widget_modify_text(widget, GTK_STATE_NORMAL, success ? NULL : &white);
|
|
|
|
old_value = success;
|
|
}
|
|
}
|
|
|
|
|
|
// store text, clear search flags so we can use Search->Find Next/Previous
|
|
static void setup_find_next(GtkEditable *editable)
|
|
{
|
|
g_free(search_data.text);
|
|
search_data.text = gtk_editable_get_chars(editable, 0, -1);
|
|
search_data.flags = 0;
|
|
search_data.backwards = FALSE;
|
|
search_data.search_bar = TRUE;
|
|
}
|
|
|
|
|
|
// search text
|
|
void
|
|
on_entry1_activate (GtkEntry *entry,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
gboolean result;
|
|
|
|
setup_find_next(GTK_EDITABLE(entry));
|
|
result = document_search_bar_find(idx, search_data.text, 0, FALSE);
|
|
set_search_bar_background(result);
|
|
}
|
|
|
|
|
|
// search text
|
|
void
|
|
on_entry1_changed (GtkEditable *editable,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
gboolean result;
|
|
|
|
setup_find_next(editable);
|
|
result = document_search_bar_find(idx, search_data.text, 0, TRUE);
|
|
set_search_bar_background(result);
|
|
}
|
|
|
|
|
|
gboolean
|
|
on_entry1_key_press_event (GtkWidget *widget,
|
|
GdkEventKey *event,
|
|
gpointer user_data)
|
|
{
|
|
if (event->keyval == GDK_Escape)
|
|
{
|
|
keybindings_cmd(GEANY_KEYS_SWITCH_EDITOR);
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// search text
|
|
void
|
|
on_toolbutton18_clicked (GtkToolButton *toolbutton,
|
|
gpointer user_data)
|
|
{
|
|
//on_entry1_changed(NULL, NULL);
|
|
gint idx = document_get_cur_idx();
|
|
gboolean result;
|
|
GtkWidget *entry = lookup_widget(GTK_WIDGET(app->window), "entry1");
|
|
|
|
setup_find_next(GTK_EDITABLE(entry));
|
|
result = document_search_bar_find(idx, search_data.text, 0, FALSE);
|
|
set_search_bar_background(result);
|
|
}
|
|
|
|
|
|
void
|
|
on_toolbar_large_icons1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_toolbar_toggle) return;
|
|
|
|
prefs.toolbar_icon_size = GTK_ICON_SIZE_LARGE_TOOLBAR;
|
|
ui_update_toolbar_icons(GTK_ICON_SIZE_LARGE_TOOLBAR);
|
|
}
|
|
|
|
|
|
void
|
|
on_toolbar_small_icons1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (ignore_toolbar_toggle) return;
|
|
|
|
prefs.toolbar_icon_size = GTK_ICON_SIZE_SMALL_TOOLBAR;
|
|
ui_update_toolbar_icons(GTK_ICON_SIZE_SMALL_TOOLBAR);
|
|
}
|
|
|
|
|
|
// hides toolbar from toolbar popup menu
|
|
void
|
|
on_hide_toolbar1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
GtkWidget *tool_item = lookup_widget(GTK_WIDGET(app->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)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
static gboolean done = 1;
|
|
|
|
if (idx >= 0 && doc_list[idx].is_valid)
|
|
{
|
|
if (done++ % 3 == 0) sci_set_line_numbers(doc_list[idx].sci, editor_prefs.show_linenumber_margin,
|
|
(sci_get_zoom(doc_list[idx].sci) / 2));
|
|
sci_zoom_in(doc_list[idx].sci);
|
|
}
|
|
}
|
|
|
|
// zoom out from menu bar and popup menu
|
|
void
|
|
on_zoom_out1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (idx >= 0 && doc_list[idx].is_valid)
|
|
{
|
|
if (sci_get_zoom(doc_list[idx].sci) == 0)
|
|
sci_set_line_numbers(doc_list[idx].sci, editor_prefs.show_linenumber_margin, 0);
|
|
sci_zoom_out(doc_list[idx].sci);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_normal_size1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (idx >= 0 && doc_list[idx].is_valid)
|
|
{
|
|
sci_zoom_off(doc_list[idx].sci);
|
|
sci_set_line_numbers(doc_list[idx].sci, editor_prefs.show_linenumber_margin, 0);
|
|
}
|
|
}
|
|
|
|
|
|
// close tab
|
|
void
|
|
on_toolbutton15_clicked (GtkToolButton *toolbutton,
|
|
gpointer user_data)
|
|
{
|
|
gint cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(app->notebook));
|
|
document_remove(cur_page);
|
|
}
|
|
|
|
|
|
void
|
|
on_notebook1_switch_page (GtkNotebook *notebook,
|
|
GtkNotebookPage *page,
|
|
guint page_num,
|
|
gpointer user_data)
|
|
{
|
|
callbacks_data.last_doc_idx = document_get_cur_idx();
|
|
}
|
|
|
|
|
|
// changes window-title on switching tabs and lots of other things
|
|
void
|
|
on_notebook1_switch_page_after (GtkNotebook *notebook,
|
|
GtkNotebookPage *page,
|
|
guint page_num,
|
|
gpointer user_data)
|
|
{
|
|
gint idx;
|
|
|
|
if (closing_all) return;
|
|
|
|
// guint == -1 seems useless, but it isn't!
|
|
if (page_num == (guint) -1 && page != NULL)
|
|
idx = document_find_by_sci(SCINTILLA(page));
|
|
else
|
|
idx = document_get_n_idx(page_num);
|
|
|
|
if (idx >= 0 && main_status.opening_session_files == FALSE)
|
|
{
|
|
treeviews_select_openfiles_item(idx);
|
|
document_set_text_changed(idx); // also sets window title and status bar
|
|
ui_update_popup_reundo_items(idx);
|
|
ui_document_show_hide(idx); // update the document menu
|
|
build_menu_update(idx);
|
|
treeviews_update_tag_list(idx, FALSE);
|
|
|
|
utils_check_disk_status(idx, FALSE);
|
|
|
|
#ifdef HAVE_VTE
|
|
vte_cwd(doc_list[idx].file_name, FALSE);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_tv_notebook_switch_page (GtkNotebook *notebook,
|
|
GtkNotebookPage *page,
|
|
guint page_num,
|
|
gpointer user_data)
|
|
{
|
|
//switch_tv_notebook_page = TRUE;
|
|
}
|
|
|
|
|
|
gboolean
|
|
on_window_key_press_event (GtkWidget *widget,
|
|
GdkEventKey *event,
|
|
gpointer user_data)
|
|
{
|
|
return event->keyval == 0 ? FALSE : keybindings_got_event(widget, event, user_data);
|
|
}
|
|
|
|
|
|
void
|
|
on_crlf_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (app->ignore_callback || idx == -1 || ! doc_list[idx].is_valid) return;
|
|
sci_convert_eols(doc_list[idx].sci, SC_EOL_CRLF);
|
|
sci_set_eol_mode(doc_list[idx].sci, SC_EOL_CRLF);
|
|
}
|
|
|
|
|
|
void
|
|
on_lf_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (app->ignore_callback || idx == -1 || ! doc_list[idx].is_valid) return;
|
|
sci_convert_eols(doc_list[idx].sci, SC_EOL_LF);
|
|
sci_set_eol_mode(doc_list[idx].sci, SC_EOL_LF);
|
|
}
|
|
|
|
|
|
void
|
|
on_cr_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (app->ignore_callback || idx == -1 || ! doc_list[idx].is_valid) return;
|
|
sci_convert_eols(doc_list[idx].sci, SC_EOL_CR);
|
|
sci_set_eol_mode(doc_list[idx].sci, SC_EOL_CR);
|
|
}
|
|
|
|
|
|
void
|
|
on_replace_tabs_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
|
|
document_replace_tabs(idx);
|
|
}
|
|
|
|
|
|
gboolean
|
|
toolbar_popup_menu (GtkWidget *widget,
|
|
GdkEventButton *event,
|
|
gpointer user_data)
|
|
{
|
|
if (event->button == 3)
|
|
{
|
|
GtkWidget *w;
|
|
|
|
ignore_toolbar_toggle = TRUE;
|
|
|
|
switch (prefs.toolbar_icon_style)
|
|
{
|
|
case 0: w = lookup_widget(ui_widgets.toolbar_menu, "images_only2"); break;
|
|
case 1: w = lookup_widget(ui_widgets.toolbar_menu, "text_only2"); break;
|
|
default: w = lookup_widget(ui_widgets.toolbar_menu, "images_and_text2"); break;
|
|
}
|
|
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w), TRUE);
|
|
|
|
switch (prefs.toolbar_icon_size)
|
|
{
|
|
case GTK_ICON_SIZE_LARGE_TOOLBAR:
|
|
widget = lookup_widget(ui_widgets.toolbar_menu, "large_icons1"); break;
|
|
default: widget = lookup_widget(ui_widgets.toolbar_menu, "small_icons1"); break;
|
|
}
|
|
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w), TRUE);
|
|
|
|
ignore_toolbar_toggle = FALSE;
|
|
|
|
gtk_menu_popup(GTK_MENU(ui_widgets.toolbar_menu), NULL, NULL, NULL, NULL, event->button, event->time);
|
|
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void
|
|
on_to_lower_case1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
|
|
if (idx < 0 || ! doc_list[idx].is_valid) return;
|
|
|
|
sci_cmd(doc_list[idx].sci, SCI_LOWERCASE);
|
|
}
|
|
|
|
|
|
void
|
|
on_to_upper_case1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
|
|
if (idx < 0 || ! doc_list[idx].is_valid) return;
|
|
|
|
sci_cmd(doc_list[idx].sci, SCI_UPPERCASE);
|
|
}
|
|
|
|
|
|
void
|
|
on_show_toolbar1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (app->ignore_callback) return;
|
|
|
|
prefs.toolbar_visible = (prefs.toolbar_visible) ? FALSE : TRUE;;
|
|
ui_widget_show_hide(GTK_WIDGET(app->toolbar), prefs.toolbar_visible);
|
|
}
|
|
|
|
|
|
void
|
|
on_fullscreen1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
ui_prefs.fullscreen = (ui_prefs.fullscreen) ? FALSE : TRUE;
|
|
ui_set_fullscreen();
|
|
}
|
|
|
|
|
|
void
|
|
on_show_messages_window1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (app->ignore_callback) return;
|
|
|
|
ui_prefs.msgwindow_visible = (ui_prefs.msgwindow_visible) ? FALSE : TRUE;
|
|
ui_widget_show_hide(lookup_widget(app->window, "scrolledwindow1"), ui_prefs.msgwindow_visible);
|
|
}
|
|
|
|
|
|
void
|
|
on_markers_margin1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
editor_prefs.show_markers_margin = (editor_prefs.show_markers_margin) ? FALSE : TRUE;
|
|
ui_show_markers_margin();
|
|
}
|
|
|
|
|
|
void
|
|
on_show_line_numbers1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
editor_prefs.show_linenumber_margin = (editor_prefs.show_linenumber_margin) ? FALSE : TRUE;
|
|
ui_show_linenumber_margin();
|
|
}
|
|
|
|
|
|
void
|
|
on_line_breaking1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (! app->ignore_callback)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (idx == -1 || ! doc_list[idx].is_valid) return;
|
|
doc_list[idx].line_breaking = ! doc_list[idx].line_breaking;
|
|
sci_set_lines_wrapped(doc_list[idx].sci, doc_list[idx].line_breaking);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_set_file_readonly1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (! app->ignore_callback)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (idx == -1 || ! doc_list[idx].is_valid) return;
|
|
doc_list[idx].readonly = ! doc_list[idx].readonly;
|
|
sci_set_readonly(doc_list[idx].sci, doc_list[idx].readonly);
|
|
ui_update_tab_status(idx);
|
|
ui_update_statusbar(idx, -1);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_use_auto_indentation1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (! app->ignore_callback)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (idx == -1 || ! doc_list[idx].is_valid) return;
|
|
doc_list[idx].auto_indent = ! doc_list[idx].auto_indent;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_find_usage1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint flags, idx;
|
|
gchar *search_text;
|
|
|
|
idx = document_get_cur_idx();
|
|
if (! DOC_IDX_VALID(idx)) return;
|
|
|
|
if (sci_can_copy(doc_list[idx].sci))
|
|
{ // take selected text if there is a selection
|
|
search_text = g_malloc(sci_get_selected_text_length(doc_list[idx].sci) + 1);
|
|
sci_get_selected_text(doc_list[idx].sci, search_text);
|
|
flags = SCFIND_MATCHCASE;
|
|
}
|
|
else
|
|
{
|
|
search_text = g_strdup(editor_info.current_word);
|
|
flags = SCFIND_MATCHCASE | SCFIND_WHOLEWORD;
|
|
}
|
|
|
|
search_find_usage(search_text, flags, TRUE);
|
|
g_free(search_text);
|
|
}
|
|
|
|
|
|
void
|
|
on_goto_tag_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
const gint forward_types = tm_tag_prototype_t | tm_tag_externvar_t;
|
|
gint type;
|
|
TMTag *tmtag;
|
|
|
|
// goto tag definition: all except prototypes / forward declarations / externs
|
|
if (menuitem == GTK_MENU_ITEM(lookup_widget(app->popup_menu, "goto_tag_definition1")))
|
|
type = tm_tag_max_t - forward_types;
|
|
else
|
|
type = forward_types;
|
|
|
|
tmtag = symbols_find_in_workspace(editor_info.current_word, type);
|
|
if (tmtag != NULL)
|
|
{
|
|
gint old_idx = document_get_cur_idx(); // get idx before switching the file
|
|
|
|
if (utils_goto_file_line(
|
|
tmtag->atts.entry.file->work_object.file_name,
|
|
TRUE, tmtag->atts.entry.line))
|
|
{
|
|
// first add old file as old position
|
|
if (doc_list[old_idx].tm_file)
|
|
navqueue_new_position(doc_list[old_idx].tm_file->file_name,
|
|
sci_get_line_from_position(doc_list[old_idx].sci, editor_info.click_pos) + 1);
|
|
|
|
navqueue_new_position(tmtag->atts.entry.file->work_object.file_name,
|
|
tmtag->atts.entry.line);
|
|
return;
|
|
}
|
|
}
|
|
// if we are here, there was no match and we are beeping ;-)
|
|
utils_beep();
|
|
if (type == forward_types)
|
|
ui_set_statusbar(_("Forward declaration \"%s\" not found."), editor_info.current_word);
|
|
else
|
|
ui_set_statusbar(_("Definition of \"%s\" not found."), editor_info.current_word);
|
|
}
|
|
|
|
|
|
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];
|
|
gint idx = document_get_cur_idx();
|
|
gint pos = sci_get_current_position(doc_list[idx].sci);
|
|
|
|
if (idx == -1 || ! doc_list[idx].is_valid)
|
|
return;
|
|
|
|
editor_find_current_word(doc_list[idx].sci, pos, colour, sizeof colour, GEANY_WORDCHARS"#");
|
|
tools_color_chooser(colour);
|
|
}
|
|
|
|
|
|
void
|
|
on_compile_button_clicked (GtkToolButton *toolbutton,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_cmd(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)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
|
|
if (search_data.text)
|
|
{
|
|
gint result = document_find_text(idx, search_data.text, search_data.flags,
|
|
search_data.backwards, TRUE, NULL);
|
|
|
|
set_search_bar_background((result > -1) ? TRUE : FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_find_previous1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
|
|
if (search_data.text == NULL) return;
|
|
|
|
if (search_data.flags & SCFIND_REGEXP)
|
|
utils_beep(); //Can't reverse search order for a regex (find next ignores search backwards)
|
|
else
|
|
{
|
|
gint result = document_find_text(idx, search_data.text, search_data.flags,
|
|
!search_data.backwards, TRUE, NULL);
|
|
|
|
set_search_bar_background((result > -1) ? TRUE : FALSE);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_find_nextsel1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
search_find_selection(document_get_cur_idx(), FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
on_find_prevsel1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
search_find_selection(document_get_cur_idx(), 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();
|
|
}
|
|
|
|
|
|
void
|
|
on_toolbutton_new_clicked (GtkToolButton *toolbutton,
|
|
gpointer user_data)
|
|
{
|
|
document_new_file(NULL, NULL);
|
|
}
|
|
|
|
|
|
void
|
|
on_go_to_line_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
dialogs_show_goto_line();
|
|
}
|
|
|
|
|
|
void
|
|
on_goto_line_dialog_response (GtkDialog *dialog,
|
|
gint response,
|
|
gpointer user_data)
|
|
{
|
|
if (response == GTK_RESPONSE_ACCEPT)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
gint line = strtol(gtk_entry_get_text(GTK_ENTRY(user_data)), NULL, 10);
|
|
|
|
if (line > 0 && line <= sci_get_line_count(doc_list[idx].sci))
|
|
{
|
|
utils_goto_line(idx, line);
|
|
}
|
|
else
|
|
{
|
|
utils_beep();
|
|
}
|
|
|
|
}
|
|
if (dialog) gtk_widget_destroy(GTK_WIDGET(dialog));
|
|
}
|
|
|
|
|
|
void
|
|
on_goto_line_entry_activate (GtkEntry *entry,
|
|
gpointer user_data)
|
|
{
|
|
on_goto_line_dialog_response(GTK_DIALOG(user_data), GTK_RESPONSE_ACCEPT, entry);
|
|
}
|
|
|
|
|
|
void
|
|
on_entry_goto_line_activate (GtkEntry *entry,
|
|
gpointer user_data)
|
|
{
|
|
on_goto_line_dialog_response(NULL, GTK_RESPONSE_ACCEPT, entry);
|
|
}
|
|
|
|
|
|
gboolean
|
|
on_entry_goto_line_key_press_event (GtkWidget *widget,
|
|
GdkEventKey *event,
|
|
gpointer user_data)
|
|
{
|
|
return on_entry1_key_press_event(widget, event, user_data);
|
|
}
|
|
|
|
|
|
void
|
|
on_toolbutton_goto_clicked (GtkToolButton *toolbutton,
|
|
gpointer user_data)
|
|
{
|
|
on_goto_line_dialog_response(NULL, GTK_RESPONSE_ACCEPT,
|
|
lookup_widget(app->window, "entry_goto_line"));
|
|
}
|
|
|
|
|
|
void
|
|
on_help1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint skip;
|
|
gchar *uri;
|
|
|
|
#ifdef G_OS_WIN32
|
|
skip = 8;
|
|
uri = g_strconcat("file:///", app->docdir, "/index.html", NULL);
|
|
g_strdelimit(uri, "\\", '/'); // replace '\\' by '/'
|
|
#else
|
|
skip = 7;
|
|
uri = g_strconcat("file://", app->docdir, "index.html", NULL);
|
|
#endif
|
|
|
|
if (! g_file_test(uri + skip, G_FILE_TEST_IS_REGULAR))
|
|
{ // fall back to online documentation if it is not found on the hard disk
|
|
g_free(uri);
|
|
uri = g_strconcat(GEANY_HOMEPAGE, "manual/index.html", NULL);
|
|
}
|
|
|
|
utils_start_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_start_browser(GEANY_HOMEPAGE);
|
|
}
|
|
|
|
|
|
void
|
|
on_comments_function_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
gchar *text;
|
|
const gchar *cur_tag = NULL;
|
|
gint line = -1, pos = 0;
|
|
|
|
if (doc_list[idx].file_type == NULL)
|
|
{
|
|
ui_set_statusbar(_("Please set the filetype for the current file before using this function."));
|
|
return;
|
|
}
|
|
|
|
// utils_get_current_function returns -1 on failure, so sci_get_position_from_line
|
|
// returns the current position, so it should be safe
|
|
line = utils_get_current_function(idx, &cur_tag);
|
|
pos = sci_get_position_from_line(doc_list[idx].sci, line - 1);
|
|
|
|
text = templates_get_template_function(doc_list[idx].file_type->id, cur_tag);
|
|
|
|
sci_insert_text(doc_list[idx].sci, pos, text);
|
|
g_free(text);
|
|
}
|
|
|
|
|
|
void
|
|
on_comments_multiline_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
|
|
if (! DOC_IDX_VALID(idx) || doc_list[idx].file_type == NULL)
|
|
{
|
|
ui_set_statusbar(_("Please set the filetype for the current file before using this function."));
|
|
return;
|
|
}
|
|
|
|
verify_click_pos(idx); // make sure that the click_pos is valid
|
|
|
|
editor_insert_multiline_comment(idx);
|
|
}
|
|
|
|
|
|
void
|
|
on_comments_gpl_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
gchar *text;
|
|
|
|
text = templates_get_template_licence(FILETYPE_ID(doc_list[idx].file_type), GEANY_TEMPLATE_GPL);
|
|
|
|
verify_click_pos(idx); // make sure that the click_pos is valid
|
|
|
|
sci_insert_text(doc_list[idx].sci, editor_info.click_pos, text);
|
|
g_free(text);
|
|
}
|
|
|
|
|
|
void
|
|
on_comments_bsd_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
|
|
gint idx = document_get_cur_idx();
|
|
gchar *text;
|
|
|
|
text = templates_get_template_licence(FILETYPE_ID(doc_list[idx].file_type), GEANY_TEMPLATE_BSD);
|
|
|
|
verify_click_pos(idx); // make sure that the click_pos is valid
|
|
|
|
sci_insert_text(doc_list[idx].sci, editor_info.click_pos, text);
|
|
g_free(text);
|
|
|
|
}
|
|
|
|
|
|
void
|
|
on_comments_changelog_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
gchar *text;
|
|
|
|
text = templates_get_template_changelog();
|
|
sci_insert_text(doc_list[idx].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_list[idx].sci, 21 + strlen(prefs.template_developer) + strlen(prefs.template_mail), TRUE);
|
|
|
|
g_free(text);
|
|
}
|
|
|
|
|
|
void
|
|
on_comments_fileheader_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
gchar *text;
|
|
gchar *fname;
|
|
filetype *ft;
|
|
|
|
g_return_if_fail(DOC_IDX_VALID(idx));
|
|
|
|
ft = doc_list[idx].file_type;
|
|
fname = doc_list[idx].file_name;
|
|
text = templates_get_template_fileheader(FILETYPE_ID(ft), fname);
|
|
|
|
sci_insert_text(doc_list[idx].sci, 0, text);
|
|
sci_goto_pos(doc_list[idx].sci, 0, FALSE);
|
|
g_free(text);
|
|
}
|
|
|
|
|
|
void
|
|
on_custom_date_dialog_response (GtkDialog *dialog,
|
|
gint response,
|
|
gpointer user_data)
|
|
{
|
|
if (response == GTK_RESPONSE_ACCEPT)
|
|
{
|
|
g_free(ui_prefs.custom_date_format);
|
|
ui_prefs.custom_date_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(user_data)));
|
|
}
|
|
gtk_widget_destroy(GTK_WIDGET(dialog));
|
|
}
|
|
|
|
|
|
void
|
|
on_custom_date_entry_activate (GtkEntry *entry,
|
|
gpointer user_data)
|
|
{
|
|
on_custom_date_dialog_response(GTK_DIALOG(user_data), GTK_RESPONSE_ACCEPT, entry);
|
|
}
|
|
|
|
|
|
void
|
|
on_insert_date_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
gchar *format;
|
|
gchar time_str[300]; // the entered format string can be maximal 256 chars long, so we have
|
|
// 44 additional characters for strtime's conversion
|
|
time_t t;
|
|
struct tm *tm;
|
|
|
|
if (idx < 0 || ! doc_list[idx].is_valid) return;
|
|
|
|
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
|
|
{
|
|
// 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");
|
|
}
|
|
|
|
dialogs_show_input(_("Custom Date Format"),
|
|
_("Enter here a custom date and time format. You can use any conversion specifiers which can be used with the ANSI C strftime function. See \"man strftime\" for more information."),
|
|
ui_prefs.custom_date_format,
|
|
G_CALLBACK(on_custom_date_dialog_response),
|
|
G_CALLBACK(on_custom_date_entry_activate));
|
|
return;
|
|
}
|
|
|
|
// get the current time
|
|
t = time(NULL);
|
|
tm = localtime(&t);
|
|
if (strftime(time_str, sizeof time_str, format, tm) != 0)
|
|
{
|
|
verify_click_pos(idx); // make sure that the click_pos is valid
|
|
|
|
sci_insert_text(doc_list[idx].sci, editor_info.click_pos, time_str);
|
|
}
|
|
else
|
|
{
|
|
utils_beep();
|
|
msgwin_status_add(
|
|
_("Date format string could not be converted (possibly too long)."));
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_insert_include_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
gint pos = -1;
|
|
gchar *text;
|
|
|
|
if (! DOC_IDX_VALID(idx) || user_data == NULL) return;
|
|
|
|
verify_click_pos(idx); // 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_insert_text(doc_list[idx].sci, editor_info.click_pos, text);
|
|
g_free(text);
|
|
if (pos >= 0)
|
|
sci_goto_pos(doc_list[idx].sci, pos, FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
on_file_properties_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
dialogs_show_file_properties(idx);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_fold_all1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
|
|
document_fold_all(idx);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_unfold_all1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
|
|
document_unfold_all(idx);
|
|
}
|
|
|
|
|
|
void
|
|
on_run_button_clicked (GtkToolButton *toolbutton,
|
|
gpointer user_data)
|
|
{
|
|
keybindings_cmd(GEANY_KEYS_BUILD_RUN);
|
|
}
|
|
|
|
|
|
void
|
|
on_go_to_line1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
// this is search menu cb; call popup menu goto cb
|
|
on_go_to_line_activate(menuitem, user_data);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_remove_indicators1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
|
|
if (! DOC_IDX_VALID(idx))
|
|
return;
|
|
document_clear_indicators(idx);
|
|
}
|
|
|
|
|
|
void
|
|
on_encoding_change (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
guint i = GPOINTER_TO_INT(user_data);
|
|
|
|
if (app->ignore_callback || ! DOC_IDX_VALID(idx) || encodings[i].charset == NULL ||
|
|
utils_str_equal(encodings[i].charset, doc_list[idx].encoding)) return;
|
|
|
|
if (doc_list[idx].readonly)
|
|
{
|
|
utils_beep();
|
|
return;
|
|
}
|
|
document_undo_add(idx, UNDO_ENCODING, g_strdup(doc_list[idx].encoding));
|
|
|
|
document_set_encoding(idx, encodings[i].charset);
|
|
}
|
|
|
|
|
|
void
|
|
on_print1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
|
|
document_print(idx);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_select_all1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
|
|
if (idx < 0 || ! doc_list[idx].is_valid) return;
|
|
|
|
sci_select_all(doc_list[idx].sci);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_show_sidebar1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
static gint active_page = -1;
|
|
|
|
if (app->ignore_callback) return;
|
|
|
|
if (ui_prefs.sidebar_visible)
|
|
{
|
|
// to remember the active page because GTK (e.g. 2.8.18) doesn't do it and shows always
|
|
// the last page (for unknown reason, with GTK 2.6.4 it works)
|
|
active_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(app->treeview_notebook));
|
|
}
|
|
|
|
ui_prefs.sidebar_visible = ! ui_prefs.sidebar_visible;
|
|
|
|
if ((! prefs.sidebar_openfiles_visible && ! prefs.sidebar_symbol_visible))
|
|
{
|
|
prefs.sidebar_openfiles_visible = TRUE;
|
|
prefs.sidebar_symbol_visible = TRUE;
|
|
}
|
|
|
|
ui_treeviews_show_hide(TRUE);
|
|
gtk_notebook_set_current_page(GTK_NOTEBOOK(app->treeview_notebook), active_page);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_write_unicode_bom1_toggled (GtkCheckMenuItem *checkmenuitem,
|
|
gpointer user_data)
|
|
{
|
|
if (! app->ignore_callback)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
|
|
if (idx == -1 || ! doc_list[idx].is_valid) return;
|
|
if (doc_list[idx].readonly)
|
|
{
|
|
utils_beep();
|
|
return;
|
|
}
|
|
|
|
document_undo_add(idx, UNDO_BOM, GINT_TO_POINTER(doc_list[idx].has_bom));
|
|
|
|
doc_list[idx].has_bom = ! doc_list[idx].has_bom;
|
|
|
|
ui_update_statusbar(idx, -1);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_comment_line1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (idx == -1 || ! doc_list[idx].is_valid) return;
|
|
editor_do_comment(idx, -1, FALSE, FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_uncomment_line1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (idx == -1 || ! doc_list[idx].is_valid) return;
|
|
editor_do_uncomment(idx, -1, FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_toggle_line_commentation1_activate
|
|
(GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (idx == -1 || ! doc_list[idx].is_valid) return;
|
|
editor_do_comment_toggle(idx);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_duplicate_line1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (idx == -1 || ! doc_list[idx].is_valid) return;
|
|
if (sci_can_copy(doc_list[idx].sci))
|
|
sci_selection_duplicate(doc_list[idx].sci);
|
|
else
|
|
sci_line_duplicate(doc_list[idx].sci);
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_increase_indent1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (! DOC_IDX_VALID(idx)) return;
|
|
|
|
if (sci_get_lines_selected(doc_list[idx].sci) > 1)
|
|
{
|
|
sci_cmd(doc_list[idx].sci, SCI_TAB);
|
|
}
|
|
else
|
|
{
|
|
gint line, ind_pos, old_pos, new_pos, step;
|
|
|
|
old_pos = sci_get_current_position(doc_list[idx].sci);
|
|
line = sci_get_current_line(doc_list[idx].sci, old_pos);
|
|
ind_pos = sci_get_line_indent_position(doc_list[idx].sci, line);
|
|
// when using tabs increase cur pos by 1, when using space increase it by tab_width
|
|
step = (editor_prefs.use_tabs) ? 1 : editor_prefs.tab_width;
|
|
new_pos = (old_pos > ind_pos) ? old_pos + step : old_pos;
|
|
|
|
sci_set_current_position(doc_list[idx].sci, ind_pos, TRUE);
|
|
sci_cmd(doc_list[idx].sci, SCI_TAB);
|
|
sci_set_current_position(doc_list[idx].sci, new_pos, TRUE);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_decrease_indent1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
if (! DOC_IDX_VALID(idx)) return;
|
|
|
|
if (sci_get_lines_selected(doc_list[idx].sci) > 1)
|
|
{
|
|
sci_cmd(doc_list[idx].sci, SCI_BACKTAB);
|
|
}
|
|
else
|
|
{
|
|
gint line, ind_pos, old_pos, new_pos, step, indent;
|
|
|
|
old_pos = sci_get_current_position(doc_list[idx].sci);
|
|
line = sci_get_current_line(doc_list[idx].sci, old_pos);
|
|
ind_pos = sci_get_line_indent_position(doc_list[idx].sci, line);
|
|
step = (editor_prefs.use_tabs) ? 1 : editor_prefs.tab_width;
|
|
new_pos = (old_pos >= ind_pos) ? old_pos - step : old_pos;
|
|
|
|
if (ind_pos == sci_get_position_from_line(doc_list[idx].sci, line))
|
|
return;
|
|
|
|
sci_set_current_position(doc_list[idx].sci, ind_pos, TRUE);
|
|
indent = sci_get_line_indentation(doc_list[idx].sci, line);
|
|
indent -= editor_prefs.tab_width;
|
|
if (indent < 0)
|
|
indent = 0;
|
|
sci_set_line_indentation(doc_list[idx].sci, line, indent);
|
|
|
|
sci_set_current_position(doc_list[idx].sci, new_pos, TRUE);
|
|
}
|
|
}
|
|
|
|
|
|
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(_("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();
|
|
}
|
|
|
|
|
|
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 = lookup_widget(app->window, "project_close1");
|
|
item_properties = lookup_widget(app->window, "project_properties1");
|
|
}
|
|
|
|
gtk_widget_set_sensitive(item_close, (app->project != NULL));
|
|
gtk_widget_set_sensitive(item_properties, (app->project != NULL));
|
|
}
|
|
|
|
|
|
void
|
|
on_menu_open_selected_file1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
gchar *filename = NULL;
|
|
|
|
if (idx == -1 || ! doc_list[idx].is_valid) return;
|
|
|
|
if (sci_get_lines_selected(doc_list[idx].sci) == 1)
|
|
{
|
|
gint len = sci_get_selected_text_length(doc_list[idx].sci);
|
|
|
|
filename = g_malloc(len + 1);
|
|
sci_get_selected_text(doc_list[idx].sci, filename);
|
|
}
|
|
else if (sci_get_lines_selected(doc_list[idx].sci) == 0)
|
|
{ // use the word at current cursor position
|
|
gchar word[GEANY_MAX_WORD_LENGTH];
|
|
|
|
editor_find_current_word(doc_list[idx].sci, -1, word, sizeof(word), GEANY_WORDCHARS"./");
|
|
if (word[0] != '\0')
|
|
filename = g_strdup(word);
|
|
}
|
|
|
|
if (filename != NULL)
|
|
{
|
|
gchar *locale_filename;
|
|
|
|
if (! g_path_is_absolute(filename))
|
|
{ // relative filename, add the path of the current file
|
|
gchar *path;
|
|
gchar *tmp = filename;
|
|
|
|
// use the projects base path if we have an open project (useful?)
|
|
if (app->project != NULL && app->project->base_path != NULL)
|
|
path = g_strdup(app->project->base_path);
|
|
else
|
|
path = g_path_get_dirname(doc_list[idx].file_name);
|
|
|
|
filename = g_strconcat(path, G_DIR_SEPARATOR_S, filename, NULL);
|
|
g_free(tmp);
|
|
g_free(path);
|
|
}
|
|
|
|
locale_filename = utils_get_locale_from_utf8(filename);
|
|
document_open_file(-1, locale_filename, 0, FALSE, NULL, NULL);
|
|
|
|
g_free(filename);
|
|
g_free(locale_filename);
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
on_remove_markers1_activate (GtkMenuItem *menuitem,
|
|
gpointer user_data)
|
|
{
|
|
gint idx = document_get_cur_idx();
|
|
|
|
if (! DOC_IDX_VALID(idx))
|
|
return;
|
|
|
|
sci_marker_delete_all(doc_list[idx].sci, 0); // delete the yellow tag marker
|
|
sci_marker_delete_all(doc_list[idx].sci, 1); // delete user markers
|
|
}
|
|
|
|
|
|
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)
|
|
{
|
|
gint idx;
|
|
gchar *word, *command;
|
|
GError *error = NULL;
|
|
|
|
idx = document_get_cur_idx();
|
|
if (! DOC_IDX_VALID(idx)) return;
|
|
|
|
if (sci_can_copy(doc_list[idx].sci))
|
|
{ // take selected text if there is a selection
|
|
word = g_malloc(sci_get_selected_text_length(doc_list[idx].sci) + 1);
|
|
sci_get_selected_text(doc_list[idx].sci, word);
|
|
}
|
|
else
|
|
{
|
|
word = g_strdup(editor_info.current_word);
|
|
}
|
|
|
|
// use the filetype specific command if available, fallback to global command otherwise
|
|
if (doc_list[idx].file_type != NULL &&
|
|
doc_list[idx].file_type->context_action_cmd != NULL &&
|
|
*doc_list[idx].file_type->context_action_cmd != '\0')
|
|
{
|
|
command = g_strdup(doc_list[idx].file_type->context_action_cmd);
|
|
}
|
|
else
|
|
{
|
|
command = g_strdup(prefs.context_action_cmd);
|
|
}
|
|
|
|
// substitute the wildcard %s and run the command if it is non empty
|
|
if (command != NULL && *command != '\0')
|
|
{
|
|
command = utils_str_replace(command, "%s", word);
|
|
|
|
if (! g_spawn_command_line_async(command, &error))
|
|
{
|
|
msgwin_status_add("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(lookup_widget(app->window, "menu_show_messages_window1"));
|
|
GtkCheckMenuItem *toolbari = GTK_CHECK_MENU_ITEM(lookup_widget(app->window, "menu_show_toolbar1"));
|
|
|
|
// get the initial state (necessary if Geany was closed with hide_all = TRUE)
|
|
if (hide_all == -1)
|
|
{
|
|
if (! gtk_check_menu_item_get_active(msgw) &&
|
|
! 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));
|
|
|
|
prefs.show_notebook_tabs = FALSE;
|
|
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(app->notebook), 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));
|
|
|
|
prefs.show_notebook_tabs = TRUE;
|
|
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(app->notebook), 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;
|
|
}
|
|
|