📄 view.c
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- *//* Clean part of this 10-00, by Chema. divided the ugly code and the nice one *//* * gedit * * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. */#include <config.h>#include <gnome.h>#include "auto.h"#include "undo.h"#include "print.h"#include "utils.h"#include "file.h"#include "menus.h"#include "view.h"#include "document.h"#include "commands.h"#include "prefs.h"#include "window.h"static GtkVBoxClass * parent_class;struct _GeditViewClass{ GtkVBoxClass parent_class;};static void gedit_view_class_init (GeditViewClass *klass);static void gedit_view_init (GeditView *view);/** * gedit_view_get_type: * @void: * * Std. get type function * * Return Value: **//* ------------------ Cleaned stuff -------------------------*/guintgedit_view_get_type (void){ static GtkType gedit_view_type = 0; if (!gedit_view_type) { GtkTypeInfo gedit_view_info = { "GeditView", sizeof (GeditView), sizeof (GeditViewClass), (GtkClassInitFunc) gedit_view_class_init, (GtkObjectInitFunc) gedit_view_init, (GtkArgSetFunc) NULL, (GtkArgGetFunc) NULL, }; gedit_view_type = gtk_type_unique (gtk_vbox_get_type (), &gedit_view_info); } return gedit_view_type;}/** * gedit_view_finalize: * @object: * * View finalize function. **/static void gedit_view_destroy (GtkObject *object){ GeditView *view; gedit_debug (DEBUG_VIEW, ""); view = GEDIT_VIEW (object); g_return_if_fail (GEDIT_IS_VIEW (view)); g_free (view->toolbar); if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);}/** * gedit_view_class_init: * @klass: * * Std GTk class init **/static voidgedit_view_class_init (GeditViewClass *klass){ GtkObjectClass *object_class; gedit_debug (DEBUG_VIEW, ""); object_class = (GtkObjectClass *)klass; parent_class = gtk_type_class (gtk_vbox_get_type ()); object_class->destroy = gedit_view_destroy;}/** * gedit_view_active: * @void: * * Get the active view * * Return Value: The active view, NULL if thera aren't any views **/GeditView *gedit_view_active (void){ GeditView *current_view = NULL; gedit_debug (DEBUG_VIEW, ""); if (mdi->active_view) current_view = GEDIT_VIEW (mdi->active_view); return current_view;}/** * gedit_view_get_window_position: * @view: View to get the position from * * Get the visible position of a view * * Return Value: the current visible position of the view **/gfloatgedit_view_get_window_position (GeditView *view){ gedit_debug (DEBUG_VIEW, ""); g_return_val_if_fail (GEDIT_IS_VIEW (view), 0.0); return GTK_ADJUSTMENT(view->text->vadj)->value;}/** * gedit_view_set_window_position: * @view: View to set * @position: Position. * * Set the visible view position **/voidgedit_view_set_window_position (GeditView *view, gfloat position){ gedit_debug (DEBUG_VIEW, ""); g_return_if_fail (GEDIT_IS_VIEW (view)); gtk_adjustment_set_value (GTK_ADJUSTMENT(view->text->vadj), position);}/** * gedit_view_set_window_position_from_lines: * @view: * @line: line to move to * @lines: total number of line in the view (document) * * Given a line number and the toltal number of lines, move to visible part of * the view so that line is visible. This is usefull so that the screen does not * scroll and we can move rapidly to a different visible section of the view **/voidgedit_view_set_window_position_from_lines (GeditView *view, guint line, guint lines){ gfloat upper; gfloat value; gfloat page_size; gfloat gt; gfloat min; gfloat max; gedit_debug (DEBUG_VIEW, ""); g_return_if_fail (GEDIT_IS_VIEW (view)); g_return_if_fail (line <= lines); upper = GTK_ADJUSTMENT (view->text->vadj)->upper; value = GTK_ADJUSTMENT (view->text->vadj)->value; page_size = GTK_ADJUSTMENT (view->text->vadj)->page_size; min = value; max = value + (0.9 * page_size); /* We don't want to be in the lower 10%*/ gt = upper * (float)(line-1) / (float)(lines-1); /* No need to move */ if (gt > min && gt < max) return; gedit_view_set_window_position (view, gt); }/** * gedit_view_set_selection: * @view: View to set the selection * @start: start of selection to be set * @end: end of selection to be set * * Sets the selection from start to end. If start & end are 0, it clears the * selection **/voidgedit_view_set_selection (GeditView *view, guint start, guint end){ gedit_debug (DEBUG_VIEW, ""); g_return_if_fail (GEDIT_IS_VIEW (view)); if (start == 0 && end == 0) gtk_text_set_point (view->text, GTK_EDITABLE(view->text)->selection_end_pos); gtk_editable_select_region (GTK_EDITABLE (view->text), start, end); if (start == 0 && end == 0) { gtk_text_insert (view->text, NULL, NULL, NULL, " ", 1); gtk_text_backward_delete (view->text, 1); }}/** * gedit_view_get_selection: * @view: View to get the selection from * @start: return here the start position of the selection * @end: return here the end position of the selection * * Gets the current selection for View * * Return Value: TRUE if there is a selection active, FALSE if not **/gintgedit_view_get_selection (GeditView *view, guint *start, guint *end){ guint start_pos, end_pos; gedit_debug (DEBUG_VIEW, ""); g_return_val_if_fail (GEDIT_IS_VIEW (view), FALSE); start_pos = GTK_EDITABLE(view->text)->selection_start_pos; end_pos = GTK_EDITABLE(view->text)->selection_end_pos; /* The user can select from end to start too. If so, swap it*/ if (end_pos < start_pos) { guint swap_pos; swap_pos = end_pos; end_pos = start_pos; start_pos = swap_pos; } if (start != NULL) *start = start_pos; if (end != NULL) *end = end_pos; if ((start_pos > 0 || end_pos > 0) && (start_pos != end_pos)) return TRUE; else return FALSE;}/** * gedit_view_set_position: * @view: View to set the cusor * @pos: position to set the curor at * * set the cursor position position for this view **/voidgedit_view_set_position (GeditView *view, gint pos){ gedit_debug (DEBUG_VIEW, ""); g_return_if_fail (GEDIT_IS_VIEW (view)); gtk_text_set_point (view->text, pos); gtk_text_insert (view->text, NULL, NULL, NULL, " ", 1); gtk_text_backward_delete (view->text, 1);}/** * gedit_view_get_position: * @view: View to get the cursor position * * get the cursor position in this view * * Return Value: the current cursor position **/guintgedit_view_get_position (GeditView *view){ guint start_pos, end_pos; gedit_debug (DEBUG_VIEW, ""); g_return_val_if_fail (GEDIT_IS_VIEW (view), 0); if (gedit_view_get_selection (view, &start_pos, &end_pos)) { return end_pos; }#if 0 /* I don't think we need this, but I am going to leave it here just in case it is to work around yet another gtktext bug*/ gtk_text_freeze (view->text); gtk_text_thaw (view->text);#endif return gtk_editable_get_position (GTK_EDITABLE(view->text));}/** * gedit_view_set_readonly: * @view: View to set/unset readonly * @readonly: TRUE to turn on the readonly flag, FALSE otherwise * * Change the Readonly atribute of a view. Update the title accordingly **/voidgedit_view_set_readonly (GeditView *view, gint readonly){ gchar * doc_name = NULL; gedit_debug (DEBUG_VIEW, ""); g_return_if_fail (GEDIT_IS_VIEW (view)); view->readonly = readonly; gtk_text_set_editable (view->text, !view->readonly); doc_name = gedit_document_get_tab_name (view->doc, TRUE); gnome_mdi_child_set_name (GNOME_MDI_CHILD (view->doc), doc_name); gedit_document_set_title (view->doc); g_free (doc_name);}/** * gedit_view_get_document: * @view: * * get the document from a view * * Return Value: document for the @view, NULL on error **/GeditDocument *gedit_view_get_document (GeditView *view){ if (view == NULL) return NULL; return view->doc;}static voidgedit_view_update_line_indicator (void){ static char col [32]; return; /* FIXME: Disable by chema for 0.7.0 . this hack is not working correctly */ gedit_debug (DEBUG_VIEW, ""); sprintf (col, "Column: %d", GEDIT_VIEW(gedit_view_active())->text->cursor_pos_x/7); if (settings->show_status) { GnomeApp *app = gedit_window_active_app(); gnome_appbar_set_status (GNOME_APPBAR(app->statusbar), col); }}static gintgedit_event_button_press (GtkWidget *widget, GdkEventButton *event){ gedit_debug (DEBUG_VIEW, ""); gedit_view_update_line_indicator (); return FALSE;}static gintgedit_event_key_press (GtkWidget *w, GdkEventKey *event){ gedit_debug (DEBUG_VIEW, ""); gedit_view_update_line_indicator (); if (event->state & GDK_MOD1_MASK) { gtk_signal_emit_stop_by_name (GTK_OBJECT (w), "key_press_event"); return FALSE; } /* Control key related */ if (event->state & GDK_CONTROL_MASK) { switch (event->keyval) { /* This is nasty, NASTY NASTY !!!!!!! since it is dependent on the current languaje */ case 's': file_save_cb (w, NULL); break; case 'p': gedit_print_cb (w, NULL); break; case 'n': return FALSE; break; case 'w': file_close_cb (w, NULL); /* If the user cancels the file_close action, the cut still happens*/ gtk_signal_emit_stop_by_name (GTK_OBJECT (w), "key_press_event"); return TRUE; case 'z': /* Undo is getting called twice, 1 thru this function and 1 time thru the aceleratior. Chema gedit_undo_do (w, NULL); */ break; case 'r': /* Same as undo_do gedit_undo_redo (w, NULL); */ break; case 'q': file_quit_cb (w, NULL); break; default: return TRUE; break; } } return TRUE;}static voidgedit_view_insert (GeditView *view, guint position, const gchar * text, gint length){ gint p1; g_return_if_fail (length > 0); g_return_if_fail (text != NULL); gedit_debug (DEBUG_VIEW, ""); if (!GTK_WIDGET_MAPPED (GTK_WIDGET (view->text))) g_warning ("Inserting text into an unmapped text widget (%i)", length); p1 = gtk_text_get_point (view->text); gtk_text_set_point (view->text, position); gtk_text_insert (view->text, NULL, NULL, NULL, text, length);}static voidgedit_views_insert (GeditDocument *doc, guint position, gchar * text, gint length, GeditView * view_exclude){ gint i; GeditView *nth_view; gedit_debug (DEBUG_VIEW, ""); g_return_if_fail (doc!=NULL); if (length < 1) return; /* Why do we have to call view_text_changed_cb ? why is the "chaged" signal not calling it ?. Chema */ if (!doc->changed) if (g_list_length (doc->views)) gedit_view_text_changed_cb (NULL, (gpointer) g_list_nth_data (doc->views, 0)); for (i = 0; i < g_list_length (doc->views); i++) { nth_view = g_list_nth_data (doc->views, i); if (nth_view == view_exclude) continue; gedit_view_insert (nth_view, position, text, length); } }voiddoc_insert_text_real_cb (GtkWidget *editable, const guchar *insertion_text,int length, int *pos, GeditView *view, gint exclude_this_view, gint undo){ gint position = *pos; GeditDocument *doc; guchar *text_to_insert; gedit_debug (DEBUG_VIEW, ""); doc = view->doc; /* This strings are not be terminated with a null cero */ text_to_insert = g_strndup (insertion_text, length); if (undo) gedit_undo_add (text_to_insert, position, (position + length), GEDIT_UNDO_ACTION_INSERT, doc, view); if (!exclude_this_view) gedit_views_insert (doc, position, text_to_insert, length, NULL); else gedit_views_insert (doc, position, text_to_insert, length, view); g_free (text_to_insert);}static voiddoc_insert_text_cb (GtkWidget *editable, const guchar *insertion_text,int length, int *pos, GeditView *view){ gedit_debug (DEBUG_VIEW, ""); doc_insert_text_real_cb (editable, insertion_text, length, pos, view, TRUE, TRUE);}/* Work arround for a gtktext bug*/static gintgedit_view_refresh_line_hack (GeditView *view){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -