diff --git a/src/editor.c b/src/editor.c index 434c8a2b..da000335 100644 --- a/src/editor.c +++ b/src/editor.c @@ -64,7 +64,7 @@ const gchar style[][3][20] = { { "tool_right", "\\begin{flushright}", "\\end{flushright}"} }; -GuEditor* editor_new (GuMotion* mc) { +GuEditor* editor_new (GuMotion* mc, GuEditor* rootEditor) { GuEditor* ec = g_new0 (GuEditor, 1); /* File related member initialization */ @@ -76,6 +76,11 @@ GuEditor* editor_new (GuMotion* mc) { ec->workfile = NULL; ec->bibfile = NULL; ec->projfile = NULL; + /* NULL if the file is not part of project or if the file is the root + * document of a project. Otherwise, rootEditor points to the editor + * instance of the root file. This is required for providing the + * "preview-on-save"-feature for projects. */ + ec->rootEditor = rootEditor; GtkSourceLanguageManager* manager = gtk_source_language_manager_new (); GtkSourceLanguage* lang = gtk_source_language_manager_get_language (manager, diff --git a/src/editor.h b/src/editor.h index ea059d86..2463811d 100644 --- a/src/editor.h +++ b/src/editor.h @@ -59,6 +59,7 @@ struct _GuEditor { gchar* workfile; gchar* bibfile; gchar* projfile; + GuEditor* rootEditor; /* GUI related members */ GtkSourceView* view; @@ -78,7 +79,7 @@ struct _GuEditor { gboolean sync_to_last_edit; }; -GuEditor* editor_new (GuMotion* mc); +GuEditor* editor_new (GuMotion* mc, GuEditor* rootEditor); void editor_fileinfo_update (GuEditor* ec, const gchar* filename); void editor_fileinfo_cleanup (GuEditor* ec); gboolean editor_fileinfo_update_biblio (GuEditor* ec, const gchar* filename); diff --git a/src/environment.c b/src/environment.c index 14036788..f7f2d6e3 100644 --- a/src/environment.c +++ b/src/environment.c @@ -61,8 +61,8 @@ gchar* gummi_get_projectfile (void) { return gummi->project->projfile; } -GuEditor* gummi_new_environment (const gchar* filename) { - GuEditor* ec = editor_new (gummi->motion); +GuEditor* gummi_new_environment (const gchar* filename, GuEditor* rootEditor) { + GuEditor* ec = editor_new (gummi->motion, rootEditor); editor_fileinfo_update (ec, filename); slog (L_INFO, "\n"); diff --git a/src/environment.h b/src/environment.h index e7bc04e7..c8d078c4 100644 --- a/src/environment.h +++ b/src/environment.h @@ -112,7 +112,7 @@ struct _Gummi { Gummi* gummi_init (GuMotion* mo, GuIOFunc* io, GuLatex* latex, GuBiblio* bib, GuTemplate* tpl, GuSnippets* snip, GuTabmanager* tabm, GuProject* proj); -GuEditor* gummi_new_environment (const gchar* filename); +GuEditor* gummi_new_environment (const gchar* filename, GuEditor* rootEditor); /** * Following APIs is used to eliminate the need of exposing global Gummi to diff --git a/src/gui/gui-main.c b/src/gui/gui-main.c index d64b3b08..43680be2 100644 --- a/src/gui/gui-main.c +++ b/src/gui/gui-main.c @@ -387,14 +387,15 @@ void gui_recovery_mode_disable (GtkInfoBar *infobar) { gtk_widget_set_sensitive (GTK_WIDGET (g_active_editor->view), TRUE); } -void gui_open_file (const gchar* filename) { +// we're just passing root and created through to tabmanager_create_tab +void gui_open_file (const gchar* filename, GuEditor* root, GuEditor** created) { if (!g_file_test(filename, G_FILE_TEST_EXISTS)) { slog(L_G_ERROR, "Failed to open file '%s': No such file or " "directory\n", filename); return; } - tabmanager_create_tab (A_LOAD, filename, NULL); + tabmanager_create_tab (A_LOAD, filename, NULL, root, created); if (!gtk_widget_get_sensitive (GTK_WIDGET (gui->rightpane))) { gui_set_hastabs_sensitive (TRUE); } @@ -525,7 +526,7 @@ void on_button_template_open_clicked (GtkWidget* widget, void* user) { statusbar_set_message (status); g_free (status); - tabmanager_create_tab (A_LOAD_OPT, NULL, templ_name); + tabmanager_create_tab (A_LOAD_OPT, NULL, templ_name, NULL, NULL); gtk_widget_hide (GTK_WIDGET (gummi->templ->templatewindow)); } g_free(templ_name); diff --git a/src/gui/gui-main.h b/src/gui/gui-main.h index de200811..bd904ccb 100644 --- a/src/gui/gui-main.h +++ b/src/gui/gui-main.h @@ -126,7 +126,7 @@ void gui_set_filename_display (GuTabContext* tc, void gui_set_window_title (const gchar* filename, const gchar* text); -void gui_open_file (const gchar* filename); +void gui_open_file (const gchar* filename, GuEditor* root, GuEditor** created); void gui_save_file (GuTabContext* tab, gboolean saveas); void gui_set_hastabs_sensitive (gboolean enable); diff --git a/src/gui/gui-menu.c b/src/gui/gui-menu.c index 90e0b38a..d3c7b54e 100644 --- a/src/gui/gui-menu.c +++ b/src/gui/gui-menu.c @@ -131,7 +131,7 @@ G_MODULE_EXPORT void on_menu_new_activate (GtkWidget *widget, void* user) { if (!gtk_widget_get_sensitive (GTK_WIDGET (gui->rightpane))) gui_set_hastabs_sensitive (TRUE); - tabmanager_create_tab (A_NONE, NULL, NULL); + tabmanager_create_tab (A_NONE, NULL, NULL, NULL, NULL); } G_MODULE_EXPORT @@ -146,7 +146,7 @@ void on_menu_open_activate (GtkWidget *widget, void* user) { gchar *filename = NULL; if ( (filename = get_open_filename (TYPE_LATEX))) - gui_open_file (filename); + gui_open_file (filename, NULL, NULL); g_free (filename); if (g_active_editor) @@ -180,7 +180,7 @@ void on_menu_recent_activate (GtkWidget *widget, void *user) { gint index = name[0] - '0' -1; if (utils_path_exists (gui->recent_list[index])) { - gui_open_file (gui->recent_list[index]); + gui_open_file (gui->recent_list[index], NULL, NULL); } else { tstr = g_strdup_printf (_("Error loading recent file: %s"), gui->recent_list[index]); diff --git a/src/gui/gui-project.c b/src/gui/gui-project.c index 48f50fe5..cc927d0c 100644 --- a/src/gui/gui-project.c +++ b/src/gui/gui-project.c @@ -174,7 +174,7 @@ void on_projfile_add_clicked (GtkWidget* widget, void* user) { int amount = projectgui_list_projfiles (gummi->project->projfile); gtk_label_set_text (gui->projectgui->proj_nroffiles, g_strdup_printf("%d", amount)); - gui_open_file (selected); + gui_open_file (selected, NULL, NULL); } else { statusbar_set_message ("Error adding document to the project.."); diff --git a/src/main.c b/src/main.c index b5bdc5e3..4dca65cd 100644 --- a/src/main.c +++ b/src/main.c @@ -156,14 +156,14 @@ int main (int argc, char *argv[]) { gtk_window_add_accel_group (gui->mainwindow, snippets->accel_group); if (argc != 2) - tabmanager_create_tab (A_DEFAULT, NULL, NULL); + tabmanager_create_tab (A_DEFAULT, NULL, NULL, NULL, NULL); else { if (!g_file_test(argv[1], G_FILE_TEST_EXISTS)) { slog(L_ERROR, "Failed to open file '%s': No such file or " "directory\n", argv[1]); exit(1); } - tabmanager_create_tab (A_LOAD, argv[1], NULL); + tabmanager_create_tab (A_LOAD, argv[1], NULL, NULL, NULL); } if (config_get_value ("autosaving")) iofunctions_start_autosave (); diff --git a/src/motion.c b/src/motion.c index 75c338b5..6f9a60eb 100644 --- a/src/motion.c +++ b/src/motion.c @@ -163,6 +163,7 @@ gpointer motion_compile_thread (gpointer data) { L_F_DEBUG; GuMotion* mc = GU_MOTION (data); GuEditor* editor = NULL; + GuEditor* editor_to_compile = NULL; GuLatex* latex = NULL; GuPreviewGui* pc = NULL; GtkWidget* focus = NULL; @@ -183,6 +184,8 @@ gpointer motion_compile_thread (gpointer data) { g_mutex_unlock (&mc->compile_mutex); continue; } + editor_to_compile = editor; + if (!mc->keep_running) { g_mutex_unlock (&mc->compile_mutex); g_thread_exit (NULL); @@ -203,14 +206,25 @@ gpointer motion_compile_thread (gpointer data) { gtk_widget_grab_focus (focus); if (!precompile_ok) { - motion_start_errormode (mc, "document_error"); - gdk_threads_leave(); - g_mutex_unlock (&mc->compile_mutex); - continue; + // a reason for the document to not being compilable is that it's + // a non-root file of a project. so, we'll check this case + if (editor->projfile != NULL && editor->rootEditor != NULL) { + // dirty hack to force update of file (compilation will only be + // done when the root file has changed, however since we're + // editing a non-root file, this won't be the case) + latex->modified_since_compile = 1; + editor_to_compile = editor->rootEditor; + } else { + motion_start_errormode (mc, "document_error"); + gdk_threads_leave(); + g_mutex_unlock (&mc->compile_mutex); + continue; + } + } gdk_threads_leave(); - compile_status = latex_update_pdffile (latex, editor); + compile_status = latex_update_pdffile (latex, editor_to_compile); *mc->typesetter_pid = 0; g_mutex_unlock (&mc->compile_mutex); @@ -230,7 +244,8 @@ gpointer motion_compile_thread (gpointer data) { } else { if (!pc->uri) { - char* uri = g_strconcat (urifrmt, editor->pdffile, NULL); + char* uri = g_strconcat (urifrmt, + editor_to_compile->pdffile, NULL); previewgui_set_pdffile (pc, uri); g_free(uri); } else { diff --git a/src/project.c b/src/project.c index dea4c1d1..0007ec0d 100644 --- a/src/project.c +++ b/src/project.c @@ -202,6 +202,7 @@ gboolean project_load_files (const gchar* projfile, const gchar* content) { gboolean status = FALSE; gint rootpos, i; gchar* filename; + GuEditor* rootEditor = NULL; GList* filelist = project_list_files (content); gint length = g_list_length (filelist); @@ -211,7 +212,14 @@ gboolean project_load_files (const gchar* projfile, const gchar* content) { if (g_file_test (filename, G_FILE_TEST_EXISTS)) { if (!tabmanager_check_exists (filename)) { - gui_open_file (filename); + if (i == 0) { + /* The first file is always the root file */ + gui_open_file (filename, NULL, &rootEditor); + } + else { + gui_open_file (filename, rootEditor, NULL); + } + // TODO: no direct calling this: g_active_editor->projfile = g_strdup (projfile); } diff --git a/src/tabmanager.c b/src/tabmanager.c index 22bfce0b..87ba422e 100644 --- a/src/tabmanager.c +++ b/src/tabmanager.c @@ -110,11 +110,17 @@ void tabmanager_set_active_tab (int position) { } } - -void tabmanager_create_tab (OpenAct act, const gchar* filename, gchar* opt) { +// rootEditor: pointer to instance of editor of the root file (in a project) +// createdEditor: if non-NULL, a pointer to the newly created editor is saved to +// this variable +void tabmanager_create_tab (OpenAct act, const gchar* filename, gchar* opt, + GuEditor* rootEditor, GuEditor** createdEditor) { gint pos = 0; - GuEditor* editor = gummi_new_environment (filename); + GuEditor* editor = gummi_new_environment (filename, rootEditor); + if (createdEditor != NULL) { + *createdEditor = editor; + } if (current_tab_replaceable (act)) { pos = tabmanagergui_replace_page (g_active_tab, editor); diff --git a/src/tabmanager.h b/src/tabmanager.h index 4bbe9d66..ea03ae8a 100644 --- a/src/tabmanager.h +++ b/src/tabmanager.h @@ -65,7 +65,8 @@ gboolean tabmanager_remove_tab (GuTabContext* tab); /*------------------------------------------------------------------------*/ -void tabmanager_create_tab (OpenAct act, const gchar* filename, gchar* opt); +void tabmanager_create_tab (OpenAct act, const gchar* filename, gchar* opt, + GuEditor* rootEditor, GuEditor** createdEditor); void tabmanager_update_tab (const gchar* filename); gboolean tabmanager_has_tabs (); gboolean tabmanager_check_exists (const gchar* filename);