diff options
Diffstat (limited to 'support/autolatex/plugins/gedit2/autolatex/config/cli')
8 files changed, 2165 insertions, 0 deletions
diff --git a/support/autolatex/plugins/gedit2/autolatex/config/cli/__init__.py b/support/autolatex/plugins/gedit2/autolatex/config/cli/__init__.py new file mode 100644 index 0000000000..9b81392286 --- /dev/null +++ b/support/autolatex/plugins/gedit2/autolatex/config/cli/__init__.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# autolatex/config/cli/__init__.py +# Copyright (C) 2013 Stephane Galland <galland@arakhne.org> +# +# 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; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +__all__ = [ 'window', 'abstract_panel', 'figure_assignment_panel', 'figure_panel', 'generator_panel', 'plugin_config_panel', 'translator_panel', 'viewer_panel' ] diff --git a/support/autolatex/plugins/gedit2/autolatex/config/cli/abstract_panel.py b/support/autolatex/plugins/gedit2/autolatex/config/cli/abstract_panel.py new file mode 100644 index 0000000000..8e8f997d39 --- /dev/null +++ b/support/autolatex/plugins/gedit2/autolatex/config/cli/abstract_panel.py @@ -0,0 +1,272 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# autolatex/config/cli/figure_assignment_panel.py +# Copyright (C) 2013 Stephane Galland <galland@arakhne.org> +# +# 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; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +#--------------------------------- +# IMPORTS +#--------------------------------- + +# Include the Glib, Gtk and Gedit libraries +from gi.repository import GObject, Gtk +# AutoLaTeX internal libs +from ...utils import utils +from ...widgets import inherit_button + +#--------------------------------- +# CLASS Panel +#--------------------------------- + +# Gtk panel that is managing the configuration of the figure assignments +class AbstractPanel(Gtk.Box): + __gtype_name__ = "AutoLaTeXAbstractConfigurationPanel" + + def __init__(self, is_document_level, directory, window): + # Use an intermediate GtkBox to be sure that + # the child GtkGrid will not be expanded vertically + Gtk.Box.__init__(self) + self._is_document_level = is_document_level + self._directory = directory + self._window = window + self._settings = None + # + # Create the grid for the panel + # + self.set_property('orientation', Gtk.Orientation.VERTICAL) + self._grid = Gtk.Grid() + self.pack_start(self._grid, False, False, 0) + self._grid.set_row_homogeneous(False) + self._grid.set_column_homogeneous(False) + self._grid.set_row_spacing(5) + self._grid.set_column_spacing(5) + self._grid.set_property('margin', 5) + self._grid.set_property('vexpand', False) + self._grid.set_property('hexpand', True) + self._grid_row = 0 + # + # Create the panel's widgets + # + self._init_widgets() + # + # Initialize the content + # + self._init_content() + # + # Update the state of the widgets + # + self.update_widget_states() + # + # Connext the signals + # + self._connect_signals() + + def _init_widgets(self): + """Invoked to fill the given grid with the widgets""" + raise NotImplementedError("Please implement this method") + + def _init_content(self): + """Invoked to initialize the values in the widgets""" + raise NotImplementedError("Please implement this method") + + def _connect_signals(self): + """Invoked to connect methods to the widgets' signals""" + raise NotImplementedError("Please implement this method") + + def update_widget_states(self): + """Invoked to change the states of the widgets""" + raise NotImplementedError("Please implement this method") + + def save(self): + """Invoked when the changes in the panel must be saved""" + raise NotImplementedError("Please implement this method") + + # Utility function that permits to change the sensitivity + # of a widget according to a given flag and the "inheriting" flag + def _update_sentitivity(self, widget, is_sensitive): + inherit_flag = widget.get_data('autolatex_overriding_configuration_value') + if inherit_flag: + inherit_flag = inherit_flag() + if inherit_flag: + return inherit_flag.set_widget_sensitivity(is_sensitive) + widget.set_sensitive(is_sensitive) + return is_sensitive + + # Utility function that permits to change the overriding of a widget + def _init_overriding(self, widget, is_overriding): + inherit_flag = widget.get_data('autolatex_overriding_configuration_value') + if inherit_flag: + inherit_flag = inherit_flag() + if inherit_flag: + inherit_flag.set_overriding_value(is_overriding) + + # Utility function that permits to get the sensitivity + # of a widget according to a given flag and the "inheriting" flag + def _get_sentitivity(self, widget): + inherit_flag = widget.get_data('autolatex_overriding_configuration_value') + if inherit_flag: + inherit_flag = inherit_flag() + if inherit_flag: + return inherit_flag.get_widget_sensitivity(widget) + return widget.get_sensitive() + + # Utility function that permits to get the overriding + # of a widget according to a given flag and the "inheriting" flag + def _get_overriding(self, widget): + inherit_flag = widget.get_data('autolatex_overriding_configuration_value') + if inherit_flag: + inherit_flag = inherit_flag() + if inherit_flag: + return inherit_flag.get_overriding_value() + return True + + # Utility function that permits to read the settings. + def _read_settings(self, section): + self._settings = utils.backend_get_configuration( + self._directory, + 'project' if self._is_document_level else 'user', + section) + self._settings_section = section + + # Utility function to extract a string value from the settings + def _get_settings_str(self, key, default_value=None): + if self._settings and self._settings.has_option(self._settings_section, key): + return str(self._settings.get(self._settings_section, key)) + else: + return default_value + + # Utility function to extract a boolean value from the settings + def _get_settings_bool(self, key, default_value=None): + if self._settings and self._settings.has_option(self._settings_section, key): + return bool(self._settings.getboolean(self._settings_section, key)) + else: + return default_value + + # Utility function to extract an inherited string value from the settings + def _get_settings_str_inh(self, key, default_value=None): + return self._get_settings_str(key+'_INHERITED', default_value) + + # Utility function to extract an inherited boolean value from the settings + def _get_settings_bool_inh(self, key, default_value=None): + return self._get_settings_bool(key+'_INHERITED', default_value) + + # Utility function to set a string value from the settings + def _set_settings_str(self, key, value): + if self._settings: + if not value: + value = utils.CONFIG_EMPTY_VALUE + self._settings.set(self._settings_section, key, value) + + # Utility function to set a boolean value from the settings + def _set_settings_bool(self, key, value): + if self._settings: + if value is None: + value = utils.CONFIG_EMPTY_VALUE + else: + value = ('true' if value else 'false') + self._settings.set(self._settings_section, key, value) + + # Utility function to reset a section in the settings + def _reset_settings_section(self, section=None): + if self._settings: + if not section: + section = self._settings_section + self._settings.remove_section(section) + self._settings.add_section(section) + + # Utility function to create a label + def _create_label(self, text, hexpand=False): + ui_label = Gtk.Label(text) + ui_label.set_property('hexpand', hexpand) + ui_label.set_property('vexpand', False) + ui_label.set_property('halign', Gtk.Align.START) + ui_label.set_property('valign', Gtk.Align.CENTER) + return ui_label + + # Utility function to create a row in a grid + def _insert_row(self, left_widget, right_widget=None, enable_inherit=True): + if right_widget: + self._grid.attach( left_widget, + 0,self._grid_row,1,1) # left, top, width, height + self._grid.attach( right_widget, + 1,self._grid_row,1,1) # left, top, width, height + else: + self._grid.attach( left_widget, + 0,self._grid_row,2,1) # left, top, width, height + inheriting_widget = None + if enable_inherit: + height = 1 + if isinstance(enable_inherit, (int, long)) and int(enable_inherit)>1: + height = int(enable_inherit) + inheriting_widget = inherit_button.InheritButton(self, left_widget, right_widget) + inheriting_widget.set_property('expand', False) + inheriting_widget.set_property('halign', Gtk.Align.CENTER) + inheriting_widget.set_property('valign', Gtk.Align.CENTER) + self._grid.attach( inheriting_widget, + 2,self._grid_row,1,height) # left, top, width, height + self._grid_row = self._grid_row + 1 + return [ left_widget, right_widget, inheriting_widget ] + + # Utility function to create a row in a grid + def _create_row(self, label_text, right_widget, enable_inherit=True): + ui_label = self._create_label(label_text) + right_widget.set_property('hexpand', True) + right_widget.set_property('vexpand', False) + return self._insert_row(ui_label, right_widget, enable_inherit) + + # Utility function to create a row in a grid with a Switch + def _create_switch(self, label_text, enable_inherit=True): + widget = Gtk.Switch() + tab = self._create_row(label_text, widget, enable_inherit) + widget.set_property('hexpand', False) + widget.set_property('vexpand', False) + widget.set_property('halign', Gtk.Align.END) + widget.set_property('valign', Gtk.Align.CENTER) + return tab + + + # Utility function to create a row in a grid with an Entry + def _create_entry(self, label_text, enable_inherit=True): + widget = Gtk.Entry() + return self._create_row(label_text, widget, enable_inherit) + + + # Utility function to create a row in a grid with a ComboText + def _create_combo(self, label_text, values=None, combo_name=None, enable_inherit=True): + widget = Gtk.ComboBoxText() + if combo_name: + widget.set_name(combo_name) + if values: + for value in values: + widget.append_text(value) + return self._create_row(label_text, widget, enable_inherit) + + + # Utility function to create a scroll panel for the given widget + def _create_scroll_for(self, widget, width=400, height=400): + scroll = Gtk.ScrolledWindow() + scroll.add(widget) + scroll.set_size_request(width, height) + scroll.set_policy( + Gtk.PolicyType.AUTOMATIC, + Gtk.PolicyType.AUTOMATIC) + scroll.set_shadow_type(Gtk.ShadowType.IN) + scroll.set_property('hexpand', True) + scroll.set_property('vexpand', True) + return scroll + diff --git a/support/autolatex/plugins/gedit2/autolatex/config/cli/figure_assignment_panel.py b/support/autolatex/plugins/gedit2/autolatex/config/cli/figure_assignment_panel.py new file mode 100644 index 0000000000..35efbd61aa --- /dev/null +++ b/support/autolatex/plugins/gedit2/autolatex/config/cli/figure_assignment_panel.py @@ -0,0 +1,203 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# autolatex/config/cli/figure_assignment_panel.py +# Copyright (C) 2013 Stephane Galland <galland@arakhne.org> +# +# 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; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +#--------------------------------- +# IMPORTS +#--------------------------------- + +# Standard libraries +import os +import re +import ConfigParser +# Include the Glib, Gtk and Gedit libraries +from gi.repository import Gtk +# AutoLaTeX internal libs +from ...utils import utils +from . import abstract_panel + +#--------------------------------- +# INTERNATIONALIZATION +#--------------------------------- + +import gettext +_T = gettext.gettext + +#--------------------------------- +# CLASS Panel +#--------------------------------- + +# Gtk panel that is managing the configuration of the figure assignments +class Panel(abstract_panel.AbstractPanel): + __gtype_name__ = "AutoLaTeXFigureAssignmentPanel" + + def __init__(self, is_document_level, directory, window): + abstract_panel.AbstractPanel.__init__(self, is_document_level, directory, window) + + + # + # Fill the grid + # + def _init_widgets(self): + # Comment + ui_label = self._create_label(_T("List of the figures detected in your document's directory.\nYou can edit the second column to set the translator used for a particular figure.")) + self._insert_row(ui_label, None, False) + # List of figures + self._ui_figure_edit_store = Gtk.ListStore(str) + self._ui_figure_store = Gtk.ListStore(str, str) + ui_figure_widget = Gtk.TreeView() + ui_figure_widget.set_model(self._ui_figure_store) + ui_figure_widget.append_column(Gtk.TreeViewColumn(_T("Figure"), Gtk.CellRendererText(), text=0)) + renderer_combo = Gtk.CellRendererCombo() + renderer_combo.set_property("editable", True) + renderer_combo.set_property("model", self._ui_figure_edit_store) + renderer_combo.set_property("text-column", 0) + renderer_combo.set_property("has-entry", False) + renderer_combo.connect("edited", self.on_figure_translator_changed) + ui_figure_widget.append_column(Gtk.TreeViewColumn(_T("Translator"), renderer_combo, text=1)) + ui_figure_widget.set_headers_clickable(False) + ui_figure_widget.set_headers_visible(True) + self._ui_figure_selection = ui_figure_widget.get_selection() + self._ui_figure_selection.set_mode(Gtk.SelectionMode.SINGLE) + # Scroll + ui_figure_scroll = self._create_scroll_for(ui_figure_widget) + self._insert_row(ui_figure_scroll, None, False) + + + # + # Initialize the content + # + def _init_content(self): + self._settings = utils.backend_get_translators(self._directory) + self._translators = {} + self._regex = re.compile('^([^2]+)') + for translator in self._settings.sections(): + result = re.match(self._regex, translator) + if result: + source = result.group(1) + if source not in self._translators: + self._translators[source] = [] + self._translators[source].append(translator) + + self._settings = utils.backend_get_images(self._directory) + self._file_list = {} + for translator in self._settings.sections(): + if self._settings.has_option(translator, 'automatic assignment'): + data = self._settings.get(translator, 'automatic assignment') + files = data.split(os.pathsep) + for afile in files: + if afile not in self._file_list: + self._file_list[afile] = {} + self._file_list[afile]['translator'] = translator + self._file_list[afile]['override'] = False + self._file_list[afile]['selected'] = translator + if self._settings.has_option(translator, 'files to convert'): + data = self._settings.get(translator, 'files to convert') + files = data.split(os.pathsep) + for afile in files: + if afile not in self._file_list: + self._file_list[afile] = {} + self._file_list[afile]['translator'] = translator + self._file_list[afile]['override'] = True + self._file_list[afile]['selected'] = translator + if self._settings.has_option(translator, 'overriden assignment'): + data = self._settings.get(translator, 'overriden assignment') + files = data.split(os.pathsep) + for afile in files: + if afile not in self._file_list: + self._file_list[afile] = {} + self._file_list[afile]['auto-translator'] = translator + + for filename in sorted(self._file_list): + if 'translator' in self._file_list[filename]: + self._ui_figure_store.append( [ filename, self._file_list[filename]['translator'] ] ) + + + # + # Connect signals + # + def _connect_signals(self): + self._ui_figure_selection.connect('changed',self.on_figure_selection_changed) + + + def update_widget_states(self): + pass + + # Invoked when the selection in the lsit of figure paths has changed + def on_figure_selection_changed(self, selection, data=None): + n_sel = self._ui_figure_selection.count_selected_rows() + if n_sel > 0: + path = self._ui_figure_selection.get_selected_rows()[1][0] + sel_iter = self._ui_figure_store.get_iter(path) + value = self._ui_figure_store.get_value(sel_iter, 1) + afile = self._ui_figure_store.get_value(sel_iter, 0) + self._ui_figure_edit_store.clear() + result = re.match(self._regex, value) + if result: + source = result.group(1) + if afile in self._file_list and self._file_list[afile]['override']: + auto_translator = self._file_list[afile]['auto-translator'] + else: + auto_translator = self._file_list[afile]['translator'] + for translator in self._translators[source]: + label = translator + if translator == auto_translator: + label = label+' (default)' + self._ui_figure_edit_store.append( [label] ) + + # Invoked when the selection in the lsit of figure paths has changed + def on_figure_translator_changed(self, combo, path, new_text, data=None): + if new_text: + if new_text.endswith(' (default)'): + new_text = new_text[0:len(new_text)-10] + sel_iter = self._ui_figure_store.get_iter(path) + self._ui_figure_store.set_value(sel_iter, 1, new_text) + afile = self._ui_figure_store.get_value(sel_iter, 0) + self._file_list[afile]['selected'] = new_text + + def _append_file(self, config, section, option, afile): + if config.has_option(section, option): + path = config.get(section, option) + if path: + path = path+os.pathsep+afile + else: + path = afile + else: + path = afile + config.set(section, option, path) + + # Invoked when the changes in the panel must be saved + def save(self): + config = ConfigParser.ConfigParser() + for source in self._translators: + for translator in self._translators[source]: + config.add_section(translator) + for afile in self._file_list: + current = self._file_list[afile]['selected'] + if self._file_list[afile]['override']: + std = self._file_list[afile]['auto-translator'] + else: + std = self._file_list[afile]['translator'] + if current == std: + self._append_file(config, current, 'automatic assignment', afile) + else: + self._append_file(config, current, 'files to convert', afile) + self._append_file(config, std, 'overriden assignment', afile) + return utils.backend_set_images(self._directory, config) diff --git a/support/autolatex/plugins/gedit2/autolatex/config/cli/figure_panel.py b/support/autolatex/plugins/gedit2/autolatex/config/cli/figure_panel.py new file mode 100644 index 0000000000..e2bbe3f2eb --- /dev/null +++ b/support/autolatex/plugins/gedit2/autolatex/config/cli/figure_panel.py @@ -0,0 +1,273 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# autolatex/config/cli/figure_panel.py +# Copyright (C) 2013 Stephane Galland <galland@arakhne.org> +# +# 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; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +#--------------------------------- +# IMPORTS +#--------------------------------- + +# Standard libraries +import os +# Include the Glib, Gtk and Gedit libraries +from gi.repository import GObject, Gtk, Gio +# AutoLaTeX internal libs +from ...utils import utils +from . import abstract_panel + +#--------------------------------- +# INTERNATIONALIZATION +#--------------------------------- + +import gettext +_T = gettext.gettext + +#--------------------------------- +# CLASS Panel +#--------------------------------- + +# Gtk panel that is managing the configuration of the figures +class Panel(abstract_panel.AbstractPanel): + __gtype_name__ = "AutoLaTeXFigurePanel" + + def __init__(self, is_document_level, directory, window): + abstract_panel.AbstractPanel.__init__(self, is_document_level, directory, window) + + + # + # Fill the grid + # + def _init_widgets(self): + # Automatic generation of figures + self._ui_is_figure_generated_checkbox = self._create_switch( + _T("Automatic generation of pictures with translators"))[1] + # Toolbar for the search paths + self._ui_figure_path_label = self._create_label( + _T("Search paths for the pictures")) + hbox = Gtk.Box() + hbox.set_property('orientation', Gtk.Orientation.HORIZONTAL) + hbox.set_property('hexpand', False) + hbox.set_property('vexpand', False) + hbox.set_property('halign', Gtk.Align.END) + hbox.set_property('valign', Gtk.Align.CENTER) + inherting_button = self._insert_row(self._ui_figure_path_label, hbox, 2)[2] + inherting_button.unbind_widget(hbox) + + # Button 1 + self._ui_figure_path_add_button = Gtk.Button() + self._ui_figure_path_add_button.set_image(Gtk.Image.new_from_stock(Gtk.STOCK_ADD, Gtk.IconSize.BUTTON)) + inherting_button.bind_widget(self._ui_figure_path_add_button) + hbox.add(self._ui_figure_path_add_button) + # Button 2 + self._ui_figure_path_remove_button = Gtk.Button() + self._ui_figure_path_remove_button.set_image(Gtk.Image.new_from_stock(Gtk.STOCK_REMOVE, Gtk.IconSize.BUTTON)) + inherting_button.bind_widget(self._ui_figure_path_remove_button) + hbox.add(self._ui_figure_path_remove_button) + # Button 3 + self._ui_figure_path_up_button = Gtk.Button() + self._ui_figure_path_up_button.set_image(Gtk.Image.new_from_stock(Gtk.STOCK_GO_UP, Gtk.IconSize.BUTTON)) + inherting_button.bind_widget(self._ui_figure_path_up_button) + hbox.add(self._ui_figure_path_up_button) + # Button 4 + self._ui_figure_path_down_button = Gtk.Button() + self._ui_figure_path_down_button.set_image(Gtk.Image.new_from_stock(Gtk.STOCK_GO_DOWN, Gtk.IconSize.BUTTON)) + inherting_button.bind_widget(self._ui_figure_path_down_button) + hbox.add(self._ui_figure_path_down_button) + # List + self._ui_figure_path_store = Gtk.ListStore(str) + self._ui_figure_path_widget = Gtk.TreeView() + self._ui_figure_path_widget.set_model(self._ui_figure_path_store) + self._ui_figure_path_widget.append_column(Gtk.TreeViewColumn("path", Gtk.CellRendererText(), text=0)) + self._ui_figure_path_widget.set_headers_clickable(False) + self._ui_figure_path_widget.set_headers_visible(False) + self._ui_figure_path_selection = self._ui_figure_path_widget.get_selection() + self._ui_figure_path_selection.set_mode(Gtk.SelectionMode.MULTIPLE) + inherting_button.bind_widget(self._ui_figure_path_widget) + # Scroll + ui_figure_path_scroll = self._create_scroll_for( + self._ui_figure_path_widget, 400, 100) + self._insert_row(ui_figure_path_scroll, None, False) + + + # + # Initialize the content + # + def _init_content(self): + self._read_settings('generation') + # + inh = self._get_settings_bool_inh('generate images') + cur = self._get_settings_bool('generate images') + self._init_overriding(self._ui_is_figure_generated_checkbox, cur is not None) + self._ui_is_figure_generated_checkbox.set_active(utils.first_of(cur, inh, True)) + # + inh = self._get_settings_str_inh('image directory') + cur = self._get_settings_str('image directory') + self._init_overriding(self._ui_figure_path_widget, cur is not None) + full_path = utils.first_of(cur, inh, '') + if full_path: + full_path = full_path.split(os.pathsep) + for path in full_path: + self._ui_figure_path_store.append( [ path.strip() ] ) + self._tmp_figure_path_moveup = False + self._tmp_figure_path_movedown = False + + + # + # Connect signals + # + def _connect_signals(self): + self._ui_is_figure_generated_checkbox.connect('notify::active',self.on_generate_image_toggled) + self._ui_figure_path_selection.connect('changed',self.on_figure_path_selection_changed) + self._ui_figure_path_add_button.connect('clicked',self.on_figure_path_add_button_clicked) + self._ui_figure_path_remove_button.connect('clicked',self.on_figure_path_remove_button_clicked) + self._ui_figure_path_up_button.connect('clicked',self.on_figure_path_up_button_clicked) + self._ui_figure_path_down_button.connect('clicked',self.on_figure_path_down_button_clicked) + + + # Change the state of the widgets according to the state of other widgets + def update_widget_states(self): + is_active = self._ui_is_figure_generated_checkbox.get_active() + if not self._get_overriding(self._ui_is_figure_generated_checkbox): + inh = self._get_settings_bool_inh('generate images', True) + if (inh!=is_active): + GObject.idle_add(self._ui_is_figure_generated_checkbox.set_active, inh) + is_active = inh + is_active = self._update_sentitivity(self._ui_figure_path_label, is_active) + if is_active: + if self._ui_figure_path_selection.count_selected_rows() > 0: + self._ui_figure_path_up_button.set_sensitive(self._tmp_figure_path_moveup) + self._ui_figure_path_down_button.set_sensitive(self._tmp_figure_path_movedown) + else: + self._ui_figure_path_remove_button.set_sensitive(False) + self._ui_figure_path_up_button.set_sensitive(False) + self._ui_figure_path_down_button.set_sensitive(False) + + # Invoke when the flag 'generate images' has changed + def on_generate_image_toggled(self, widget, data=None): + self.update_widget_states() + + def _check_figure_path_up_down(self, selection): + n_data = len(self._ui_figure_path_store) + self._tmp_figure_path_moveup = False + self._tmp_figure_path_movedown = False + selected_rows = selection.get_selected_rows()[1] + i = 0 + last_row = len(selected_rows)-1 + while (i<=last_row and (not self._tmp_figure_path_moveup or not self._tmp_figure_path_movedown)): + c_idx = selected_rows[i].get_indices()[0] + if (i==0 and c_idx>0) or (i>0 and c_idx-1 > selected_rows[i-1].get_indices()[0]): + self._tmp_figure_path_moveup = True + if (i==last_row and c_idx<n_data-1) or (i<last_row and c_idx+1 < selected_rows[i+1].get_indices()[0]): + self._tmp_figure_path_movedown = True + i = i + 1 + + # Invoked when the selection in the lsit of figure paths has changed + def on_figure_path_selection_changed(self, selection, data=None): + self._check_figure_path_up_down(selection) + self.update_widget_states() + + # Invoked when the button "Add figure figure" was clicked + def on_figure_path_add_button_clicked(self, button, data=None): + dialog = Gtk.FileChooserDialog(_T("Select a figure path"), + self._window, + Gtk.FileChooserAction.SELECT_FOLDER, + [ Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, + Gtk.STOCK_OPEN, Gtk.ResponseType.ACCEPT ]) + dialog.set_modal(True) + response = dialog.run() + filename = dialog.get_filename() + dialog.destroy() + if response == Gtk.ResponseType.ACCEPT: + if self._is_document_level: + c = Gio.File.new_for_path(filename) + p = Gio.File.new_for_path(self._directory) + r = p.get_relative_path(c) + if r: filename = r + self._ui_figure_path_store.append( [filename] ) + + # Invoked when the button "Remove figure figure" was clicked + def on_figure_path_remove_button_clicked(self, button, data=None): + count = self._ui_figure_path_selection.count_selected_rows() + if count > 0: + selections = self._ui_figure_path_selection.get_selected_rows()[1] + for i in range(len(selections)-1, -1, -1): + list_iter = self._ui_figure_path_store.get_iter(selections[i]) + self._ui_figure_path_store.remove(list_iter) + + # Invoked when the button "Move up the figure paths" was clicked + def on_figure_path_up_button_clicked(self, button, data=None): + n_sel = self._ui_figure_path_selection.count_selected_rows() + if n_sel > 0: + selected_rows = self._ui_figure_path_selection.get_selected_rows()[1] + movable = False + p_idx = -1 + for i in range(0, n_sel): + c_idx = selected_rows[i].get_indices()[0] + if not movable and c_idx-1>p_idx: movable = True + if movable: + self._ui_figure_path_store.swap( + self._ui_figure_path_store.get_iter( + Gtk.TreePath(c_idx-1)), + self._ui_figure_path_store.get_iter(selected_rows[i])) + else: p_idx = c_idx + self._check_figure_path_up_down(self._ui_figure_path_selection) + self.update_widget_states() + + # Invoked when the button "Move down the figure paths" was clicked + def on_figure_path_down_button_clicked(self, button, data=None): + n_sel = self._ui_figure_path_selection.count_selected_rows() + if n_sel > 0: + selected_rows = self._ui_figure_path_selection.get_selected_rows()[1] + movable = False + p_idx = len(self._ui_figure_path_store) + for i in range(n_sel-1, -1, -1): + c_idx = selected_rows[i].get_indices()[0] + if not movable and c_idx+1<p_idx: movable = True + if movable: + self._ui_figure_path_store.swap( + self._ui_figure_path_store.get_iter( + Gtk.TreePath(c_idx+1)), + self._ui_figure_path_store.get_iter(selected_rows[i])) + else: p_idx = c_idx + self._check_figure_path_up_down(self._ui_figure_path_selection) + self.update_widget_states() + + # Invoked when the changes in the panel must be saved + def save(self): + self._reset_settings_section() + # + if self._get_sentitivity(self._ui_is_figure_generated_checkbox): + v = self._ui_is_figure_generated_checkbox.get_active() + else: + v = None + self._set_settings_bool('generate images', v) + # + if self._get_sentitivity(self._ui_figure_path_label): + path = '' + for row in self._ui_figure_path_store: + if path: path = path + os.pathsep + path = path + row[0].strip() + else: + path = None + self._set_settings_str('image directory', path) + # + return utils.backend_set_configuration( + self._directory, + 'project' if self._is_document_level else 'user', + self._settings) diff --git a/support/autolatex/plugins/gedit2/autolatex/config/cli/generator_panel.py b/support/autolatex/plugins/gedit2/autolatex/config/cli/generator_panel.py new file mode 100644 index 0000000000..cb4b1f024c --- /dev/null +++ b/support/autolatex/plugins/gedit2/autolatex/config/cli/generator_panel.py @@ -0,0 +1,269 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# autolatex/config/cli/generator_panel.py +# Copyright (C) 2013 Stephane Galland <galland@arakhne.org> +# +# 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; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +#--------------------------------- +# IMPORTS +#--------------------------------- + +# Include the Glib, Gtk and Gedit libraries +from gi.repository import GObject, Gdk, Gtk, GdkPixbuf +# AutoLaTeX internal libs +from ...utils import utils +from . import abstract_panel + +#--------------------------------- +# INTERNATIONALIZATION +#--------------------------------- + +import gettext +_T = gettext.gettext + +#--------------------------------- +# CLASS _GenerationType +#--------------------------------- + +class _GenerationType: + PDF = 'pdf' + DVI = 'dvi' + POSTSCRIPT = 'ps' + + def index(v): + if v == _GenerationType.POSTSCRIPT: return 2 + elif v == _GenerationType.DVI: return 1 + else: return 0 + + def label(i): + if i == 2: return _GenerationType.POSTSCRIPT + elif i == 1: return _GenerationType.DVI + else: return _GenerationType.PDF + + index = staticmethod(index) + label = staticmethod(label) + +#--------------------------------- +# CLASS _IndexType +#--------------------------------- + +class _IndexType: + FILE = 0 # [ <str> ] + DETECTION = 1 # [@detect] or [@detect, @system] + DEFAULT = 2 # [@system] + NONE = 3 # empty or [@none] + USER = 4 # other + + def parse(s): + tab = s.split(',') + for i in range(len(tab)): + tab[i] = tab[i].strip() + return tab + + def index(t): + if t and len(t)>0: + if len(t) == 2: + if t[0] == '@detect' and t[1] == '@system': return _IndexType.DETECTION + else: return _IndexType.USER + elif len(t) == 1: + if t[0] == '@detect': return _IndexType.DETECTION + elif t[0] == '@system': return _IndexType.DEFAULT + elif not t[0] or t[0] == '@none': return _IndexType.NONE + else: return _IndexType.USER + else: + return _IndexType.USER + else: + return _IndexType.NONE + + def label(i, file_value, original_value): + if i == 0: return file_value + elif i == 1: return '@detect, @system' + elif i == 2: return '@system' + elif i == 3: return '@none' + else: return original_value + + parse = staticmethod(parse) + index = staticmethod(index) + label = staticmethod(label) + +#--------------------------------- +# CLASS Panel +#--------------------------------- + +# Gtk panel that is managing the configuration of the generator +class Panel(abstract_panel.AbstractPanel): + __gtype_name__ = "AutoLaTeXGeneratorPanel" + + def __init__(self, is_document_level, directory, window): + abstract_panel.AbstractPanel.__init__(self, is_document_level, directory, window) + + # + # Fill the grid + # + def _init_widgets(self): + table_row = 0 + if self._is_document_level: + # Main TeX File + self._ui_main_tex_file_editor = self._create_entry( + _T("Main TeX file (optional)"))[1] + # Execute the bibtex tools + self._ui_run_biblio_checkbox = self._create_switch( + _T("Execute the bibliography tool (BibTeX, Bibber...)"))[1] + # Type of generation + self._ui_generation_type_combo = self._create_combo( + _T("Type of generation"), + [ "PDF", "DVI", "Postscript" ], + 'generation_type')[1] + # SyncTeX + self._ui_run_synctex_checkbox = self._create_switch( + _T("Use SyncTeX when generating the document"))[1] + # Type of MakeIndex style + r = self._create_combo( + _T("Type of style for MakeIndex"), + [ _T("Specific '.ist' file"), + _T("Autodetect the style inside the project directory"), + _T("Use only the default AutoLaTeX style"), + _T("No style is passed to MakeIndex"), + _T("Custom definition by the user (do not change the original configuration)") ], + 'makeindex_style_type') + self._ui_makeindex_type_combo = r[1] + # File of the MakeIndex style + label = _T("Style file for MakeIndex") + self._ui_makeindex_file_field = Gtk.FileChooserButton() + self._ui_makeindex_file_field.set_width_chars(40) + self._ui_makeindex_file_field.set_title(label) + self._ui_makeindex_file_label = self._create_row( + label, + self._ui_makeindex_file_field, + False)[0] + + + # + # Initialize the content + # + def _init_content(self): + self._read_settings('generation') + # + if self._is_document_level: + inh = self._get_settings_str_inh('main file') + cur = self._get_settings_str('main file') + self._init_overriding(self._ui_main_tex_file_editor, cur is not None) + self._ui_main_tex_file_editor.set_text(utils.first_of(cur, inh, '')) + # + inh = self._get_settings_str_inh('biblio') + cur = self._get_settings_str('biblio') + self._init_overriding(self._ui_run_biblio_checkbox, cur is not None) + self._ui_run_biblio_checkbox.set_active(utils.first_of(cur, inh, True)) + # + inh = self._get_settings_str_inh('synctex') + cur = self._get_settings_str('synctex') + self._init_overriding(self._ui_run_synctex_checkbox, cur is not None) + self._ui_run_synctex_checkbox.set_active(utils.first_of(cur, inh, False)) + # + inh = self._get_settings_str_inh('generation type') + cur = self._get_settings_str('generation type') + self._init_overriding(self._ui_generation_type_combo, cur is not None) + self._ui_generation_type_combo.set_active( + _GenerationType.index( + utils.first_of(cur,inh,_GenerationType.PDF))) + # + inh = self._get_settings_str_inh('makeindex style') + cur = self._get_settings_str('makeindex style') + self._init_overriding(self._ui_makeindex_type_combo, cur is not None) + self._default_makeindex = utils.first_of(cur, inh, None) + makeindex_value = utils.first_of(self._default_makeindex, '@detect, @system') + makeindex_type = _IndexType.index(_IndexType.parse(makeindex_value)) + if makeindex_type == _IndexType.FILE: + self._ui_makeindex_file_field.set_filename(self._default_makeindex) + self._ui_makeindex_type_combo.set_active(makeindex_type) + + + # + # Connect signals + # + def _connect_signals(self): + self._ui_makeindex_type_combo.connect('changed',self.on_generation_type_changed) + + + + + # Change the state of the widgets according to the state of other widgets + def update_widget_states(self): + makeindex_type = self._ui_makeindex_type_combo.get_active() + is_over = self._get_overriding(self._ui_makeindex_type_combo) + if not is_over: + inh = self._get_settings_str_inh('makeindex style', '@detect, @system') + inh = _IndexType.index(_IndexType.parse(inh)) + if inh!=makeindex_type: + GObject.idle_add(self._ui_makeindex_type_combo.set_active, inh) + makeindex_type = inh + if is_over and (makeindex_type == _IndexType.FILE): + self._ui_makeindex_file_field.set_sensitive(True) + self._ui_makeindex_file_label.set_sensitive(True) + else: + self._ui_makeindex_file_field.unselect_all() + self._ui_makeindex_file_field.set_sensitive(False) + self._ui_makeindex_file_label.set_sensitive(False) + + # Invoke when the style of MakeIndex has changed + def on_generation_type_changed(self, widget, data=None): + self.update_widget_states() + + # Invoked when the changes in the panel must be saved + def save(self): + self._reset_settings_section() + # + if self._is_document_level and self._get_sentitivity(self._ui_main_tex_file_editor): + v = self._ui_main_tex_file_editor.get_text() + else: + v = None + self._set_settings_str('main file', v) + # + if self._get_sentitivity(self._ui_run_biblio_checkbox): + v = self._ui_run_biblio_checkbox.get_active() + else: + v = None + self._set_settings_bool('biblio', v) + # + if self._get_sentitivity(self._ui_run_synctex_checkbox): + v = self._ui_run_synctex_checkbox.get_active() + else: + v = None + self._set_settings_bool('synctex', v) + # + if self._get_sentitivity(self._ui_generation_type_combo): + v = _GenerationType.label( + self._ui_generation_type_combo.get_active()) + else: + v = None + self._set_settings_str('generation type', v) + # + if self._get_sentitivity(self._ui_makeindex_type_combo): + v = _IndexType.label( + self._ui_makeindex_type_combo.get_active(), + self._ui_makeindex_file_field.get_filename(), + self._default_makeindex) + else: + v = None + self._set_settings_str('makeindex style', v) + # + return utils.backend_set_configuration( + self._directory, + 'project' if self._is_document_level else 'user', + self._settings) + diff --git a/support/autolatex/plugins/gedit2/autolatex/config/cli/translator_panel.py b/support/autolatex/plugins/gedit2/autolatex/config/cli/translator_panel.py new file mode 100644 index 0000000000..43ddd968f4 --- /dev/null +++ b/support/autolatex/plugins/gedit2/autolatex/config/cli/translator_panel.py @@ -0,0 +1,876 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# autolatex/config/cli/translator_panel.py +# Copyright (C) 2013 Stephane Galland <galland@arakhne.org> +# +# 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; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +#--------------------------------- +# IMPORTS +#--------------------------------- + +# Include standard libraries +import os +import shutil +import re +# Include the Glib, Gtk and Gedit libraries +from gi.repository import GObject, Gdk, Gtk, GdkPixbuf, GtkSource +# AutoLaTeX internal libs +from ...utils import utils +from ...utils import gtk_utils +from . import abstract_panel + +#--------------------------------- +# INTERNATIONALIZATION +#--------------------------------- + +import gettext +_T = gettext.gettext + +#--------------------------------- +# CLASS _IconType +#--------------------------------- + +class _IconType: + INHERITED = 0 + INCLUDED = 1 + EXCLUDED = 2 + INHERITED_CONFLICT = 3 + CONFLICT = 4 + +#--------------------------------- +# CLASS _IconType +#--------------------------------- + +class _Level: + SYSTEM = 0 + USER = 1 + PROJECT = 2 + +#--------------------------------- +# CLASS _TranslatorCreationDialog +#--------------------------------- + +class _TranslatorCreationDialog(Gtk.Dialog): + __gtype_name__ = "AutoLaTeXTranslatorCreationDialog" + + def __init__(self, parent): + Gtk.Dialog.__init__(self, + _T("Create a translator"), + parent, 0, + ( Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT)) + self.set_default_size(600, 500) + # Prepare the grid for the widgets + self._grid = Gtk.Grid() + self.get_content_area().add(self._grid) + self._grid.set_row_homogeneous(False) + self._grid.set_column_homogeneous(False) + self._grid.set_row_spacing(5) + self._grid.set_column_spacing(5) + self._grid.set_property('margin', 5) + self._grid.set_property('vexpand', False) + self._grid.set_property('hexpand', True) + self._grid_row = 0 + # Top label + self._insert_row(self._create_label( + _T("Note: read the tooltips of the fields for help."))) + # Input extensions + self._ui_input_extensions = self._create_row( + _T("Input extensions"), Gtk.Entry())[1] + self._ui_input_extensions.set_tooltip_text( + _T("List of filename extensions, separated by spaces. Ex: .svg .svgz")) + # Output extension + self._ui_output_extension = Gtk.ComboBoxText() + self._ui_output_extension.set_name('output_extension') + self._ui_output_extension.append_text(_T("PDF or Postscript")) + self._ui_output_extension.append_text(_T("TeX macros inside PDF or Postscript")) + self._ui_output_extension.append_text(_T("Beamer Layer")) + self._ui_output_extension.append_text(_T("TeX macros inside Beamer Layer")) + self._ui_output_extension.append_text(_T("PNG Picture")) + self._create_row(_T("Output"), self._ui_output_extension) + # Variante + self._ui_variante = self._create_row(_T("Variante"), Gtk.Entry())[1] + # Execution mode + self._ui_execution_mode = Gtk.ComboBoxText() + self._ui_execution_mode.set_name('execution_mode') + self._ui_execution_mode.append_text(_T("Shell Command line")) + regex = re.compile('^([a-z0-9_]+)\.pm$') + script_modes = ['perl'] + interpreter_dir = os.path.join(utils.AUTOLATEX_PM_PATH, 'AutoLaTeX', 'Interpreter') + for c in os.listdir(interpreter_dir): + mo = re.match(regex, c) + if mo: + script_modes.append(mo.group(1)) + script_modes.sort() + self._script_modes = [] + for c in script_modes: + self._ui_execution_mode.append_text(_T("Script in %s") % c) + self._script_modes.append(c) + self._create_row(_T("Execution mode"), self._ui_execution_mode) + # Command line + tab = self._create_row(_T("Command line"), Gtk.Entry()) + self._ui_command_line_label = tab[0] + self._ui_command_line = tab[1] + self._ui_command_line.set_tooltip_text( + _T("Type a command line. Type:\n$in for the input filename;\n$out for the output filename;\n$outbasename for the basename with the dirname and extension;\n$outwoext for filename without the extension;\n$NAME for any environment variable named 'NAME'.")) + # Script code + self._lang_manager = GtkSource.LanguageManager.get_default() + self._ui_script_source = GtkSource.View() + self._ui_script_source_buffer = GtkSource.Buffer() + self._ui_script_source.set_buffer(self._ui_script_source_buffer) + self._ui_script_source_buffer.set_highlight_syntax(True) + scroll = Gtk.ScrolledWindow() + scroll.add(self._ui_script_source) + scroll.set_size_request(300, 200) + scroll.set_policy( + Gtk.PolicyType.AUTOMATIC, + Gtk.PolicyType.AUTOMATIC) + scroll.set_shadow_type(Gtk.ShadowType.IN) + scroll.set_property('hexpand', True) + scroll.set_property('vexpand', True) + self._ui_script_source_label = self._insert_row( + self._create_label(_T("Script source code"), True))[0] + self._insert_row(scroll) + # Files to clean + self._ui_files_to_clean = self._create_row( + _T("Files to clean"), Gtk.Entry())[1] + self._ui_files_to_clean.set_tooltip_text( + _T("Type list of patterns, separated by spaces. Type:\n$in for the input basename without the extension and without the directory;\n$out for the output basename without the extension and without the directory.")) + # Connect signals + self._ui_execution_mode.connect('changed', self.on_execution_mode_changed) + # Initialize fields + self._ui_script_source_label.set_sensitive(False) + self._ui_script_source.set_sensitive(False) + self._ui_output_extension.set_active(0) + self._ui_execution_mode.set_active(0) + # Finalization + self.show_all() + + def on_execution_mode_changed(self, widget, data=None): + execution_mode = self._ui_execution_mode.get_active() + is_command_line_mode = (execution_mode == 0) + self._ui_command_line_label.set_sensitive(is_command_line_mode) + self._ui_command_line.set_sensitive(is_command_line_mode) + self._ui_script_source_label.set_sensitive(not is_command_line_mode) + self._ui_script_source.set_sensitive(not is_command_line_mode) + if execution_mode>0: + lang_txt = self._script_modes[execution_mode-1] + lang = self._lang_manager.get_language(lang_txt) + if lang: + self._ui_script_source_buffer.set_language(lang) + self._ui_script_source_buffer.set_highlight_syntax(True) + else: + self._ui_script_source_buffer.set_highlight_syntax(False) + text = _T("Type a source code. Type:\n#1in for the input filename;\n#1out for the output filename;\n#1outbasename for the basename without extension and dirname;\n#1outwoext for the filename without extension;\n#2inexts is the array of the input extensions;\n#1outext is the first output extension;\n#2outexts is the array of the output extensions;\n#1ispdfmode indicates if the translator is used in PDF mode;\n#1isepsmode indicates if the translator is used in EPS mode.") + if lang_txt == 'perl': + scalar_prefix = '$' + array_prefix = '@' + elif lang_txt == 'sh': + scalar_prefix = '$_' + array_prefix = '$_' + elif lang_txt == 'batch' or lang_txt == 'wincmd': + scalar_prefix = '%_' + array_prefix = '%_' + else: + scalar_prefix = '_' + array_prefix = '_' + text = text.replace('#1', scalar_prefix) + text = text.replace('#2', array_prefix) + self._ui_script_source.set_tooltip_text(text) + + def _create_row(self, label_text, right_widget): + ui_label = self._create_label(label_text) + right_widget.set_property('hexpand', True) + right_widget.set_property('vexpand', False) + return self._insert_row(ui_label, right_widget) + + # Utility function to create a label + def _create_label(self, text, hexpand=False): + ui_label = Gtk.Label(text) + ui_label.set_property('hexpand', hexpand) + ui_label.set_property('vexpand', False) + ui_label.set_property('halign', Gtk.Align.START) + ui_label.set_property('valign', Gtk.Align.CENTER) + return ui_label + + # Utility function to create a row in a grid + def _insert_row(self, left_widget, right_widget=None): + if right_widget: + self._grid.attach( left_widget, + 0,self._grid_row,1,1) # left, top, width, height + self._grid.attach( right_widget, + 1,self._grid_row,1,1) # left, top, width, height + else: + self._grid.attach( left_widget, + 0,self._grid_row,2,1) # left, top, width, height + self._grid_row = self._grid_row + 1 + return [ left_widget, right_widget ] + + def _append(self, txt1, prefix, txt2): + if txt2: + return txt1 + prefix + "=" + txt2 + "\n\n" + return txt1 + + # Generate the basename for the new translator + def generate_translator_basename(self): + tmp = self._ui_input_extensions.get_text() + tmp = re.split('\s+', tmp) + for t in tmp: + if t: + input_extension = t + break + input_extension = input_extension[1:] + + active = self._ui_output_extension.get_active() + if active == 1: + output_extension = "pdf" + flag = "+tex" + elif active == 2: + output_extension = "pdf" + flag = "+layers" + elif active == 3: + output_extension = "pdf" + flag = "+layers+tex" + elif active == 4: + output_extension = "png" + flag = "" + else: + output_extension = "pdf" + flag = "" + + variante = self._ui_variante.get_text() + + filename = input_extension + '2' + output_extension + flag + if variante: + filename = filename + '_' + variante + + mo = re.match("^[a-zA-Z0-9_]+2[a-zA-Z0-9_]+(?:\\+[^_.]+)*(?:\\_.+)?$", filename) + if mo: + filename = filename + '.transdef' + return filename + return None + + # Generate the content of the file .transdef + def generate_translator_spec(self): + content = self._append( + '', + 'INPUT_EXTENSIONS', + self._ui_input_extensions.get_text()) + + active = self._ui_output_extension.get_active() + if active == 1: + content = content+"OUTPUT_EXTENSIONS for pdf=.pdf .pdftex_t\n" + content = content+"OUTPUT_EXTENSIONS for eps=.eps .pstex_t\n\n" + elif active == 2: + content = content+"OUTPUT_EXTENSIONS for pdf=.pdftex_t .pdf\n" + content = content+"OUTPUT_EXTENSIONS for eps=.pstex_t .eps\n\n" + elif active == 3: + content = content+"OUTPUT_EXTENSIONS for pdf=.pdftex_t .pdf\n" + content = content+"OUTPUT_EXTENSIONS for eps=.pstex_t .eps\n\n" + elif active == 4: + content = content+"OUTPUT_EXTENSIONS=.png\n" + else: + content = content+"OUTPUT_EXTENSIONS for pdf=.pdf\n" + content = content+"OUTPUT_EXTENSIONS for eps=.eps\n\n" + + active = self._ui_execution_mode.get_active() + if active==0: + content = self._append( + content, + "COMMAND_LINE", + self._ui_command_line.get_text()) + else: + lang_txt = self._script_modes[active-1] + start_iter = self._ui_script_source_buffer.get_start_iter() + end_iter = self._ui_script_source_buffer.get_end_iter() + script_text = self._ui_script_source_buffer.get_text( + start_iter, + end_iter, + False) + if lang_txt == 'perl': + content = self._append( + content, + "TRANSLATOR_FUNCTION", + "<<ENDOFSCRIPT\n"+script_text+"\nENDOFSCRIPT") + else: + content = self._append( + content, + "TRANSLATOR_FUNCTION with "+lang_txt, + "<<ENDOFSCRIPT\n"+script_text+"\nENDOFSCRIPT") + + content = self._append( + content, + "FILES_TO_CLEAN", + self._ui_files_to_clean.get_text()) + + return content + +#--------------------------------- +# CLASS Panel +#--------------------------------- + +# Gtk panel that is managing the configuration of the translators +class Panel(abstract_panel.AbstractPanel): + __gtype_name__ = "AutoLaTeXTranslatorPanel" + + def __init__(self, is_document_level, directory, window): + abstract_panel.AbstractPanel.__init__(self, is_document_level, directory, window) + + # + # Fill the grid + # + def _init_widgets(self): + # Preload the images + self._preload_icons() + # Top label + ui_label = self._create_label(_T("List of available translators:\n(click on the second column to change the loading state of the translators)")) + self._insert_row(ui_label, None, False) + # List of translators + self._ui_translator_list = Gtk.ListStore( + GdkPixbuf.Pixbuf.__gtype__, + GdkPixbuf.Pixbuf.__gtype__, + str, + str) + self._ui_translator_list_widget = Gtk.TreeView() + self._ui_translator_list_widget.set_model(self._ui_translator_list) + if self._is_document_level: + label1 = _T('usr') + self._clickable_column_label = _T('doc') + else: + label1 = 'sys' + self._clickable_column_label = _T('usr') + column = Gtk.TreeViewColumn(label1, Gtk.CellRendererPixbuf(), pixbuf=0) + self._ui_translator_list_widget.append_column(column) + column = Gtk.TreeViewColumn(self._clickable_column_label, Gtk.CellRendererPixbuf(), pixbuf=1) + self._ui_translator_list_widget.append_column(column) + column = Gtk.TreeViewColumn(_T("name"), Gtk.CellRendererText(), text=2) + self._ui_translator_list_widget.append_column(column) + column = Gtk.TreeViewColumn(_T("description"), Gtk.CellRendererText(), text=3) + self._ui_translator_list_widget.append_column(column) + self._ui_translator_list_widget.set_headers_clickable(False) + self._ui_translator_list_widget.set_headers_visible(True) + # Scrolling pane for translator list + ui_translator_list_scroll = self._create_scroll_for(self._ui_translator_list_widget) + # Management buttons + ui_right_toolbar = Gtk.Box(False, 5) + ui_right_toolbar.set_property('orientation', Gtk.Orientation.VERTICAL) + ui_right_toolbar.set_property('hexpand', False) + ui_right_toolbar.set_property('vexpand', True) + # Button "New" + self._ui_button_new_translator = Gtk.Button.new_from_stock(Gtk.STOCK_NEW) + ui_right_toolbar.add(self._ui_button_new_translator) + # Button "Import" + self._ui_button_import_translator = Gtk.Button(_T("Import")) + ui_right_toolbar.add(self._ui_button_import_translator) + # Button "Delete" + self._ui_button_delete_translator = Gtk.Button.new_from_stock(Gtk.STOCK_DELETE) + self._ui_button_delete_translator.set_sensitive(False) + ui_right_toolbar.add(self._ui_button_delete_translator) + # Separator + ui_separator = Gtk.Separator() + ui_separator.set_orientation(Gtk.Orientation.HORIZONTAL) + ui_right_toolbar.add(ui_separator) + # Help - Part 1 + if self._is_document_level: + label1 = _T('Current user') + label2 = _T('Current document') + else: + label1 = _T('All users') + label2 = _T('Current user') + ui_right_toolbar.add(self._make_legend(self._get_level_icon(0), label1)) + ui_right_toolbar.add(self._make_legend(self._get_level_icon(1), label2)) + # Separator + ui_separator = Gtk.Separator() + ui_separator.set_orientation(Gtk.Orientation.HORIZONTAL) + ui_right_toolbar.add(ui_separator) + # Help - Part 2 + ui_right_toolbar.add(self._make_legend(self._get_level_icon(1), _T('Loaded, no conflict'))) + ui_right_toolbar.add(self._make_legend(self._get_level_icon(1, _IconType.CONFLICT), _T('Loaded, conflict'))) + ui_right_toolbar.add(self._make_legend(self._get_level_icon(1, _IconType.EXCLUDED), _T('Not loaded'))) + ui_right_toolbar.add(self._make_legend(self._get_level_icon(1, _IconType.INHERITED), _T('Unspecified, no conflict'))) + ui_right_toolbar.add(self._make_legend(self._get_level_icon(1, _IconType.INHERITED_CONFLICT), _T('Unspecified, conflict'))) + # Add the list and the toolbar + self._insert_row(ui_translator_list_scroll, ui_right_toolbar, False) + + + # + # Initialize the content + # + def _init_content(self): + if self._is_document_level: + left_level = _Level.USER + right_level = _Level.PROJECT + else: + left_level = _Level.SYSTEM + right_level = _Level.USER + # Get the data from the backend + self._translator_config = utils.backend_get_translators(self._directory) + self._load_config = utils.backend_get_loads(self._directory) + # Build the conflict map and the inclusion states + self._translator_conflict_candidates = {} + self._translator_inclusions_constants = {} + self._translator_inclusions = {} + self._translator_deletions = [] + for translator in self._translator_config.sections(): + source = self._translator_config.get(translator, 'full-source') + if source not in self._translator_conflict_candidates: + self._translator_conflict_candidates[source] = [] + self._translator_conflict_candidates[source].append(translator) + self._translator_inclusions_constants[translator] = self._compute_inclusion_state(translator, left_level, right_level) + self._translator_inclusions[translator] = self._compute_inclusion_state(translator, right_level, right_level) + # Detect initial conflicts + for translator in self._translator_config.sections(): + self._update_translator_states(translator) + # Fill the table + self._translator_indexes = {} + index = 0 + for translator in self._translator_config.sections(): + human_readable = self._translator_config.get(translator, 'human-readable') + icon1 = self._get_level_icon(0, self._translator_inclusions_constants[translator]) + icon2 = self._get_level_icon(1, self._translator_inclusions[translator]) + self._ui_translator_list.append( [ icon1, icon2, translator, human_readable ] ) + self._translator_indexes[translator] = index + index = index + 1 + + + # + # Connect signals + # + def _connect_signals(self): + self._ui_translator_list_widget.connect( + 'button-press-event', self.on_list_click_action); + self._ui_button_new_translator.connect( + 'button-press-event', self.on_new_button_click_action); + self._ui_button_import_translator.connect( + 'button-press-event', self.on_import_button_click_action); + self._ui_button_delete_translator.connect( + 'button-press-event', self.on_delete_button_click_action); + + def update_widget_states(self): + pass + + # Preloading the states' icons + def _preload_icons(self): + if self._is_document_level: + left_level = _Level.USER + right_level = _Level.PROJECT + else: + left_level = _Level.SYSTEM + right_level = _Level.USER + # Preload icons + self._preloaded_icons = [[None,None,None,None,None],[None,None,None,None,None]] + for i in range(5): + self._preloaded_icons[0][i] = self.__get_level_icon(left_level, i) + self._preloaded_icons[1][i] = self.__get_level_icon(right_level, i) + + # Load the bitmap of an icon + def __get_level_icon(self, level, icon_type=_IconType.INCLUDED): + if level == _Level.SYSTEM: + icon_name = 'systemLevel' + elif level == _Level.USER: + icon_name = 'userLevel' + else: + icon_name = 'projectLevel' + + if icon_type == _IconType.INHERITED_CONFLICT: + icon_name = icon_name + '_uc' + elif icon_type == _IconType.INHERITED: + icon_name = icon_name + '_u' + elif icon_type == _IconType.CONFLICT: + icon_name = icon_name + '_c' + elif icon_type == _IconType.EXCLUDED: + icon_name = icon_name + '_ko' + icon_name = icon_name + '.png' + return GdkPixbuf.Pixbuf.new_from_file(utils.make_table_icon_path(icon_name)) + + # Replies an icon + def _get_level_icon(self, column, icon_type=_IconType.INCLUDED): + return self._preloaded_icons[column][int(icon_type)] + + # Utility function to create the "help" legend + def _make_legend(self, icon, label, top_padding=0): + legend_alignment = Gtk.Box(False, 3) + legend_alignment.set_property('vexpand', False) + legend_alignment.set_property('hexpand', False) + legend_alignment.set_property('orientation', Gtk.Orientation.HORIZONTAL) + icon_label = Gtk.Image.new_from_pixbuf(icon) + icon_label.set_property('vexpand', False) + icon_label.set_property('hexpand', False) + legend_alignment.add(icon_label) + text = Gtk.Label(label) + text.set_property('vexpand', False) + text.set_property('hexpand', False) + text.set_property('valign', Gtk.Align.CENTER) + text.set_property('halign', Gtk.Align.START) + legend_alignment.add(text) + return legend_alignment + + # Replies if the given translator, in the given state, may be assumed as included + def _is_includable_with(self, translator, state): + if state == _IconType.INHERITED: + state = self._translator_inclusions_constants[translator] + elif state == _IconType.INHERITED_CONFLICT: + state = self._add_conflict_in_state(self._translator_inclusions_constants[translator]) + if state == _IconType.INCLUDED or state == _IconType.CONFLICT: + return 1 # Sure, it is included + if state == _IconType.EXCLUDED: + return 0 # Sure, it is not included + return -1 # Don't know + + # Detect a conflict for the given translator, and update + # the states of all the translators in the same group + def _update_translator_states(self, translator): + translators_to_update = [] + inclusion_state = self._translator_inclusions[translator] + if inclusion_state != _IconType.EXCLUDED: + # Detect any conflict + is_includable = self._is_includable_with(translator, inclusion_state) + source = self._translator_config.get(translator, 'full-source') + for candidate in self._translator_conflict_candidates[source]: + if translator != candidate: + other_state = self._translator_inclusions[candidate] + is_other_includable = self._is_includable_with(candidate, other_state) + if is_includable and is_other_includable: + inclusion_state = self._add_conflict_in_state(inclusion_state) + # change the state of the other translators + if inclusion_state == _IconType.CONFLICT or inclusion_state == _IconType.INHERITED_CONFLICT: + for candidate in self._translator_conflict_candidates[source]: + if translator != candidate: + other_state = self._translator_inclusions[candidate] + new_other_state = self._add_conflict_in_state(other_state) + if other_state!=new_other_state: + self._translator_inclusions[candidate] = new_other_state + translators_to_update.append(candidate) + self._translator_inclusions[translator] = inclusion_state + for translator in translators_to_update: + self._update_translator_states(translator) + return inclusion_state + + # Compute the state of a translator for the given level + def _compute_inclusion_state(self, translator, query_level, editable_level): + flag = _IconType.INHERITED + if query_level < editable_level: + if self._load_config.has_option('system', translator): + flag = _IconType.INCLUDED if self._load_config.getboolean('system', translator) else _IconType.EXCLUDED + if query_level > _Level.SYSTEM: + if self._load_config.has_option('user', translator): + flag = _IconType.INCLUDED if self._load_config.getboolean('user', translator) else _IconType.EXCLUDED + if query_level > _Level.USER: + if self._load_config.has_option('project', translator): + flag = _IconType.INCLUDED if self._load_config.getboolean('project', translator) else _IconType.EXCLUDED + elif query_level == _Level.SYSTEM: + if self._load_config.has_option('system', translator): + flag = _IconType.INCLUDED if self._load_config.getboolean('system', translator) else _IconType.EXCLUDED + elif query_level == _Level.USER: + if self._load_config.has_option('user', translator): + flag = _IconType.INCLUDED if self._load_config.getboolean('user', translator) else _IconType.EXCLUDED + else: + if self._load_config.has_option('project', translator): + flag = _IconType.INCLUDED if self._load_config.getboolean('project', translator) else _IconType.EXCLUDED + return flag + + # Translate the state by removing the conflict flag + def _remove_conflict_in_state(self, state): + if state == _IconType.CONFLICT: + return _IconType.INCLUDED + elif state == _IconType.INHERITED_CONFLICT: + return _IconType.INHERITED + return state + + # Translate the state by adding the conflict flag + def _add_conflict_in_state(self, state): + if state == _IconType.INCLUDED: + return _IconType.CONFLICT + elif state == _IconType.INHERITED: + return _IconType.INHERITED_CONFLICT + return state + + # Callback for changing the state of a translator + def on_list_click_action(self, action, data=None): + delete_button_sensitivity = False + x, y = data.get_coords() #Gdk.Event + path, column, cell_x, cell_y = action.get_path_at_pos(x,y) + if path: + # Get the translator name + list_iter = self._ui_translator_list.get_iter(path) + translator = self._ui_translator_list[list_iter][2] + # Update the buttons + translator_filename = self._translator_config.get(translator, 'file') + if translator_filename: + translator_filename = os.path.dirname(translator_filename) + delete_button_sensitivity = os.access(translator_filename, os.W_OK) + # Change the state of the translator if queried + title = column.get_title() + if title == self._clickable_column_label: + inclusion_state = self._translator_inclusions[translator] + inclusion_state = self._remove_conflict_in_state(inclusion_state) + # Move up + inclusion_state = (inclusion_state + 1) % 3 + # Reset the states for the group + source = self._translator_config.get(translator, 'full-source') + for candidate in self._translator_conflict_candidates[source]: + if translator != candidate: + other_state = self._translator_inclusions[candidate] + other_state = self._remove_conflict_in_state(other_state) + self._translator_inclusions[candidate] = other_state + self._translator_inclusions[translator] = inclusion_state + # Detect conflicts in the group + for candidate in self._translator_conflict_candidates[source]: + self._update_translator_states(candidate) + # Update the UI + for translator in self._translator_conflict_candidates[source]: + inclusion_state = self._translator_inclusions[translator] + index = self._translator_indexes[translator] + path = Gtk.TreePath(index) + list_iter = self._ui_translator_list.get_iter(path) + self._ui_translator_list[list_iter][1] = self._get_level_icon(1, inclusion_state) + self._ui_button_delete_translator.set_sensitive(delete_button_sensitivity) + + # Callback for adding a translator + def on_new_button_click_action(self, action, data=None): + dialog = _TranslatorCreationDialog(self._window) + dialog.set_modal(True) + answer = dialog.run() + if answer == Gtk.ResponseType.ACCEPT: + file_content = dialog.generate_translator_spec() + basename = dialog.generate_translator_basename() + dialog.destroy() + if basename: + directory = self._prepare_config_directory() + target_filename = os.path.join(directory, basename) + make_copy = True + if os.path.isfile(target_filename): + dialog = Gtk.MessageDialog( + self._window, + Gtk.DialogFlags.MODAL, + Gtk.MessageType.QUESTION, + Gtk.ButtonsType.YES_NO, + _T("The translator file '%s' already exists.\nDo you want to replace it with the selected file?") % basename) + answer = dialog.run() + dialog.destroy() + make_copy = (answer == Gtk.ResponseType.YES) + if make_copy: + fo = open(target_filename, "wt") + fo.write(file_content) + fo.close() + self._register_translator(target_filename) + else: + dialog = Gtk.MessageDialog( + self._window, + Gtk.DialogFlags.MODAL, + Gtk.MessageType.ERROR, + Gtk.ButtonsType.OK, + _T("Cannot compute a valid basename with the inputs.")) + answer = dialog.run() + dialog.destroy() + else: + dialog.destroy() + + # Callback for importing a translator + def on_import_button_click_action(self, action, data=None): + dialog = Gtk.FileChooserDialog(_T("Select a translator definition"), + self._window, + Gtk.FileChooserAction.OPEN, + [ Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, + Gtk.STOCK_OPEN, Gtk.ResponseType.ACCEPT ]) + file_filter = Gtk.FileFilter() + file_filter.set_name(_T("AutoLaTeX Translator")) + file_filter.add_pattern("*.transdef") + dialog.set_modal(True) + dialog.set_select_multiple(True) + dialog.set_filter(file_filter) + response = dialog.run() + filename = dialog.get_filename() + dialog.destroy() + if response == Gtk.ResponseType.ACCEPT: + directory = self._prepare_config_directory() + basename = os.path.basename(filename) + target_filename = os.path.join(directory, basename) + make_copy = True + if os.path.isfile(target_filename): + dialog = Gtk.MessageDialog( + self._window, + Gtk.DialogFlags.MODAL, + Gtk.MessageType.QUESTION, + Gtk.ButtonsType.YES_NO, + _T("The translator file '%s' already exists.\nDo you want to replace it with the selected file?") % basename) + answer = dialog.run() + dialog.destroy() + make_copy = (answer == Gtk.ResponseType.YES) + if make_copy: + shutil.copyfile(filename, target_filename) + self._register_translator(target_filename) + + def _prepare_config_directory(self): + directory = utils.get_autolatex_user_config_directory() + if not os.path.isdir(directory): + conf_file = utils.get_autolatex_user_config_file() + tmpfile = None + if os.path.isfile(conf_file): + tmpfile = conf_file+".tmp" + shutil.move(conf_file, tmpfile) + os.makedirs(directory) + if tmpfile: + shutil.move(tmpfile, os.path.join(directory, 'autolatex.conf')) + directory = os.path.join(directory, 'translators') + if not os.path.isdir(directory): + os.makedirs(directory) + return directory + + def _register_translator(self, filename): + # Reload the translator informations + self._translator_config = utils.backend_get_translators(self._directory) + # Search the new translator + translator = '' + for t in self._translator_config.sections(): + if self._translator_config.has_option(t, 'file'): + f = self._translator_config.get(t, 'file') + if f == filename: + translator = t + break + if translator: + # Determine the levels of the columns + if self._is_document_level: + left_level = _Level.USER + right_level = _Level.PROJECT + else: + left_level = _Level.SYSTEM + right_level = _Level.USER + # Update the conflict map and the inclusion states + source = self._translator_config.get(translator, 'full-source') + if source not in self._translator_conflict_candidates: + self._translator_conflict_candidates[source] = [] + self._translator_conflict_candidates[source].append(translator) + self._translator_inclusions_constants[translator] = self._compute_inclusion_state(translator, left_level, right_level) + self._translator_inclusions[translator] = self._compute_inclusion_state(translator, right_level, right_level) + # Detect new conflicts + for t in self._translator_config.sections(): + self._update_translator_states(t) + # Add in the table + human_readable = self._translator_config.get(translator, 'human-readable') + icon1 = self._get_level_icon(0, self._translator_inclusions_constants[translator]) + icon2 = self._get_level_icon(1, self._translator_inclusions[translator]) + insert_index = gtk_utils.get_insert_index_dichotomic( + self._ui_translator_list, + 2, + translator) + if insert_index>=0: + insert_iter = self._ui_translator_list.insert(insert_index) + self._ui_translator_list.set(insert_iter, + 0, icon1, + 1, icon2, + 2, translator, + 3, human_readable ) + self._translator_indexes[translator] = insert_index + else: + self._ui_translator_list.append( [ icon1, icon2, translator, human_readable ] ) + self._translator_indexes[translator] = self._ui_translator_list.iter_n_children(None) - 1 + # Update the UI + for t in self._translator_conflict_candidates[source]: + if t != translator: + inclusion_state = self._translator_inclusions[t] + index = self._translator_indexes[t] + if index>=insert_index: + index = index + 1 + self._translator_indexes[t] = index + path = Gtk.TreePath(index) + list_iter = self._ui_translator_list.get_iter(path) + self._ui_translator_list[list_iter][1] = self._get_level_icon(1, inclusion_state) + else: + # Something wrong append + dialog = Gtk.MessageDialog( + self._window, + Gtk.DialogFlags.MODAL, + Gtk.MessageType.ERROR, + Gtk.ButtonsType.OK, + _T("There is a problem when reading the translator's definition.\nPlease close and re-open the configuration dialog\nfor trying to read the configuration of the new translator.")) + dialog.run() + dialog.destroy() + + # Callback for deleting a translator + def on_delete_button_click_action(self, action, data=None): + select_iter = self._ui_translator_list_widget.get_selection().get_selected()[1] + translator = self._ui_translator_list[select_iter][2] + dialog = Gtk.MessageDialog( + self._window, + Gtk.DialogFlags.MODAL, + Gtk.MessageType.QUESTION, + Gtk.ButtonsType.YES_NO, + _T("Do you want to delete the translator '%s'?") % translator) + answer = dialog.run() + dialog.destroy() + if answer == Gtk.ResponseType.YES: + # Remove the file + translator_filename = self._translator_config.get(translator, 'file') + os.unlink(translator_filename) + # Remove from the table + self._ui_translator_list.remove(select_iter) + # Update the indexes + the_index = self._translator_indexes[translator] + for t in self._translator_indexes: + if the_index<=self._translator_indexes[t]: + self._translator_indexes[t] = self._translator_indexes[t] - 1 + # Clear the conflict map and the inclusion states + source = self._translator_config.get(translator, 'full-source') + self._translator_conflict_candidates[source].remove(translator) + del self._translator_inclusions[translator] + self._translator_deletions.append(translator) + # Reset the states of the other translators related to the removed one. + for other_translator in self._translator_conflict_candidates[source]: + other_state = self._translator_inclusions[other_translator] + other_state = self._remove_conflict_in_state(other_state) + self._translator_inclusions[other_translator] = other_state + # Update the states of the other translators related to the removed one. + for other_translator in self._translator_conflict_candidates[source]: + self._update_translator_states(other_translator) + # Remove the translator from the backend data + self._translator_config.remove_section(translator) + if self._is_document_level: + section_name = 'project' + else: + section_name = 'user' + if self._load_config.has_section(section_name) and self._load_config.has_option(section_name, translator): + self._load_config.remove_option(section_name, translator) + # Update the UI + for translator in self._translator_conflict_candidates[source]: + inclusion_state = self._translator_inclusions[translator] + index = self._translator_indexes[translator] + path = Gtk.TreePath(index) + list_iter = self._ui_translator_list.get_iter(path) + self._ui_translator_list[list_iter][1] = self._get_level_icon(1, inclusion_state) + + + + # Invoked when the changes in the panel must be saved + def save(self): + if self._is_document_level: + section_name = 'project' + else: + section_name = 'user' + self._load_config.remove_section(section_name) + self._load_config.add_section(section_name) + # Save the loading state of the translators + for translator in self._translator_inclusions: + state = self._translator_inclusions[translator] + if state == _IconType.INCLUDED or state == _IconType.CONFLICT: + self._load_config.set(section_name, translator, 'true') + elif state == _IconType.EXCLUDED: + self._load_config.set(section_name, translator, 'false') + # Force the removed translators to be removed from the configuration + for translator in self._translator_deletions: + self._load_config.set(section_name, translator, utils.CONFIG_EMPTY_VALUE) + return utils.backend_set_loads(self._directory, self._load_config) diff --git a/support/autolatex/plugins/gedit2/autolatex/config/cli/viewer_panel.py b/support/autolatex/plugins/gedit2/autolatex/config/cli/viewer_panel.py new file mode 100644 index 0000000000..3a7708bca4 --- /dev/null +++ b/support/autolatex/plugins/gedit2/autolatex/config/cli/viewer_panel.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# autolatex/config/cli/viewer_panel.py +# Copyright (C) 2013 Stephane Galland <galland@arakhne.org> +# +# 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; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +#--------------------------------- +# IMPORTS +#--------------------------------- + +# Include the Glib, Gtk and Gedit libraries +from gi.repository import GObject, Gdk, Gtk, GdkPixbuf +# AutoLaTeX internal libs +from ...utils import utils +from . import abstract_panel + +#--------------------------------- +# INTERNATIONALIZATION +#--------------------------------- + +import gettext +_T = gettext.gettext + +#--------------------------------- +# CLASS Panel +#--------------------------------- + +# Gtk panel that is managing the configuration of the viewer +class Panel(abstract_panel.AbstractPanel): + __gtype_name__ = "AutoLaTeXViewerPanel" + + def __init__(self, is_document_level, directory, window): + abstract_panel.AbstractPanel.__init__(self, is_document_level, directory, window) + + # + # Fill the grid + # + def _init_widgets(self): + # Launch the viewer + self._ui_launch_viewer_checkbox = self._create_switch( + _T("Launch a viewer after compilation"))[1] + # Viewer command line + self._ui_viewer_command_field = self._create_entry( + _T("Command for launching the viewer (optional)"))[1] + + + # + # Initialize the content + # + def _init_content(self): + self._read_settings('viewer') + # + inh = self._get_settings_bool_inh('view') + cur = self._get_settings_bool('view') + self._init_overriding(self._ui_launch_viewer_checkbox, cur is not None) + self._ui_launch_viewer_checkbox.set_active(utils.first_of(cur, inh, False)) + # + inh = self._get_settings_str_inh('viewer') + cur = self._get_settings_str('viewer') + self._init_overriding(self._ui_viewer_command_field, cur is not None) + self._ui_viewer_command_field.set_text(utils.first_of(cur, inh, '')) + + + # + # Connect signals + # + def _connect_signals(self): + self._ui_launch_viewer_checkbox.connect('notify::active',self.on_launch_viewer_toggled) + + + + + # Change the state of the widgets according to the state of other widgets + def update_widget_states(self): + is_active = self._ui_launch_viewer_checkbox.get_active() + if not self._get_overriding(self._ui_launch_viewer_checkbox): + inh = self._get_settings_bool_inh('view', False) + if (inh!=is_active): + GObject.idle_add(self._ui_launch_viewer_checkbox.set_active, inh) + is_active = inh + self._update_sentitivity(self._ui_viewer_command_field, is_active) + + + # Invoke when the flag 'launch viewer' has changed + def on_launch_viewer_toggled(self, widget, data=None): + self.update_widget_states() + + # Invoked when the changes in the panel must be saved + def save(self): + self._reset_settings_section() + # + if self._get_sentitivity(self._ui_launch_viewer_checkbox): + v = self._ui_launch_viewer_checkbox.get_active() + else: + v = None + self._set_settings_bool('view', v) + # + if self._get_sentitivity(self._ui_viewer_command_field): + v = self._ui_viewer_command_field.get_text() + else: + v = None + self._set_settings_str('viewer', v) + # + return utils.backend_set_configuration(self._directory, + 'project' if self._is_document_level else 'user', self._settings) diff --git a/support/autolatex/plugins/gedit2/autolatex/config/cli/window.py b/support/autolatex/plugins/gedit2/autolatex/config/cli/window.py new file mode 100644 index 0000000000..6b75cd6407 --- /dev/null +++ b/support/autolatex/plugins/gedit2/autolatex/config/cli/window.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# autolatex/config/cli/window.py +# Copyright (C) 2013 Stephane Galland <galland@arakhne.org> +# +# 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; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +#--------------------------------- +# IMPORTS +#--------------------------------- + +# Include the Glib, Gtk and Gedit libraries +from gi.repository import Gtk, GdkPixbuf +# AutoLaTeX internal libs +from ...utils import utils +from . import generator_panel, figure_panel, figure_assignment_panel, translator_panel, viewer_panel + +#--------------------------------- +# INTERNATIONALIZATION +#--------------------------------- + +import gettext +_T = gettext.gettext + +#--------------------------------- +# Global function to open the dialog +#--------------------------------- + +def open_configuration_dialog(parent, is_document_level, directory): + dialog = _Window(parent, is_document_level, directory) + dialog.run() + dialog.destroy() + +#--------------------------------- +# CLASS NotbookTab +#--------------------------------- + +class _NotebookTab(Gtk.Box): + __gtype_name__ = "AutoLaTeXConfigurationNotebookTab" + + def __init__(self, label, icon): + Gtk.Box.__init__(self,False,2) + self.set_property('orientation', Gtk.Orientation.HORIZONTAL) + self.set_property('expand', False) + self._label = label + pixbuf = GdkPixbuf.Pixbuf.new_from_file(utils.make_notebook_icon_path(icon)) + iconwgt = Gtk.Image.new_from_pixbuf(pixbuf) + self.add(iconwgt) + labelwgt = Gtk.Label(self._label) + labelwgt.set_alignment(0, 0.5) + self.add(labelwgt) + self.show_all() + + def get_text(self): + return self._label + +#--------------------------------- +# CLASS AutoLaTeXConfigurationWindow +#--------------------------------- + +# Gtk window that is displaying the configuration panels +class _Window(Gtk.Dialog): + __gtype_name__ = "AutoLaTeXConfigurationWindow" + + def __init__(self, parent, is_document_level, directory): + Gtk.Dialog.__init__(self, + (_T("Document Configuration") if is_document_level else _T("User Configuration")), + parent, 0, + ( Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_APPLY, Gtk.ResponseType.APPLY)) + self.set_default_size(600, 500) + # Notebook + self._ui_notebook = Gtk.Notebook() + self.get_content_area().add(self._ui_notebook); + # Tab for translators + tab = generator_panel.Panel(is_document_level, directory, self) + self._ui_notebook.append_page( + tab, + _NotebookTab( + _T("Generator"), "autolatex-compile.png")) + tab = figure_panel.Panel(is_document_level, directory, self) + self._ui_notebook.append_page( + tab, + _NotebookTab( + _T("Figures"), "autolatex-images.png")) + if is_document_level: + tab = figure_assignment_panel.Panel(is_document_level, directory, self) + self._ui_notebook.append_page( + tab, + _NotebookTab( + _T("List of figures"), "autolatex-images.png")) + tab = translator_panel.Panel(is_document_level, directory, self) + self._ui_notebook.append_page( + tab, + _NotebookTab( + _T("Translators"), "autolatex-images.png")) + tab = viewer_panel.Panel(is_document_level, directory, self) + self._ui_notebook.append_page( + tab, + _NotebookTab( + _T("Viewer"), "autolatex-view.png")) + self.show_all() + # Listening the response signal + self.connect('response', self.on_response_signal); + + # Callback for response in the dialog + def on_response_signal(self, action, data=None): + if data == Gtk.ResponseType.APPLY: + for i in range(self._ui_notebook.get_n_pages()): + page = self._ui_notebook.get_nth_page(i) + result = page.save() + if not result: + tab_label = self._ui_notebook.get_tab_label(page) + dialog = Gtk.MessageDialog(self, Gtk.DialogFlags.MODAL, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, _T("The page '%s' cannot save its fields.\n You will loose the changes on this pages.") % tab_label.get_text()) + answer = dialog.run() + dialog.destroy() + |