Example #1
0
 private void ScrollPages_PreviewMouseDown(object sender, MouseButtonEventArgs e)
 {
     ScrollPages.Focus();
 }
        internal void PDFRendererControl_KeyUp(object sender, KeyEventArgs e)
        {
            if ((Keyboard.Modifiers & ModifierKeys.Control) != 0)
            {
                switch (e.Key)
                {
                case Key.P:
                    if (ZoomType.Zoom1Up == zoom_type)
                    {
                        PageZoom(ZoomType.Zoom2Up);
                    }
                    else
                    {
                        PageZoom(ZoomType.Zoom1Up);
                    }

                    e.Handled = true;
                    break;

                case Key.M:
                    ReconsiderOperationMode(OperationMode.Hand);
                    e.Handled = true;

                    break;

                case Key.A:
                    ReconsiderOperationMode(OperationMode.Annotation);
                    e.Handled = true;
                    break;

                case Key.H:
                    ReconsiderOperationMode(OperationMode.Highlighter);
                    e.Handled = true;
                    break;

                case Key.S:
                    ReconsiderOperationMode(OperationMode.TextSentenceSelect);
                    e.Handled = true;
                    break;

                case Key.I:
                    ReconsiderOperationMode(OperationMode.Ink);
                    e.Handled = true;
                    break;

                case Key.R:
                    ReconsiderOperationMode(OperationMode.Camera);
                    e.Handled = true;
                    break;

                case Key.B:
                    GoogleBibTexSnifferControl sniffer = new GoogleBibTexSnifferControl();
                    sniffer.Show(pdf_renderer_control_stats.pdf_document);
                    e.Handled = true;
                    break;

                case Key.Add:
                case Key.OemPlus:
                    IncrementalZoom(+1);
                    e.Handled = true;
                    break;

                case Key.Subtract:
                case Key.OemMinus:
                    IncrementalZoom(-1);
                    e.Handled = true;
                    break;

                default:
                    if (Key.D1 <= e.Key && Key.D9 >= e.Key)
                    {
                        if (KeyboardTools.IsShiftDown())
                        {
                            int bookmark_number = BookmarkManager.KeyToBookmarkNumber(e.Key);
                            BookmarkManager.SetDocumentBookmark(pdf_renderer_control_stats.pdf_document, bookmark_number, ScrollPages.VerticalOffset / ScrollPages.ScrollableHeight);
                            StatusManager.Instance.UpdateStatus("Bookmarks", "Set bookmark " + bookmark_number);

                            e.Handled = true;
                        }

                        else
                        {
                            int    bookmark_number = BookmarkManager.KeyToBookmarkNumber(e.Key);
                            double vertical_offset = BookmarkManager.GetDocumentBookmark(pdf_renderer_control_stats.pdf_document, bookmark_number);
                            ScrollPages.ScrollToVerticalOffset(vertical_offset * ScrollPages.ScrollableHeight);
                            StatusManager.Instance.UpdateStatus("Bookmarks", "Jumped to bookmark " + bookmark_number);

                            e.Handled = true;
                        }
                    }
                    break;
                }
            }
        }
        public PDFRendererControl(PDFDocument pdf_document, bool remember_last_read_page, ZoomType force_zoom_type)
        {
            Theme.Initialize();

            InitializeComponent();

            pdf_renderer_control_stats   = new PDFRendererControlStats(this, pdf_document);
            this.remember_last_read_page = remember_last_read_page;

            ObjPagesPanel.Background = ThemeColours.Background_Brush_Blue_LightToDark;

            PageRenderArea.SizeChanged += PDFRendererControl_SizeChanged;
            KeyUp             += PDFRendererControl_KeyUp;
            KeyDown           += PDFRendererControl_KeyDown;
            TextInput         += PDFRendererControl_TextInput;
            PreviewMouseWheel += PDFRendererControl_MouseWheel;

            ScrollPages.PreviewMouseDown += ScrollPages_PreviewMouseDown;
            ScrollPages.ScrollChanged    += ScrollPages_ScrollChanged;

            KeyboardNavigation.SetDirectionalNavigation(this, KeyboardNavigationMode.None);
            KeyboardNavigation.SetDirectionalNavigation(ScrollPages, KeyboardNavigationMode.None);
            KeyboardNavigation.SetDirectionalNavigation(ObjPagesPanel, KeyboardNavigationMode.None);

            // Set the initial zoom
            ZoomType zoom_type = ZoomType.Other;

            switch (ConfigurationManager.Instance.ConfigurationRecord.GUI_LastPagesUp)
            {
            case "1":
                zoom_type = ZoomType.Zoom1Up;
                break;

            case "2":
                zoom_type = ZoomType.Zoom2Up;
                break;

            case "N":
                zoom_type = ZoomType.ZoomNUp;
                break;

            case "W":
                zoom_type = ZoomType.ZoomWholeUp;
                break;

            default:
                zoom_type = ZoomType.Zoom1Up;
                break;
            }

            // Is the zoomtype forced? (e.g. by the metadata panel or the sniffer)
            if (ZoomType.Other != force_zoom_type)
            {
                zoom_type = force_zoom_type;
            }

            PageZoom(zoom_type);

            // Add the child pages
            bool add_bells_and_whistles = pdf_renderer_control_stats.pdf_document.PDFRenderer.PageCount < 50;

            Logging.Info("+Creating child page controls");
            for (int page = 1; page <= pdf_renderer_control_stats.pdf_document.PDFRenderer.PageCount; ++page)
            {
                PDFRendererPageControl page_control = new PDFRendererPageControl(page, this, pdf_renderer_control_stats, add_bells_and_whistles);
                ObjPagesPanel.Children.Add(page_control);
            }
            Logging.Info("-Creating child page controls");

            Logging.Info("+Setting initial viewport");
            ReconsiderOperationMode(OperationMode.Hand);

            SetSearchKeywords();  // Eventually this should move into the reconsideroperationmode
            ScrollPages.Focus();

            Logging.Info("-Setting initial viewport");
        }
        private void ScrollPages_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            // Weirdly, ScrollChanged is a bubbling event - not a callback on the very object
            // So you can receive a scroll event from ANY of your children?!!?!!!!!
            // Inside the reading page, there are scrollbars in the annotation popups, which cause this to fire.  So ignore those...
            if (e.Source != ScrollPages)
            {
                return;
            }

            if (DateTime.MaxValue == first_scroll_timestamp)
            {
                first_scroll_timestamp = DateTime.UtcNow;

                if (remember_last_read_page)
                {
                    if (0 < pdf_renderer_control_stats.pdf_document.PageLastRead)
                    {
                        Logging.Debug("**********************************Restoring page to page {0}", pdf_renderer_control_stats.pdf_document.PageLastRead);
                        PDFRendererPageControl page_control = (PDFRendererPageControl)ObjPagesPanel.Children[pdf_renderer_control_stats.pdf_document.PageLastRead - 1];
                        page_control.BringIntoView();
                    }
                }
            }

            /*
             *  Logging.Info(
             *      "\n----------------------------------------------------------" +
             *      "\nExtentHeight={0}," +
             *      "\nExtentHeightChange={1}," +
             *      "\nExtentWidth={2}," +
             *      "\nExtentWidthChange={3}," +
             *      "\nHorizontalChange={4}," +
             *      "\nHorizontalOffset={5}," +
             *      "\nVerticalChange={6}," +
             *      "\nVerticalOffset={7}," +
             *      "\nViewportHeight={8}," +
             *      "\nViewportHeightChange={9}," +
             *      "\nViewportWidth={10}," +
             *      "\nViewportWidthChange={11}," +
             *      "",
             *
             *      e.ExtentHeight,
             *      e.ExtentHeightChange,
             *      e.ExtentWidth,
             *      e.ExtentWidthChange,
             *      e.HorizontalChange,
             *      e.HorizontalOffset,
             *      e.VerticalChange,
             *      e.VerticalOffset,
             *      e.ViewportHeight,
             *      e.ViewportHeightChange,
             *      e.ViewportWidth,
             *      e.ViewportWidthChange
             *      );
             */

            // Lets see which pages are in view
            PDFRendererPageControl        first_page_in_view = null;
            List <PDFRendererPageControl> pages_in_view      = new List <PDFRendererPageControl>();
            List <PDFRendererPageControl> pages_not_in_view  = new List <PDFRendererPageControl>();

            foreach (PDFRendererPageControl page in ObjPagesPanel.Children.OfType <PDFRendererPageControl>().Reverse())
            {
                GeneralTransform childTransform = page.TransformToAncestor(ScrollPages);
                Rect             rectangle      = childTransform.TransformBounds(new Rect(new Point(0, 0), page.RenderSize));
                Rect             result         = Rect.Intersect(new Rect(new Point(0, 0), ScrollPages.RenderSize), rectangle);

                if (result != Rect.Empty)
                {
                    if (null == first_page_in_view)
                    {
                        first_page_in_view = page;
                    }

                    pages_in_view.Add(page);
                }
                else
                {
                    pages_not_in_view.Add(page);
                }
            }

            // Check if the selected page has gone off screen.  If so, select the next page.
            if (null != SelectedPage)
            {
                if (!pages_in_view.Contains(SelectedPage))
                {
                    // IF this is the first time the selected page has gone off screen, record the moment
                    if (DateTime.MaxValue == selected_page_first_offscreen_timestamp)
                    {
                        selected_page_first_offscreen_timestamp = DateTime.UtcNow;
                    }

                    // We wait for a few moments after it has gone off the screen...2 is arbitrary, but large enough that we can zoom without changing the selected page before the zoom gets time to move thesleected page back onto the screen...
                    if (DateTime.UtcNow.Subtract(selected_page_first_offscreen_timestamp).TotalSeconds > 1)
                    {
                        if (null != first_page_in_view)
                        {
                            SelectedPage = first_page_in_view;
                            selected_page_first_offscreen_timestamp = DateTime.MaxValue;
                        }
                    }
                }
                else
                {
                    selected_page_first_offscreen_timestamp = DateTime.MaxValue;
                }
            }

