1# -*- coding: utf-8 -*-
2# Pitivi video editor
3# Copyright (c) 2005, Edward Hervey <bilboed@bilboed.com>
4#
5# This program is free software; you can redistribute it and/or
6# modify it under the terms of the GNU Lesser General Public
7# License as published by the Free Software Foundation; either
8# version 2.1 of the License, or (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 GNU
13# Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public
16# License along with this program; if not, write to the
17# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18# Boston, MA 02110-1301, USA.
19"""Assets discovery errors."""
20import os
21from gettext import gettext as _
22from urllib.parse import unquote
23
24from gi.repository import GObject
25from gi.repository import Gtk
26from gi.repository import Pango
27
28from pitivi.configure import get_ui_dir
29from pitivi.utils.loggable import Loggable
30
31
32class FileListErrorDialog(GObject.Object, Loggable):
33    """Dialog for showing errors blocking importing media files."""
34
35    __gsignals__ = {
36        'close': (GObject.SIGNAL_RUN_LAST, None, ()),
37        'response': (GObject.SIGNAL_RUN_LAST, None, (object,))}
38
39    def __init__(self, title, headline):
40        GObject.Object.__init__(self)
41        Loggable.__init__(self)
42        self.builder = Gtk.Builder()
43        self.builder.add_from_file(os.path.join(get_ui_dir(),
44                                                "filelisterrordialog.ui"))
45        self.builder.connect_signals(self)
46
47        self.window = self.builder.get_object("filelisterrordialog")
48        self.window.set_modal(False)
49        self.window.set_title(title)
50
51        self.builder.get_object("headline").set_text(headline)
52        self.errorvbox = self.builder.get_object("errorvbox")
53
54    def addFailedFile(self, uri, reason=_("Unknown reason"), extra=None):
55        """Adds the specified URI to the list of failures.
56
57        Args:
58            uri (str): The URI of the asset which cannot be imported.
59            reason (Optional[str]): The reason of the file discovery failure.
60        """
61        self.debug("Uri: %s, reason: %s, extra: %s", uri, reason, extra)
62        exp = self.__createFileExpander(uri, reason, extra)
63        self.errorvbox.pack_start(exp, False, False, 0)
64        if len(self.errorvbox.get_children()) < 3:
65            exp.set_expanded(True)  # Let's save the user some clicks
66        exp.show_all()
67
68    @staticmethod
69    def __createFileExpander(uri, reason, extra=None):
70        if uri:
71            if uri.startswith("file://"):
72                uri = uri[7:]
73            uri = uri.split('/')[-1]
74            uri = unquote(uri)
75            exp = Gtk.Expander(label=uri)
76        else:
77            exp = Gtk.Expander(label=reason)
78
79        textbuffer = Gtk.TextBuffer()
80        table = textbuffer.get_tag_table()
81        boldtag = Gtk.TextTag()
82        boldtag.props.weight = Pango.Weight.BOLD
83        table.add(boldtag)
84
85        end = textbuffer.get_end_iter()
86        textbuffer.insert_with_tags(end, _("Problem:") + " ", boldtag)
87
88        end = textbuffer.get_end_iter()
89        textbuffer.insert(end, "%s\n" % reason)
90
91        if extra:
92            end = textbuffer.get_end_iter()
93            textbuffer.insert_with_tags(
94                end, _("Extra information:") + " ", boldtag)
95
96            end = textbuffer.get_end_iter()
97            textbuffer.insert(end, "%s\n" % extra)
98
99        textview = Gtk.TextView(buffer=textbuffer)
100        textview.set_wrap_mode(Gtk.WrapMode.WORD)
101
102        exp.add(textview)
103
104        return exp
105
106    def isVisible(self):
107        """Returns True if the dialog is currently shown."""
108        return self.window.get_property("visible")
109
110    def destroy(self):
111        """Destroys the dialog."""
112        self.window.destroy()
113
114    # Callbacks from glade
115
116    def _closeCb(self, unused_dialog):
117        """Emits the `close` signal."""
118        self.emit('close')
119
120    def _responseCb(self, unused_dialog, response):
121        """Emits the `response` signal."""
122        self.emit('response', response)
123