1# -*- coding: utf-8 -*-
2
3# Copyright (C) 2005 Osmo Salomaa
4#
5# This program is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18"""Base class for dialogs for selecting subtitle files."""
19
20import aeidon
21import gaupol
22
23from aeidon.i18n   import _
24from gi.repository import Gtk
25
26__all__ = ("FileDialog",)
27
28
29class FileDialog:
30
31    """Base class for dialogs for selecting subtitle files."""
32
33    _use_autodetection = False
34
35    def get_encoding(self):
36        """Return the selected encoding or ``None``."""
37        index = self._encoding_combo.get_active()
38        if index < 0: return None
39        store = self._encoding_combo.get_model()
40        return store[index][0]
41
42    def _init_encoding_combo(self):
43        """Initialize the character encoding combo box."""
44        store = Gtk.ListStore(str, str)
45        self._encoding_combo.set_model(store)
46        self._populate_encoding_combo()
47        view = self._encoding_combo.get_child()
48        path = gaupol.util.tree_row_to_path(0)
49        view.set_displayed_row(path)
50        renderer = Gtk.CellRendererText()
51        self._encoding_combo.pack_start(renderer, expand=True)
52        self._encoding_combo.add_attribute(renderer, "text", 1)
53        func = gaupol.util.separate_combo
54        self._encoding_combo.set_row_separator_func(func, None)
55
56    def _init_filters(self):
57        """Initialize file filters."""
58        file_filter = Gtk.FileFilter()
59        file_filter.set_name(_("All files"))
60        file_filter.add_pattern("*")
61        self.add_filter(file_filter)
62        file_filter = Gtk.FileFilter()
63        file_filter.set_name(_("All supported files"))
64        for format in aeidon.formats:
65            pattern = "*."
66            for x in format.extension[1:]:
67                pattern += "[{}{}]".format(x.upper(), x.lower())
68            file_filter.add_pattern(pattern)
69        self.add_filter(file_filter)
70        self.set_filter(file_filter)
71        for format in aeidon.formats:
72            extension = format.extension
73            pattern = "*."
74            for x in extension[1:]:
75                pattern += "[{}{}]".format(x.upper(), x.lower())
76            format = format.label
77            name = _("{format} (*{extension})").format(**locals())
78            file_filter = Gtk.FileFilter()
79            file_filter.set_name(name)
80            file_filter.add_pattern(pattern)
81            self.add_filter(file_filter)
82
83    def _on_encoding_combo_changed(self, *args):
84        """Show the encoding selection dialog."""
85        encoding = self.get_encoding()
86        if encoding != "other": return
87        dialog = gaupol.MenuEncodingDialog(self)
88        response = gaupol.util.run_dialog(dialog)
89        encoding = dialog.get_encoding()
90        visible = dialog.get_visible_encodings()
91        dialog.destroy()
92        self._encoding_combo.set_active(0)
93        if response != Gtk.ResponseType.OK: return
94        gaupol.conf.encoding.visible = visible
95        if encoding is None: return
96        self._populate_encoding_combo(encoding)
97        self.set_encoding(encoding)
98
99    def _populate_encoding_combo(self, custom=None):
100        """Populate the encoding combo box, including custom encoding."""
101        encodings = list(gaupol.conf.encoding.visible)
102        locale = aeidon.encodings.get_locale_code()
103        encodings.insert(0, locale)
104        encodings.append(custom)
105        while None in encodings:
106            encodings.remove(None)
107        encodings = aeidon.util.get_unique(encodings)
108        encodings = encodings or ["utf_8"]
109        for i, encoding in enumerate(encodings):
110            name = aeidon.encodings.code_to_long_name(encoding)
111            encodings[i] = (encoding, name)
112        if locale is not None:
113            name = aeidon.encodings.get_locale_long_name()
114            encodings[0] = (locale, name)
115        a = (0 if locale is None else 1)
116        encodings[a:] = sorted(encodings[a:], key=lambda x: x[1])
117        separator = gaupol.COMBO_SEPARATOR
118        if self._use_autodetection:
119            encodings.append((separator, separator))
120            encodings.append(("auto", _("Auto-detected")))
121        encodings.append((separator, separator))
122        encodings.append(("other", _("Other…")))
123        self._encoding_combo.get_model().clear()
124        store = self._encoding_combo.get_model()
125        for encoding in encodings:
126            store.append(tuple(encoding))
127
128    def set_encoding(self, encoding):
129        """Set the selected encoding."""
130        if encoding is None: return
131        store = self._encoding_combo.get_model()
132        for i in range(len(store)):
133            if store[i][0] == encoding:
134                return self._encoding_combo.set_active(i)
135        if aeidon.encodings.is_valid_code(encoding):
136            # Add encoding if not found in store.
137            self._populate_encoding_combo(encoding)
138            return self.set_encoding(encoding)
139        self._encoding_combo.set_active(0)
140