123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- using Adw;
- using Gtk;
- namespace PpubViewer {
- public class ViewerWindow : Adw.ApplicationWindow {
- private Adw.HeaderBar header_bar;
- private Box box;
- private Flap flap;
- private DocumentView.DocumentViewManager document_view;
- private Button back_button;
- private Button forward_button;
- private Button properties_button;
- private Button menu_button;
- private PopoverMenu menu;
- private ZoomSpinButton zoom_spin;
- private Ppub.Publication publication;
- private NavigationHistoryItem current_page = null;
- private WindowTitle window_title;
- public ViewerWindow(Adw.Application app) {
- application = app;
- header_bar = new Adw.HeaderBar ();
- window_title = new WindowTitle("PPUB Viewer", "");
- flap = new Flap();
- box = new Box (Orientation.VERTICAL, 0);
- box.append (header_bar);
- box.append (flap);
- content = box;
- header_bar.show_end_title_buttons = true;
- default_width = 900;
- default_height = 700;
- header_bar.title_widget = window_title;
- flap.separator = new Separator(Orientation.VERTICAL);
- properties_button = new Button.from_icon_name("sidebar-show-symbolic");
- header_bar.pack_start(properties_button);
- header_bar.pack_start(new Separator(Orientation.VERTICAL));
- back_button = new Button.from_icon_name("go-previous-symbolic");
- back_button.sensitive = false;
- back_button.clicked.connect(go_back);
- header_bar.pack_start(back_button);
- forward_button = new Button.from_icon_name("go-next-symbolic");
- forward_button.sensitive = false;
- forward_button.clicked.connect(go_forward);
- header_bar.pack_start(forward_button);
- // menu = new PopoverMenu.from_model(null);
- // header_bar.pack_end(menu);
- // menu_button = new Button.from_icon_name("open-menu-symbolic");
- // menu_button.clicked.connect(() => menu.popup());
- // header_bar.pack_end(menu_button);
- var zoom_squeezer = new Squeezer();
- zoom_squeezer.transition_type = SqueezerTransitionType.CROSSFADE;
- zoom_spin = new ZoomSpinButton(false);
- var zoom_spin_small = new ZoomSpinButton(true);
- zoom_spin_small.adjustment = zoom_spin.adjustment;
- zoom_squeezer.add(zoom_spin);
- zoom_squeezer.add(zoom_spin_small);
- zoom_spin.zoom_level_changed.connect(change_zoom);
- header_bar.pack_end(zoom_squeezer);
- document_view = new DocumentView.DocumentViewManager();
- document_view.link_clicked.connect(link_clicked);
- flap.content = document_view;
- properties_button.clicked.connect(() => {
- flap.reveal_flap = !flap.reveal_flap;
- });
- }
- public void load_ppub(File file) throws Error {
- publication = new Ppub.Publication(file.get_path());
- var asset = publication.get_default_asset ();
- window_title.title = publication.metadata.title ?? "Untitled PPUB";
- window_title.subtitle = publication.metadata.author_name ?? "";
- title = window_title.title + " - PPUB Viewer";
- var scroller = new ScrolledWindow();
- scroller.add_css_class("background");
- scroller.hscrollbar_policy = PolicyType.NEVER;
- var pane = new PropertiesPane(publication.metadata, false);
- scroller.child = pane;
- pane.link_clicked.connect(property_link_clicked);
- flap.flap = scroller;
- navigate(asset.name);
- }
- public void navigate(string file) {
- if(current_page == null) {
- current_page = new NavigationHistoryItem();
- current_page.file_name = file;
- current_page.scroll_position = 0;
- }
- else {
- current_page = current_page.add_next(file, document_view.get_scroll_position());
- }
- load_document(file);
- }
- public void go_back() {
- current_page.scroll_position = document_view.get_scroll_position();
- current_page = current_page.previous;
- load_document(current_page.file_name);
- }
- public void go_forward() {
- current_page.scroll_position = document_view.get_scroll_position();
- current_page = current_page.next;
- load_document(current_page.file_name);
- }
- public void load_document(string file) {
- back_button.sensitive = current_page.previous != null;
- forward_button.sensitive = current_page.next != null;
- document_view.load_asset(publication, publication.get_asset(file));
- Idle.add_once(() => {
- document_view.set_scroll_position(current_page.scroll_position);
- return false;
- });
- }
- private void link_clicked(string url) {
- var asset = publication.get_asset(Uri.unescape_string(url));
- if(asset != null) {
- navigate(asset.name);
- return;
- }
- Uri uri;
- try{
- uri = Uri.parse(url, UriFlags.PARSE_RELAXED);
- }
- catch {
- var dialog = new Adw.MessageDialog(this, "Unrecognised link", @"Could not determine how to handle the link <i>$url</i>.");
- dialog.body_use_markup = true;
- dialog.add_response("close", "Close");
- dialog.present();
- dialog.response.connect(() => dialog.close());
- return;
- }
- var app = AppInfo.get_default_for_uri_scheme(uri.get_scheme());
- if(app == null) {
- var dialog = new Adw.MessageDialog(this, "No application", @"Could not find an application to handle the URI <i>$uri</i>.");
- dialog.body_use_markup = true;
- dialog.add_response("close", "Close");
- dialog.present();
- dialog.response.connect(() => dialog.close());
- return;
- }
- var uris = new List<string>();
- uris.append(uri.to_string());
- var dialog = new Adw.MessageDialog(this, "Open external link?", @"Do you want to open the external link <i>$uri</i>?");
- dialog.body_use_markup = true;
- dialog.add_response("cancel", @"Cancel");
- dialog.add_response("open", @"Open in $(app.get_display_name())");
- dialog.present();
- dialog.response.connect(id => {
- if(id == "open") {
- app.launch_uris(uris, null);
- }
- dialog.close();
- });
-
- }
- private void property_link_clicked(string file) {
- link_clicked(file);
- if(flap.folded) {
- flap.reveal_flap = false;
- }
- }
- private void change_zoom(int percent) {
- document_view.set_zoom_percentage(percent);
- }
- public override void size_allocate(int width, int height, int baseline) {
- base.size_allocate(width, height, baseline);
- document_view.reflow();
- }
- }
- }
|