summaryrefslogtreecommitdiff
path: root/support/autolatex/plugins/gedit2/autolatex/config/cli
diff options
context:
space:
mode:
Diffstat (limited to 'support/autolatex/plugins/gedit2/autolatex/config/cli')
-rw-r--r--support/autolatex/plugins/gedit2/autolatex/config/cli/__init__.py22
-rw-r--r--support/autolatex/plugins/gedit2/autolatex/config/cli/abstract_panel.py272
-rw-r--r--support/autolatex/plugins/gedit2/autolatex/config/cli/figure_assignment_panel.py203
-rw-r--r--support/autolatex/plugins/gedit2/autolatex/config/cli/figure_panel.py273
-rw-r--r--support/autolatex/plugins/gedit2/autolatex/config/cli/generator_panel.py269
-rw-r--r--support/autolatex/plugins/gedit2/autolatex/config/cli/translator_panel.py876
-rw-r--r--support/autolatex/plugins/gedit2/autolatex/config/cli/viewer_panel.py120
-rw-r--r--support/autolatex/plugins/gedit2/autolatex/config/cli/window.py130
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()
+