New upstream version 119
Jonas Smedegaard
6 years ago
0 | 119 | |
1 | ||
2 | * New translations (Chris Leonard, et al) | |
3 | * Remove EPUB support to remove WebKit 3.0 API dependency (James Cameron) | |
4 | * Replace BeautifulSoup dependency with ElementTree (James Cameron) | |
5 | * Remove unused screenshots (James Cameron) | |
6 | * Remove some unnecessary errors from log (James Cameron) | |
7 | ||
0 | 8 | 118 |
1 | 9 | |
2 | 10 | * Trim headers, synch to Pootle (Chris Leonard) |
2 | 2 | bundle_id = org.laptop.sugar.ReadActivity |
3 | 3 | icon = activity-read |
4 | 4 | exec = sugar-activity readactivity.ReadActivity |
5 | activity_version = 118 | |
6 | mime_types = application/pdf;image/vnd.djvu;image/x.djvu;image/tiff;application/epub+zip;text/plain;application/zip;application/x-cbz | |
5 | activity_version = 119 | |
6 | mime_types = application/pdf;image/vnd.djvu;image/x.djvu;image/tiff;text/plain;application/zip;application/x-cbz | |
7 | 7 | license = GPLv2+ |
8 | 8 | summary = Use this activity when you are ready to read! Remember to flip your computer around to feel like you are really holding a book! |
9 | 9 | categories = language documents media system |
0 | <?xml version="1.0" encoding="UTF-8"?> | |
1 | <mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info"> | |
2 | <mime-type type="application/epub+zip"> | |
3 | <comment xml:lang="en">Epub document</comment> | |
4 | <glob pattern="*.epub"/> | |
5 | </mime-type> | |
6 | </mime-info> |
43 | 43 | |
44 | 44 | empty_widgets.add(vbox) |
45 | 45 | empty_widgets.show_all() |
46 | logging.error('Showing empty Panel') | |
47 | 46 | activity.set_canvas(empty_widgets) |
0 | from gi.repository import GObject | |
1 | import logging | |
2 | ||
3 | import epubview | |
4 | ||
5 | # import speech | |
6 | ||
7 | from cStringIO import StringIO | |
8 | ||
9 | _logger = logging.getLogger('read-activity') | |
10 | ||
11 | ||
12 | class EpubViewer(epubview.EpubView): | |
13 | ||
14 | def __init__(self): | |
15 | epubview.EpubView.__init__(self) | |
16 | ||
17 | def setup(self, activity): | |
18 | self.set_screen_dpi(activity.dpi) | |
19 | self.connect('selection-changed', | |
20 | activity._view_selection_changed_cb) | |
21 | ||
22 | activity._hbox.pack_start(self, True, True, 0) | |
23 | self.show_all() | |
24 | self._modified_files = [] | |
25 | ||
26 | # text to speech initialization | |
27 | self.current_word = 0 | |
28 | self.word_tuples = [] | |
29 | ||
30 | def load_document(self, file_path): | |
31 | self.set_document(EpubDocument(self, file_path.replace('file://', ''))) | |
32 | # speech.highlight_cb = self.highlight_next_word | |
33 | # speech.reset_cb = self.reset_text_to_speech | |
34 | # speech.end_text_cb = self.get_more_text | |
35 | ||
36 | def load_metadata(self, activity): | |
37 | ||
38 | self.metadata = activity.metadata | |
39 | ||
40 | if not self.metadata['title_set_by_user'] == '1': | |
41 | title = self._epub._info._get_title() | |
42 | if title: | |
43 | self.metadata['title'] = title | |
44 | if 'Read_zoom' in self.metadata: | |
45 | try: | |
46 | logging.error('Loading zoom %s', self.metadata['Read_zoom']) | |
47 | self.set_zoom(float(self.metadata['Read_zoom'])) | |
48 | except: | |
49 | pass | |
50 | ||
51 | def update_metadata(self, activity): | |
52 | self.metadata = activity.metadata | |
53 | logging.error('Saving zoom %s', self.get_zoom()) | |
54 | self.metadata['Read_zoom'] = self.get_zoom() | |
55 | ||
56 | def zoom_to_width(self): | |
57 | pass | |
58 | ||
59 | def zoom_to_best_fit(self): | |
60 | pass | |
61 | ||
62 | def zoom_to_actual_size(self): | |
63 | pass | |
64 | ||
65 | def can_zoom_to_width(self): | |
66 | return False | |
67 | ||
68 | def can_highlight(self): | |
69 | return True | |
70 | ||
71 | def show_highlights(self, page): | |
72 | # we save the highlights in the page as html | |
73 | pass | |
74 | ||
75 | def toggle_highlight(self, highlight): | |
76 | self._view.set_editable(True) | |
77 | ||
78 | if highlight: | |
79 | self._view.execute_script( | |
80 | 'document.execCommand("backColor", false, "yellow");') | |
81 | else: | |
82 | # need remove the highlight nodes | |
83 | js = """ | |
84 | var selObj = window.getSelection(); | |
85 | var range = selObj.getRangeAt(0); | |
86 | var node = range.startContainer; | |
87 | while (node.parentNode != null) { | |
88 | if (node.localName == "span") { | |
89 | if (node.hasAttributes()) { | |
90 | var attrs = node.attributes; | |
91 | for(var i = attrs.length - 1; i >= 0; i--) { | |
92 | if (attrs[i].name == "style" && | |
93 | attrs[i].value == "background-color: yellow;") { | |
94 | node.removeAttribute("style"); | |
95 | break; | |
96 | }; | |
97 | }; | |
98 | }; | |
99 | }; | |
100 | node = node.parentNode; | |
101 | };""" | |
102 | self._view.execute_script(js) | |
103 | ||
104 | self._view.set_editable(False) | |
105 | # mark the file as modified | |
106 | current_file = self.get_current_file() | |
107 | logging.error('file %s was modified', current_file) | |
108 | if current_file not in self._modified_files: | |
109 | self._modified_files.append(current_file) | |
110 | GObject.idle_add(self._save_page) | |
111 | ||
112 | def _save_page(self): | |
113 | oldtitle = self._view.get_title() | |
114 | self._view.execute_script( | |
115 | "document.title=document.documentElement.innerHTML;") | |
116 | html = self._view.get_title() | |
117 | file_path = self.get_current_file().replace('file:///', '/') | |
118 | logging.error(html) | |
119 | with open(file_path, 'w') as fd: | |
120 | header = """<?xml version="1.0" encoding="utf-8" standalone="no"?> | |
121 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" | |
122 | "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> | |
123 | <html xmlns="http://www.w3.org/1999/xhtml">""" | |
124 | fd.write(header) | |
125 | fd.write(html) | |
126 | fd.write('</html>') | |
127 | self._view.execute_script('document.title=%s;' % oldtitle) | |
128 | ||
129 | def save(self, file_path): | |
130 | if self._modified_files: | |
131 | self._epub.write(file_path) | |
132 | return True | |
133 | ||
134 | return False | |
135 | ||
136 | def in_highlight(self): | |
137 | # Verify if the selection already exist or the cursor | |
138 | # is in a highlighted area | |
139 | page_title = self._view.get_title() | |
140 | js = """ | |
141 | var selObj = window.getSelection(); | |
142 | var range = selObj.getRangeAt(0); | |
143 | var node = range.startContainer; | |
144 | var onHighlight = false; | |
145 | while (node.parentNode != null) { | |
146 | if (node.localName == "span") { | |
147 | if (node.hasAttributes()) { | |
148 | var attrs = node.attributes; | |
149 | for(var i = attrs.length - 1; i >= 0; i--) { | |
150 | if (attrs[i].name == "style" && | |
151 | attrs[i].value == "background-color: yellow;") { | |
152 | onHighlight = true; | |
153 | }; | |
154 | }; | |
155 | }; | |
156 | }; | |
157 | node = node.parentNode; | |
158 | }; | |
159 | document.title=onHighlight;""" | |
160 | self._view.execute_script(js) | |
161 | on_highlight = self._view.get_title() == 'true' | |
162 | self._view.execute_script('document.title = "%s";' % page_title) | |
163 | # the second parameter is only used in the text backend | |
164 | return on_highlight, None | |
165 | ||
166 | def can_do_text_to_speech(self): | |
167 | return False | |
168 | ||
169 | def can_rotate(self): | |
170 | return False | |
171 | ||
172 | def get_marked_words(self): | |
173 | "Adds a mark between each word of text." | |
174 | i = self.current_word | |
175 | file_str = StringIO() | |
176 | file_str.write('<speak> ') | |
177 | end_range = i + 40 | |
178 | if end_range > len(self.word_tuples): | |
179 | end_range = len(self.word_tuples) | |
180 | for word_tuple in self.word_tuples[self.current_word:end_range]: | |
181 | file_str.write('<mark name="' + str(i) + '"/>' + | |
182 | word_tuple[2].encode('utf-8')) | |
183 | i = i + 1 | |
184 | self.current_word = i | |
185 | file_str.write('</speak>') | |
186 | return file_str.getvalue() | |
187 | ||
188 | def get_more_text(self): | |
189 | pass | |
190 | """ | |
191 | if self.current_word < len(self.word_tuples): | |
192 | speech.stop() | |
193 | more_text = self.get_marked_words() | |
194 | speech.play(more_text) | |
195 | else: | |
196 | if speech.reset_buttons_cb is not None: | |
197 | speech.reset_buttons_cb() | |
198 | """ | |
199 | ||
200 | def reset_text_to_speech(self): | |
201 | self.current_word = 0 | |
202 | ||
203 | def highlight_next_word(self, word_count): | |
204 | pass | |
205 | """ | |
206 | TODO: disabled because javascript can't be executed | |
207 | with the velocity needed | |
208 | self.current_word = word_count | |
209 | self._view.highlight_next_word() | |
210 | return True | |
211 | """ | |
212 | ||
213 | def connect_zoom_handler(self, handler): | |
214 | self._zoom_handler = handler | |
215 | self._view_notify_zoom_handler = \ | |
216 | self.connect('notify::scale', handler) | |
217 | return self._view_notify_zoom_handler | |
218 | ||
219 | def connect_page_changed_handler(self, handler): | |
220 | self.connect('page-changed', handler) | |
221 | ||
222 | def _try_load_page(self, n): | |
223 | if self._ready: | |
224 | self._load_page(n) | |
225 | return False | |
226 | else: | |
227 | return True | |
228 | ||
229 | def set_screen_dpi(self, dpi): | |
230 | return | |
231 | ||
232 | def find_set_highlight_search(self, set_highlight_search): | |
233 | self._view.set_highlight_text_matches(set_highlight_search) | |
234 | ||
235 | def set_current_page(self, n): | |
236 | # When the book is being loaded, calling this does not help | |
237 | # In such a situation, we go into a loop and try to load the | |
238 | # supplied page when the book has loaded completely | |
239 | n += 1 | |
240 | if self._ready: | |
241 | self._load_page(n) | |
242 | else: | |
243 | GObject.timeout_add(200, self._try_load_page, n) | |
244 | ||
245 | def get_current_page(self): | |
246 | return int(self._loaded_page) - 1 | |
247 | ||
248 | def get_current_link(self): | |
249 | # the _loaded_filename include all the path, | |
250 | # need only the part included in the link | |
251 | return self._loaded_filename[len(self._epub._tempdir) + 1:] | |
252 | ||
253 | def update_toc(self, activity): | |
254 | if self._epub.has_document_links(): | |
255 | activity.show_navigator_button() | |
256 | activity.set_navigator_model(self._epub.get_links_model()) | |
257 | return True | |
258 | else: | |
259 | return False | |
260 | ||
261 | def get_link_iter(self, current_link): | |
262 | """ | |
263 | Returns the iter related to a link | |
264 | """ | |
265 | link_iter = self._epub.get_links_model().get_iter_first() | |
266 | ||
267 | while link_iter is not None and \ | |
268 | self._epub.get_links_model().get_value(link_iter, 1) \ | |
269 | != current_link: | |
270 | link_iter = self._epub.get_links_model().iter_next(link_iter) | |
271 | return link_iter | |
272 | ||
273 | def find_changed(self, job, page=None): | |
274 | self._find_changed(job) | |
275 | ||
276 | def handle_link(self, link): | |
277 | self._load_file(link) | |
278 | ||
279 | def setup_find_job(self, text, updated_cb): | |
280 | self._find_job = JobFind(document=self._epub, | |
281 | start_page=0, n_pages=self.get_pagecount(), | |
282 | text=text, case_sensitive=False) | |
283 | self._find_updated_handler = self._find_job.connect('updated', | |
284 | updated_cb) | |
285 | return self._find_job, self._find_updated_handler | |
286 | ||
287 | ||
288 | class EpubDocument(epubview.Epub): | |
289 | ||
290 | def __init__(self, view, docpath): | |
291 | epubview.Epub.__init__(self, docpath) | |
292 | self._page_cache = view | |
293 | ||
294 | def get_n_pages(self): | |
295 | return int(self._page_cache.get_pagecount()) | |
296 | ||
297 | def has_document_links(self): | |
298 | return True | |
299 | ||
300 | def get_links_model(self): | |
301 | return self.get_toc_model() | |
302 | ||
303 | ||
304 | class JobFind(epubview.JobFind): | |
305 | ||
306 | def __init__(self, document, start_page, n_pages, text, | |
307 | case_sensitive=False): | |
308 | epubview.JobFind.__init__(self, document, start_page, n_pages, text, | |
309 | case_sensitive=False) |
0 | # Copyright 2009 One Laptop Per Child | |
1 | # Author: Sayamindu Dasgupta <sayamindu@laptop.org> | |
2 | # | |
3 | # This program is free software; you can redistribute it and/or modify | |
4 | # it under the terms of the GNU General Public License as published by | |
5 | # the Free Software Foundation; either version 2 of the License, or | |
6 | # (at your option) any later version. | |
7 | # | |
8 | # This program is distributed in the hope that it will be useful, | |
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | # GNU General Public License for more details. | |
12 | # | |
13 | # You should have received a copy of the GNU General Public License | |
14 | # along with this program; if not, write to the Free Software | |
15 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
16 | ||
17 | from epub import _Epub as Epub | |
18 | from epubview import _View as EpubView | |
19 | from jobs import _JobFind as JobFind |
0 | # Copyright 2009 One Laptop Per Child | |
1 | # Author: Sayamindu Dasgupta <sayamindu@laptop.org> | |
2 | # | |
3 | # This program is free software; you can redistribute it and/or modify | |
4 | # it under the terms of the GNU General Public License as published by | |
5 | # the Free Software Foundation; either version 2 of the License, or | |
6 | # (at your option) any later version. | |
7 | # | |
8 | # This program is distributed in the hope that it will be useful, | |
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | # GNU General Public License for more details. | |
12 | # | |
13 | # You should have received a copy of the GNU General Public License | |
14 | # along with this program; if not, write to the Free Software | |
15 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
16 | ||
17 | import zipfile | |
18 | import tempfile | |
19 | import os | |
20 | import xml.etree.ElementTree as etree | |
21 | import shutil | |
22 | import logging | |
23 | ||
24 | import navmap | |
25 | import epubinfo | |
26 | ||
27 | ||
28 | class _Epub(object): | |
29 | ||
30 | def __init__(self, _file): | |
31 | """ | |
32 | _file: can be either a path to a file (a string) or a file-like object. | |
33 | """ | |
34 | self._file = _file | |
35 | self._zobject = None | |
36 | self._opfpath = None | |
37 | self._ncxpath = None | |
38 | self._basepath = None | |
39 | self._tempdir = tempfile.mkdtemp() | |
40 | ||
41 | if not self._verify(): | |
42 | print 'Warning: This does not seem to be a valid epub file' | |
43 | ||
44 | self._get_opf() | |
45 | self._get_ncx() | |
46 | ||
47 | ncxfile = self._zobject.open(self._ncxpath) | |
48 | opffile = self._zobject.open(self._opfpath) | |
49 | self._navmap = navmap.NavMap(opffile, ncxfile, self._basepath) | |
50 | ||
51 | opffile = self._zobject.open(self._opfpath) | |
52 | self._info = epubinfo.EpubInfo(opffile) | |
53 | ||
54 | self._unzip() | |
55 | ||
56 | def _unzip(self): | |
57 | # This is broken upto python 2.7 | |
58 | # self._zobject.extractall(path = self._tempdir) | |
59 | orig_cwd = os.getcwd() | |
60 | os.chdir(self._tempdir) | |
61 | for name in self._zobject.namelist(): | |
62 | # Some weird zip file entries start with a slash, | |
63 | # and we don't want to write to the root directory | |
64 | try: | |
65 | if name.startswith(os.path.sep): | |
66 | name = name[1:] | |
67 | if name.endswith(os.path.sep) or name.endswith('\\'): | |
68 | os.makedirs(name) | |
69 | except: | |
70 | logging.error('ERROR unziping %s', name) | |
71 | else: | |
72 | self._zobject.extract(name) | |
73 | os.chdir(orig_cwd) | |
74 | ||
75 | def _get_opf(self): | |
76 | containerfile = self._zobject.open('META-INF/container.xml') | |
77 | ||
78 | tree = etree.parse(containerfile) | |
79 | root = tree.getroot() | |
80 | ||
81 | r_id = './/{urn:oasis:names:tc:opendocument:xmlns:container}rootfile' | |
82 | for element in root.iterfind(r_id): | |
83 | if element.get('media-type') == 'application/oebps-package+xml': | |
84 | self._opfpath = element.get('full-path') | |
85 | ||
86 | if self._opfpath.rpartition('/')[0]: | |
87 | self._basepath = self._opfpath.rpartition('/')[0] + '/' | |
88 | else: | |
89 | self._basepath = '' | |
90 | ||
91 | containerfile.close() | |
92 | ||
93 | def _get_ncx(self): | |
94 | opffile = self._zobject.open(self._opfpath) | |
95 | ||
96 | tree = etree.parse(opffile) | |
97 | root = tree.getroot() | |
98 | ||
99 | spine = root.find('.//{http://www.idpf.org/2007/opf}spine') | |
100 | tocid = spine.get('toc') | |
101 | ||
102 | for element in root.iterfind('.//{http://www.idpf.org/2007/opf}item'): | |
103 | if element.get('id') == tocid: | |
104 | self._ncxpath = self._basepath + element.get('href') | |
105 | ||
106 | opffile.close() | |
107 | ||
108 | def _verify(self): | |
109 | ''' | |
110 | Method to crudely check to verify that what we | |
111 | are dealing with is a epub file or not | |
112 | ''' | |
113 | if isinstance(self._file, basestring): | |
114 | if not os.path.exists(self._file): | |
115 | return False | |
116 | ||
117 | self._zobject = zipfile.ZipFile(self._file) | |
118 | ||
119 | if 'mimetype' not in self._zobject.namelist(): | |
120 | return False | |
121 | ||
122 | mtypefile = self._zobject.open('mimetype') | |
123 | mimetype = mtypefile.readline() | |
124 | ||
125 | # Some files seem to have trailing characters | |
126 | if not mimetype.startswith('application/epub+zip'): | |
127 | return False | |
128 | ||
129 | return True | |
130 | ||
131 | def get_toc_model(self): | |
132 | ''' | |
133 | Returns a GtkTreeModel representation of the | |
134 | Epub table of contents | |
135 | ''' | |
136 | return self._navmap.get_gtktreestore() | |
137 | ||
138 | def get_flattoc(self): | |
139 | ''' | |
140 | Returns a flat (linear) list of files to be | |
141 | rendered. | |
142 | ''' | |
143 | return self._navmap.get_flattoc() | |
144 | ||
145 | def get_basedir(self): | |
146 | ''' | |
147 | Returns the base directory where the contents of the | |
148 | epub has been unzipped | |
149 | ''' | |
150 | return self._tempdir | |
151 | ||
152 | def get_info(self): | |
153 | ''' | |
154 | Returns a EpubInfo object title | |
155 | ''' | |
156 | return self._info.title | |
157 | ||
158 | def write(self, file_path): | |
159 | '''Create the ZIP archive. | |
160 | The mimetype must be the first file in the archive | |
161 | and it must not be compressed.''' | |
162 | ||
163 | # The EPUB must contain the META-INF and mimetype files at the root, so | |
164 | # we'll create the archive in the working directory first | |
165 | # and move it later | |
166 | current_dir = os.getcwd() | |
167 | os.chdir(self._tempdir) | |
168 | ||
169 | # Open a new zipfile for writing | |
170 | epub = zipfile.ZipFile(file_path, 'w') | |
171 | ||
172 | # Add the mimetype file first and set it to be uncompressed | |
173 | epub.write('mimetype', compress_type=zipfile.ZIP_STORED) | |
174 | ||
175 | # For the remaining paths in the EPUB, add all of their files | |
176 | # using normal ZIP compression | |
177 | self._scan_dir('.', epub) | |
178 | ||
179 | epub.close() | |
180 | os.chdir(current_dir) | |
181 | ||
182 | def _scan_dir(self, path, epub_file): | |
183 | for p in os.listdir(path): | |
184 | logging.error('add file %s', p) | |
185 | if os.path.isdir(os.path.join(path, p)): | |
186 | self._scan_dir(os.path.join(path, p), epub_file) | |
187 | else: | |
188 | if p != 'mimetype': | |
189 | epub_file.write( | |
190 | os.path.join(path, p), | |
191 | compress_type=zipfile.ZIP_DEFLATED) | |
192 | ||
193 | def close(self): | |
194 | ''' | |
195 | Cleans up (closes open zip files and deletes | |
196 | uncompressed content of Epub. | |
197 | Please call this when a file is being closed or during | |
198 | application exit. | |
199 | ''' | |
200 | self._zobject.close() | |
201 | shutil.rmtree(self._tempdir) |
0 | import xml.etree.ElementTree as etree | |
1 | ||
2 | ||
3 | class EpubInfo(): | |
4 | ||
5 | # TODO: Cover the entire DC range | |
6 | ||
7 | def __init__(self, opffile): | |
8 | self._tree = etree.parse(opffile) | |
9 | self._root = self._tree.getroot() | |
10 | self._e_metadata = self._root.find( | |
11 | '{http://www.idpf.org/2007/opf}metadata') | |
12 | ||
13 | self.title = self._get_title() | |
14 | self.creator = self._get_creator() | |
15 | self.date = self._get_date() | |
16 | self.subject = self._get_subject() | |
17 | self.source = self._get_source() | |
18 | self.rights = self._get_rights() | |
19 | self.identifier = self._get_identifier() | |
20 | self.language = self._get_language() | |
21 | self.summary = self._get_description() | |
22 | self.cover_image = self._get_cover_image() | |
23 | ||
24 | def _get_data(self, tagname): | |
25 | element = self._e_metadata.find(tagname) | |
26 | return element.text | |
27 | ||
28 | def _get_title(self): | |
29 | try: | |
30 | ret = self._get_data('.//{http://purl.org/dc/elements/1.1/}title') | |
31 | except AttributeError: | |
32 | return None | |
33 | ||
34 | return ret | |
35 | ||
36 | def _get_description(self): | |
37 | try: | |
38 | ret = self._get_data( | |
39 | './/{http://purl.org/dc/elements/1.1/}description') | |
40 | except AttributeError: | |
41 | return None | |
42 | ||
43 | return ret | |
44 | ||
45 | def _get_creator(self): | |
46 | try: | |
47 | ret = self._get_data( | |
48 | './/{http://purl.org/dc/elements/1.1/}creator') | |
49 | except AttributeError: | |
50 | return None | |
51 | return ret | |
52 | ||
53 | def _get_date(self): | |
54 | # TODO: iter | |
55 | try: | |
56 | ret = self._get_data('.//{http://purl.org/dc/elements/1.1/}date') | |
57 | except AttributeError: | |
58 | return None | |
59 | ||
60 | return ret | |
61 | ||
62 | def _get_source(self): | |
63 | try: | |
64 | ret = self._get_data('.//{http://purl.org/dc/elements/1.1/}source') | |
65 | except AttributeError: | |
66 | return None | |
67 | ||
68 | return ret | |
69 | ||
70 | def _get_rights(self): | |
71 | try: | |
72 | ret = self._get_data('.//{http://purl.org/dc/elements/1.1/}rights') | |
73 | except AttributeError: | |
74 | return None | |
75 | ||
76 | return ret | |
77 | ||
78 | def _get_identifier(self): | |
79 | # TODO: iter | |
80 | element = self._e_metadata.find( | |
81 | './/{http://purl.org/dc/elements/1.1/}identifier') | |
82 | ||
83 | if element is not None: | |
84 | return {'id': element.get('id'), 'value': element.text} | |
85 | else: | |
86 | return None | |
87 | ||
88 | def _get_language(self): | |
89 | try: | |
90 | ret = self._get_data( | |
91 | './/{http://purl.org/dc/elements/1.1/}language') | |
92 | except AttributeError: | |
93 | return None | |
94 | ||
95 | return ret | |
96 | ||
97 | def _get_subject(self): | |
98 | try: | |
99 | subjectlist = [] | |
100 | for element in self._e_metadata.iterfind( | |
101 | './/{http://purl.org/dc/elements/1.1/}subject'): | |
102 | subjectlist.append(element.text) | |
103 | except AttributeError: | |
104 | return None | |
105 | ||
106 | return subjectlist | |
107 | ||
108 | def _get_cover_image(self): | |
109 | element = self._e_metadata.find('{http://www.idpf.org/2007/opf}meta') | |
110 | if element is not None and element.get('name') == 'cover': | |
111 | return element.get('content') | |
112 | else: | |
113 | return None |
0 | # Copyright 2009 One Laptop Per Child | |
1 | # Author: Sayamindu Dasgupta <sayamindu@laptop.org> | |
2 | # | |
3 | # This program is free software; you can redistribute it and/or modify | |
4 | # it under the terms of the GNU General Public License as published by | |
5 | # the Free Software Foundation; either version 2 of the License, or | |
6 | # (at your option) any later version. | |
7 | # | |
8 | # This program is distributed in the hope that it will be useful, | |
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | # GNU General Public License for more details. | |
12 | # | |
13 | # You should have received a copy of the GNU General Public License | |
14 | # along with this program; if not, write to the Free Software | |
15 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
16 | ||
17 | from gi.repository import Gtk | |
18 | from gi.repository import GObject | |
19 | from gi.repository import Gdk | |
20 | import widgets | |
21 | ||
22 | import logging | |
23 | import os.path | |
24 | import math | |
25 | import shutil | |
26 | ||
27 | from jobs import _JobPaginator as _Paginator | |
28 | ||
29 | LOADING_HTML = ''' | |
30 | <div style="width:100%;height:100%;text-align:center;padding-top:50%;"> | |
31 | <h1>Loading...</h1> | |
32 | </div> | |
33 | ''' | |
34 | ||
35 | ||
36 | class _View(Gtk.HBox): | |
37 | ||
38 | __gproperties__ = { | |
39 | 'scale': (GObject.TYPE_FLOAT, 'the zoom level', | |
40 | 'the zoom level of the widget', | |
41 | 0.5, 4.0, 1.0, GObject.PARAM_READWRITE), | |
42 | } | |
43 | __gsignals__ = { | |
44 | 'page-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, | |
45 | ([int, int])), | |
46 | 'selection-changed': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, | |
47 | ([])), | |
48 | } | |
49 | ||
50 | def __init__(self): | |
51 | GObject.threads_init() | |
52 | Gtk.HBox.__init__(self) | |
53 | ||
54 | self.connect("destroy", self._destroy_cb) | |
55 | ||
56 | self._ready = False | |
57 | self._paginator = None | |
58 | self._loaded_page = -1 | |
59 | self._file_loaded = True | |
60 | # self._old_scrollval = -1 | |
61 | self._loaded_filename = None | |
62 | self._pagecount = -1 | |
63 | self.__going_fwd = True | |
64 | self.__going_back = False | |
65 | self.__page_changed = False | |
66 | self._has_selection = False | |
67 | self.scale = 1.0 | |
68 | self._epub = None | |
69 | self._findjob = None | |
70 | self.__in_search = False | |
71 | self.__search_fwd = True | |
72 | self._filelist = None | |
73 | self._internal_link = None | |
74 | ||
75 | self._sw = Gtk.ScrolledWindow() | |
76 | self._view = widgets._WebView() | |
77 | self._view.load_string(LOADING_HTML, 'text/html', 'utf-8', '/') | |
78 | settings = self._view.get_settings() | |
79 | settings.props.default_font_family = 'DejaVu LGC Serif' | |
80 | settings.props.enable_plugins = False | |
81 | settings.props.default_encoding = 'utf-8' | |
82 | self._view.connect('load-finished', self._view_load_finished_cb) | |
83 | self._view.connect('scroll-event', self._view_scroll_event_cb) | |
84 | self._view.connect('key-press-event', self._view_keypress_event_cb) | |
85 | self._view.connect('selection-changed', | |
86 | self._view_selection_changed_cb) | |
87 | self._view.connect_after('populate-popup', | |
88 | self._view_populate_popup_cb) | |
89 | self._view.connect('touch-change-page', self.__touch_page_changed_cb) | |
90 | ||
91 | self._sw.add(self._view) | |
92 | self._v_vscrollbar = self._sw.get_vscrollbar() | |
93 | self._v_scrollbar_value_changed_cb_id = self._v_vscrollbar.connect( | |
94 | 'value-changed', self._v_scrollbar_value_changed_cb) | |
95 | self._scrollbar = Gtk.VScrollbar() | |
96 | self._scrollbar_change_value_cb_id = self._scrollbar.connect( | |
97 | 'change-value', self._scrollbar_change_value_cb) | |
98 | ||
99 | overlay = Gtk.Overlay() | |
100 | hbox = Gtk.HBox() | |
101 | overlay.add(hbox) | |
102 | hbox.add(self._sw) | |
103 | ||
104 | self._scrollbar.props.halign = Gtk.Align.END | |
105 | self._scrollbar.props.valign = Gtk.Align.FILL | |
106 | overlay.add_overlay(self._scrollbar) | |
107 | ||
108 | self.pack_start(overlay, True, True, 0) | |
109 | ||
110 | self._view.set_can_default(True) | |
111 | self._view.set_can_focus(True) | |
112 | ||
113 | def map_cp(widget): | |
114 | widget.setup_touch() | |
115 | widget.disconnect(self._setup_handle) | |
116 | ||
117 | self._setup_handle = self._view.connect('map', map_cp) | |
118 | ||
119 | def set_document(self, epubdocumentinstance): | |
120 | ''' | |
121 | Sets document (should be a Epub instance) | |
122 | ''' | |
123 | self._epub = epubdocumentinstance | |
124 | GObject.idle_add(self._paginate) | |
125 | ||
126 | def do_get_property(self, property): | |
127 | if property.name == 'has-selection': | |
128 | return self._has_selection | |
129 | elif property.name == 'scale': | |
130 | return self.scale | |
131 | else: | |
132 | raise AttributeError('unknown property %s' % property.name) | |
133 | ||
134 | def do_set_property(self, property, value): | |
135 | if property.name == 'scale': | |
136 | self.__set_zoom(value) | |
137 | else: | |
138 | raise AttributeError('unknown property %s' % property.name) | |
139 | ||
140 | def get_has_selection(self): | |
141 | ''' | |
142 | Returns True if any part of the content is selected | |
143 | ''' | |
144 | return self._view.can_copy_clipboard() | |
145 | ||
146 | def get_zoom(self): | |
147 | ''' | |
148 | Returns the current zoom level | |
149 | ''' | |
150 | return self.get_property('scale') * 100.0 | |
151 | ||
152 | def set_zoom(self, value): | |
153 | ''' | |
154 | Sets the current zoom level | |
155 | ''' | |
156 | scrollbar_pos = self.get_vertical_pos() | |
157 | self._view.set_zoom_level(value / 100.0) | |
158 | self.set_vertical_pos(scrollbar_pos) | |
159 | ||
160 | def _get_scale(self): | |
161 | ''' | |
162 | Returns the current zoom level | |
163 | ''' | |
164 | return self.get_property('scale') | |
165 | ||
166 | def _set_scale(self, value): | |
167 | ''' | |
168 | Sets the current zoom level | |
169 | ''' | |
170 | self.set_property('scale', value) | |
171 | ||
172 | def zoom_in(self): | |
173 | ''' | |
174 | Zooms in (increases zoom level by 0.1) | |
175 | ''' | |
176 | if self.can_zoom_in(): | |
177 | scrollbar_pos = self.get_vertical_pos() | |
178 | self._set_scale(self._get_scale() + 0.1) | |
179 | self.set_vertical_pos(scrollbar_pos) | |
180 | return True | |
181 | else: | |
182 | return False | |
183 | ||
184 | def zoom_out(self): | |
185 | ''' | |
186 | Zooms out (decreases zoom level by 0.1) | |
187 | ''' | |
188 | if self.can_zoom_out(): | |
189 | scrollbar_pos = self.get_vertical_pos() | |
190 | self._set_scale(self._get_scale() - 0.1) | |
191 | self.set_vertical_pos(scrollbar_pos) | |
192 | return True | |
193 | else: | |
194 | return False | |
195 | ||
196 | def get_vertical_pos(self): | |
197 | """ | |
198 | Used to save the scrolled position and restore when needed | |
199 | """ | |
200 | return self._v_vscrollbar.get_adjustment().get_value() | |
201 | ||
202 | def set_vertical_pos(self, position): | |
203 | """ | |
204 | Used to save the scrolled position and restore when needed | |
205 | """ | |
206 | self._v_vscrollbar.get_adjustment().set_value(position) | |
207 | ||
208 | def can_zoom_in(self): | |
209 | ''' | |
210 | Returns True if it is possible to zoom in further | |
211 | ''' | |
212 | if self.scale < 4: | |
213 | return True | |
214 | else: | |
215 | return False | |
216 | ||
217 | def can_zoom_out(self): | |
218 | ''' | |
219 | Returns True if it is possible to zoom out further | |
220 | ''' | |
221 | if self.scale > 0.5: | |
222 | return True | |
223 | else: | |
224 | return False | |
225 | ||
226 | def get_current_page(self): | |
227 | ''' | |
228 | Returns the currently loaded page | |
229 | ''' | |
230 | return self._loaded_page | |
231 | ||
232 | def get_current_file(self): | |
233 | ''' | |
234 | Returns the currently loaded XML file | |
235 | ''' | |
236 | # return self._loaded_filename | |
237 | if self._paginator: | |
238 | return self._paginator.get_file_for_pageno(self._loaded_page) | |
239 | else: | |
240 | return None | |
241 | ||
242 | def get_pagecount(self): | |
243 | ''' | |
244 | Returns the pagecount of the loaded file | |
245 | ''' | |
246 | return self._pagecount | |
247 | ||
248 | def set_current_page(self, n): | |
249 | ''' | |
250 | Loads page number n | |
251 | ''' | |
252 | if n < 1 or n > self._pagecount: | |
253 | return False | |
254 | self._load_page(n) | |
255 | return True | |
256 | ||
257 | def next_page(self): | |
258 | ''' | |
259 | Loads next page if possible | |
260 | Returns True if transition to next page is possible and done | |
261 | ''' | |
262 | if self._loaded_page == self._pagecount: | |
263 | return False | |
264 | self._load_next_page() | |
265 | return True | |
266 | ||
267 | def previous_page(self): | |
268 | ''' | |
269 | Loads previous page if possible | |
270 | Returns True if transition to previous page is possible and done | |
271 | ''' | |
272 | if self._loaded_page == 1: | |
273 | return False | |
274 | self._load_prev_page() | |
275 | return True | |
276 | ||
277 | def scroll(self, scrolltype, horizontal): | |
278 | ''' | |
279 | Scrolls through the pages. | |
280 | Scrolling is horizontal if horizontal is set to True | |
281 | Valid scrolltypes are: | |
282 | Gtk.ScrollType.PAGE_BACKWARD, Gtk.ScrollType.PAGE_FORWARD, | |
283 | Gtk.ScrollType.STEP_BACKWARD, Gtk.ScrollType.STEP_FORWARD | |
284 | Gtk.ScrollType.STEP_START and Gtk.ScrollType.STEP_STOP | |
285 | ''' | |
286 | if scrolltype == Gtk.ScrollType.PAGE_BACKWARD: | |
287 | self.__going_back = True | |
288 | self.__going_fwd = False | |
289 | if not self._do_page_transition(): | |
290 | self._view.move_cursor(Gtk.MovementStep.PAGES, -1) | |
291 | elif scrolltype == Gtk.ScrollType.PAGE_FORWARD: | |
292 | self.__going_back = False | |
293 | self.__going_fwd = True | |
294 | if not self._do_page_transition(): | |
295 | self._view.move_cursor(Gtk.MovementStep.PAGES, 1) | |
296 | elif scrolltype == Gtk.ScrollType.STEP_BACKWARD: | |
297 | self.__going_fwd = False | |
298 | self.__going_back = True | |
299 | if not self._do_page_transition(): | |
300 | self._view.move_cursor(Gtk.MovementStep.DISPLAY_LINES, -1) | |
301 | elif scrolltype == Gtk.ScrollType.STEP_FORWARD: | |
302 | self.__going_fwd = True | |
303 | self.__going_back = False | |
304 | if not self._do_page_transition(): | |
305 | self._view.move_cursor(Gtk.MovementStep.DISPLAY_LINES, 1) | |
306 | elif scrolltype == Gtk.ScrollType.START: | |
307 | self.__going_back = True | |
308 | self.__going_fwd = False | |
309 | if not self._do_page_transition(): | |
310 | self.set_current_page(1) | |
311 | elif scrolltype == Gtk.ScrollType.END: | |
312 | self.__going_back = False | |
313 | self.__going_fwd = True | |
314 | if not self._do_page_transition(): | |
315 | self.set_current_page(self._pagecount - 1) | |
316 | else: | |
317 | print ('Got unsupported scrolltype %s' % str(scrolltype)) | |
318 | ||
319 | def __touch_page_changed_cb(self, widget, forward): | |
320 | if forward: | |
321 | self.scroll(Gtk.ScrollType.PAGE_FORWARD, False) | |
322 | else: | |
323 | self.scroll(Gtk.ScrollType.PAGE_BACKWARD, False) | |
324 | ||
325 | def copy(self): | |
326 | ''' | |
327 | Copies the current selection to clipboard. | |
328 | ''' | |
329 | self._view.copy_clipboard() | |
330 | ||
331 | def find_next(self): | |
332 | ''' | |
333 | Highlights the next matching item for current search | |
334 | ''' | |
335 | self._view.grab_focus() | |
336 | ||
337 | if self._view.search_text(self._findjob.get_search_text(), | |
338 | self._findjob.get_case_sensitive(), | |
339 | True, False): | |
340 | return | |
341 | else: | |
342 | path = os.path.join(self._epub.get_basedir(), | |
343 | self._findjob.get_next_file()) | |
344 | self.__in_search = True | |
345 | self.__search_fwd = True | |
346 | self._load_file(path) | |
347 | ||
348 | def find_previous(self): | |
349 | ''' | |
350 | Highlights the previous matching item for current search | |
351 | ''' | |
352 | self._view.grab_focus() | |
353 | ||
354 | if self._view.search_text(self._findjob.get_search_text(), | |
355 | self._findjob.get_case_sensitive(), | |
356 | False, False): | |
357 | return | |
358 | else: | |
359 | path = os.path.join(self._epub.get_basedir(), | |
360 | self._findjob.get_prev_file()) | |
361 | self.__in_search = True | |
362 | self.__search_fwd = False | |
363 | self._load_file(path) | |
364 | ||
365 | def _find_changed(self, job): | |
366 | self._view.grab_focus() | |
367 | self._findjob = job | |
368 | self._mark_found_text() | |
369 | self.find_next() | |
370 | ||
371 | def _mark_found_text(self): | |
372 | self._view.unmark_text_matches() | |
373 | self._view.mark_text_matches( | |
374 | self._findjob.get_search_text(), | |
375 | case_sensitive=self._findjob.get_case_sensitive(), limit=0) | |
376 | self._view.set_highlight_text_matches(True) | |
377 | ||
378 | def __set_zoom(self, value): | |
379 | self._view.set_zoom_level(value) | |
380 | self.scale = value | |
381 | ||
382 | def _view_populate_popup_cb(self, view, menu): | |
383 | menu.destroy() # HACK | |
384 | return | |
385 | ||
386 | def _view_selection_changed_cb(self, view): | |
387 | self.emit('selection-changed') | |
388 | ||
389 | def _view_keypress_event_cb(self, view, event): | |
390 | name = Gdk.keyval_name(event.keyval) | |
391 | if name == 'Page_Down' or name == 'Down': | |
392 | self.__going_back = False | |
393 | self.__going_fwd = True | |
394 | elif name == 'Page_Up' or name == 'Up': | |
395 | self.__going_back = True | |
396 | self.__going_fwd = False | |
397 | ||
398 | self._do_page_transition() | |
399 | ||
400 | def _view_scroll_event_cb(self, view, event): | |
401 | if event.direction == Gdk.ScrollDirection.DOWN: | |
402 | self.__going_back = False | |
403 | self.__going_fwd = True | |
404 | elif event.direction == Gdk.ScrollDirection.UP: | |
405 | self.__going_back = True | |
406 | self.__going_fwd = False | |
407 | ||
408 | self._do_page_transition() | |
409 | ||
410 | def _do_page_transition(self): | |
411 | if self.__going_fwd: | |
412 | if self._v_vscrollbar.get_value() >= \ | |
413 | self._v_vscrollbar.props.adjustment.props.upper - \ | |
414 | self._v_vscrollbar.props.adjustment.props.page_size: | |
415 | self._load_page(self._loaded_page + 1) | |
416 | return True | |
417 | elif self.__going_back: | |
418 | if self._v_vscrollbar.get_value() == \ | |
419 | self._v_vscrollbar.props.adjustment.props.lower: | |
420 | self._load_page(self._loaded_page - 1) | |
421 | return True | |
422 | ||
423 | return False | |
424 | ||
425 | def _view_load_finished_cb(self, v, frame): | |
426 | ||
427 | self._file_loaded = True | |
428 | filename = self._view.props.uri.replace('file://', '') | |
429 | if os.path.exists(filename.replace('xhtml', 'xml')): | |
430 | # Hack for making javascript work | |
431 | filename = filename.replace('xhtml', 'xml') | |
432 | ||
433 | filename = filename.split('#')[0] # Get rid of anchors | |
434 | ||
435 | if self._loaded_page < 1 or filename is None: | |
436 | return False | |
437 | ||
438 | self._loaded_filename = filename | |
439 | ||
440 | remfactor = self._paginator.get_remfactor_for_file(filename) | |
441 | pages = self._paginator.get_pagecount_for_file(filename) | |
442 | extra = int(math.ceil( | |
443 | remfactor * self._view.get_page_height() / (pages - remfactor))) | |
444 | if extra > 0: | |
445 | self._view.add_bottom_padding(extra) | |
446 | ||
447 | if self.__in_search: | |
448 | self._mark_found_text() | |
449 | self._view.search_text(self._findjob.get_search_text(), | |
450 | self._findjob.get_case_sensitive(), | |
451 | self.__search_fwd, False) | |
452 | self.__in_search = False | |
453 | else: | |
454 | if self.__going_back: | |
455 | # We need to scroll to the last page | |
456 | self._scroll_page_end() | |
457 | else: | |
458 | self._scroll_page() | |
459 | ||
460 | # process_file = True | |
461 | if self._internal_link is not None: | |
462 | self._view.go_to_link(self._internal_link) | |
463 | vertical_pos = \ | |
464 | self._view.get_vertical_position_element(self._internal_link) | |
465 | # set the page number based in the vertical position | |
466 | initial_page = self._paginator.get_base_pageno_for_file(filename) | |
467 | self._loaded_page = initial_page + int( | |
468 | vertical_pos / self._paginator.get_single_page_height()) | |
469 | ||
470 | # There are epub files, created with Calibre, | |
471 | # where the link in the index points to the end of the previos | |
472 | # file to the needed chapter. | |
473 | # if the link is at the bottom of the page, we open the next file | |
474 | one_page_height = self._paginator.get_single_page_height() | |
475 | self._internal_link = None | |
476 | if vertical_pos > self._view.get_page_height() - one_page_height: | |
477 | logging.error('bottom page link, go to next file') | |
478 | next_file = self._paginator.get_next_filename(filename) | |
479 | if next_file is not None: | |
480 | logging.error('load next file %s', next_file) | |
481 | self.__in_search = False | |
482 | self.__going_back = False | |
483 | # process_file = False | |
484 | GObject.idle_add(self._load_file, next_file) | |
485 | ||
486 | # if process_file: | |
487 | # # prepare text to speech | |
488 | # html_file = open(self._loaded_filename) | |
489 | # soup = BeautifulSoup.BeautifulSoup(html_file) | |
490 | # body = soup.find('body') | |
491 | # tags = body.findAll(text=True) | |
492 | # self._all_text = ''.join([tag for tag in tags]) | |
493 | # self._prepare_text_to_speech(self._all_text) | |
494 | ||
495 | def _prepare_text_to_speech(self, page_text): | |
496 | i = 0 | |
497 | j = 0 | |
498 | word_begin = 0 | |
499 | word_end = 0 | |
500 | ignore_chars = [' ', '\n', u'\r', '_', '[', '{', ']', '}', '|', | |
501 | '<', '>', '*', '+', '/', '\\'] | |
502 | ignore_set = set(ignore_chars) | |
503 | self.word_tuples = [] | |
504 | len_page_text = len(page_text) | |
505 | while i < len_page_text: | |
506 | if page_text[i] not in ignore_set: | |
507 | word_begin = i | |
508 | j = i | |
509 | while j < len_page_text and page_text[j] not in ignore_set: | |
510 | j = j + 1 | |
511 | word_end = j | |
512 | i = j | |
513 | word_tuple = (word_begin, word_end, | |
514 | page_text[word_begin: word_end]) | |
515 | if word_tuple[2] != u'\r': | |
516 | self.word_tuples.append(word_tuple) | |
517 | i = i + 1 | |
518 | ||
519 | def _scroll_page_end(self): | |
520 | v_upper = self._v_vscrollbar.props.adjustment.props.upper | |
521 | # v_page_size = self._v_vscrollbar.props.adjustment.props.page_size | |
522 | self._v_vscrollbar.set_value(v_upper) | |
523 | ||
524 | def _scroll_page(self): | |
525 | pageno = self._loaded_page | |
526 | ||
527 | v_upper = self._v_vscrollbar.props.adjustment.props.upper | |
528 | v_page_size = self._v_vscrollbar.props.adjustment.props.page_size | |
529 | ||
530 | scrollfactor = self._paginator.get_scrollfactor_pos_for_pageno(pageno) | |
531 | self._v_vscrollbar.set_value((v_upper - v_page_size) * scrollfactor) | |
532 | ||
533 | def _paginate(self): | |
534 | filelist = [] | |
535 | for i in self._epub._navmap.get_flattoc(): | |
536 | filelist.append(os.path.join(self._epub._tempdir, i)) | |
537 | # init files info | |
538 | self._filelist = filelist | |
539 | self._paginator = _Paginator(filelist) | |
540 | self._paginator.connect('paginated', self._paginated_cb) | |
541 | ||
542 | def get_filelist(self): | |
543 | return self._filelist | |
544 | ||
545 | def get_tempdir(self): | |
546 | return self._epub._tempdir | |
547 | ||
548 | def _load_next_page(self): | |
549 | self._load_page(self._loaded_page + 1) | |
550 | ||
551 | def _load_prev_page(self): | |
552 | self._load_page(self._loaded_page - 1) | |
553 | ||
554 | def _v_scrollbar_value_changed_cb(self, scrollbar): | |
555 | if self._loaded_page < 1: | |
556 | return | |
557 | scrollval = scrollbar.get_value() | |
558 | scroll_upper = self._v_vscrollbar.props.adjustment.props.upper | |
559 | scroll_page_size = self._v_vscrollbar.props.adjustment.props.page_size | |
560 | ||
561 | if self.__going_fwd and not self._loaded_page == self._pagecount: | |
562 | if self._paginator.get_file_for_pageno(self._loaded_page) != \ | |
563 | self._paginator.get_file_for_pageno(self._loaded_page + 1): | |
564 | # We don't need this if the next page is in another file | |
565 | return | |
566 | ||
567 | scrollfactor_next = \ | |
568 | self._paginator.get_scrollfactor_pos_for_pageno( | |
569 | self._loaded_page + 1) | |
570 | if scrollval > 0: | |
571 | scrollfactor = scrollval / (scroll_upper - scroll_page_size) | |
572 | else: | |
573 | scrollfactor = 0 | |
574 | if scrollfactor >= scrollfactor_next: | |
575 | self._on_page_changed(self._loaded_page, self._loaded_page + 1) | |
576 | elif self.__going_back and self._loaded_page > 1: | |
577 | if self._paginator.get_file_for_pageno(self._loaded_page) != \ | |
578 | self._paginator.get_file_for_pageno(self._loaded_page - 1): | |
579 | return | |
580 | ||
581 | scrollfactor_cur = \ | |
582 | self._paginator.get_scrollfactor_pos_for_pageno( | |
583 | self._loaded_page) | |
584 | if scrollval > 0: | |
585 | scrollfactor = scrollval / (scroll_upper - scroll_page_size) | |
586 | else: | |
587 | scrollfactor = 0 | |
588 | ||
589 | if scrollfactor <= scrollfactor_cur: | |
590 | self._on_page_changed(self._loaded_page, self._loaded_page - 1) | |
591 | ||
592 | def _on_page_changed(self, oldpage, pageno): | |
593 | if oldpage == pageno: | |
594 | return | |
595 | self.__page_changed = True | |
596 | self._loaded_page = pageno | |
597 | self._scrollbar.handler_block(self._scrollbar_change_value_cb_id) | |
598 | self._scrollbar.set_value(pageno) | |
599 | self._scrollbar.handler_unblock(self._scrollbar_change_value_cb_id) | |
600 | # the indexes in read activity are zero based | |
601 | self.emit('page-changed', (oldpage - 1), (pageno - 1)) | |
602 | ||
603 | def _load_page(self, pageno): | |
604 | if pageno > self._pagecount or pageno < 1: | |
605 | # TODO: Cause an exception | |
606 | return | |
607 | if self._loaded_page == pageno: | |
608 | return | |
609 | ||
610 | filename = self._paginator.get_file_for_pageno(pageno) | |
611 | filename = filename.replace('file://', '') | |
612 | ||
613 | if filename != self._loaded_filename: | |
614 | self._loaded_filename = filename | |
615 | if not self._file_loaded: | |
616 | # wait until the file is loaded | |
617 | return | |
618 | self._file_loaded = False | |
619 | ||
620 | """ | |
621 | TODO: disabled because javascript can't be executed | |
622 | with the velocity needed | |
623 | # Copy javascript to highligth text to speech | |
624 | destpath, destname = os.path.split(filename.replace('file://', '')) | |
625 | shutil.copy('./epubview/highlight_words.js', destpath) | |
626 | self._insert_js_reference(filename.replace('file://', ''), | |
627 | destpath) | |
628 | IMPORTANT: Find a way to do this without modify the files | |
629 | now text highlight is implemented and the epub file is saved | |
630 | """ | |
631 | ||
632 | if filename.endswith('xml'): | |
633 | dest = filename.replace('xml', 'xhtml') | |
634 | if not os.path.exists(dest): | |
635 | os.symlink(filename, dest) | |
636 | self._view.load_uri('file://' + dest) | |
637 | else: | |
638 | self._view.load_uri('file://' + filename) | |
639 | else: | |
640 | self._loaded_page = pageno | |
641 | self._scroll_page() | |
642 | self._on_page_changed(self._loaded_page, pageno) | |
643 | ||
644 | def _insert_js_reference(self, file_name, path): | |
645 | js_reference = '<script type="text/javascript" ' + \ | |
646 | 'src="./highlight_words.js"></script>' | |
647 | o = open(file_name + '.tmp', 'a') | |
648 | for line in open(file_name): | |
649 | line = line.replace('</head>', js_reference + '</head>') | |
650 | o.write(line + "\n") | |
651 | o.close() | |
652 | shutil.copy(file_name + '.tmp', file_name) | |
653 | ||
654 | def _load_file(self, path): | |
655 | self._internal_link = None | |
656 | if path.find('#') > -1: | |
657 | self._internal_link = path[path.find('#'):] | |
658 | path = path[:path.find('#')] | |
659 | ||
660 | for filepath in self._filelist: | |
661 | if filepath.endswith(path): | |
662 | self._view.load_uri('file://' + filepath) | |
663 | oldpage = self._loaded_page | |
664 | self._loaded_page = \ | |
665 | self._paginator.get_base_pageno_for_file(filepath) | |
666 | self._scroll_page() | |
667 | self._on_page_changed(oldpage, self._loaded_page) | |
668 | break | |
669 | ||
670 | def _scrollbar_change_value_cb(self, range, scrolltype, value): | |
671 | if scrolltype == Gtk.ScrollType.STEP_FORWARD: | |
672 | self.__going_fwd = True | |
673 | self.__going_back = False | |
674 | if not self._do_page_transition(): | |
675 | self._view.move_cursor(Gtk.MovementStep.DISPLAY_LINES, 1) | |
676 | elif scrolltype == Gtk.ScrollType.STEP_BACKWARD: | |
677 | self.__going_fwd = False | |
678 | self.__going_back = True | |
679 | if not self._do_page_transition(): | |
680 | self._view.move_cursor(Gtk.MovementStep.DISPLAY_LINES, -1) | |
681 | elif scrolltype == Gtk.ScrollType.JUMP or \ | |
682 | scrolltype == Gtk.ScrollType.PAGE_FORWARD or \ | |
683 | scrolltype == Gtk.ScrollType.PAGE_BACKWARD: | |
684 | if value > self._scrollbar.props.adjustment.props.upper: | |
685 | self._load_page(self._pagecount) | |
686 | else: | |
687 | self._load_page(round(value)) | |
688 | else: | |
689 | print 'Warning: unknown scrolltype %s with value %f' \ | |
690 | % (str(scrolltype), value) | |
691 | ||
692 | # FIXME: This should not be needed here | |
693 | self._scrollbar.set_value(self._loaded_page) | |
694 | ||
695 | if self.__page_changed: | |
696 | self.__page_changed = False | |
697 | return False | |
698 | else: | |
699 | return True | |
700 | ||
701 | def _paginated_cb(self, object): | |
702 | self._ready = True | |
703 | ||
704 | self._pagecount = self._paginator.get_total_pagecount() | |
705 | self._scrollbar.set_range(1.0, self._pagecount - 1.0) | |
706 | self._scrollbar.set_increments(1.0, 1.0) | |
707 | self._view.grab_focus() | |
708 | self._view.grab_default() | |
709 | ||
710 | def _destroy_cb(self, widget): | |
711 | self._epub.close() |
0 | var parentElement; | |
1 | var actualChild; | |
2 | var actualWord; | |
3 | var words; | |
4 | var originalNode = null; | |
5 | var modifiedNode = null; | |
6 | ||
7 | function trim(s) { | |
8 | s = ( s || '' ).replace( /^\s+|\s+$/g, '' ); | |
9 | return s.replace(/[\n\r\t]/g,' '); | |
10 | } | |
11 | ||
12 | ||
13 | function init() { | |
14 | parentElement = document.getElementsByTagName("body")[0]; | |
15 | actualChild = new Array(); | |
16 | actualWord = 0; | |
17 | actualChild.push(0); | |
18 | } | |
19 | ||
20 | function highLightNextWordInt() { | |
21 | var nodeList = parentElement.childNodes; | |
22 | ini_posi = actualChild[actualChild.length - 1]; | |
23 | for (var i=ini_posi; i < nodeList.length; i++) { | |
24 | var node = nodeList[i]; | |
25 | if ((node.nodeName == "#text") && (trim(node.nodeValue) != '')) { | |
26 | node_text = trim(node.nodeValue); | |
27 | words = node_text.split(" "); | |
28 | if (actualWord < words.length) { | |
29 | originalNode = document.createTextNode(node.nodeValue); | |
30 | ||
31 | prev_text = ''; | |
32 | for (var p1 = 0; p1 < actualWord; p1++) { | |
33 | prev_text = prev_text + words[p1] + " "; | |
34 | } | |
35 | var textNode1 = document.createTextNode(prev_text); | |
36 | var textNode2 = document.createTextNode(words[actualWord]+" "); | |
37 | post_text = ''; | |
38 | for (var p2 = actualWord + 1; p2 < words.length; p2++) { | |
39 | post_text = post_text + words[p2] + " "; | |
40 | } | |
41 | var textNode3 = document.createTextNode(post_text); | |
42 | var newParagraph = document.createElement('p'); | |
43 | var boldNode = document.createElement('b'); | |
44 | boldNode.appendChild(textNode2); | |
45 | newParagraph.appendChild(textNode1); | |
46 | newParagraph.appendChild(boldNode); | |
47 | newParagraph.appendChild(textNode3); | |
48 | ||
49 | parentElement.insertBefore(newParagraph, node); | |
50 | parentElement.removeChild(node); | |
51 | modifiedNode = newParagraph; | |
52 | ||
53 | actualWord = actualWord + 1; | |
54 | if (actualWord >= words.length) { | |
55 | actualChild.pop(); | |
56 | actualChild[actualChild.length - 1] = actualChild[actualChild.length - 1] + 2; | |
57 | actualWord = 0; | |
58 | parentElement = parentElement.parentNode; | |
59 | } | |
60 | } | |
61 | throw "exit"; | |
62 | } else { | |
63 | if (node.childNodes.length > 0) { | |
64 | parentElement = node; | |
65 | actualChild.push(0); | |
66 | actualWord = 0; | |
67 | highLightNextWordInt(); | |
68 | actualChild.pop(); | |
69 | } | |
70 | } | |
71 | } | |
72 | return; | |
73 | } | |
74 | ||
75 | ||
76 | function highLightNextWord() { | |
77 | if (typeof parentElement == "undefined") { | |
78 | init(); | |
79 | } | |
80 | if (originalNode != null) { | |
81 | modifiedNode.parentNode.insertBefore(originalNode, modifiedNode); | |
82 | modifiedNode.parentNode.removeChild(modifiedNode); | |
83 | } | |
84 | try { | |
85 | highLightNextWordInt(); | |
86 | } catch(er) { | |
87 | } | |
88 | } |
0 | # Copyright 2009 One Laptop Per Child | |
1 | # Author: Sayamindu Dasgupta <sayamindu@laptop.org> | |
2 | # | |
3 | # This program is free software; you can redistribute it and/or modify | |
4 | # it under the terms of the GNU General Public License as published by | |
5 | # the Free Software Foundation; either version 2 of the License, or | |
6 | # (at your option) any later version. | |
7 | # | |
8 | # This program is distributed in the hope that it will be useful, | |
9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | # GNU General Public License for more details. | |
12 | # | |
13 | # You should have received a copy of the GNU General Public License | |
14 | # along with this program; if not, write to the Free Software | |
15 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
16 | ||
17 | ||
18 | from gi.repository import GObject | |
19 | from gi.repository import Gtk | |
20 | import widgets | |
21 | import math | |
22 | import os.path | |
23 | import BeautifulSoup | |
24 | ||
25 | import threading | |
26 | ||
27 | PAGE_WIDTH = 135 | |
28 | PAGE_HEIGHT = 216 | |
29 | ||
30 | ||
31 | def _pixel_to_mm(pixel, dpi): | |
32 | inches = pixel / dpi | |
33 | return int(inches / 0.03937) | |
34 | ||
35 | ||
36 | def _mm_to_pixel(mm, dpi): | |
37 | inches = mm * 0.03937 | |
38 | return int(inches * dpi) | |
39 | ||
40 | ||
41 | class SearchThread(threading.Thread): | |
42 | ||
43 | def __init__(self, obj): | |
44 | threading.Thread.__init__(self) | |
45 | self.obj = obj | |
46 | self.stopthread = threading.Event() | |
47 | ||
48 | def _start_search(self): | |
49 | for entry in self.obj.flattoc: | |
50 | if self.stopthread.isSet(): | |
51 | break | |
52 | filepath = os.path.join(self.obj._document.get_basedir(), entry) | |
53 | f = open(filepath) | |
54 | if self._searchfile(f): | |
55 | self.obj._matchfilelist.append(entry) | |
56 | f.close() | |
57 | ||
58 | self.obj._finished = True | |
59 | GObject.idle_add(self.obj.emit, 'updated') | |
60 | ||
61 | return False | |
62 | ||
63 | def _searchfile(self, fileobj): | |
64 | soup = BeautifulSoup.BeautifulSoup(fileobj) | |
65 | body = soup.find('body') | |
66 | tags = body.findChildren(True) | |
67 | for tag in tags: | |
68 | if tag.string is not None: | |
69 | if tag.string.lower().find(self.obj._text.lower()) > -1: | |
70 | return True | |
71 | ||
72 | return False | |
73 | ||
74 | def run(self): | |
75 | self._start_search() | |
76 | ||
77 | def stop(self): | |
78 | self.stopthread.set() | |
79 | ||
80 | ||
81 | class _JobPaginator(GObject.GObject): | |
82 | ||
83 | __gsignals__ = { | |
84 | 'paginated': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ([])), | |
85 | } | |
86 | ||
87 | def __init__(self, filelist): | |
88 | GObject.GObject.__init__(self) | |
89 | ||
90 | self._filelist = filelist | |
91 | self._filedict = {} | |
92 | self._pagemap = {} | |
93 | ||
94 | self._bookheight = 0 | |
95 | self._count = 0 | |
96 | self._pagecount = 0 | |
97 | ||
98 | # TODO | |
99 | """ | |
100 | self._screen = Gdk.Screen.get_default() | |
101 | self._old_fontoptions = self._screen.get_font_options() | |
102 | options = cairo.FontOptions() | |
103 | options.set_hint_style(cairo.HINT_STYLE_MEDIUM) | |
104 | options.set_antialias(cairo.ANTIALIAS_GRAY) | |
105 | options.set_subpixel_order(cairo.SUBPIXEL_ORDER_DEFAULT) | |
106 | options.set_hint_metrics(cairo.HINT_METRICS_DEFAULT) | |
107 | self._screen.set_font_options(options) | |
108 | """ | |
109 | ||
110 | self._temp_win = Gtk.Window() | |
111 | self._temp_view = widgets._WebView(only_to_measure=True) | |
112 | ||
113 | settings = self._temp_view.get_settings() | |
114 | settings.props.default_font_family = 'DejaVu LGC Serif' | |
115 | settings.props.sans_serif_font_family = 'DejaVu LGC Sans' | |
116 | settings.props.serif_font_family = 'DejaVu LGC Serif' | |
117 | settings.props.monospace_font_family = 'DejaVu LGC Sans Mono' | |
118 | settings.props.enforce_96_dpi = True | |
119 | # FIXME: This does not seem to work | |
120 | # settings.props.auto_shrink_images = False | |
121 | settings.props.enable_plugins = False | |
122 | settings.props.default_font_size = 12 | |
123 | settings.props.default_monospace_font_size = 10 | |
124 | settings.props.default_encoding = 'utf-8' | |
125 | ||
126 | sw = Gtk.ScrolledWindow() | |
127 | sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER) | |
128 | self._dpi = 96 | |
129 | self._single_page_height = _mm_to_pixel(PAGE_HEIGHT, self._dpi) | |
130 | sw.set_size_request(_mm_to_pixel(PAGE_WIDTH, self._dpi), | |
131 | self._single_page_height) | |
132 | sw.add(self._temp_view) | |
133 | self._temp_win.add(sw) | |
134 | self._temp_view.connect('load-finished', self._page_load_finished_cb) | |
135 | ||
136 | self._temp_win.show_all() | |
137 | self._temp_win.unmap() | |
138 | ||
139 | self._temp_view.open(self._filelist[self._count]) | |
140 | ||
141 | def get_single_page_height(self): | |
142 | """ | |
143 | Returns the height in pixels of a single page | |
144 | """ | |
145 | return self._single_page_height | |
146 | ||
147 | def get_next_filename(self, actual_filename): | |
148 | for n in range(len(self._filelist)): | |
149 | filename = self._filelist[n] | |
150 | if filename == actual_filename: | |
151 | if n < len(self._filelist): | |
152 | return self._filelist[n + 1] | |
153 | return None | |
154 | ||
155 | def _page_load_finished_cb(self, v, frame): | |
156 | f = v.get_main_frame() | |
157 | pageheight = v.get_page_height() | |
158 | ||
159 | if pageheight <= self._single_page_height: | |
160 | pages = 1 | |
161 | else: | |
162 | pages = pageheight / float(self._single_page_height) | |
163 | for i in range(1, int(math.ceil(pages) + 1)): | |
164 | if pages - i < 0: | |
165 | pagelen = (pages - math.floor(pages)) / pages | |
166 | else: | |
167 | pagelen = 1 / pages | |
168 | self._pagemap[float(self._pagecount + i)] = \ | |
169 | (f.props.uri, (i - 1) / math.ceil(pages), pagelen) | |
170 | ||
171 | self._pagecount += int(math.ceil(pages)) | |
172 | self._filedict[f.props.uri.replace('file://', '')] = \ | |
173 | (math.ceil(pages), math.ceil(pages) - pages) | |
174 | self._bookheight += pageheight | |
175 | ||
176 | if self._count + 1 >= len(self._filelist): | |
177 | # TODO | |
178 | # self._screen.set_font_options(self._old_fontoptions) | |
179 | self.emit('paginated') | |
180 | GObject.idle_add(self._cleanup) | |
181 | else: | |
182 | self._count += 1 | |
183 | self._temp_view.open(self._filelist[self._count]) | |
184 | ||
185 | def _cleanup(self): | |
186 | self._temp_win.destroy() | |
187 | ||
188 | def get_file_for_pageno(self, pageno): | |
189 | ''' | |
190 | Returns the file in which pageno occurs | |
191 | ''' | |
192 | return self._pagemap[pageno][0] | |
193 | ||
194 | def get_scrollfactor_pos_for_pageno(self, pageno): | |
195 | ''' | |
196 | Returns the position scrollfactor (fraction) for pageno | |
197 | ''' | |
198 | return self._pagemap[pageno][1] | |
199 | ||
200 | def get_scrollfactor_len_for_pageno(self, pageno): | |
201 | ''' | |
202 | Returns the length scrollfactor (fraction) for pageno | |
203 | ''' | |
204 | return self._pagemap[pageno][2] | |
205 | ||
206 | def get_pagecount_for_file(self, filename): | |
207 | ''' | |
208 | Returns the number of pages in file | |
209 | ''' | |
210 | return self._filedict[filename][0] | |
211 | ||
212 | def get_base_pageno_for_file(self, filename): | |
213 | ''' | |
214 | Returns the pageno which begins in filename | |
215 | ''' | |
216 | for key in self._pagemap.keys(): | |
217 | if self._pagemap[key][0].replace('file://', '') == filename: | |
218 | return key | |
219 | ||
220 | return None | |
221 | ||
222 | def get_remfactor_for_file(self, filename): | |
223 | ''' | |
224 | Returns the remainder | |
225 | factor (1 - fraction length of last page in file) | |
226 | ''' | |
227 | return self._filedict[filename][1] | |
228 | ||
229 | def get_total_pagecount(self): | |
230 | ''' | |
231 | Returns the total pagecount for the Epub file | |
232 | ''' | |
233 | return self._pagecount | |
234 | ||
235 | def get_total_height(self): | |
236 | ''' | |
237 | Returns the total height of the Epub in pixels | |
238 | ''' | |
239 | return self._bookheight | |
240 | ||
241 | ||
242 | class _JobFind(GObject.GObject): | |
243 | __gsignals__ = { | |
244 | 'updated': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, ([])), | |
245 | } | |
246 | ||
247 | def __init__(self, document, start_page, n_pages, text, | |
248 | case_sensitive=False): | |
249 | """ | |
250 | Only case_sensitive=False is implemented | |
251 | """ | |
252 | GObject.GObject.__init__(self) | |
253 | ||
254 | self._finished = False | |
255 | self._document = document | |
256 | self._start_page = start_page | |
257 | self._n_pages = n_pages | |
258 | self._text = text | |
259 | self._case_sensitive = case_sensitive | |
260 | self.flattoc = self._document.get_flattoc() | |
261 | self._matchfilelist = [] | |
262 | self._current_file_index = 0 | |
263 | self.threads = [] | |
264 | ||
265 | s_thread = SearchThread(self) | |
266 | self.threads.append(s_thread) | |
267 | s_thread.start() | |
268 | ||
269 | def cancel(self): | |
270 | ''' | |
271 | Cancels the search job | |
272 | ''' | |
273 | for s_thread in self.threads: | |
274 | s_thread.stop() | |
275 | ||
276 | def is_finished(self): | |
277 | ''' | |
278 | Returns True if the entire search job has been finished | |
279 | ''' | |
280 | return self._finished | |
281 | ||
282 | def get_next_file(self): | |
283 | ''' | |
284 | Returns the next file which has the search pattern | |
285 | ''' | |
286 | self._current_file_index += 1 | |
287 | try: | |
288 | path = self._matchfilelist[self._current_file_index] | |
289 | except IndexError: | |
290 | self._current_file_index = 0 | |
291 | path = self._matchfilelist[self._current_file_index] | |
292 | ||
293 | return path | |
294 | ||
295 | def get_prev_file(self): | |
296 | ''' | |
297 | Returns the previous file which has the search pattern | |
298 | ''' | |
299 | self._current_file_index -= 1 | |
300 | try: | |
301 | path = self._matchfilelist[self._current_file_index] | |
302 | except IndexError: | |
303 | self._current_file_index = -1 | |
304 | path = self._matchfilelist[self._current_file_index] | |
305 | ||
306 | return path | |
307 | ||
308 | def get_search_text(self): | |
309 | ''' | |
310 | Returns the search text | |
311 | ''' | |
312 | return self._text | |
313 | ||
314 | def get_case_sensitive(self): | |
315 | ''' | |
316 | Returns True if the search is case-sensitive | |
317 | ''' | |
318 | return self._case_sensitive |
0 | import xml.etree.ElementTree as etree | |
1 | from gi.repository import Gtk | |
2 | ||
3 | ||
4 | class NavPoint(object): | |
5 | ||
6 | def __init__(self, label, contentsrc, children=[]): | |
7 | self._label = label | |
8 | self._contentsrc = contentsrc | |
9 | self._children = children | |
10 | ||
11 | def get_label(self): | |
12 | return self._label | |
13 | ||
14 | def get_contentsrc(self): | |
15 | return self._contentsrc | |
16 | ||
17 | def get_children(self): | |
18 | return self._children | |
19 | ||
20 | ||
21 | class NavMap(object): | |
22 | def __init__(self, opffile, ncxfile, basepath): | |
23 | self._basepath = basepath | |
24 | self._opffile = opffile | |
25 | self._tree = etree.parse(ncxfile) | |
26 | self._root = self._tree.getroot() | |
27 | self._gtktreestore = Gtk.TreeStore(str, str) | |
28 | self._flattoc = [] | |
29 | ||
30 | self._populate_flattoc() | |
31 | self._populate_toc() | |
32 | ||
33 | def _populate_flattoc(self): | |
34 | tree = etree.parse(self._opffile) | |
35 | root = tree.getroot() | |
36 | ||
37 | itemmap = {} | |
38 | manifest = root.find('.//{http://www.idpf.org/2007/opf}manifest') | |
39 | for element in manifest.iterfind('{http://www.idpf.org/2007/opf}item'): | |
40 | itemmap[element.get('id')] = element | |
41 | ||
42 | spine = root.find('.//{http://www.idpf.org/2007/opf}spine') | |
43 | for element in spine.iterfind('{http://www.idpf.org/2007/opf}itemref'): | |
44 | idref = element.get('idref') | |
45 | href = itemmap[idref].get('href') | |
46 | self._flattoc.append(self._basepath + href) | |
47 | ||
48 | self._opffile.close() | |
49 | ||
50 | def _populate_toc(self): | |
51 | navmap = self._root.find( | |
52 | '{http://www.daisy.org/z3986/2005/ncx/}navMap') | |
53 | for navpoint in navmap.iterfind( | |
54 | './{http://www.daisy.org/z3986/2005/ncx/}navPoint'): | |
55 | self._process_navpoint(navpoint) | |
56 | ||
57 | def _gettitle(self, navpoint): | |
58 | text = navpoint.find( | |
59 | './{http://www.daisy.org/z3986/2005/ncx/}' + | |
60 | 'navLabel/{http://www.daisy.org/z3986/2005/ncx/}text') | |
61 | return text.text | |
62 | ||
63 | def _getcontent(self, navpoint): | |
64 | text = navpoint.find( | |
65 | './{http://www.daisy.org/z3986/2005/ncx/}content') | |
66 | if text is not None: | |
67 | return self._basepath + text.get('src') | |
68 | else: | |
69 | return "" | |
70 | ||
71 | def _process_navpoint(self, navpoint, parent=None): | |
72 | title = self._gettitle(navpoint) | |
73 | content = self._getcontent(navpoint) | |
74 | ||
75 | # print title, content | |
76 | ||
77 | iter = self._gtktreestore.append(parent, [title, content]) | |
78 | # self._flattoc.append((title, content)) | |
79 | ||
80 | childnavpointlist = list(navpoint.iterfind( | |
81 | './{http://www.daisy.org/z3986/2005/ncx/}navPoint')) | |
82 | ||
83 | if len(childnavpointlist): | |
84 | for childnavpoint in childnavpointlist: | |
85 | self._process_navpoint(childnavpoint, parent=iter) | |
86 | else: | |
87 | return | |
88 | ||
89 | def get_gtktreestore(self): | |
90 | ''' | |
91 | Returns a GtkTreeModel representation of the | |
92 | Epub table of contents | |
93 | ''' | |
94 | return self._gtktreestore | |
95 | ||
96 | def get_flattoc(self): | |
97 | ''' | |
98 | Returns a flat (linear) list of files to be | |
99 | rendered. | |
100 | ''' | |
101 | return self._flattoc |
0 | import logging | |
1 | ||
2 | from gi.repository import WebKit | |
3 | from gi.repository import Gdk | |
4 | from gi.repository import GObject | |
5 | ||
6 | ||
7 | class _WebView(WebKit.WebView): | |
8 | ||
9 | __gsignals__ = { | |
10 | 'touch-change-page': (GObject.SignalFlags.RUN_FIRST, GObject.TYPE_NONE, | |
11 | ([bool])), } | |
12 | ||
13 | def __init__(self, only_to_measure=False): | |
14 | WebKit.WebView.__init__(self) | |
15 | self._only_to_measure = only_to_measure | |
16 | ||
17 | def setup_touch(self): | |
18 | self.get_window().set_events( | |
19 | self.get_window().get_events() | Gdk.EventMask.TOUCH_MASK) | |
20 | self.connect('event', self.__event_cb) | |
21 | ||
22 | def __event_cb(self, widget, event): | |
23 | if event.type == Gdk.EventType.TOUCH_BEGIN: | |
24 | x = event.touch.x | |
25 | view_width = widget.get_allocation().width | |
26 | if x > view_width * 3 / 4: | |
27 | self.emit('touch-change-page', True) | |
28 | elif x < view_width * 1 / 4: | |
29 | self.emit('touch-change-page', False) | |
30 | ||
31 | def get_page_height(self): | |
32 | ''' | |
33 | Gets height (in pixels) of loaded (X)HTML page. | |
34 | This is done via javascript at the moment | |
35 | ''' | |
36 | hide_scrollbar_js = '' | |
37 | if self._only_to_measure: | |
38 | hide_scrollbar_js = \ | |
39 | 'document.documentElement.style.overflow = "hidden";' | |
40 | ||
41 | oldtitle = self.get_main_frame().get_title() | |
42 | ||
43 | js = """ | |
44 | document.documentElement.style.margin = "50px"; | |
45 | if (document.body == null) { | |
46 | document.title = 0; | |
47 | } else { | |
48 | %s | |
49 | document.title=Math.max(document.body.scrollHeight, | |
50 | document.body.offsetHeight, | |
51 | document.documentElement.clientHeight, | |
52 | document.documentElement.scrollHeight, | |
53 | document.documentElement.offsetHeight); | |
54 | }; | |
55 | """ % hide_scrollbar_js | |
56 | self.execute_script(js) | |
57 | ret = self.get_main_frame().get_title() | |
58 | logging.error('get_page_height %s', ret) | |
59 | self.execute_script('document.title=%s;' % oldtitle) | |
60 | try: | |
61 | return int(ret) | |
62 | except ValueError: | |
63 | return 0 | |
64 | ||
65 | def add_bottom_padding(self, incr): | |
66 | ''' | |
67 | Adds incr pixels of padding to the end of the loaded (X)HTML page. | |
68 | This is done via javascript at the moment | |
69 | ''' | |
70 | js = """ | |
71 | var newdiv = document.createElement("div"); | |
72 | newdiv.style.height = "%dpx"; | |
73 | document.body.appendChild(newdiv); | |
74 | """ % incr | |
75 | self.execute_script(js) | |
76 | ||
77 | def highlight_next_word(self): | |
78 | ''' | |
79 | Highlight next word (for text to speech) | |
80 | ''' | |
81 | self.execute_script('highLightNextWord();') | |
82 | ||
83 | def go_to_link(self, id_link): | |
84 | self.execute_script('window.location.href = "%s";' % id_link) | |
85 | ||
86 | def get_vertical_position_element(self, id_link): | |
87 | ''' | |
88 | Get the vertical position of a element, in pixels | |
89 | ''' | |
90 | # remove the first '#' char | |
91 | id_link = id_link[1:] | |
92 | oldtitle = self.get_main_frame().get_title() | |
93 | js = """ | |
94 | obj = document.getElementById('%s'); | |
95 | var top = 0; | |
96 | if(obj.offsetParent) { | |
97 | while(1) { | |
98 | top += obj.offsetTop; | |
99 | if(!obj.offsetParent) { | |
100 | break; | |
101 | }; | |
102 | obj = obj.offsetParent; | |
103 | }; | |
104 | } else if(obj.y) { | |
105 | top += obj.y; | |
106 | }; | |
107 | document.title=top;""" % id_link | |
108 | self.execute_script(js) | |
109 | ret = self.get_main_frame().get_title() | |
110 | self.execute_script('document.title=%s;' % oldtitle) | |
111 | try: | |
112 | return int(ret) | |
113 | except ValueError: | |
114 | return 0 |
7 | 7 | msgstr "" |
8 | 8 | "Project-Id-Version: PACKAGE VERSION\n" |
9 | 9 | "Report-Msgid-Bugs-To: \n" |
10 | "POT-Creation-Date: 2017-06-01 08:19+1000\n" | |
10 | "POT-Creation-Date: 2017-08-12 13:27+1000\n" | |
11 | 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
12 | 12 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
13 | 13 | "Language-Team: LANGUAGE <LL@li.org>\n" |
117 | 117 | msgid "All the information related with this bookmark will be lost" |
118 | 118 | msgstr "" |
119 | 119 | |
120 | #: readactivity.py:954 | |
120 | #: readactivity.py:953 | |
121 | 121 | msgid "Receiving book..." |
122 | 122 | msgstr "" |
123 | 123 | |
124 | #: readactivity.py:1032 readactivity.py:1227 | |
124 | #: readactivity.py:1027 readactivity.py:1222 | |
125 | 125 | #, python-format |
126 | 126 | msgid "%s (Page %d)" |
127 | 127 | msgstr "" |
224 | 224 | #: comicadapter.py:70 |
225 | 225 | msgid "No readable images were found" |
226 | 226 | msgstr "Calere maromo kwane pe onwongere" |
227 | ||
228 | #, python-format | |
229 | #~ msgid "Page %d" | |
230 | #~ msgstr "Potbuk %d" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
221 | 229 | #: comicadapter.py:70 |
222 | 230 | msgid "No readable images were found" |
223 | 231 | msgstr "" |
232 | ||
233 | #~ msgid "%" | |
234 | #~ msgstr "%" | |
235 | ||
236 | #~ msgid "Choose document" | |
237 | #~ msgstr "Kies dokument" | |
238 | ||
239 | #~ msgid "Edit" | |
240 | #~ msgstr "Redigeer" | |
241 | ||
242 | #~ msgid "View" | |
243 | #~ msgstr "Besigtig" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
8 | # SOME DESCRIPTIVE TITLE. | |
9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
10 | # This file is distributed under the same license as the PACKAGE package. | |
11 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
12 | # SOME DESCRIPTIVE TITLE. | |
13 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
14 | # This file is distributed under the same license as the PACKAGE package. | |
15 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
16 | # SOME DESCRIPTIVE TITLE. | |
17 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
18 | # This file is distributed under the same license as the PACKAGE package. | |
19 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 20 | # SOME DESCRIPTIVE TITLE. |
1 | 21 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 22 | # This file is distributed under the same license as the PACKAGE package. |
222 | 242 | #: comicadapter.py:70 |
223 | 243 | msgid "No readable images were found" |
224 | 244 | msgstr "" |
245 | ||
246 | #~ msgid "%" | |
247 | #~ msgstr "%" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
0 | 3 | # translation of read-activity.po to Arabic |
1 | 4 | # Khaled Hosny <khaledhosny@eglug.org>, 2007, 2011. |
2 | 5 | # Ahmed Mansour <atphalix@users.arabeyes.org>, 2008. |
225 | 228 | #: comicadapter.py:70 |
226 | 229 | msgid "No readable images were found" |
227 | 230 | msgstr "" |
231 | ||
232 | #, python-format | |
233 | #~ msgid "Page %d" | |
234 | #~ msgstr "الصفحه %d" | |
235 | ||
236 | #, python-format | |
237 | #~ msgid "Page %(current)i of %(total_pages)i" | |
238 | #~ msgstr "صفحة %(current)i من %(total_pages)i" | |
239 | ||
240 | #~ msgid "%" | |
241 | #~ msgstr "%" | |
242 | ||
243 | #~ msgid "pitch adjusted" | |
244 | #~ msgstr "ضُبِطت الشَّدة" | |
245 | ||
246 | #~ msgid "rate adjusted" | |
247 | #~ msgstr "ضُبِطت السرعة" | |
248 | ||
249 | #~ msgid "Choose document" | |
250 | #~ msgstr "اختر الوثيقة" | |
251 | ||
252 | #, python-format | |
253 | #~ msgid "Page %i of %i" | |
254 | #~ msgstr "صفحة %i من %i" | |
255 | ||
256 | #~ msgid "Edit" | |
257 | #~ msgstr "تحرير" | |
258 | ||
259 | #~ msgid "View" | |
260 | #~ msgstr "عرض" | |
261 | ||
262 | #~ msgid "Read Activity" | |
263 | #~ msgstr "نشاط القراءة" |
258 | 258 | #: comicadapter.py:70 |
259 | 259 | msgid "No readable images were found" |
260 | 260 | msgstr "" |
261 | ||
262 | #, python-format | |
263 | #~ msgid "Page %d" | |
264 | #~ msgstr "%d jakhuni laphi" | |
265 | ||
266 | # "Página | |
267 | #, python-format | |
268 | #~ msgid "Page %(current)i of %(total_pages)i" | |
269 | #~ msgstr "Laphi %(current)i qipatsti %(total_pages)i" | |
270 | ||
271 | # "%" | |
272 | #~ msgid "%" | |
273 | #~ msgstr "%" | |
274 | ||
275 | # "tono ajustado" | |
276 | #~ msgid "pitch adjusted" | |
277 | #~ msgstr "istaña jitinakayaña" | |
278 | ||
279 | # "velocidad ajustada" | |
280 | #~ msgid "rate adjusted" | |
281 | #~ msgstr "katakikuna jitinakayaña" | |
282 | ||
283 | # "Escoger documento" | |
284 | #~ msgid "Choose document" | |
285 | #~ msgstr "Wakichaña qatukaña" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
222 | 230 | #: comicadapter.py:70 |
223 | 231 | msgid "No readable images were found" |
224 | 232 | msgstr "" |
233 | ||
234 | #~ msgid "%" | |
235 | #~ msgstr "%" | |
236 | ||
237 | #~ msgid "Edit" | |
238 | #~ msgstr "Редактиране" | |
239 | ||
240 | #~ msgid "View" | |
241 | #~ msgstr "Изглед" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
221 | 229 | #: comicadapter.py:70 |
222 | 230 | msgid "No readable images were found" |
223 | 231 | msgstr "" |
232 | ||
233 | #~ msgid "%" | |
234 | #~ msgstr "%" | |
235 | ||
236 | #~ msgid "Choose document" | |
237 | #~ msgstr "নথি বেছে নাও" | |
238 | ||
239 | #, python-format | |
240 | #~ msgid "Page %i of %i" | |
241 | #~ msgstr "%i এর %i তম পৃষ্ঠা" | |
242 | ||
243 | #~ msgid "Edit" | |
244 | #~ msgstr "সম্পাদনা" | |
245 | ||
246 | #~ msgid "View" | |
247 | #~ msgstr "প্রদর্শন" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
225 | 233 | #: comicadapter.py:70 |
226 | 234 | msgid "No readable images were found" |
227 | 235 | msgstr "" |
236 | ||
237 | #~ msgid "%" | |
238 | #~ msgstr "%" | |
239 | ||
240 | #~ msgid "Edit" | |
241 | #~ msgstr "সম্পাদন" | |
242 | ||
243 | #~ msgid "View" | |
244 | #~ msgstr "প্রদর্শন" |
221 | 221 | #: comicadapter.py:70 |
222 | 222 | msgid "No readable images were found" |
223 | 223 | msgstr "" |
224 | ||
225 | #~ msgid "%" | |
226 | #~ msgstr "%" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
225 | 233 | #: comicadapter.py:70 |
226 | 234 | msgid "No readable images were found" |
227 | 235 | msgstr "" |
236 | ||
237 | #, python-format | |
238 | #~ msgid "Page %d" | |
239 | #~ msgstr "Pàgina %d" | |
240 | ||
241 | #~ msgid "%" | |
242 | #~ msgstr "%" | |
243 | ||
244 | #~ msgid "Choose document" | |
245 | #~ msgstr "Triar document" | |
246 | ||
247 | #, python-format | |
248 | #~ msgid "Page %i of %i" | |
249 | #~ msgstr "Pàgina %i sobre %i" | |
250 | ||
251 | #~ msgid "Edit" | |
252 | #~ msgstr "Editar" | |
253 | ||
254 | #~ msgid "View" | |
255 | #~ msgstr "Veure" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
221 | 229 | #: comicadapter.py:70 |
222 | 230 | msgid "No readable images were found" |
223 | 231 | msgstr "" |
232 | ||
233 | #~ msgid "%" | |
234 | #~ msgstr "%" | |
235 | ||
236 | #~ msgid "Choose document" | |
237 | #~ msgstr "Vybrat dokument" | |
238 | ||
239 | #~ msgid "Edit" | |
240 | #~ msgstr "Upravit" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
223 | 231 | #: comicadapter.py:70 |
224 | 232 | msgid "No readable images were found" |
225 | 233 | msgstr "" |
234 | ||
235 | #, python-format | |
236 | #~ msgid "Page %d" | |
237 | #~ msgstr "Side %d" | |
238 | ||
239 | #, python-format | |
240 | #~ msgid "Page %(current)i of %(total_pages)i" | |
241 | #~ msgstr "Side %(current)i af %(total_pages)i" | |
242 | ||
243 | #~ msgid "%" | |
244 | #~ msgstr "%" | |
245 | ||
246 | #~ msgid "pitch adjusted" | |
247 | #~ msgstr "tonehøjde tilpasset" | |
248 | ||
249 | #~ msgid "rate adjusted" | |
250 | #~ msgstr "hastighed tilpasset" | |
251 | ||
252 | #~ msgid "Choose document" | |
253 | #~ msgstr "Vælg dokument" | |
254 | ||
255 | #, python-format | |
256 | #~ msgid "Page %i of %i" | |
257 | #~ msgstr "Side %i af %i" | |
258 | ||
259 | #~ msgid "Edit" | |
260 | #~ msgstr "Redigér" | |
261 | ||
262 | #~ msgid "View" | |
263 | #~ msgstr "Vis" |
0 | 0 | # SOME DESCRIPTIVE TITLE. |
1 | 1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # SOME DESCRIPTIVE TITLE. | |
4 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
5 | # This file is distributed under the same license as the PACKAGE package. | |
6 | # SOME DESCRIPTIVE TITLE. | |
7 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
8 | # This file is distributed under the same license as the PACKAGE package. | |
9 | # SOME DESCRIPTIVE TITLE. | |
10 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
11 | # This file is distributed under the same license as the PACKAGE package. | |
12 | # SOME DESCRIPTIVE TITLE. | |
13 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
14 | # This file is distributed under the same license as the PACKAGE package. | |
15 | # SOME DESCRIPTIVE TITLE. | |
16 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
17 | # This file is distributed under the same license as the PACKAGE package. | |
18 | # SOME DESCRIPTIVE TITLE. | |
19 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
20 | # This file is distributed under the same license as the PACKAGE package. | |
21 | # SOME DESCRIPTIVE TITLE. | |
22 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
23 | # This file is distributed under the same license as the PACKAGE package. | |
24 | # SOME DESCRIPTIVE TITLE. | |
25 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
26 | # This file is distributed under the same license as the PACKAGE package. | |
27 | # SOME DESCRIPTIVE TITLE. | |
28 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
29 | # This file is distributed under the same license as the PACKAGE package. | |
30 | # SOME DESCRIPTIVE TITLE. | |
31 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
32 | # This file is distributed under the same license as the PACKAGE package. | |
33 | # SOME DESCRIPTIVE TITLE. | |
34 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
35 | # This file is distributed under the same license as the PACKAGE package. | |
36 | # SOME DESCRIPTIVE TITLE. | |
37 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
38 | # This file is distributed under the same license as the PACKAGE package. | |
2 | 39 | # This file is distributed under the same license as the PACKAGE package. |
3 | 40 | # Fabian Affolter <fab@fedoraproject.org>, 2007. |
4 | 41 | # Markus Schlager <m.slg@gmx.de>, 2012. |
227 | 264 | #: comicadapter.py:70 |
228 | 265 | msgid "No readable images were found" |
229 | 266 | msgstr "Es wurden keine lesbaren Bilder gefunden" |
267 | ||
268 | #, python-format | |
269 | #~ msgid "Page %d" | |
270 | #~ msgstr "Seite %d" | |
271 | ||
272 | #, python-format | |
273 | #~ msgid "Page %(current)i of %(total_pages)i" | |
274 | #~ msgstr "Seite %(current)i von %(total_pages)i" | |
275 | ||
276 | #~ msgid "%" | |
277 | #~ msgstr "%" | |
278 | ||
279 | #~ msgid "pitch adjusted" | |
280 | #~ msgstr "Tonhöhe angepasst" | |
281 | ||
282 | #~ msgid "rate adjusted" | |
283 | #~ msgstr "Rate angepasst" | |
284 | ||
285 | #~ msgid "Choose document" | |
286 | #~ msgstr "Dokument auswählen" | |
287 | ||
288 | #, python-format | |
289 | #~ msgid "Page %i of %i" | |
290 | #~ msgstr "Seite %i von %i" | |
291 | ||
292 | #~ msgid "Edit" | |
293 | #~ msgstr "Bearbeiten" | |
294 | ||
295 | #~ msgid "View" | |
296 | #~ msgstr "Ansehen" | |
297 | ||
298 | #~ msgid "Read Activity" | |
299 | #~ msgstr "Lese-Aktivitäten" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
220 | 228 | #: comicadapter.py:70 |
221 | 229 | msgid "No readable images were found" |
222 | 230 | msgstr "" |
231 | ||
232 | #~ msgid "%" | |
233 | #~ msgstr "%" | |
234 | ||
235 | #~ msgid "Edit" | |
236 | #~ msgstr "ཞུན་དག" | |
237 | ||
238 | #~ msgid "View" | |
239 | #~ msgstr "མཐོང་སྣང་།" |
0 | # Greek translation of Read project. | |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
8 | # Greek translation of Xbook project. | |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
3 | 11 | # Simos Xenitellis <simos.lists@googlemail.com>, 2007. |
221 | 229 | #: comicadapter.py:70 |
222 | 230 | msgid "No readable images were found" |
223 | 231 | msgstr "" |
232 | ||
233 | #, python-format | |
234 | #, python-format, | |
235 | #~ msgid "Page %(current)i of %(total_pages)i" | |
236 | #~ msgstr "Σελίδα %(current)i από %(total_pages)i" | |
237 | ||
238 | #~ msgid "%" | |
239 | #~ msgstr "%" | |
240 | ||
241 | #~ msgid "pitch adjusted" | |
242 | #~ msgstr "ο τόνος ρυθμίστηκε" | |
243 | ||
244 | #~ msgid "rate adjusted" | |
245 | #~ msgstr "ο ρυθμός ρυθμίστηκε" | |
246 | ||
247 | #~ msgid "Choose document" | |
248 | #~ msgstr "Επιλογή εγγράφου" | |
249 | ||
250 | #, python-format | |
251 | #~ msgid "Page %i of %i" | |
252 | #~ msgstr "Σελίδα %i από %i" | |
253 | ||
254 | #~ msgid "Edit" | |
255 | #~ msgstr "Επεξεργασία" | |
256 | ||
257 | #~ msgid "View" | |
258 | #~ msgstr "Προβολή" | |
259 | ||
260 | #~ msgid "Read Activity" | |
261 | #~ msgstr "Ανάγνωση δραστηριότητας" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
224 | 232 | #: comicadapter.py:70 |
225 | 233 | msgid "No readable images were found" |
226 | 234 | msgstr "No readable images were found" |
235 | ||
236 | #, python-format | |
237 | #~ msgid "Page %d" | |
238 | #~ msgstr "Page %d" | |
239 | ||
240 | #, python-format | |
241 | #~ msgid "Page %(current)i of %(total_pages)i" | |
242 | #~ msgstr "Page %(current)i of %(total_pages)i" | |
243 | ||
244 | #~ msgid "%" | |
245 | #~ msgstr "%" | |
246 | ||
247 | #~ msgid "pitch adjusted" | |
248 | #~ msgstr "pitch adjusted" | |
249 | ||
250 | #~ msgid "rate adjusted" | |
251 | #~ msgstr "rate adjusted" | |
252 | ||
253 | #~ msgid "Choose document" | |
254 | #~ msgstr "Choose document" | |
255 | ||
256 | #, python-format | |
257 | #~ msgid "Page %i of %i" | |
258 | #~ msgstr "Page %i of %i" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
224 | 232 | #: comicadapter.py:70 |
225 | 233 | msgid "No readable images were found" |
226 | 234 | msgstr "No readable images were found" |
235 | ||
236 | #, python-format | |
237 | #~ msgid "Page %d" | |
238 | #~ msgstr "Page %d" | |
239 | ||
240 | #, python-format | |
241 | #~ msgid "Page %(current)i of %(total_pages)i" | |
242 | #~ msgstr "Page %(current)i of %(total_pages)i" | |
243 | ||
244 | #~ msgid "%" | |
245 | #~ msgstr "%" | |
246 | ||
247 | #~ msgid "pitch adjusted" | |
248 | #~ msgstr "pitch adjusted" | |
249 | ||
250 | #~ msgid "rate adjusted" | |
251 | #~ msgstr "rate adjusted" | |
252 | ||
253 | #~ msgid "Choose document" | |
254 | #~ msgstr "Choose document" | |
255 | ||
256 | #, python-format | |
257 | #~ msgid "Page %i of %i" | |
258 | #~ msgstr "Page %i of %i" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
8 | # SOME DESCRIPTIVE TITLE. | |
9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
10 | # This file is distributed under the same license as the PACKAGE package. | |
11 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
12 | # SOME DESCRIPTIVE TITLE. | |
13 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
14 | # This file is distributed under the same license as the PACKAGE package. | |
15 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
16 | # SOME DESCRIPTIVE TITLE. | |
17 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
18 | # This file is distributed under the same license as the PACKAGE package. | |
19 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 20 | # Spanish translations for PACKAGE package. |
1 | 21 | # Copyright (C) 2007 THE PACKAGE'S COPYRIGHT HOLDER |
2 | 22 | # This file is distributed under the same license as the PACKAGE package. |
224 | 244 | #: comicadapter.py:70 |
225 | 245 | msgid "No readable images were found" |
226 | 246 | msgstr "No se encontraron imágenes legibles" |
247 | ||
248 | #, python-format | |
249 | #~ msgid "Page %d" | |
250 | #~ msgstr "Página %d" | |
251 | ||
252 | #, python-format | |
253 | #~ msgid "Page %(current)i of %(total_pages)i" | |
254 | #~ msgstr "Página %(current)i de %(total_pages)i" | |
255 | ||
256 | #~ msgid "%" | |
257 | #~ msgstr "%" | |
258 | ||
259 | #~ msgid "pitch adjusted" | |
260 | #~ msgstr "tono ajustado" | |
261 | ||
262 | #~ msgid "rate adjusted" | |
263 | #~ msgstr "velocidad ajustada" | |
264 | ||
265 | #~ msgid "Choose document" | |
266 | #~ msgstr "Escoger documento" | |
267 | ||
268 | #, python-format | |
269 | #~ msgid "Page %i of %i" | |
270 | #~ msgstr "Página %i de %i" | |
271 | ||
272 | #~ msgid "Edit" | |
273 | #~ msgstr "Editar" | |
274 | ||
275 | #~ msgid "View" | |
276 | #~ msgstr "Ver" | |
277 | ||
278 | #~ msgid "Read Activity" | |
279 | #~ msgstr "Actividad Leer" | |
280 | ||
281 | #~ msgid "Open a document to read" | |
282 | #~ msgstr "Abrir un documento para leer" | |
283 | ||
284 | #~ msgid "All supported formats" | |
285 | #~ msgstr "Todos los formatos soportados" | |
286 | ||
287 | #~ msgid "All files" | |
288 | #~ msgstr "Todos los ficheros" | |
289 | ||
290 | #~ msgid "Open" | |
291 | #~ msgstr "Abrir" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
225 | 233 | #: comicadapter.py:70 |
226 | 234 | msgid "No readable images were found" |
227 | 235 | msgstr "" |
236 | ||
237 | #, python-format | |
238 | #~ msgid "Page %d" | |
239 | #~ msgstr "صفحهی %d" | |
240 | ||
241 | #~ msgid "%" | |
242 | #~ msgstr "٪" | |
243 | ||
244 | #~ msgid "Edit" | |
245 | #~ msgstr "ویراستن" | |
246 | ||
247 | #~ msgid "View" | |
248 | #~ msgstr "دیدن" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
221 | 229 | #: comicadapter.py:70 |
222 | 230 | msgid "No readable images were found" |
223 | 231 | msgstr "" |
232 | ||
233 | #~ msgid "%" | |
234 | #~ msgstr "%" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # translation of xbook.master.po to Français |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
224 | 232 | #: comicadapter.py:70 |
225 | 233 | msgid "No readable images were found" |
226 | 234 | msgstr "Aucune image lisible n'a été trouvée" |
235 | ||
236 | #, python-format | |
237 | #~ msgid "Page %d" | |
238 | #~ msgstr "Page %d" | |
239 | ||
240 | #, python-format | |
241 | #~ msgid "Page %(current)i of %(total_pages)i" | |
242 | #~ msgstr "Page %(current)i sur %(total_pages)i" | |
243 | ||
244 | #~ msgid "%" | |
245 | #~ msgstr "%" | |
246 | ||
247 | #~ msgid "pitch adjusted" | |
248 | #~ msgstr "hauteur ajustée" | |
249 | ||
250 | #~ msgid "rate adjusted" | |
251 | #~ msgstr "fréquence ajustée" | |
252 | ||
253 | #~ msgid "Choose document" | |
254 | #~ msgstr "Choisir un document" | |
255 | ||
256 | #, python-format | |
257 | #~ msgid "Page %i of %i" | |
258 | #~ msgstr "Page %i sur %i" | |
259 | ||
260 | #~ msgid "Edit" | |
261 | #~ msgstr "Éditer" | |
262 | ||
263 | #~ msgid "View" | |
264 | #~ msgstr "Afficher" | |
265 | ||
266 | #~ msgid "Read Activity" | |
267 | #~ msgstr "Lecture" |
224 | 224 | #: comicadapter.py:70 |
225 | 225 | msgid "No readable images were found" |
226 | 226 | msgstr "Ndojetopái ta'anga hesakãva" |
227 | ||
228 | #, python-format | |
229 | #~ msgid "Page %d" | |
230 | #~ msgstr "Kuatia rogue %d." |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
6 | 14 | "Project-Id-Version: PACKAGE VERSION\n" |
7 | 15 | "Report-Msgid-Bugs-To: \n" |
8 | 16 | "POT-Creation-Date: 2017-03-24 17:39+1100\n" |
9 | "PO-Revision-Date: 2016-11-13 12:53+0000\n" | |
17 | "PO-Revision-Date: 2017-04-23 18:07+0000\n" | |
10 | 18 | "Last-Translator: Yaron <sh.yaron@gmail.com>\n" |
11 | 19 | "Language-Team: LANGUAGE <LL@li.org>\n" |
12 | 20 | "Language: he\n" |
15 | 23 | "Content-Transfer-Encoding: 8bit\n" |
16 | 24 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" |
17 | 25 | "X-Generator: Pootle 2.5.1.1\n" |
18 | "X-POOTLE-MTIME: 1479041587.000000\n" | |
26 | "X-POOTLE-MTIME: 1492970823.000000\n" | |
19 | 27 | |
20 | 28 | #: activity/activity.info:2 |
21 | 29 | msgid "Read" |
43 | 51 | |
44 | 52 | #: readdialog.py:147 |
45 | 53 | msgid "<b>Author</b>:" |
46 | msgstr "" | |
54 | msgstr "<b>מחבר</b>:" | |
47 | 55 | |
48 | 56 | #: readdialog.py:163 |
49 | 57 | msgid "<b>Details</b>:" |
63 | 71 | |
64 | 72 | #: readactivity.py:379 |
65 | 73 | msgid "Please wait" |
66 | msgstr "" | |
74 | msgstr "נא להמתין" | |
67 | 75 | |
68 | 76 | #: readactivity.py:380 |
69 | 77 | msgid "Starting connection..." |
70 | msgstr "" | |
78 | msgstr "החיבור נוצר…" | |
71 | 79 | |
72 | 80 | #: readactivity.py:388 |
73 | 81 | msgid "No book" |
115 | 123 | |
116 | 124 | #: readactivity.py:954 |
117 | 125 | msgid "Receiving book..." |
118 | msgstr "" | |
126 | msgstr "הספר מתקבל…" | |
119 | 127 | |
120 | 128 | #: readactivity.py:1032 readactivity.py:1227 |
121 | 129 | #, python-format |
122 | 130 | msgid "%s (Page %d)" |
123 | msgstr "" | |
131 | msgstr "%s (עמוד %d)" | |
124 | 132 | |
125 | 133 | #: readtoolbar.py:61 |
126 | 134 | msgid "Previous" |
176 | 184 | |
177 | 185 | #: readtoolbar.py:252 |
178 | 186 | msgid "Rotate left" |
179 | msgstr "" | |
187 | msgstr "הטייה שמאלה" | |
180 | 188 | |
181 | 189 | #: readtoolbar.py:258 |
182 | 190 | msgid "Rotate right" |
183 | msgstr "" | |
191 | msgstr "הטייה ימינה" | |
184 | 192 | |
185 | 193 | #: readtoolbar.py:324 |
186 | 194 | msgid "Show Tray" |
219 | 227 | |
220 | 228 | #: comicadapter.py:69 |
221 | 229 | msgid "Can not read Comic Book Archive" |
222 | msgstr "" | |
230 | msgstr "לא ניתן לקרוא את ארכיון ספרי הקומיקס" | |
223 | 231 | |
224 | 232 | #: comicadapter.py:70 |
225 | 233 | msgid "No readable images were found" |
226 | msgstr "" | |
234 | msgstr "לא נמצאו תמונות שניתן לקרוא" | |
235 | ||
236 | #, python-format | |
237 | #~ msgid "Page %d" | |
238 | #~ msgstr "עמוד %d" | |
239 | ||
240 | #, fuzzy | |
241 | #~ msgid "%" | |
242 | #~ msgstr "%" | |
243 | ||
244 | #, fuzzy | |
245 | #~ msgid "Edit" | |
246 | #~ msgstr "עריכה" | |
247 | ||
248 | #, fuzzy | |
249 | #~ msgid "View" | |
250 | #~ msgstr "צפייה" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
8 | # SOME DESCRIPTIVE TITLE. | |
9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
10 | # This file is distributed under the same license as the PACKAGE package. | |
11 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 12 | # translation of read-activity.po to Hindi |
1 | 13 | # G Karunakar <karunakar@indlinux.org>, 2007. |
2 | 14 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
224 | 236 | #: comicadapter.py:70 |
225 | 237 | msgid "No readable images were found" |
226 | 238 | msgstr "कोई छवियां नहीं मिलीं" |
239 | ||
240 | #, python-format | |
241 | #~ msgid "Page %d" | |
242 | #~ msgstr "पृष्ठ %d" | |
243 | ||
244 | #, python-format | |
245 | #, python-format, | |
246 | #~ msgid "Page %(current)i of %(total_pages)i" | |
247 | #~ msgstr "पेज %(current)i मैं %(total_pages)i" | |
248 | ||
249 | #~ msgid "%" | |
250 | #~ msgstr "%" | |
251 | ||
252 | #~ msgid "pitch adjusted" | |
253 | #~ msgstr "पिच समायोजित" | |
254 | ||
255 | #~ msgid "rate adjusted" | |
256 | #~ msgstr "दर समायोजित" | |
257 | ||
258 | #~ msgid "Choose document" | |
259 | #~ msgstr "दस्तावेज़ चुनें" | |
260 | ||
261 | #, python-format | |
262 | #~ msgid "Page %i of %i" | |
263 | #~ msgstr "पृष्ठ %i में से: %i" | |
264 | ||
265 | #~ msgid "Edit" | |
266 | #~ msgstr "संपादन" | |
267 | ||
268 | #~ msgid "View" | |
269 | #~ msgstr "दृश्य" | |
270 | ||
271 | #~ msgid "Read Activity" | |
272 | #~ msgstr "पढ़ने के क्रियाकलाप" |
0 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
1 | # This file is distributed under the same license as the Read package. | |
2 | # Božidar Putanec <bozidarp@yahoo.com>, 2017. | |
3 | msgid "" | |
4 | msgstr "" | |
5 | "Project-Id-Version: Read\n" | |
6 | "Report-Msgid-Bugs-To: \n" | |
7 | "POT-Creation-Date: 2017-03-24 17:39+1100\n" | |
8 | "PO-Revision-Date: 2017-05-16 15:02-0700\n" | |
9 | "Last-Translator: Božidar Putanec <bozidarp@yahoo.com>\n" | |
10 | "Language-Team: Croatian <LL@li.org>\n" | |
11 | "Language: hr\n" | |
12 | "MIME-Version: 1.0\n" | |
13 | "Content-Type: text/plain; charset=UTF-8\n" | |
14 | "Content-Transfer-Encoding: 8bit\n" | |
15 | "X-Generator: Poedit 2.0.1\n" | |
16 | "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" | |
17 | "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" | |
18 | ||
19 | #: activity/activity.info:2 | |
20 | msgid "Read" | |
21 | msgstr "Čitamo" | |
22 | ||
23 | #: activity/activity.info:3 | |
24 | msgid "" | |
25 | "Use this activity when you are ready to read! Remember to flip your computer " | |
26 | "around to feel like you are really holding a book!" | |
27 | msgstr "" | |
28 | "Otvori ovu aktivnost kad si spreman i želiš čitati. Koristi računalo kao " | |
29 | "knjigu!" | |
30 | ||
31 | #: readdialog.py:52 | |
32 | msgid "Cancel" | |
33 | msgstr "Odustajem" | |
34 | ||
35 | #: readdialog.py:58 | |
36 | msgid "Ok" | |
37 | msgstr "U redu" | |
38 | ||
39 | #: readdialog.py:120 | |
40 | msgid "<b>Title</b>:" | |
41 | msgstr "<b>Naslov</b>:" | |
42 | ||
43 | #: readdialog.py:147 | |
44 | msgid "<b>Author</b>:" | |
45 | msgstr "<b>Autor</b>:" | |
46 | ||
47 | #: readdialog.py:163 | |
48 | msgid "<b>Details</b>:" | |
49 | msgstr "<b>Pojedinosti</b>:" | |
50 | ||
51 | #: evinceadapter.py:92 | |
52 | msgid "URL from Read" | |
53 | msgstr "URL od „Čitamo“" | |
54 | ||
55 | #: speechtoolbar.py:57 | |
56 | msgid "Play / Pause" | |
57 | msgstr "Kreni/Stani" | |
58 | ||
59 | #: speechtoolbar.py:65 | |
60 | msgid "Stop" | |
61 | msgstr "Stop" | |
62 | ||
63 | #: readactivity.py:379 | |
64 | msgid "Please wait" | |
65 | msgstr "Pričekaj" | |
66 | ||
67 | #: readactivity.py:380 | |
68 | msgid "Starting connection..." | |
69 | msgstr "Započinje povezivanje..." | |
70 | ||
71 | #: readactivity.py:388 | |
72 | msgid "No book" | |
73 | msgstr "Nema knjige" | |
74 | ||
75 | #: readactivity.py:388 | |
76 | msgid "Choose something to read" | |
77 | msgstr "Odaberi nešto za čitanje" | |
78 | ||
79 | #: readactivity.py:393 | |
80 | msgid "Back" | |
81 | msgstr "Natrag" | |
82 | ||
83 | #: readactivity.py:397 | |
84 | msgid "Previous page" | |
85 | msgstr "Prethodna stranica" | |
86 | ||
87 | #: readactivity.py:399 | |
88 | msgid "Previous bookmark" | |
89 | msgstr "Prethodna knjižna oznaka" | |
90 | ||
91 | #: readactivity.py:411 | |
92 | msgid "Forward" | |
93 | msgstr "Naprijed" | |
94 | ||
95 | #: readactivity.py:415 | |
96 | msgid "Next page" | |
97 | msgstr "Sljedeća stranica" | |
98 | ||
99 | #: readactivity.py:417 | |
100 | msgid "Next bookmark" | |
101 | msgstr "Sljedeća knjižna oznaka" | |
102 | ||
103 | #: readactivity.py:468 | |
104 | msgid "Index" | |
105 | msgstr "Indeks" | |
106 | ||
107 | #: readactivity.py:564 | |
108 | msgid "Delete bookmark" | |
109 | msgstr "Ukloni knjižnu oznaku" | |
110 | ||
111 | #: readactivity.py:565 | |
112 | msgid "All the information related with this bookmark will be lost" | |
113 | msgstr "Sve informacije vezane uz ovu knjižnu oznaku biti će izgubljene" | |
114 | ||
115 | #: readactivity.py:954 | |
116 | msgid "Receiving book..." | |
117 | msgstr "Preuzimanje knjige..." | |
118 | ||
119 | #: readactivity.py:1032 readactivity.py:1227 | |
120 | #, python-format | |
121 | msgid "%s (Page %d)" | |
122 | msgstr "%s (Stranica %d)" | |
123 | ||
124 | #: readtoolbar.py:61 | |
125 | msgid "Previous" | |
126 | msgstr "Prethodna" | |
127 | ||
128 | #: readtoolbar.py:68 | |
129 | msgid "Next" | |
130 | msgstr "Sljedeća" | |
131 | ||
132 | #: readtoolbar.py:79 | |
133 | msgid "Highlight" | |
134 | msgstr "Isticanje" | |
135 | ||
136 | #: readtoolbar.py:160 | |
137 | msgid "Find first" | |
138 | msgstr "Nađi prvi" | |
139 | ||
140 | #: readtoolbar.py:166 | |
141 | msgid "Find previous" | |
142 | msgstr "Nađi prethodni" | |
143 | ||
144 | #: readtoolbar.py:168 | |
145 | msgid "Find next" | |
146 | msgstr "Nađi sljedeći" | |
147 | ||
148 | #: readtoolbar.py:188 | |
149 | msgid "Table of contents" | |
150 | msgstr "Sadržaj" | |
151 | ||
152 | #: readtoolbar.py:197 | |
153 | msgid "Zoom out" | |
154 | msgstr "Smanjivanje" | |
155 | ||
156 | #: readtoolbar.py:203 | |
157 | msgid "Zoom in" | |
158 | msgstr "Povećavanje" | |
159 | ||
160 | #: readtoolbar.py:209 | |
161 | msgid "Zoom to width" | |
162 | msgstr "Povećaj do širine" | |
163 | ||
164 | #: readtoolbar.py:215 | |
165 | msgid "Zoom to fit" | |
166 | msgstr "Povećaj da stane" | |
167 | ||
168 | #: readtoolbar.py:221 | |
169 | msgid "Actual size" | |
170 | msgstr "Stvarna veličina" | |
171 | ||
172 | #: readtoolbar.py:232 | |
173 | msgid "Fullscreen" | |
174 | msgstr "Po cijelom zaslonu" | |
175 | ||
176 | #: readtoolbar.py:252 | |
177 | msgid "Rotate left" | |
178 | msgstr "Rotiraj nalijevo" | |
179 | ||
180 | #: readtoolbar.py:258 | |
181 | msgid "Rotate right" | |
182 | msgstr "Rotiraj nadesno" | |
183 | ||
184 | #: readtoolbar.py:324 | |
185 | msgid "Show Tray" | |
186 | msgstr "Pokaži traku" | |
187 | ||
188 | #: readtoolbar.py:326 | |
189 | msgid "Hide Tray" | |
190 | msgstr "Sakrij traku" | |
191 | ||
192 | #: linkbutton.py:133 | |
193 | msgid "Go to Bookmark" | |
194 | msgstr "Idi na knjižnu oznaku" | |
195 | ||
196 | #: linkbutton.py:139 | |
197 | msgid "Remove" | |
198 | msgstr "Ukloni" | |
199 | ||
200 | #: bookmarkview.py:107 | |
201 | #, python-format | |
202 | msgid "Bookmark added by %(user)s %(time)s" | |
203 | msgstr "Knjižnu oznaku je dodao %(user)s %(time)s" | |
204 | ||
205 | #: bookmarkview.py:143 bookmarkview.py:192 | |
206 | msgid "Add notes for bookmark: " | |
207 | msgstr "Dodaj bilješku za knjižnu oznaku: " | |
208 | ||
209 | #: bookmarkview.py:188 | |
210 | #, python-format | |
211 | msgid "%s's bookmark" | |
212 | msgstr "knjižna oznaka od %s" | |
213 | ||
214 | #: bookmarkview.py:189 | |
215 | #, python-format | |
216 | msgid "Bookmark for page %d" | |
217 | msgstr "Knjižna oznaka za stranicu %d" | |
218 | ||
219 | #: comicadapter.py:69 | |
220 | msgid "Can not read Comic Book Archive" | |
221 | msgstr "Nije moguće čitati Comic Book arhivu" | |
222 | ||
223 | #: comicadapter.py:70 | |
224 | msgid "No readable images were found" | |
225 | msgstr "Nijedna čitljiva slika nije nađena" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
222 | 230 | #: comicadapter.py:70 |
223 | 231 | msgid "No readable images were found" |
224 | 232 | msgstr "" |
233 | ||
234 | #~ msgid "%" | |
235 | #~ msgstr "%" | |
236 | ||
237 | #~ msgid "Edit" | |
238 | #~ msgstr "Edite" | |
239 | ||
240 | #~ msgid "View" | |
241 | #~ msgstr "Vizyalize" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
222 | 230 | #: comicadapter.py:70 |
223 | 231 | msgid "No readable images were found" |
224 | 232 | msgstr "" |
233 | ||
234 | #~ msgid "%" | |
235 | #~ msgstr "%" | |
236 | ||
237 | #~ msgid "Choose document" | |
238 | #~ msgstr "Dokumentum kiválasztása" | |
239 | ||
240 | #, python-format | |
241 | #~ msgid "Page %i of %i" | |
242 | #~ msgstr "Oldal %i ból %i" |
222 | 222 | #: comicadapter.py:70 |
223 | 223 | msgid "No readable images were found" |
224 | 224 | msgstr "" |
225 | ||
226 | #, python-format | |
227 | #, python-format, , | |
228 | #~ msgid "Page %(current)i of %(total_pages)i" | |
229 | #~ msgstr "Walxeklek %(current)i a xi ti %(total_pages)i" | |
230 | ||
231 | #~ msgid "%" | |
232 | #~ msgstr "%" | |
233 | ||
234 | #~ msgid "pitch adjusted" | |
235 | #~ msgstr "janidhtaláb t'ojojodh" | |
236 | ||
237 | # tasa ajustada (tasa se refiere a un nivel, índice) | |
238 | # Ejemplo: "Tasa de natalidad"="ïndice de natalidad" | |
239 | #~ msgid "rate adjusted" | |
240 | #~ msgstr "bajudh adhiktalab" | |
241 | ||
242 | #~ msgid "Choose document" | |
243 | #~ msgstr "Takuy dhuchadh úw" | |
244 | ||
245 | #, python-format | |
246 | #~ msgid "Page %i of %i" | |
247 | #~ msgstr "Walxeklek %i a xi ti %i" |
224 | 224 | #: comicadapter.py:70 |
225 | 225 | msgid "No readable images were found" |
226 | 226 | msgstr "" |
227 | ||
228 | #, python-format | |
229 | #~ msgid "Page %d" | |
230 | #~ msgstr "Էջ %d" | |
231 | ||
232 | #, python-format | |
233 | #~ msgid "Page %(current)i of %(total_pages)i" | |
234 | #~ msgstr "Էջ %(current)i of %(total_pages)i" | |
235 | ||
236 | #~ msgid "%" | |
237 | #~ msgstr "%" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
224 | 232 | #: comicadapter.py:70 |
225 | 233 | msgid "No readable images were found" |
226 | 234 | msgstr "Tidak ditemukan citra yang dapat dibaca" |
235 | ||
236 | #, python-format | |
237 | #~ msgid "Page %d" | |
238 | #~ msgstr "Halaman %d" | |
239 | ||
240 | #, python-format | |
241 | #~ msgid "Page %(current)i of %(total_pages)i" | |
242 | #~ msgstr "Halaman %(current)i dari %(total_pages)i" | |
243 | ||
244 | #~ msgid "%" | |
245 | #~ msgstr "%" | |
246 | ||
247 | #~ msgid "Choose document" | |
248 | #~ msgstr "Pilih dokumen" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
224 | 232 | #: comicadapter.py:70 |
225 | 233 | msgid "No readable images were found" |
226 | 234 | msgstr "Engar læsilegar myndir fundust" |
235 | ||
236 | #, python-format | |
237 | #~ msgid "Page %d" | |
238 | #~ msgstr "Síða %d" | |
239 | ||
240 | #~ msgid "%" | |
241 | #~ msgstr "%" | |
242 | ||
243 | #~ msgid "Edit" | |
244 | #~ msgstr "Breyta" | |
245 | ||
246 | #~ msgid "View" | |
247 | #~ msgstr "Sýna" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
225 | 233 | #: comicadapter.py:70 |
226 | 234 | msgid "No readable images were found" |
227 | 235 | msgstr "" |
236 | ||
237 | #, python-format | |
238 | #~ msgid "Page %d" | |
239 | #~ msgstr "Pagina %d" | |
240 | ||
241 | #, python-format | |
242 | #~ msgid "Page %(current)i of %(total_pages)i" | |
243 | #~ msgstr "Pagina %(current)i di %(total_pages)i" | |
244 | ||
245 | #~ msgid "%" | |
246 | #~ msgstr "%" | |
247 | ||
248 | #~ msgid "pitch adjusted" | |
249 | #~ msgstr "Regolazione altezza" | |
250 | ||
251 | #~ msgid "rate adjusted" | |
252 | #~ msgstr "Regolazione della frequenza" | |
253 | ||
254 | #~ msgid "Choose document" | |
255 | #~ msgstr "Scegli documento" | |
256 | ||
257 | #, python-format | |
258 | #~ msgid "Page %i of %i" | |
259 | #~ msgstr "Pagina %i di %i" | |
260 | ||
261 | #~ msgid "Edit" | |
262 | #~ msgstr "Modifica" | |
263 | ||
264 | #~ msgid "View" | |
265 | #~ msgstr "Vista" | |
266 | ||
267 | #, fuzzy | |
268 | #~ msgid "Read Activity" | |
269 | #~ msgstr "Attività di lettura" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
222 | 230 | #: comicadapter.py:70 |
223 | 231 | msgid "No readable images were found" |
224 | 232 | msgstr "" |
233 | ||
234 | #, python-format | |
235 | #~ msgid "Page %(current)i of %(total_pages)i" | |
236 | #~ msgstr "ページ %(current)i / %(total_pages)i" | |
237 | ||
238 | #~ msgid "%" | |
239 | #~ msgstr "%" | |
240 | ||
241 | #~ msgid "pitch adjusted" | |
242 | #~ msgstr "ピッチを調整しました" | |
243 | ||
244 | #~ msgid "rate adjusted" | |
245 | #~ msgstr "レートを調整しました" | |
246 | ||
247 | #~ msgid "Choose document" | |
248 | #~ msgstr "文書を選ぶ" | |
249 | ||
250 | #, python-format | |
251 | #~ msgid "Page %i of %i" | |
252 | #~ msgstr "ページ %i/%i" | |
253 | ||
254 | #~ msgid "Edit" | |
255 | #~ msgstr "編集" | |
256 | ||
257 | #~ msgid "View" | |
258 | #~ msgstr "ビュー" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | msgid "" | |
5 | msgstr "" | |
6 | "Project-Id-Version: PACKAGE VERSION\n" | |
7 | "Report-Msgid-Bugs-To: \n" | |
8 | "POT-Creation-Date: 2017-03-24 17:39+1100\n" | |
9 | "PO-Revision-Date: 2017-06-10 11:29+0000\n" | |
10 | "Last-Translator: belkacem77 <belkacem77@gmail.com>\n" | |
11 | "Language-Team: LANGUAGE <LL@li.org>\n" | |
12 | "Language: kab\n" | |
13 | "MIME-Version: 1.0\n" | |
14 | "Content-Type: text/plain; charset=UTF-8\n" | |
15 | "Content-Transfer-Encoding: 8bit\n" | |
16 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" | |
17 | "X-Generator: Pootle 2.5.1.1\n" | |
18 | "X-POOTLE-MTIME: 1497094194.000000\n" | |
19 | ||
20 | #: activity/activity.info:2 | |
21 | msgid "Read" | |
22 | msgstr "Ɣer" | |
23 | ||
24 | #: activity/activity.info:3 | |
25 | msgid "" | |
26 | "Use this activity when you are ready to read! Remember to flip your computer " | |
27 | "around to feel like you are really holding a book!" | |
28 | msgstr "" | |
29 | "Seqdec armud-agi ticki theggaḍ i tɣuri! Mekti-d ad terreḍ aselkim deg idis " | |
30 | "akken ad tɣileḍ teṭṭfeḍ adlis!" | |
31 | ||
32 | #: readdialog.py:52 | |
33 | msgid "Cancel" | |
34 | msgstr "Sefsex" | |
35 | ||
36 | #: readdialog.py:58 | |
37 | msgid "Ok" | |
38 | msgstr "Ih" | |
39 | ||
40 | #: readdialog.py:120 | |
41 | msgid "<b>Title</b>:" | |
42 | msgstr "<b>Azwel</b> :" | |
43 | ||
44 | #: readdialog.py:147 | |
45 | msgid "<b>Author</b>:" | |
46 | msgstr "<b>Ameskar</b> :" | |
47 | ||
48 | #: readdialog.py:163 | |
49 | msgid "<b>Details</b>:" | |
50 | msgstr "<b>Talqayt</b> :" | |
51 | ||
52 | #: evinceadapter.py:92 | |
53 | msgid "URL from Read" | |
54 | msgstr "Tansa URL seg Ɣer" | |
55 | ||
56 | #: speechtoolbar.py:57 | |
57 | msgid "Play / Pause" | |
58 | msgstr "Urar/ Rǧu" | |
59 | ||
60 | #: speechtoolbar.py:65 | |
61 | msgid "Stop" | |
62 | msgstr "Seḥbes" | |
63 | ||
64 | #: readactivity.py:379 | |
65 | msgid "Please wait" | |
66 | msgstr "Rǧu ma ulac aɣilif" | |
67 | ||
68 | #: readactivity.py:380 | |
69 | msgid "Starting connection..." | |
70 | msgstr "Tuqqna tetteddu..." | |
71 | ||
72 | #: readactivity.py:388 | |
73 | msgid "No book" | |
74 | msgstr "Ulac adlis" | |
75 | ||
76 | #: readactivity.py:388 | |
77 | msgid "Choose something to read" | |
78 | msgstr "Fren ayen ara d-iniḍ" | |
79 | ||
80 | #: readactivity.py:393 | |
81 | msgid "Back" | |
82 | msgstr "Ar deffir" | |
83 | ||
84 | #: readactivity.py:397 | |
85 | msgid "Previous page" | |
86 | msgstr "Asebter yezrin" | |
87 | ||
88 | #: readactivity.py:399 | |
89 | msgid "Previous bookmark" | |
90 | msgstr "" | |
91 | ||
92 | #: readactivity.py:411 | |
93 | msgid "Forward" | |
94 | msgstr "" | |
95 | ||
96 | #: readactivity.py:415 | |
97 | msgid "Next page" | |
98 | msgstr "" | |
99 | ||
100 | #: readactivity.py:417 | |
101 | msgid "Next bookmark" | |
102 | msgstr "" | |
103 | ||
104 | #: readactivity.py:468 | |
105 | msgid "Index" | |
106 | msgstr "" | |
107 | ||
108 | #: readactivity.py:564 | |
109 | msgid "Delete bookmark" | |
110 | msgstr "" | |
111 | ||
112 | #: readactivity.py:565 | |
113 | msgid "All the information related with this bookmark will be lost" | |
114 | msgstr "" | |
115 | ||
116 | #: readactivity.py:954 | |
117 | msgid "Receiving book..." | |
118 | msgstr "" | |
119 | ||
120 | #: readactivity.py:1032 readactivity.py:1227 | |
121 | #, python-format | |
122 | msgid "%s (Page %d)" | |
123 | msgstr "" | |
124 | ||
125 | #: readtoolbar.py:61 | |
126 | msgid "Previous" | |
127 | msgstr "" | |
128 | ||
129 | #: readtoolbar.py:68 | |
130 | msgid "Next" | |
131 | msgstr "" | |
132 | ||
133 | #: readtoolbar.py:79 | |
134 | msgid "Highlight" | |
135 | msgstr "" | |
136 | ||
137 | #: readtoolbar.py:160 | |
138 | msgid "Find first" | |
139 | msgstr "" | |
140 | ||
141 | #: readtoolbar.py:166 | |
142 | msgid "Find previous" | |
143 | msgstr "" | |
144 | ||
145 | #: readtoolbar.py:168 | |
146 | msgid "Find next" | |
147 | msgstr "" | |
148 | ||
149 | #: readtoolbar.py:188 | |
150 | msgid "Table of contents" | |
151 | msgstr "" | |
152 | ||
153 | #: readtoolbar.py:197 | |
154 | msgid "Zoom out" | |
155 | msgstr "" | |
156 | ||
157 | #: readtoolbar.py:203 | |
158 | msgid "Zoom in" | |
159 | msgstr "" | |
160 | ||
161 | #: readtoolbar.py:209 | |
162 | msgid "Zoom to width" | |
163 | msgstr "" | |
164 | ||
165 | #: readtoolbar.py:215 | |
166 | msgid "Zoom to fit" | |
167 | msgstr "" | |
168 | ||
169 | #: readtoolbar.py:221 | |
170 | msgid "Actual size" | |
171 | msgstr "" | |
172 | ||
173 | #: readtoolbar.py:232 | |
174 | msgid "Fullscreen" | |
175 | msgstr "" | |
176 | ||
177 | #: readtoolbar.py:252 | |
178 | msgid "Rotate left" | |
179 | msgstr "" | |
180 | ||
181 | #: readtoolbar.py:258 | |
182 | msgid "Rotate right" | |
183 | msgstr "" | |
184 | ||
185 | #: readtoolbar.py:324 | |
186 | msgid "Show Tray" | |
187 | msgstr "" | |
188 | ||
189 | #: readtoolbar.py:326 | |
190 | msgid "Hide Tray" | |
191 | msgstr "" | |
192 | ||
193 | #: linkbutton.py:133 | |
194 | msgid "Go to Bookmark" | |
195 | msgstr "" | |
196 | ||
197 | #: linkbutton.py:139 | |
198 | msgid "Remove" | |
199 | msgstr "" | |
200 | ||
201 | #: bookmarkview.py:107 | |
202 | #, python-format | |
203 | msgid "Bookmark added by %(user)s %(time)s" | |
204 | msgstr "" | |
205 | ||
206 | #: bookmarkview.py:143 bookmarkview.py:192 | |
207 | msgid "Add notes for bookmark: " | |
208 | msgstr "" | |
209 | ||
210 | #: bookmarkview.py:188 | |
211 | #, python-format | |
212 | msgid "%s's bookmark" | |
213 | msgstr "" | |
214 | ||
215 | #: bookmarkview.py:189 | |
216 | #, python-format | |
217 | msgid "Bookmark for page %d" | |
218 | msgstr "" | |
219 | ||
220 | #: comicadapter.py:69 | |
221 | msgid "Can not read Comic Book Archive" | |
222 | msgstr "" | |
223 | ||
224 | #: comicadapter.py:70 | |
225 | msgid "No readable images were found" | |
226 | msgstr "" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
222 | 230 | #: comicadapter.py:70 |
223 | 231 | msgid "No readable images were found" |
224 | 232 | msgstr "" |
233 | ||
234 | #~ msgid "%" | |
235 | #~ msgstr "%" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
221 | 229 | #: comicadapter.py:70 |
222 | 230 | msgid "No readable images were found" |
223 | 231 | msgstr "" |
232 | ||
233 | #~ msgid "%" | |
234 | #~ msgstr "%" | |
235 | ||
236 | #~ msgid "Choose document" | |
237 | #~ msgstr "문서 고르기" | |
238 | ||
239 | #~ msgid "Edit" | |
240 | #~ msgstr "편집" | |
241 | ||
242 | #~ msgid "View" | |
243 | #~ msgstr "보기" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
222 | 230 | #: comicadapter.py:70 |
223 | 231 | msgid "No readable images were found" |
224 | 232 | msgstr "" |
233 | ||
234 | #~ msgid "%" | |
235 | #~ msgstr "%" | |
236 | ||
237 | #~ msgid "Choose document" | |
238 | #~ msgstr "Mifidiana tahirin-kevitra" | |
239 | ||
240 | #, python-format | |
241 | #~ msgid "Page %i of %i" | |
242 | #~ msgstr "Pejy %i amin'ny %i" | |
243 | ||
244 | #~ msgid "Edit" | |
245 | #~ msgstr "Amboary" | |
246 | ||
247 | #~ msgid "View" | |
248 | #~ msgstr "jereo" |
223 | 223 | #: comicadapter.py:70 |
224 | 224 | msgid "No readable images were found" |
225 | 225 | msgstr "" |
226 | ||
227 | #, python-format | |
228 | #~ msgid "Page %(current)i of %(total_pages)i" | |
229 | #~ msgstr "Whārangi %(current)i o %(total_pages)i" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # translation of mk.po to Macedonian |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
220 | 228 | #: comicadapter.py:70 |
221 | 229 | msgid "No readable images were found" |
222 | 230 | msgstr "" |
231 | ||
232 | #~ msgid "%" | |
233 | #~ msgstr "%" | |
234 | ||
235 | #~ msgid "Edit" | |
236 | #~ msgstr "Уреди" | |
237 | ||
238 | #~ msgid "View" | |
239 | #~ msgstr "Поглед" | |
240 | ||
241 | #~ msgid "Read Activity" | |
242 | #~ msgstr "Активност за читање" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
8 | # SOME DESCRIPTIVE TITLE. | |
9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
10 | # This file is distributed under the same license as the PACKAGE package. | |
11 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
12 | # SOME DESCRIPTIVE TITLE. | |
13 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
14 | # This file is distributed under the same license as the PACKAGE package. | |
15 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
16 | # SOME DESCRIPTIVE TITLE. | |
17 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
18 | # This file is distributed under the same license as the PACKAGE package. | |
19 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 20 | # SOME DESCRIPTIVE TITLE. |
1 | 21 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 22 | # This file is distributed under the same license as the PACKAGE package. |
221 | 241 | #: comicadapter.py:70 |
222 | 242 | msgid "No readable images were found" |
223 | 243 | msgstr "" |
244 | ||
245 | #~ msgid "%" | |
246 | #~ msgstr "%" | |
247 | ||
248 | #~ msgid "Choose document" | |
249 | #~ msgstr "Баримт сонгох" | |
250 | ||
251 | #, python-format | |
252 | #~ msgid "Page %i of %i" | |
253 | #~ msgstr "%i-н %i-р хуудас" | |
254 | ||
255 | #~ msgid "Edit" | |
256 | #~ msgstr "Засварлах" | |
257 | ||
258 | #~ msgid "View" | |
259 | #~ msgstr "Харах" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
220 | 228 | #: comicadapter.py:70 |
221 | 229 | msgid "No readable images were found" |
222 | 230 | msgstr "" |
231 | ||
232 | #~ msgid "%" | |
233 | #~ msgstr "%" | |
234 | ||
235 | #~ msgid "Edit" | |
236 | #~ msgstr "संपादन करणे" | |
237 | ||
238 | #~ msgid "View" | |
239 | #~ msgstr "पाहा" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
226 | 234 | #: comicadapter.py:70 |
227 | 235 | msgid "No readable images were found" |
228 | 236 | msgstr "" |
237 | ||
238 | #, python-format | |
239 | #~ msgid "Page %d" | |
240 | #~ msgstr "पृष्ठ %d" | |
241 | ||
242 | #, python-format | |
243 | #~ msgid "Page %(current)i of %(total_pages)i" | |
244 | #~ msgstr "%(total_pages)i को पृष्ठ %(current)i" | |
245 | ||
246 | #~ msgid "%" | |
247 | #~ msgstr "%" | |
248 | ||
249 | #~ msgid "pitch adjusted" | |
250 | #~ msgstr "पिच समायोजन गरिसक्यो" | |
251 | ||
252 | #~ msgid "rate adjusted" | |
253 | #~ msgstr "दर समायोजन गरिसक्यो" | |
254 | ||
255 | #~ msgid "Choose document" | |
256 | #~ msgstr "कागतपत्र छान" | |
257 | ||
258 | #, python-format, | |
259 | #~ msgid "Page %i of %i" | |
260 | #~ msgstr "%iको %i पाना" | |
261 | ||
262 | #~ msgid "Edit" | |
263 | #~ msgstr "सम्पादन" | |
264 | ||
265 | #~ msgid "View" | |
266 | #~ msgstr "दृश्य" | |
267 | ||
268 | #~ msgid "Read Activity" | |
269 | #~ msgstr "पढाई क्रियाकलाप " |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
8 | # SOME DESCRIPTIVE TITLE. | |
9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
10 | # This file is distributed under the same license as the PACKAGE package. | |
11 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 12 | # SOME DESCRIPTIVE TITLE. |
1 | 13 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 14 | # This file is distributed under the same license as the PACKAGE package. |
225 | 237 | #: comicadapter.py:70 |
226 | 238 | msgid "No readable images were found" |
227 | 239 | msgstr "Geen leesbare afbeeldingen gevonden" |
240 | ||
241 | #, python-format | |
242 | #~ msgid "Page %d" | |
243 | #~ msgstr "Pagina %d" | |
244 | ||
245 | #, python-format | |
246 | #~ msgid "Page %(current)i of %(total_pages)i" | |
247 | #~ msgstr "Pagina %(current)i van %(total_pages)i" | |
248 | ||
249 | #~ msgid "%" | |
250 | #~ msgstr "%" | |
251 | ||
252 | #~ msgid "pitch adjusted" | |
253 | #~ msgstr "toonhoogte aangepast" | |
254 | ||
255 | #~ msgid "rate adjusted" | |
256 | #~ msgstr "frequentie aangepast" | |
257 | ||
258 | #~ msgid "Choose document" | |
259 | #~ msgstr "Kies document" | |
260 | ||
261 | #, python-format | |
262 | #~ msgid "Page %i of %i" | |
263 | #~ msgstr "Pagina %i van %i" | |
264 | ||
265 | #~ msgid "Edit" | |
266 | #~ msgstr "Bewerken" | |
267 | ||
268 | #~ msgid "View" | |
269 | #~ msgstr "Beeld" | |
270 | ||
271 | #~ msgid "Read Activity" | |
272 | #~ msgstr "Lezen Activiteit" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # SOME DESCRIPTIVE TITLE. | |
4 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
5 | # This file is distributed under the same license as the PACKAGE package. | |
0 | 6 | # SOME DESCRIPTIVE TITLE. |
1 | 7 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 8 | # This file is distributed under the same license as the PACKAGE package. |
224 | 230 | #: comicadapter.py:70 |
225 | 231 | msgid "No readable images were found" |
226 | 232 | msgstr "" |
233 | ||
234 | #, python-format | |
235 | #~ msgid "Page %d" | |
236 | #~ msgstr "Página %d" | |
237 | ||
238 | #~ msgid "%" | |
239 | #~ msgstr "%" | |
240 | ||
241 | #~ msgid "Choose document" | |
242 | #~ msgstr "Skohe dokumento" | |
243 | ||
244 | # TRANS: Tradusi e saki komo página i di m (pe: Pagina 4 di 334) | |
245 | #, python-format | |
246 | #~ msgid "Page %i of %i" | |
247 | #~ msgstr "Pagina %iof%i" | |
248 | ||
249 | #~ msgid "Edit" | |
250 | #~ msgstr "Edita" | |
251 | ||
252 | #~ msgid "View" | |
253 | #~ msgstr "Mira" |
222 | 222 | #: comicadapter.py:70 |
223 | 223 | msgid "No readable images were found" |
224 | 224 | msgstr "" |
225 | ||
226 | # please do not translate %(total_pages)i | |
227 | #, python-format | |
228 | #, python-format, | |
229 | #, python-format, , | |
230 | #~ msgid "Page %(current)i of %(total_pages)i" | |
231 | #~ msgstr "Ne nixií %(current)i de %(total_pages)i" | |
232 | ||
233 | #~ msgid "%" | |
234 | #~ msgstr "%" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
225 | 233 | #: comicadapter.py:70 |
226 | 234 | msgid "No readable images were found" |
227 | 235 | msgstr "" |
236 | ||
237 | #, python-format | |
238 | #~ msgid "Page %d" | |
239 | #~ msgstr "Strona %d" | |
240 | ||
241 | #, python-format | |
242 | #~ msgid "Page %(current)i of %(total_pages)i" | |
243 | #~ msgstr "Strona %(current)i z %(total_pages)i" | |
244 | ||
245 | #~ msgid "%" | |
246 | #~ msgstr "%" | |
247 | ||
248 | #~ msgid "pitch adjusted" | |
249 | #~ msgstr "wysokość ustawiona" | |
250 | ||
251 | #~ msgid "rate adjusted" | |
252 | #~ msgstr "częstotliwość ustawiona" | |
253 | ||
254 | #~ msgid "Choose document" | |
255 | #~ msgstr "Wybierz plik" | |
256 | ||
257 | #, python-format | |
258 | #~ msgid "Page %i of %i" | |
259 | #~ msgstr "Strona %i z %i" | |
260 | ||
261 | #~ msgid "Edit" | |
262 | #~ msgstr "Edytuj" | |
263 | ||
264 | #~ msgid "View" | |
265 | #~ msgstr "Widok" | |
266 | ||
267 | #, fuzzy | |
268 | #~ msgid "Read Activity" | |
269 | #~ msgstr "Czytanka" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
222 | 230 | #: comicadapter.py:70 |
223 | 231 | msgid "No readable images were found" |
224 | 232 | msgstr "" |
233 | ||
234 | #~ msgid "%" | |
235 | #~ msgstr "%" | |
236 | ||
237 | #~ msgid "Choose document" | |
238 | #~ msgstr "لاسوند غوره کړئ" | |
239 | ||
240 | #~ msgid "Edit" | |
241 | #~ msgstr "سمون" | |
242 | ||
243 | #~ msgid "View" | |
244 | #~ msgstr "ليد" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # Portuguese translations for PACKAGE package. |
1 | 9 | # Copyright (C) 2007 THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
223 | 231 | #: comicadapter.py:70 |
224 | 232 | msgid "No readable images were found" |
225 | 233 | msgstr "" |
234 | ||
235 | #, python-format | |
236 | #~ msgid "Page %d" | |
237 | #~ msgstr "Página %d" | |
238 | ||
239 | #, python-format | |
240 | #~ msgid "Page %(current)i of %(total_pages)i" | |
241 | #~ msgstr "Página %(current)i de %(total_pages)i" | |
242 | ||
243 | #~ msgid "%" | |
244 | #~ msgstr "%" | |
245 | ||
246 | #~ msgid "pitch adjusted" | |
247 | #~ msgstr "altura ajustada" | |
248 | ||
249 | #~ msgid "rate adjusted" | |
250 | #~ msgstr "velocidade ajustada" | |
251 | ||
252 | #~ msgid "Choose document" | |
253 | #~ msgstr "Escolhe o documento" | |
254 | ||
255 | #, python-format | |
256 | #~ msgid "Page %i of %i" | |
257 | #~ msgstr "Página %i de %i" | |
258 | ||
259 | #~ msgid "Edit" | |
260 | #~ msgstr "Editar" | |
261 | ||
262 | #~ msgid "View" | |
263 | #~ msgstr "Ver" | |
264 | ||
265 | #~ msgid "Read Activity" | |
266 | #~ msgstr "Actividade Ler" | |
267 | ||
268 | #~ msgid "Open a document to read" | |
269 | #~ msgstr "Abrir um documento para o ler" | |
270 | ||
271 | #~ msgid "All supported formats" | |
272 | #~ msgstr "Todos os formatos suportados" | |
273 | ||
274 | #~ msgid "All files" | |
275 | #~ msgstr "Todos os ficheiros" | |
276 | ||
277 | #~ msgid "Open" | |
278 | #~ msgstr "Abrir" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # translation of pt_BR.po to Brazilian Portuguese |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
6 | 14 | "Project-Id-Version: pt_BR\n" |
7 | 15 | "Report-Msgid-Bugs-To: \n" |
8 | 16 | "POT-Creation-Date: 2017-03-24 17:39+1100\n" |
9 | "PO-Revision-Date: 2015-01-30 16:52+0000\n" | |
10 | "Last-Translator: Felipe <fefcas@gmail.com>\n" | |
17 | "PO-Revision-Date: 2017-06-14 21:01+0000\n" | |
18 | "Last-Translator: Mariana <dias.inkscape@gmail.com>\n" | |
11 | 19 | "Language-Team: Brazilian Portuguese <fedora-docs-br@redhat.com>\n" |
12 | 20 | "Language: pt_BR\n" |
13 | 21 | "MIME-Version: 1.0\n" |
15 | 23 | "Content-Transfer-Encoding: 8bit\n" |
16 | 24 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" |
17 | 25 | "X-Generator: Pootle 2.5.1.1\n" |
18 | "X-POOTLE-MTIME: 1422636737.000000\n" | |
26 | "X-POOTLE-MTIME: 1497474090.000000\n" | |
19 | 27 | |
20 | 28 | #: activity/activity.info:2 |
21 | 29 | msgid "Read" |
44 | 52 | |
45 | 53 | #: readdialog.py:147 |
46 | 54 | msgid "<b>Author</b>:" |
47 | msgstr "" | |
55 | msgstr "<b>Autor</b>:" | |
48 | 56 | |
49 | 57 | #: readdialog.py:163 |
50 | 58 | msgid "<b>Details</b>:" |
64 | 72 | |
65 | 73 | #: readactivity.py:379 |
66 | 74 | msgid "Please wait" |
67 | msgstr "" | |
75 | msgstr "Por favor aguarde" | |
68 | 76 | |
69 | 77 | #: readactivity.py:380 |
70 | 78 | msgid "Starting connection..." |
71 | msgstr "" | |
79 | msgstr "Iniciando conexão..." | |
72 | 80 | |
73 | 81 | #: readactivity.py:388 |
74 | 82 | msgid "No book" |
116 | 124 | |
117 | 125 | #: readactivity.py:954 |
118 | 126 | msgid "Receiving book..." |
119 | msgstr "" | |
127 | msgstr "Recebendo livro..." | |
120 | 128 | |
121 | 129 | #: readactivity.py:1032 readactivity.py:1227 |
122 | 130 | #, python-format |
123 | 131 | msgid "%s (Page %d)" |
124 | msgstr "" | |
132 | msgstr "%s (Página %d)" | |
125 | 133 | |
126 | 134 | #: readtoolbar.py:61 |
127 | 135 | msgid "Previous" |
178 | 186 | |
179 | 187 | #: readtoolbar.py:252 |
180 | 188 | msgid "Rotate left" |
181 | msgstr "" | |
189 | msgstr "Girar para a esquerda" | |
182 | 190 | |
183 | 191 | #: readtoolbar.py:258 |
184 | 192 | msgid "Rotate right" |
185 | msgstr "" | |
193 | msgstr "Girar para a direira" | |
186 | 194 | |
187 | 195 | #: readtoolbar.py:324 |
188 | 196 | msgid "Show Tray" |
221 | 229 | |
222 | 230 | #: comicadapter.py:69 |
223 | 231 | msgid "Can not read Comic Book Archive" |
224 | msgstr "" | |
232 | msgstr "Não é possível ler o Arquivo de Histórias em Quadrinhos" | |
225 | 233 | |
226 | 234 | #: comicadapter.py:70 |
227 | 235 | msgid "No readable images were found" |
228 | msgstr "" | |
236 | msgstr "Nenhuma imagem legível foi encontrada" | |
237 | ||
238 | #, python-format | |
239 | #~ msgid "Page %d" | |
240 | #~ msgstr "Página %d" | |
241 | ||
242 | # só o argumento % qual seria o contexto desse caracter? | |
243 | #~ msgid "%" | |
244 | #~ msgstr "%" | |
245 | ||
246 | #~ msgid "Choose document" | |
247 | #~ msgstr "Escolha o documento" | |
248 | ||
249 | #, python-format | |
250 | #~ msgid "Page %i of %i" | |
251 | #~ msgstr "Página %i de %i" | |
252 | ||
253 | #~ msgid "Edit" | |
254 | #~ msgstr "Editar" | |
255 | ||
256 | #~ msgid "View" | |
257 | #~ msgstr "Ver" | |
258 | ||
259 | #~ msgid "Read Activity" | |
260 | #~ msgstr "Ler a Atividade" |
264 | 264 | #: comicadapter.py:70 |
265 | 265 | msgid "No readable images were found" |
266 | 266 | msgstr "" |
267 | ||
268 | #, python-format | |
269 | #~ msgid "Page %d" | |
270 | #~ msgstr "Raphi %d" | |
271 | ||
272 | # "Página %(current)i de %(total_pages)i" | |
273 | #, python-format | |
274 | #~ msgid "Page %(current)i of %(total_pages)i" | |
275 | #~ msgstr "Llapan %(total_pages)i nisqamanta %(current)i kay raphi" | |
276 | ||
277 | # "%" | |
278 | #~ msgid "%" | |
279 | #~ msgstr "%" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
220 | 228 | #: comicadapter.py:70 |
221 | 229 | msgid "No readable images were found" |
222 | 230 | msgstr "" |
231 | ||
232 | #~ msgid "%" | |
233 | #~ msgstr "%" | |
234 | ||
235 | #~ msgid "Edit" | |
236 | #~ msgstr "Modifică" | |
237 | ||
238 | #~ msgid "View" | |
239 | #~ msgstr "Vizualizare" | |
240 | ||
241 | #~ msgid "Read Activity" | |
242 | #~ msgstr "Activitate de citire" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
225 | 233 | #: comicadapter.py:70 |
226 | 234 | msgid "No readable images were found" |
227 | 235 | msgstr "" |
236 | ||
237 | #, python-format | |
238 | #~ msgid "Page %d" | |
239 | #~ msgstr "Страница %d" | |
240 | ||
241 | #~ msgid "%" | |
242 | #~ msgstr "%" | |
243 | ||
244 | #~ msgid "Choose document" | |
245 | #~ msgstr "Выбрать документ" | |
246 | ||
247 | #, python-format | |
248 | #~ msgid "Page %i of %i" | |
249 | #~ msgstr "Страница %i из %i" | |
250 | ||
251 | #~ msgid "Edit" | |
252 | #~ msgstr "Редактировать" | |
253 | ||
254 | #~ msgid "View" | |
255 | #~ msgstr "Просмотреть" | |
256 | ||
257 | #~ msgid "Read Activity" | |
258 | #~ msgstr "Активность Чтение" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
228 | 236 | #: comicadapter.py:70 |
229 | 237 | msgid "No readable images were found" |
230 | 238 | msgstr "" |
239 | ||
240 | #~ msgid "%" | |
241 | #~ msgstr "%" | |
242 | ||
243 | #~ msgid "Edit" | |
244 | #~ msgstr "Hindura" | |
245 | ||
246 | #~ msgid "View" | |
247 | #~ msgstr "Irebero" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
220 | 228 | #: comicadapter.py:70 |
221 | 229 | msgid "No readable images were found" |
222 | 230 | msgstr "" |
231 | ||
232 | #~ msgid "Edit" | |
233 | #~ msgstr "edit" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
221 | 229 | #: comicadapter.py:70 |
222 | 230 | msgid "No readable images were found" |
223 | 231 | msgstr "" |
232 | ||
233 | #, python-format | |
234 | #~ msgid "Page %(current)i of %(total_pages)i" | |
235 | #~ msgstr "%(total_pages)i කින් %(current)i පිටුව" | |
236 | ||
237 | #~ msgid "%" | |
238 | #~ msgstr "%" | |
239 | ||
240 | #~ msgid "pitch adjusted" | |
241 | #~ msgstr "තාරතාව සීරු මාරු කරන ලදි" | |
242 | ||
243 | #~ msgid "rate adjusted" | |
244 | #~ msgstr "සීඝ්රතාව සීරු මාරු කරන ලදි" | |
245 | ||
246 | #~ msgid "Choose document" | |
247 | #~ msgstr "ලිපි ගොනුව තෝරන්න" | |
248 | ||
249 | #~ msgid "Edit" | |
250 | #~ msgstr "සංස්කරණය කරන්න" | |
251 | ||
252 | #~ msgid "View" | |
253 | #~ msgstr "දර්ශනය කරන්න" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
224 | 232 | #: comicadapter.py:70 |
225 | 233 | msgid "No readable images were found" |
226 | 234 | msgstr "" |
235 | ||
236 | #~ msgid "%" | |
237 | #~ msgstr "%" | |
238 | ||
239 | #~ msgid "Edit" | |
240 | #~ msgstr "Upraviť" | |
241 | ||
242 | #~ msgid "View" | |
243 | #~ msgstr "Zobraziť" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
222 | 230 | #: comicadapter.py:70 |
223 | 231 | msgid "No readable images were found" |
224 | 232 | msgstr "" |
233 | ||
234 | #, python-format | |
235 | #~ msgid "Page %(current)i of %(total_pages)i" | |
236 | #~ msgstr "Stran %(current)i od skupno %(total_pages)i" | |
237 | ||
238 | #~ msgid "%" | |
239 | #~ msgstr "%" | |
240 | ||
241 | #~ msgid "pitch adjusted" | |
242 | #~ msgstr "prilagojena višina govora" | |
243 | ||
244 | #~ msgid "rate adjusted" | |
245 | #~ msgstr "prilagojena hitrost govora" | |
246 | ||
247 | #~ msgid "Choose document" | |
248 | #~ msgstr "Izberi dokument" | |
249 | ||
250 | #~ msgid "Edit" | |
251 | #~ msgstr "Urejanje" | |
252 | ||
253 | #~ msgid "View" | |
254 | #~ msgstr "Pogled" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
225 | 233 | #: comicadapter.py:70 |
226 | 234 | msgid "No readable images were found" |
227 | 235 | msgstr "" |
236 | ||
237 | #, python-format | |
238 | #~ msgid "Page %d" | |
239 | #~ msgstr "Faqja %d" | |
240 | ||
241 | #~ msgid "%" | |
242 | #~ msgstr "%" | |
243 | ||
244 | #~ msgid "Choose document" | |
245 | #~ msgstr "Zgjidhe dokumentin" | |
246 | ||
247 | #, python-format | |
248 | #~ msgid "Page %i of %i" | |
249 | #~ msgstr "Faqe %i e %i" | |
250 | ||
251 | #~ msgid "Edit" | |
252 | #~ msgstr "Ndrysho" | |
253 | ||
254 | #~ msgid "View" | |
255 | #~ msgstr "Shikim" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
224 | 232 | #: comicadapter.py:70 |
225 | 233 | msgid "No readable images were found" |
226 | 234 | msgstr "Inga läsbara bilder hittades" |
235 | ||
236 | #~ msgid "%" | |
237 | #~ msgstr "%" | |
238 | ||
239 | #~ msgid "Choose document" | |
240 | #~ msgstr "Välj dokument" | |
241 | ||
242 | #, python-format | |
243 | #~ msgid "Page %i of %i" | |
244 | #~ msgstr "Sida %i av %i" | |
245 | ||
246 | #~ msgid "Edit" | |
247 | #~ msgstr "Redigera" | |
248 | ||
249 | #~ msgid "View" | |
250 | #~ msgstr "Visa" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
221 | 229 | #: comicadapter.py:70 |
222 | 230 | msgid "No readable images were found" |
223 | 231 | msgstr "" |
232 | ||
233 | #~ msgid "%" | |
234 | #~ msgstr "%" | |
235 | ||
236 | #~ msgid "Choose document" | |
237 | #~ msgstr "Kuchagua hati" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
222 | 230 | #: comicadapter.py:70 |
223 | 231 | msgid "No readable images were found" |
224 | 232 | msgstr "" |
233 | ||
234 | #, python-format | |
235 | #~ msgid "Page %(current)i of %(total_pages)i" | |
236 | #~ msgstr "பக்கம் %(current)i யின் %(total_pages)i" | |
237 | ||
238 | #~ msgid "%" | |
239 | #~ msgstr "%" | |
240 | ||
241 | #~ msgid "pitch adjusted" | |
242 | #~ msgstr "சுருதி சரிபார்க்கப்பட்டது" | |
243 | ||
244 | #~ msgid "rate adjusted" | |
245 | #~ msgstr "விகிதம் சரிபார்க்கப்பட்டது" | |
246 | ||
247 | #~ msgid "Choose document" | |
248 | #~ msgstr "ஆவணத்தை தெரிவுசெய்" | |
249 | ||
250 | #, python-format, | |
251 | #~ msgid "Page %i of %i" | |
252 | #~ msgstr "%i பக்கத்துக்கு %i" | |
253 | ||
254 | #~ msgid "Edit" | |
255 | #~ msgstr "திருத்து" | |
256 | ||
257 | #~ msgid "View" | |
258 | #~ msgstr "பார்வையிடு" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
222 | 230 | #: comicadapter.py:70 |
223 | 231 | msgid "No readable images were found" |
224 | 232 | msgstr "" |
233 | ||
234 | #~ msgid "%" | |
235 | #~ msgstr "%" | |
236 | ||
237 | #~ msgid "Choose document" | |
238 | #~ msgstr "దస్తావేజును కోరుకో" | |
239 | ||
240 | #~ msgid "Edit" | |
241 | #~ msgstr "కూర్చు" | |
242 | ||
243 | #~ msgid "View" | |
244 | #~ msgstr "చూడు" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
222 | 230 | #: comicadapter.py:70 |
223 | 231 | msgid "No readable images were found" |
224 | 232 | msgstr "" |
233 | ||
234 | #, python-format | |
235 | #~ msgid "Page %(current)i of %(total_pages)i" | |
236 | #~ msgstr "หน้า %(current)i of %(total_pages)i" | |
237 | ||
238 | #~ msgid "%" | |
239 | #~ msgstr "%" | |
240 | ||
241 | #~ msgid "pitch adjusted" | |
242 | #~ msgstr "ปรับระดับเสียง" | |
243 | ||
244 | #~ msgid "rate adjusted" | |
245 | #~ msgstr "ปรับความนิยม" | |
246 | ||
247 | #~ msgid "Choose document" | |
248 | #~ msgstr "เลือกเอกสาร" | |
249 | ||
250 | #~ msgid "Edit" | |
251 | #~ msgstr "แก้ไข" | |
252 | ||
253 | #~ msgid "View" | |
254 | #~ msgstr "มุมมอง" | |
255 | ||
256 | #~ msgid "Read Activity" | |
257 | #~ msgstr "กิจกรรมอ่าน" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
222 | 230 | #: comicadapter.py:70 |
223 | 231 | msgid "No readable images were found" |
224 | 232 | msgstr "" |
233 | ||
234 | #~ msgid "%" | |
235 | #~ msgstr "%" | |
236 | ||
237 | #~ msgid "Choose document" | |
238 | #~ msgstr "belge seç" | |
239 | ||
240 | #~ msgid "Edit" | |
241 | #~ msgstr "düzenlemek" | |
242 | ||
243 | #~ msgid "View" | |
244 | #~ msgstr "görünüm" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
220 | 228 | #: comicadapter.py:70 |
221 | 229 | msgid "No readable images were found" |
222 | 230 | msgstr "" |
231 | ||
232 | #~ msgid "%" | |
233 | #~ msgstr "%" | |
234 | ||
235 | #~ msgid "Edit" | |
236 | #~ msgstr "تدوین" | |
237 | ||
238 | #~ msgid "View" | |
239 | #~ msgstr "نظارہ" | |
240 | ||
241 | #~ msgid "Read Activity" | |
242 | #~ msgstr "پرھنے کی سرگرمی" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
224 | 232 | #: comicadapter.py:70 |
225 | 233 | msgid "No readable images were found" |
226 | 234 | msgstr "" |
235 | ||
236 | #~ msgid "%" | |
237 | #~ msgstr "%" | |
238 | ||
239 | #~ msgid "Choose document" | |
240 | #~ msgstr "Chọn tài liệu" | |
241 | ||
242 | #, python-format | |
243 | #~ msgid "Page %i of %i" | |
244 | #~ msgstr "Trang %i trên %i" | |
245 | ||
246 | #~ msgid "Edit" | |
247 | #~ msgstr "Sửa" | |
248 | ||
249 | #~ msgid "View" | |
250 | #~ msgstr "Xem" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
4 | # SOME DESCRIPTIVE TITLE. | |
5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
6 | # This file is distributed under the same license as the PACKAGE package. | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 8 | # SOME DESCRIPTIVE TITLE. |
1 | 9 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 10 | # This file is distributed under the same license as the PACKAGE package. |
224 | 232 | #: comicadapter.py:70 |
225 | 233 | msgid "No readable images were found" |
226 | 234 | msgstr "" |
235 | ||
236 | #, python-format | |
237 | #~ msgid "Page %d" | |
238 | #~ msgstr "Oju-iwe %d" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 4 | # SOME DESCRIPTIVE TITLE. |
1 | 5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 6 | # This file is distributed under the same license as the PACKAGE package. |
221 | 225 | #: comicadapter.py:70 |
222 | 226 | msgid "No readable images were found" |
223 | 227 | msgstr "" |
228 | ||
229 | #, python-format | |
230 | #~ msgid "Page %d" | |
231 | #~ msgstr "%d 页" | |
232 | ||
233 | #, python-format | |
234 | #~ msgid "Page %(current)i of %(total_pages)i" | |
235 | #~ msgstr "%(current)i / %(total_pages)i" | |
236 | ||
237 | #~ msgid "%" | |
238 | #~ msgstr "%" | |
239 | ||
240 | #~ msgid "Choose document" | |
241 | #~ msgstr "选择文档" | |
242 | ||
243 | #~ msgid "Edit" | |
244 | #~ msgstr "编辑" | |
245 | ||
246 | #~ msgid "View" | |
247 | #~ msgstr "查看" |
0 | # SOME DESCRIPTIVE TITLE. | |
1 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
2 | # This file is distributed under the same license as the PACKAGE package. | |
3 | # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
0 | 4 | # SOME DESCRIPTIVE TITLE. |
1 | 5 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER |
2 | 6 | # This file is distributed under the same license as the PACKAGE package. |
222 | 226 | #: comicadapter.py:70 |
223 | 227 | msgid "No readable images were found" |
224 | 228 | msgstr "" |
229 | ||
230 | #, python-format | |
231 | #~ msgid "Page %d" | |
232 | #~ msgstr "第 %d 頁" | |
233 | ||
234 | #, python-format | |
235 | #~ msgid "Page %(current)i of %(total_pages)i" | |
236 | #~ msgstr "%(total_pages)i 頁中的第 %(current)i 頁" | |
237 | ||
238 | #~ msgid "%" | |
239 | #~ msgstr "%" | |
240 | ||
241 | #~ msgid "pitch adjusted" | |
242 | #~ msgstr "音高已調整" | |
243 | ||
244 | #~ msgid "rate adjusted" | |
245 | #~ msgstr "速度已調整" | |
246 | ||
247 | #~ msgid "Choose document" | |
248 | #~ msgstr "選擇文件" | |
249 | ||
250 | #, python-format | |
251 | #~ msgid "Page %i of %i" | |
252 | #~ msgstr "第 %i 頁 共 %i 頁" | |
253 | ||
254 | #~ msgid "Edit" | |
255 | #~ msgstr "編輯" | |
256 | ||
257 | #~ msgid "View" | |
258 | #~ msgstr "檢視" |
590 | 590 | self._view.show_highlights(page_to) |
591 | 591 | |
592 | 592 | def _update_bookmark_cb(self, sidebar): |
593 | logging.error('update bookmark event') | |
594 | 593 | self.update_bookmark_button() |
595 | 594 | |
596 | 595 | def update_bookmark_button(self): |
822 | 821 | del self.unused_download_tubes |
823 | 822 | |
824 | 823 | # Use the suggested file, the mime is not recognized if the extension |
825 | # is wrong in some cases (epub) | |
824 | # is wrong in some cases | |
826 | 825 | temp_dir = os.path.dirname(tempfile) |
827 | 826 | new_name = os.path.join(temp_dir, suggested_name) |
828 | 827 | os.rename(tempfile, new_name) |
976 | 975 | else: |
977 | 976 | mimetype = self.metadata['mime_type'] |
978 | 977 | |
979 | if mimetype == 'application/epub+zip': | |
980 | import epubadapter | |
981 | self._view = epubadapter.EpubViewer() | |
982 | elif mimetype == 'text/plain' or mimetype == 'application/zip': | |
978 | if mimetype == 'text/plain' or mimetype == 'application/zip': | |
983 | 979 | import textadapter |
984 | 980 | self._view = textadapter.TextViewer() |
985 | 981 | elif mimetype == 'application/x-cbz': |
1000 | 996 | self.filehash = self.metadata.get('filehash', None) |
1001 | 997 | if self.filehash is None: |
1002 | 998 | self.filehash = get_md5(filepath) |
1003 | logging.error('Calculate hash %s', self.filehash) | |
1004 | 999 | |
1005 | 1000 | self._bookmarkmanager = BookmarkManager(self.filehash) |
1006 | 1001 |