class MainWindow(object): def __init__(self, application): self._application = application builder = gtk.Builder() builder.add_from_file(os.path.join(self._application.cli_options.share_dir, UNIX_APPNAME, "ui", "ui.glade")) self._window = builder.get_object("main_window") self._window.add_accel_group(builder.get_object("main_accelgroup")) self._window.set_title(_(APPNAME)) self._window.set_size_request(self._application.config["UI/width"], self._application.config["UI/height"]) self._maximized = self._application.config["UI/maximized"] if self._maximized: self._window.maximize() self._webview = webkit.WebView() builder.get_object("webview_container").add(self._webview) self._webview.get_settings().set_property('enable-file-access-from-file-uris', 1) self._webview.get_settings().set_property('enable-default-context-menu', 0) self._webview.connect("script-alert", self._on_webview_script_alert) self._webview_load_finished = False self._webview_pending_commands = [] self._statusbar = builder.get_object("statusbar") self._load_main_window() self._window.connect("delete_event", self._on_window_delete_event) builder.get_object("quit_menu_item").connect("activate", self._on_quit_clicked) builder.get_object("open_book_menuitem").connect("activate", self._on_open_book_clicked) builder.get_object("save_book_menuitem").connect("activate", self._on_save_book_clicked) builder.get_object("close_book_menuitem").connect("activate", self._on_close_book_clicked) builder.get_object("about_menuitem").connect("activate", self._on_about_clicked) self._open_book_dialog = OpenBookDialog(self._application, self._window) self._about_dialog = AboutDialog(self._window) self._save_quit_dialog = SaveQuitDialog(self._window) self._image_browser_dialog = ImageBrowserDialog(self._application, self._window) self._mapped = False self._window.connect("size-allocate", self._on_size_allocate) self._window.connect("window-state-event", self._on_window_state_event) self._window.connect("map-event", self._on_map_event) def _on_map_event(self, window, event): self._mapped = True self._window.connect("size-allocate", self._on_size_allocate) self._window.connect("window-state-event", self._on_window_state_event) def _on_window_state_event(self, window, event): if self._mapped: self._maximized = (event.new_window_state & gtk.gdk.WINDOW_STATE_MAXIMIZED != 0) def _on_size_allocate(self, window, rectangle): if self._mapped: if self._maximized: self._application.config["UI/maximized"] = True else: self._application.config["UI/maximized"] = False width, height = self._window.get_size() self._application.config["UI/width"] = width self._application.config["UI/height"] = height def _check_quit(self): if self._application.book and self._application.book.changed: resp = self._save_quit_dialog.run() if resp == gtk.RESPONSE_YES: self._application.book.save() elif resp != gtk.RESPONSE_NO: return True gtk.main_quit() return False def _on_window_delete_event(self, window, event): return self._check_quit() def _on_close_book_clicked(self, menuitem): if self._application.book: if self._application.book.changed: resp = self._save_quit_dialog.run() if resp == gtk.RESPONSE_YES: self._application.book.save() elif resp != gtk.RESPONSE_NO: return self._application.unload_book() self.send_command("set_doc_structure(null)") def _on_about_clicked(self, menuitem): self._about_dialog.run() def _on_quit_clicked(self, menuitem): self._check_quit() def _on_open_book_clicked(self, menuitem): filename = self._open_book_dialog.run() if filename: if self._application.book: self._on_close_book_clicked(menuitem) if self._application.book: return self._application.load_book(filename) def _on_save_book_clicked(self, menuitem): self._application.book.save() def show_all(self): self._window.show_all() def _do_send_command(self, command): self._webview.execute_script(command) def send_command(self, command): if self._webview_load_finished: self._do_send_command(command) else: self._webview_pending_commands.append(command) def _on_webview_script_alert(self, editor, frame, message): logging.debug("_on_webview_script_alert:%s" % ":".join(message.split(":")[:2])) if ":" in message: i = message.index(":") command = message[:i] params = message[i+1:] else: command = message params = "" if command == "reload_doc_structure": if self._application.book: self.send_command("set_doc_structure(%s)" % json.dumps(self._application.book.get_structure_tree())) elif command == "editor_ready": while len(self._webview_pending_commands): command = self._webview_pending_commands[0] del self._webview_pending_commands[0] self._do_send_command(command) self._webview_load_finished = True elif command == "load_doc_section": section_id = int(params) section = self._application.book.find_section_by_id(section_id) xml = section.get_xml_text() if section.edit_mode == "html": self.send_command("set_edit_data(%s)" % json.dumps({"section_id": section_id, "edit_mode": section.edit_mode, "html": str(section.get_html()), "xml": str(xml)})) else: self.send_command("set_edit_data(%s)" % json.dumps({"section_id": section_id, "edit_mode": section.edit_mode, "xml": str(xml)})) elif command == "set_section_contents": i = params.index(":") section_id = int(params[:i]) contents = params[i+1:] section = self._application.book.find_section_by_id(section_id) parsing_error = section.update_from_html(contents) if parsing_error: parsing_error_json = json.dumps(_("You have an error in your document. Please fix it before editing another section.")) else: parsing_error_json = json.dumps(None) self.send_command("set_parsing_error(%s)" % parsing_error_json) self.send_command("set_doc_structure(%s)" % json.dumps(self._application.book.get_structure_tree())) elif command == "set_section_source_contents": i = params.index(":") section_id = int(params[:i]) contents = params[i+1:] section = self._application.book.find_section_by_id(section_id) parsing_error = section.update_from_xml(contents) if parsing_error: parsing_error_json = json.dumps(_("You have an error in your document. Please fix it before editing another section.")) else: parsing_error_json = json.dumps(None) self.send_command("set_parsing_error(%s)" % parsing_error_json) self.send_command("set_doc_structure(%s)" % json.dumps(self._application.book.get_structure_tree())) elif command == "browse_image": i = params.index(":") field_name = params[:i] url = params[i+1:] if url: filename = urllib.url2pathname(url)[7:] else: filename = None new_filename = self._image_browser_dialog.run(filename) if new_filename: self.send_command("set_file_browser_filename(%s)" % json.dumps({"field_name": field_name, "url": urlparse.urljoin('file:', urllib.pathname2url(new_filename))})) elif command == "load_config": self._do_send_command("set_config(%s)" % json.dumps(self._application.config.serialize())) elif command == "translate": self.send_command("set_translation(%s)" % json.dumps({"mesg": params, "translation": _(params)})) else: return False return True def _load_main_window(self): filename = os.path.join(self._application.cli_options.share_dir, UNIX_APPNAME, "ui", "main_window.html") f = open(filename) data = f.read() f.close() while "_(" in data: i = data.index("_(") pcount = 1 j = i + 2 while pcount != 0: if data[j] == "(": pcount += 1 if data[j] == ")": pcount -= 1 j += 1 data = data[:i] + _(data[i+2:j-1]) + data[j:] self._webview.load_html_string(data, urlparse.urljoin('file:', urllib.pathname2url(filename))) def refresh_view_for_new_book(self, section_id = 0): self.send_command("refresh_view_for_new_book(%d)" % section_id) if self._application.book: self._window.set_title("%s - %s" % (_(APPNAME), self._application.book.filename)) else: self._window.set_title("%s" % _(APPNAME))