[gnome-latex: 172/205] Log output: jump to lines and files
- From: Sébastien Wilmet <swilmet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-latex: 172/205] Log output: jump to lines and files
- Date: Fri, 14 Dec 2018 11:01:20 +0000 (UTC)
commit bb274b2df3e91d7cf7081fa5fab53ea0acfcbcad
Author: Sébastien Wilmet <sebastien wilmet gmail com>
Date: Wed Jan 20 17:36:51 2010 +0100
Log output: jump to lines and files
We can now click on a message and go to the file and the line specified.
Certain row can not be selected, only those with a real filename. If the
line number is not specified, simply go to the file (but not change the
cursor position).
There are also some fixes for memory leaks, that's why a lot of files
are modified ;)
TODO | 2 +-
src/callbacks.c | 22 ++-----
src/external_commands.c | 17 ------
src/file_browser.c | 1 +
src/latex_output_filter.c | 93 ++++++++++++++++--------------
src/log.c | 142 ++++++++++++++++++++++++++++++++++++++++++----
src/log.h | 4 +-
src/main.c | 110 ++++++++++++++++++++---------------
src/prefs.c | 8 ++-
src/print.c | 1 -
src/templates.c | 7 ++-
src/ui.c | 2 +-
src/utils.c | 14 +++++
src/utils.h | 1 +
14 files changed, 280 insertions(+), 144 deletions(-)
---
diff --git a/TODO b/TODO
index cb06795..2251e6f 100644
--- a/TODO
+++ b/TODO
@@ -8,7 +8,7 @@ TODO LaTeXila
x extract informations: file, line, message
x GtkTextBuffer -> GtkListStore
x colors
- - jump to lines and files
+ x jump to lines and files
- buttons for going to the previous/next error/warning/badbox
- Auto-completion of LaTeX commands
diff --git a/src/callbacks.c b/src/callbacks.c
index 61d01d2..c8e459a 100644
--- a/src/callbacks.c
+++ b/src/callbacks.c
@@ -38,6 +38,7 @@
#include "prefs.h"
#include "file_browser.h"
#include "latex_output_filter.h"
+#include "utils.h"
static void close_document (gint index);
static void save_as_dialog (void);
@@ -46,7 +47,6 @@ static gboolean close_all (void);
static void set_title (void);
static void set_undo_redo_sensitivity (void);
static void update_cursor_position_statusbar (void);
-static void scroll_to_cursor (void);
static void find (gboolean backward);
static gboolean find_next_match (const gchar *what, GtkSourceSearchFlags flags,
gboolean backward, GtkTextIter *match_start, GtkTextIter *match_end);
@@ -1159,14 +1159,15 @@ open_new_document (const gchar *filename, const gchar *uri)
// convert the text to UTF-8
gchar *text_utf8 = g_locale_to_utf8 (contents, -1, NULL, NULL, NULL);
- create_document_in_new_tab (filename, text_utf8,
- g_path_get_basename (filename));
+ gchar *basename = g_path_get_basename (filename);
+ create_document_in_new_tab (filename, text_utf8, basename);
GtkRecentManager *manager = gtk_recent_manager_get_default ();
gtk_recent_manager_add_item (manager, uri);
g_free (contents);
g_free (text_utf8);
+ g_free (basename);
}
else
@@ -1213,6 +1214,7 @@ create_document_in_new_tab (const gchar *path, const gchar *text,
new_doc->saved = TRUE;
new_doc->source_buffer = gtk_source_buffer_new (NULL);
new_doc->source_view = gtk_source_view_new_with_buffer (new_doc->source_buffer);
+ g_object_unref (new_doc->source_buffer);
latexila.all_docs = g_list_append (latexila.all_docs, new_doc);
latexila.active_doc = new_doc;
@@ -1222,6 +1224,7 @@ create_document_in_new_tab (const gchar *path, const gchar *text,
// set the language for the syntaxic color
if (path != NULL)
{
+ // TODO check memory leaks here
GtkSourceLanguage *lang = gtk_source_language_manager_guess_language (
lm, path, NULL);
if (lang != NULL)
@@ -1616,19 +1619,6 @@ update_cursor_position_statusbar (void)
g_free (text);
}
-static void
-scroll_to_cursor (void)
-{
- if (latexila.active_doc == NULL)
- return;
-
- gtk_text_view_scroll_to_mark (
- GTK_TEXT_VIEW (latexila.active_doc->source_view),
- gtk_text_buffer_get_insert (
- GTK_TEXT_BUFFER (latexila.active_doc->source_buffer)),
- 0.25, FALSE, 0, 0);
-}
-
static void
find (gboolean backward)
{
diff --git a/src/external_commands.c b/src/external_commands.c
index a85edb4..8d0d1ff 100644
--- a/src/external_commands.c
+++ b/src/external_commands.c
@@ -328,8 +328,6 @@ cb_watch_output_command (GIOChannel *channel, GIOCondition condition,
if (condition & G_IO_IN)
{
- int nb_lines = 0;
-
GError *error = NULL;
gchar *line = NULL;
GIOStatus gio_status = g_io_channel_read_line (channel, &line, NULL, NULL, &error);
@@ -351,21 +349,7 @@ cb_watch_output_command (GIOChannel *channel, GIOCondition condition,
line_utf8[strlen (line_utf8) - 1] = '\0';
if (show_all_output)
- {
print_output_normal (line_utf8);
-
- /* Flush the queue for the 200 first lines and then every 50 lines.
- * This is for the fluidity of the output, without that the lines do
not
- * appear directly and it's ugly. But it is very slow, for a command
that
- * execute for example in 10 seconds, it could take 250 seconds (!)
if we
- * flush the queue at each line... But with commands that take 1
- * second or so there is not a big difference.
- */
- if (nb_lines < 200 || nb_lines % 50 == 0)
- flush_queue ();
- nb_lines++;
- }
-
else
latex_output_filter (line_utf8);
@@ -433,7 +417,6 @@ finish_execute (void)
print_output_exit (42, _("The child process exited abnormally"));
output_view_columns_autosize ();
- flush_queue ();
// unlock the action list and all the build actions
set_action_sensitivity (TRUE);
diff --git a/src/file_browser.c b/src/file_browser.c
index b773f84..6154095 100644
--- a/src/file_browser.c
+++ b/src/file_browser.c
@@ -147,6 +147,7 @@ fill_list_store_with_current_dir (void)
return;
}
+ //TODO check memomy leaks
gtk_list_store_clear (latexila.file_browser.list_store);
/* append all the files contained in the directory */
diff --git a/src/latex_output_filter.c b/src/latex_output_filter.c
index c3f9696..e49344c 100644
--- a/src/latex_output_filter.c
+++ b/src/latex_output_filter.c
@@ -25,7 +25,6 @@
#include "main.h"
#include "print.h"
-#include "utils.h"
#include "latex_output_filter.h"
#include "log.h"
@@ -44,6 +43,7 @@ static void update_stack_file (const gchar *line);
static void update_stack_file_heuristic (const gchar *line);
static gboolean file_exists (const gchar *filename);
+static gchar * get_path_if_file_exists (const gchar *filename);
static gchar * get_current_filename (void);
static void push_file_on_stack (gchar *filename, gboolean reliable);
static void pop_file_from_stack (void);
@@ -183,38 +183,12 @@ latex_output_filter_set_path (const gchar *dir)
void
latex_output_filter_print_stats (void)
{
- gchar *str;
- if (nb_errors > 1)
- str = g_strdup_printf (_("%d errors, "), nb_errors);
- else
- str = g_strdup_printf (_("%d error, "), nb_errors);
- if (nb_warnings > 1)
- {
- gchar *tmp = g_strdup_printf (_("%s%d warnings, "), str, nb_warnings);
- g_free (str);
- str = tmp;
- }
- else
- {
- gchar *tmp = g_strdup_printf (_("%s%d warning, "), str, nb_warnings);
- g_free (str);
- str = tmp;
- }
- if (nb_badboxes > 1)
- {
- gchar *tmp = g_strdup_printf (_("%s%d badboxes"), str, nb_badboxes);
- g_free (str);
- str = tmp;
- }
- else
- {
- gchar *tmp = g_strdup_printf (_("%s%d badbox"), str, nb_badboxes);
- g_free (str);
- str = tmp;
- }
+ gchar *str = g_strdup_printf ("%d %s, %d %s, %d %s",
+ nb_errors, nb_errors > 1 ? "errors" : "error",
+ nb_warnings, nb_warnings > 1 ? "warnings" : "warning",
+ nb_badboxes, nb_badboxes > 1 ? "badboxes" : "badbox");
print_output_info (str);
- flush_queue ();
g_free (str);
// it's finish, we reset the counters
@@ -222,12 +196,15 @@ latex_output_filter_print_stats (void)
nb_warnings = 0;
nb_errors = 0;
- // if the file stack is not empty
+ // empty the stack file
gint nb_files_in_stack = g_slist_length (stack_file);
if (nb_files_in_stack > 0)
print_warning ("the file stack was not empty!");
for (int i = 0 ; i < nb_files_in_stack ; i++)
+ {
+ print_info ("%s", get_current_filename ());
pop_file_from_stack ();
+ }
}
static gboolean
@@ -731,15 +708,36 @@ update_stack_file_heuristic (const gchar *line)
static gboolean
file_exists (const gchar *filename)
{
- if (g_path_is_absolute (filename))
- return g_file_test (filename, G_FILE_TEST_IS_REGULAR);
-
- gchar *full_path = g_build_filename (path, filename, NULL);
- if (g_file_test (full_path, G_FILE_TEST_IS_REGULAR))
+ gchar *full_path = get_path_if_file_exists (filename);
+ if (full_path != NULL)
{
g_free (full_path);
return TRUE;
}
+ return FALSE;
+}
+
+// return NULL if the filename does not exist
+// return the path of the filename if it exists (must be freed)
+static gchar *
+get_path_if_file_exists (const gchar *filename)
+{
+ if (g_path_is_absolute (filename))
+ {
+ if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
+ return g_strdup (filename);
+ else
+ return NULL;
+ }
+
+ gchar *full_path;
+ if (g_str_has_prefix (filename, "./"))
+ full_path = g_build_filename (path, filename + 2, NULL);
+ else
+ full_path = g_build_filename (path, filename, NULL);
+
+ if (g_file_test (full_path, G_FILE_TEST_IS_REGULAR))
+ return full_path;
// try to add various extensions on the filename to see if the file exists
gchar *extensions[] = {".tex", ".ltx", ".latex", ".dtx", ".ins"};
@@ -749,14 +747,14 @@ file_exists (const gchar *filename)
gchar *tmp = g_strdup_printf ("%s%s", full_path, extensions[i]);
if (g_file_test (tmp, G_FILE_TEST_IS_REGULAR))
{
- g_free (tmp);
g_free (full_path);
- return TRUE;
+ return tmp;
}
g_free (tmp);
}
- return FALSE;
+ g_free (full_path);
+ return NULL;
}
static gchar *
@@ -776,7 +774,13 @@ push_file_on_stack (gchar *filename, gboolean reliable)
{
//print_info ("***\tpush\t\"%s\" (%s)", filename, reliable ? "reliable" : "not reliable");
file_in_stack_t *file = g_malloc (sizeof (file_in_stack_t));
- file->filename = g_strdup (filename);
+
+ gchar *path = get_path_if_file_exists (filename);
+ if (path != NULL)
+ file->filename = path;
+ else
+ file->filename = g_strdup (filename);
+
file->reliable = reliable;
stack_file = g_slist_prepend (stack_file, file);
}
@@ -784,7 +788,7 @@ push_file_on_stack (gchar *filename, gboolean reliable)
static void
pop_file_from_stack (void)
{
- file_in_stack_t *file = g_slist_nth_data (stack_file, 0);
+ file_in_stack_t *file = stack_file->data;
//print_info ("***\tpop\t\"%s\" (%s)", file->filename, file->reliable ? "reliable" : "not reliable");
stack_file = g_slist_remove (stack_file, file);
g_free (file->filename);
@@ -795,7 +799,9 @@ static gboolean
top_file_on_stack_reliable (void)
{
// stack_file must contain at least one file
- file_in_stack_t *file = g_slist_nth_data (stack_file, 0);
+ g_assert (stack_file != NULL);
+
+ file_in_stack_t *file = stack_file->data;
return file->reliable;
}
@@ -804,7 +810,6 @@ print_msg (void)
{
gchar *filename = get_current_filename ();
print_output_message (filename, msg.line, msg.message, msg.message_type);
- flush_queue ();
msg.line = NO_LINE;
msg.message_type = MESSAGE_TYPE_OTHER;
diff --git a/src/log.c b/src/log.c
index 37ad211..f706eff 100644
--- a/src/log.c
+++ b/src/log.c
@@ -17,19 +17,30 @@
* along with LaTeXila. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdlib.h>
+#include <string.h>
#include <gtk/gtk.h>
#include "main.h"
#include "log.h"
+#include "utils.h"
+#include "callbacks.h"
static void cb_action_history_changed (GtkTreeSelection *selection,
gpointer user_data);
+static void cb_output_row_changed (GtkTreeSelection *selection, gpointer data);
+static gboolean output_row_selection_func (GtkTreeSelection *selection,
+ GtkTreeModel *model, GtkTreePath *path,
+ gboolean path_currently_selected, gpointer data);
static GtkListStore * get_new_output_list_store (void);
-static void scroll_to_end (GtkTreeIter *iter);
+static void scroll_to_end (GtkTreeIter *iter, gboolean force);
static GtkTreeView *history_view;
static GtkTreeView *output_view;
+// used to scroll to the end and to flush not everytime (because it is slow)
+static gint nb_lines = 0;
+
void
init_log_zone (GtkPaned *log_hpaned)
{
@@ -106,6 +117,16 @@ init_log_zone (GtkPaned *log_hpaned)
NULL);
gtk_tree_view_append_column (output_view, column);
+ // selection
+ GtkTreeSelection *select = gtk_tree_view_get_selection (output_view);
+ gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
+ g_signal_connect (G_OBJECT (select), "changed",
+ G_CALLBACK (cb_output_row_changed), NULL);
+
+ // certain rows can not be selected
+ gtk_tree_selection_set_select_function (select,
+ (GtkTreeSelectionFunc) output_row_selection_func, NULL, NULL);
+
// with a scrollbar
GtkWidget *scrollbar = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollbar),
@@ -131,6 +152,71 @@ cb_action_history_changed (GtkTreeSelection *selection, gpointer user_data)
}
}
+static void
+cb_output_row_changed (GtkTreeSelection *selection, gpointer data)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ gchar *filename;
+ gchar *line_number;
+ gint message_type;
+
+ gtk_tree_model_get (model, &iter,
+ COL_OUTPUT_FILENAME, &filename,
+ COL_OUTPUT_LINE_NUMBER, &line_number,
+ COL_OUTPUT_MESSAGE_TYPE, &message_type,
+ -1);
+
+ if (message_type != MESSAGE_TYPE_OTHER && filename != NULL
+ && strlen (filename) != 0)
+ {
+ // open the file (if the file is already opened, go to it)
+ open_new_document_without_uri (filename);
+
+ // go to line
+ if (line_number != NULL && strlen (line_number) != 0
+ && latexila.active_doc != NULL)
+ {
+ gint num = strtol (line_number, NULL, 10);
+ GtkTextIter iter_file;
+ GtkTextBuffer *buffer = GTK_TEXT_BUFFER (
+ latexila.active_doc->source_buffer);
+ gtk_text_buffer_get_iter_at_line (buffer, &iter_file, --num);
+ gtk_text_buffer_place_cursor (buffer, &iter_file);
+ scroll_to_cursor ();
+ }
+
+ gtk_widget_grab_focus (latexila.active_doc->source_view);
+ }
+ }
+}
+
+static gboolean
+output_row_selection_func (GtkTreeSelection *selection, GtkTreeModel *model,
+ GtkTreePath *path, gboolean path_currently_selected, gpointer data)
+{
+ GtkTreeIter iter;
+ if (gtk_tree_model_get_iter (model, &iter, path))
+ {
+ gint message_type;
+ gchar *filename;
+ gtk_tree_model_get (model, &iter,
+ COL_OUTPUT_FILENAME, &filename,
+ COL_OUTPUT_MESSAGE_TYPE, &message_type,
+ -1);
+
+ if (message_type == MESSAGE_TYPE_OTHER || filename == NULL
+ || strlen (filename) == 0)
+ return FALSE;
+ else
+ return TRUE;
+ }
+
+ return FALSE; // not allow the selection state to change
+}
+
static GtkListStore *
get_new_output_list_store (void)
{
@@ -154,7 +240,6 @@ add_action (const gchar *title, const gchar *command)
GtkListStore *output_list_store = get_new_output_list_store ();
gtk_tree_view_set_model (output_view, GTK_TREE_MODEL (output_list_store));
- g_object_unref (output_list_store);
// print title and command to the new list store
gchar *title_with_num = g_strdup_printf ("%d. %s", num, title);
@@ -180,12 +265,20 @@ add_action (const gchar *title, const gchar *command)
// scroll to the end
GtkTreePath *path = gtk_tree_model_get_path (history_tree_model, &iter);
gtk_tree_view_scroll_to_cell (history_view, path, NULL, FALSE, 0, 0);
+ gtk_tree_path_free (path);
// delete the first entry
if (num > 5)
{
GtkTreeIter first;
gtk_tree_model_get_iter_first (history_tree_model, &first);
+
+ // free the output model
+ GtkTreeModel *first_output_store;
+ gtk_tree_model_get (history_tree_model, &first,
+ COL_ACTION_OUTPUT_STORE, &first_output_store, -1);
+ g_object_unref (first_output_store);
+
gtk_list_store_remove (GTK_LIST_STORE (history_tree_model), &first);
}
@@ -208,6 +301,10 @@ output_view_columns_autosize (void)
void
print_output_title (const gchar *title)
{
+ // generally, the title is the first line in a new output, and is used only
+ // once, so we reset the counter...
+ nb_lines = 0;
+
GtkListStore *list_store =
GTK_LIST_STORE (gtk_tree_view_get_model (output_view));
GtkTreeIter iter;
@@ -220,12 +317,13 @@ print_output_title (const gchar *title)
COL_OUTPUT_COLOR_SET, FALSE,
COL_OUTPUT_WEIGHT, WEIGHT_BOLD,
-1);
- scroll_to_end (&iter);
}
void
print_output_info (const gchar *info)
{
+ nb_lines++;
+
GtkListStore *list_store =
GTK_LIST_STORE (gtk_tree_view_get_model (output_view));
GtkTreeIter iter;
@@ -238,13 +336,15 @@ print_output_info (const gchar *info)
COL_OUTPUT_COLOR_SET, FALSE,
COL_OUTPUT_WEIGHT, WEIGHT_NORMAL,
-1);
- scroll_to_end (&iter);
+ scroll_to_end (&iter, FALSE);
}
// if message != NULL the exit_code is not taken into account
void
print_output_exit (const gint exit_code, const gchar *message)
{
+ nb_lines++;
+
GtkListStore *list_store =
GTK_LIST_STORE (gtk_tree_view_get_model (output_view));
GtkTreeIter iter;
@@ -280,13 +380,19 @@ print_output_exit (const gint exit_code, const gchar *message)
-1);
g_free (tmp);
}
- scroll_to_end (&iter);
+
+ // force the scrolling and the flush
+ scroll_to_end (&iter, TRUE);
}
void
print_output_message (const gchar *filename, const gint line_number,
const gchar *message, gint message_type)
{
+ // this function is used only in the filter, so there are less lines
+ // but we want to flush more often
+ nb_lines += 2;
+
GtkListStore *list_store =
GTK_LIST_STORE (gtk_tree_view_get_model (output_view));
@@ -331,7 +437,7 @@ print_output_message (const gchar *filename, const gint line_number,
COL_OUTPUT_COLOR_SET, TRUE,
COL_OUTPUT_WEIGHT, WEIGHT_NORMAL,
-1);
- scroll_to_end (&iter);
+ scroll_to_end (&iter, FALSE);
g_free (basename);
g_free (line_number_str);
@@ -340,6 +446,8 @@ print_output_message (const gchar *filename, const gint line_number,
void
print_output_normal (const gchar *message)
{
+ nb_lines++;
+
GtkListStore *list_store =
GTK_LIST_STORE (gtk_tree_view_get_model (output_view));
GtkTreeIter iter;
@@ -352,13 +460,25 @@ print_output_normal (const gchar *message)
COL_OUTPUT_COLOR_SET, FALSE,
COL_OUTPUT_WEIGHT, WEIGHT_NORMAL,
-1);
- scroll_to_end (&iter);
+ scroll_to_end (&iter, FALSE);
}
static void
-scroll_to_end (GtkTreeIter *iter)
+scroll_to_end (GtkTreeIter *iter, gboolean force)
{
- GtkTreeModel *tree_model = gtk_tree_view_get_model (output_view);
- GtkTreePath *path = gtk_tree_model_get_path (tree_model, iter);
- gtk_tree_view_scroll_to_cell (output_view, path, NULL, FALSE, 0, 0);
+ /* Flush the queue for the 50 first lines and then every 40 lines.
+ * This is for the fluidity of the output, without that the lines do not
+ * appear directly and it's ugly. But it is very slow, for a command that
+ * execute for example in 10 seconds, it could take 250 seconds (!) if we
+ * flush the queue at each line... But with commands that take 1
+ * second or so there is not a big difference.
+ */
+ if (force || nb_lines < 50 || nb_lines % 40 == 0)
+ {
+ GtkTreeModel *tree_model = gtk_tree_view_get_model (output_view);
+ GtkTreePath *path = gtk_tree_model_get_path (tree_model, iter);
+ gtk_tree_view_scroll_to_cell (output_view, path, NULL, FALSE, 0, 0);
+ gtk_tree_path_free (path);
+ flush_queue ();
+ }
}
diff --git a/src/log.h b/src/log.h
index 3c2e872..386c2cb 100644
--- a/src/log.h
+++ b/src/log.h
@@ -51,9 +51,9 @@ enum history_action
enum output_message_type
{
MESSAGE_TYPE_OTHER,
- MESSAGE_TYPE_ERROR,
+ MESSAGE_TYPE_BADBOX,
MESSAGE_TYPE_WARNING,
- MESSAGE_TYPE_BADBOX
+ MESSAGE_TYPE_ERROR
};
enum output_line
diff --git a/src/main.c b/src/main.c
index 109102b..5b11c83 100644
--- a/src/main.c
+++ b/src/main.c
@@ -101,6 +101,7 @@ init_main_window (void)
for (int i = 0 ; i < nb_icons ; i++)
{
+ // TODO check memory leaks here
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (filenames[i], &error);
if (error != NULL)
{
@@ -115,6 +116,10 @@ init_main_window (void)
gtk_window_set_default_icon_list (list_icons);
+ // Gtk have a copy of the GList and adds a ref to every icon
+ g_list_foreach (list_icons, (GFunc) g_object_unref, NULL);
+ g_list_free (list_icons);
+
if (latexila.prefs.window_maximised)
gtk_window_maximize (GTK_WINDOW (window));
}
@@ -128,35 +133,39 @@ init_side_pane (void)
gtk_paned_add1 (latexila.main_hpaned, side_pane_notebook);
// symbol tables
- GtkWidget *vbox_symbols = gtk_vbox_new (FALSE, 0);
- latexila.symbols.vbox = vbox_symbols;
-
- GtkWidget *tab_label = gtk_hbox_new (FALSE, 3);
- GtkWidget *label = gtk_label_new (_("Symbols"));
- GtkWidget *image = gtk_image_new_from_file (DATA_DIR "/images/greek/01.png");
- gtk_box_pack_start (GTK_BOX (tab_label), image, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (tab_label), label, TRUE, TRUE, 0);
- gtk_widget_show_all (tab_label);
-
- gtk_notebook_append_page (GTK_NOTEBOOK (side_pane_notebook), vbox_symbols,
- tab_label);
- init_symbols ();
+ {
+ GtkWidget *vbox_symbols = gtk_vbox_new (FALSE, 0);
+ latexila.symbols.vbox = vbox_symbols;
+
+ GtkWidget *tab_label = gtk_hbox_new (FALSE, 3);
+ GtkWidget *label = gtk_label_new (_("Symbols"));
+ GtkWidget *image = gtk_image_new_from_file (DATA_DIR "/images/greek/01.png");
+ gtk_box_pack_start (GTK_BOX (tab_label), image, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (tab_label), label, TRUE, TRUE, 0);
+ gtk_widget_show_all (tab_label);
+
+ gtk_notebook_append_page (GTK_NOTEBOOK (side_pane_notebook), vbox_symbols,
+ tab_label);
+ init_symbols ();
+ }
// file browser
- GtkWidget *vbox_file_browser = gtk_vbox_new (FALSE, 0);
- latexila.file_browser.vbox = vbox_file_browser;
-
- tab_label = gtk_hbox_new (FALSE, 3);
- label = gtk_label_new (_("File Browser"));
- image = gtk_image_new_from_stock (GTK_STOCK_OPEN,
- GTK_ICON_SIZE_MENU);
- gtk_box_pack_start (GTK_BOX (tab_label), image, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (tab_label), label, TRUE, TRUE, 0);
- gtk_widget_show_all (tab_label);
-
- gtk_notebook_append_page (GTK_NOTEBOOK (side_pane_notebook),
- vbox_file_browser, tab_label);
- init_file_browser ();
+ {
+ GtkWidget *vbox_file_browser = gtk_vbox_new (FALSE, 0);
+ latexila.file_browser.vbox = vbox_file_browser;
+
+ GtkWidget *tab_label = gtk_hbox_new (FALSE, 3);
+ GtkWidget *label = gtk_label_new (_("File Browser"));
+ GtkWidget *image = gtk_image_new_from_stock (GTK_STOCK_OPEN,
+ GTK_ICON_SIZE_MENU);
+ gtk_box_pack_start (GTK_BOX (tab_label), image, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (tab_label), label, TRUE, TRUE, 0);
+ gtk_widget_show_all (tab_label);
+
+ gtk_notebook_append_page (GTK_NOTEBOOK (side_pane_notebook),
+ vbox_file_browser, tab_label);
+ init_file_browser ();
+ }
}
static void
@@ -339,14 +348,20 @@ main (int argc, char *argv[])
{
GError *error = NULL;
- /* command line options */
- gboolean option_new_document = FALSE;
-
+ /* localisation */
gchar *latexila_nls_package = NULL;
+
#ifdef LATEXILA_NLS_ENABLED
+ setlocale (LC_ALL, "");
+ bindtextdomain (LATEXILA_NLS_PACKAGE, LATEXILA_NLS_LOCALEDIR);
+ bind_textdomain_codeset (LATEXILA_NLS_PACKAGE, "UTF-8");
+ textdomain (LATEXILA_NLS_PACKAGE);
latexila_nls_package = LATEXILA_NLS_PACKAGE;
#endif
+ /* command line options */
+ gboolean option_new_document = FALSE;
+
GOptionEntry options[] = {
{ "version", 'v', G_OPTION_FLAG_IN_MAIN | G_OPTION_FLAG_NO_ARG,
G_OPTION_ARG_CALLBACK, (gpointer) option_version,
@@ -357,29 +372,29 @@ main (int argc, char *argv[])
{NULL}
};
- GOptionContext *context = g_option_context_new ("[FILES]");
- g_option_context_add_main_entries (context, options, latexila_nls_package);
+ GOptionContext *context = g_option_context_new (NULL);
g_option_context_add_group (context, gtk_get_option_group (TRUE));
+ g_option_context_add_main_entries (context, options, latexila_nls_package);
// TODO with valgrind there are a lot of memory leaks with this, can we do
// something?
- if (! g_option_context_parse (context, &argc, &argv, &error))
+ gboolean tmp = g_option_context_parse (context, &argc, &argv, &error);
+ g_option_context_free (context);
+ if (! tmp)
+ {
print_error ("option parsing failed: %s\n", error->message);
+ g_error_free (error);
+ exit (EXIT_FAILURE);
+ }
gtk_init_with_args (&argc, &argv, NULL, options, latexila_nls_package,
&error);
if (error != NULL)
+ {
print_error ("%s", error->message);
-
- g_option_context_free (context);
-
- /* localisation */
-#ifdef LATEXILA_NLS_ENABLED
- setlocale (LC_ALL, "");
- bindtextdomain (LATEXILA_NLS_PACKAGE, LATEXILA_NLS_LOCALEDIR);
- bind_textdomain_codeset (LATEXILA_NLS_PACKAGE, "UTF-8");
- textdomain (LATEXILA_NLS_PACKAGE);
-#endif
+ g_error_free (error);
+ exit (EXIT_FAILURE);
+ }
/* preferences */
load_preferences (&latexila.prefs);
@@ -470,10 +485,13 @@ main (int argc, char *argv[])
/* reopen files on startup */
gchar ** list_opened_docs = (gchar **) latexila.prefs.list_opened_docs->pdata;
- for (int i = 0 ; i < latexila.prefs.list_opened_docs->len
- && latexila.prefs.reopen_files_on_startup ; i++)
+ for (int i = 0 ; i < latexila.prefs.list_opened_docs->len ; i++)
{
- open_new_document_without_uri (list_opened_docs[i]);
+ if (latexila.prefs.reopen_files_on_startup)
+ open_new_document_without_uri (list_opened_docs[i]);
+
+ // in all cases we must free the string
+ g_free (list_opened_docs[i]);
}
g_ptr_array_free (latexila.prefs.list_opened_docs, TRUE);
latexila.prefs.list_opened_docs = g_ptr_array_new ();
diff --git a/src/prefs.c b/src/prefs.c
index 171f777..ea946e9 100644
--- a/src/prefs.c
+++ b/src/prefs.c
@@ -373,6 +373,7 @@ load_preferences (preferences_t *prefs)
gchar **current = list_opened_docs;
while (*current != NULL)
{
+ // the string must be freed later
g_ptr_array_add (prefs->list_opened_docs,
(gpointer) g_strdup (*current));
current++;
@@ -882,6 +883,7 @@ cb_style_scheme_changed (GtkTreeSelection *selection, gpointer user_data)
{
gchar *id;
gtk_tree_model_get (model, &iter, COLUMN_STYLE_SCHEME_ID, &id, -1);
+ g_free (latexila.prefs.style_scheme_id);
latexila.prefs.style_scheme_id = id;
GtkSourceStyleSchemeManager *style_scheme_manager =
@@ -890,12 +892,11 @@ cb_style_scheme_changed (GtkTreeSelection *selection, gpointer user_data)
gtk_source_style_scheme_manager_get_scheme (style_scheme_manager, id);
// set the style scheme for all opened documents
- GList *current = latexila.all_docs;
- while (current != NULL)
+ for (GList *current = latexila.all_docs ; current != NULL ;
+ current = g_list_next (current))
{
document_t *doc = g_list_nth_data (current, 0);
gtk_source_buffer_set_style_scheme (doc->source_buffer, style_scheme);
- current = g_list_next (current);
}
}
}
@@ -1102,6 +1103,7 @@ create_preferences (void)
{
GtkWidget *hbox = gtk_hbox_new (FALSE, 5);
GtkWidget *label = gtk_label_new (_("Font:"));
+ // TODO check memory leaks here
GtkWidget *font_button = gtk_font_button_new_with_font (
latexila.prefs.font_str);
g_signal_connect (G_OBJECT (font_button), "font-set",
diff --git a/src/print.c b/src/print.c
index 77c2750..bc2bf9f 100644
--- a/src/print.c
+++ b/src/print.c
@@ -50,5 +50,4 @@ print_error (const char *format, ...)
fprintf (stderr, "Error: ");
vfprintf (stderr, format, va);
fprintf (stderr, "\n");
- exit (EXIT_FAILURE);
}
diff --git a/src/templates.c b/src/templates.c
index 6060fe1..68df9ba 100644
--- a/src/templates.c
+++ b/src/templates.c
@@ -348,12 +348,15 @@ init_templates (void)
for (gint i = 0 ; i < length ; i++)
{
gchar *file = g_strdup_printf ("%s/%d.tex", rc_dir, i);
-
if (! g_file_test (file, G_FILE_TEST_EXISTS))
+ {
+ g_free (file);
continue;
-
+ }
+
add_template_from_file (personnal_store, names[i],
DATA_DIR "/images/templates/article.png", file);
+ g_free (file);
}
g_strfreev (names);
diff --git a/src/ui.c b/src/ui.c
index 1c3c221..d7ceccd 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -816,7 +816,7 @@ init_ui (GtkWidget *box)
{
print_error ("building menubar and toolbar failed: %s", error->message);
g_error_free (error);
- error = NULL;
+ exit (EXIT_FAILURE);
}
// get and put the menubar and the toolbars to the main vbox
diff --git a/src/utils.c b/src/utils.c
index ac29f2f..92d4e99 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <gtk/gtk.h>
+#include "main.h"
#include "utils.h"
void
@@ -29,3 +30,16 @@ flush_queue (void)
while (g_main_context_pending (NULL))
g_main_context_iteration (NULL, TRUE);
}
+
+void
+scroll_to_cursor (void)
+{
+ if (latexila.active_doc == NULL)
+ return;
+
+ gtk_text_view_scroll_to_mark (
+ GTK_TEXT_VIEW (latexila.active_doc->source_view),
+ gtk_text_buffer_get_insert (
+ GTK_TEXT_BUFFER (latexila.active_doc->source_buffer)),
+ 0.25, FALSE, 0, 0);
+}
diff --git a/src/utils.h b/src/utils.h
index dbab2fd..17841be 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -21,5 +21,6 @@
#define UTILS_H
void flush_queue (void);
+void scroll_to_cursor (void);
#endif /* UTILS_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]