#if false
            {
                // Lets pretend the pages just before and after the pages in view are in view - that way we dont have to wait for the render
                int min_page = Int32.MaxValue;
                int max_page = Int32.MinValue;
                foreach (PDFRendererPageControl page in pages_in_view)
                {
                    min_page = Math.Min(min_page, page.PageNumber - 1);
                    max_page = Math.Max(max_page, page.PageNumber + 1);
                }
                foreach (PDFRendererPageControl page in pages_not_in_view)
                {
                    if (min_page == page.PageNumber || max_page == page.PageNumber)
                    {
                        pages_in_view.Add(page);
                    }
                }
                foreach (PDFRendererPageControl page in pages_in_view)
                {
                    pages_not_in_view.Remove(page);
                }
            }
#endif

            // Clear down the pages NOT in view
            foreach (PDFRendererPageControl page in pages_not_in_view)
            {
                page.SetPageNotInView();
            }

            // Notify the new pages that are in view
            foreach (PDFRendererPageControl page in pages_in_view)
            {
                //Logging.Info("Page {0} is in view!!!!!!!!!!!!!!", page.PageNumber);
                page.SetPageInView();
            }

            // If the page has been resized or rescaled, try keep the scrollbars in the same place...
            if (0 != e.ExtentHeightChange)
            {
                double prev_extent_height    = e.ExtentHeight - e.ExtentHeightChange;
                double vertical_offset_ratio = e.VerticalOffset / prev_extent_height;
                double new_vertical_offset   = vertical_offset_ratio * e.ExtentHeight;

                if (!Double.IsNaN(new_vertical_offset))
                {
                    //Logging.Info("Forcing vertical offset from {0} to {1}", e.VerticalOffset, new_vertical_offset);
                    ScrollPages.ScrollToVerticalOffset(new_vertical_offset);
                    return;
                }
            }

            // Store the last seen page - but not right at the start
            if (DateTime.UtcNow.Subtract(first_scroll_timestamp).TotalSeconds > 1)
            {
                if (remember_last_read_page)
                {
                    if (0 < pages_in_view.Count)
                    {
                        PDFRendererPageControl page = pages_in_view[0];

                        // Set the last read page
                        pdf_renderer_control_stats.pdf_document.PageLastRead = page.Page;

                        // Don't notify this now as it causes many writes of the metadata to be done, which is slow for large highlightlists
                        //pdf_renderer_control_stats.pdf_document.Bindable.NotifyPropertyChanged(() => pdf_renderer_control_stats.pdf_document.PageLastRead);
                    }
                }
            }
        }