diff -ur a/data/epdfview-ui.xml b/data/epdfview-ui.xml
--- a/data/epdfview-ui.xml 2009-10-29 23:45:04.000000000 +0300
+++ b/data/epdfview-ui.xml 2009-10-30 01:19:38.000000000 +0300
@@ -27,6 +27,7 @@
+
diff -ur a/po/ru.po b/po/ru.po
--- a/po/ru.po 2009-10-29 23:45:04.000000000 +0300
+++ b/po/ru.po 2009-10-30 01:23:47.000000000 +0300
@@ -319,6 +319,10 @@
msgstr "Переключить полноэкранный режим"
#: src/gtk/MainView.cxx:179
+msgid "_Dual pages"
+msgstr "По две страницы"
+
+#: src/gtk/MainView.cxx:179
msgid "Show _Toolbar"
msgstr "Показать панель инструментов"
diff -ur a/src/Config.cxx b/src/Config.cxx
--- a/src/Config.cxx 2009-10-29 23:45:04.000000000 +0300
+++ b/src/Config.cxx 2009-10-30 01:19:38.000000000 +0300
@@ -33,6 +33,8 @@
static const gint DEFAULT_WINDOW_Y = 0;
static const gboolean DEFAULT_ZOOM_TO_FIT = FALSE;
static const gboolean DEFAULT_ZOOM_TO_WIDTH = FALSE;
+static const gboolean DEFAULT_DUAL_PAGES = FALSE;
+static const guint PAGES_COUNT = 2;
// Static member attributes.
Config *Config::m_Config = NULL;
@@ -445,6 +447,18 @@
}
///
+/// @brief Sets the dual pages option.
+///
+/// @param activate Set to TRUE to activate the dual pages option. FALSE
+/// otherwise.
+///
+void
+Config::setDualPages (gboolean activate)
+{
+ g_key_file_set_boolean (m_Values, "main window", "dualPages", activate);
+}
+
+///
/// @brief Gets if show the status bar.
///
/// @return TRUE if the status bar should be shown, FALSE otherwise.
@@ -489,6 +503,17 @@
}
///
+/// @brief Gets the dual pages mode option.
+///
+/// @return TRUE if the dual pages mode is activated. FALSE otherwise.
+///
+gboolean
+Config::dualPages ()
+{
+ return getBoolean ("main window", "dualPages", DEFAULT_DUAL_PAGES);
+}
+
+///
/// @brief Gets the configuration file name.
///
/// This function creates the directory where the configuration file should
@@ -507,3 +532,15 @@
return configFile;
}
+
+///
+/// @brief Gets count of pages being displayed to user in multi-pages mode.
+///
+/// @return The saved value of pages for multi-pages mode. Currently only dual
+/// pages mode is supported, so the result is always 2.
+///
+guint
+Config::getPagesCount ()
+{
+ return PAGES_COUNT;
+}
diff -ur a/src/Config.h b/src/Config.h
--- a/src/Config.h 2009-10-29 23:45:04.000000000 +0300
+++ b/src/Config.h 2009-10-30 01:19:38.000000000 +0300
@@ -35,6 +35,7 @@
static void destroy (void);
static Config &getConfig (void);
static void loadFile (gboolean load);
+ static guint getPagesCount (void);
~Config (void);
@@ -49,6 +50,7 @@
gboolean showToolbar (void);
gboolean zoomToFit (void);
gboolean zoomToWidth (void);
+ gboolean dualPages (void);
void save(void);
void setExternalBrowserCommandLine (const gchar *commandLine);
void setOpenFileFolder (const gchar *folder);
@@ -59,6 +61,7 @@
void setWindowPos (gint x, gint y);
void setZoomToFit (gboolean active);
void setZoomToWidth (gboolean active);
+ void setDualPages (gboolean active);
protected:
/// The configuration values.
diff -ur a/src/FindPter.cxx b/src/FindPter.cxx
--- a/src/FindPter.cxx 2009-10-29 23:45:04.000000000 +0300
+++ b/src/FindPter.cxx 2009-10-30 01:19:38.000000000 +0300
@@ -89,7 +89,10 @@
{
DocumentRectangle *rect = ((DocumentRectangle *)m_CurrentMatch->data);
m_Document->notifyFindChanged (m_FindPage, rect);
- m_Document->goToPage (m_FindPage);
+ if ( !m_Document->isPageVisible (m_FindPage) )
+ {
+ m_Document->goToPage (m_FindPage);
+ }
}
else
{
@@ -118,7 +121,10 @@
{
DocumentRectangle *rect = ((DocumentRectangle *)m_CurrentMatch->data);
m_Document->notifyFindChanged (m_FindPage, rect);
- m_Document->goToPage (m_FindPage);
+ if ( !m_Document->isPageVisible (m_FindPage) )
+ {
+ m_Document->goToPage (m_FindPage);
+ }
}
else
{
@@ -229,7 +235,10 @@
}
DocumentRectangle *rect = (DocumentRectangle *)m_CurrentMatch->data;
m_Document->notifyFindChanged (m_FindPage, rect);
- m_Document->goToPage (m_FindPage);
+ if ( !m_Document->isPageVisible (m_FindPage) )
+ {
+ m_Document->goToPage (m_FindPage);
+ }
IFindView &view = getView ();
view.setInformationText ("");
diff -ur a/src/gtk/MainView.cxx b/src/gtk/MainView.cxx
--- a/src/gtk/MainView.cxx 2009-10-29 23:45:04.000000000 +0300
+++ b/src/gtk/MainView.cxx 2009-10-30 01:19:38.000000000 +0300
@@ -53,6 +53,7 @@
gpointer);
static void main_window_find_cb (GtkWidget *, gpointer);
static void main_window_fullscreen_cb (GtkToggleAction *, gpointer);
+static void main_window_dualpages_cb (GtkToggleAction *, gpointer);
static gboolean main_window_moved_or_resized_cb (GtkWidget *,
GdkEventConfigure *, gpointer);
static void main_window_go_to_first_page_cb (GtkWidget *, gpointer);
@@ -176,6 +177,10 @@
N_("Toggle full screen window"),
G_CALLBACK (main_window_fullscreen_cb), FALSE },
+ { "DualPages", NULL, N_("_Dual pages"), NULL,
+ N_("Toggle single/dual view mode"),
+ G_CALLBACK (main_window_dualpages_cb), FALSE },
+
{ "ShowToolBar", NULL, N_("Show _Toolbar"), NULL,
N_("Show or hide the toolbar"),
G_CALLBACK (main_window_show_toolbar_cb), TRUE },
@@ -298,6 +303,14 @@
}
void
+MainView::activeDualPages (gboolean active)
+{
+ GtkAction *dualPages =
+ gtk_ui_manager_get_action (m_UIManager, "/MenuBar/ViewMenu/DualPages");
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (dualPages), active);
+}
+
+void
MainView::activePageModeScroll (gboolean active)
{
GtkAction *action =
@@ -624,6 +637,14 @@
}
void
+MainView::sensitiveDualPages (gboolean sensitive)
+{
+ GtkAction *dualPages =
+ gtk_ui_manager_get_action (m_UIManager, "/MenuBar/ViewMenu/DualPages");
+ gtk_action_set_sensitive (dualPages, sensitive);
+}
+
+void
MainView::show (void)
{
Config &config = Config::getConfig ();
@@ -1183,6 +1204,18 @@
}
///
+/// @brief The user tried to switch to dual pages mode.
+///
+void
+main_window_dualpages_cb (GtkToggleAction *action, gpointer data)
+{
+ g_assert ( NULL != data && "The data parameter is NULL.");
+
+ MainPter *pter = (MainPter *)data;
+ pter->dualPagesActivated (gtk_toggle_action_get_active (action));
+}
+
+///
/// @brief Called when the window is moved or resized.
///
/// This is used to save the current window's position and size.
diff -ur a/src/gtk/MainView.h b/src/gtk/MainView.h
--- a/src/gtk/MainView.h 2009-10-29 23:45:04.000000000 +0300
+++ b/src/gtk/MainView.h 2009-10-30 01:19:38.000000000 +0300
@@ -35,6 +35,7 @@
void activeZoomFit (gboolean active);
void activeZoomWidth (gboolean active);
+ void activeDualPages (gboolean active);
void activePageModeScroll (gboolean active);
void activePageModeText (gboolean active);
gboolean isIndexVisible () const;
@@ -61,6 +62,7 @@
void sensitiveZoomOut (gboolean sensitive);
void sensitiveZoomFit (gboolean sensitive);
void sensitiveZoomWidth (gboolean sensitive);
+ void sensitiveDualPages (gboolean sensitive);
void show (void);
void showErrorMessage (const gchar *title, const gchar *body);
void showIndex (gboolean show);
diff -ur a/src/gtk/PageView.cxx b/src/gtk/PageView.cxx
--- a/src/gtk/PageView.cxx 2009-10-29 23:45:04.000000000 +0300
+++ b/src/gtk/PageView.cxx 2009-10-30 01:19:38.000000000 +0300
@@ -54,10 +54,15 @@
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
- // The actual page image.
- m_PageImage = gtk_image_new ();
- gtk_misc_set_padding (GTK_MISC (m_PageImage),
- PAGE_VIEW_PADDING, PAGE_VIEW_PADDING);
+ guint pagesCount = Config::getPagesCount ();
+ // The actual page images.
+ m_PageImage = new GtkWidget *[pagesCount];
+ for ( guint pageNum = 0; pageNum < pagesCount ; ++pageNum )
+ {
+ m_PageImage[pageNum] = gtk_image_new ();
+ gtk_misc_set_padding (GTK_MISC (m_PageImage[pageNum]),
+ PAGE_VIEW_PADDING, PAGE_VIEW_PADDING);
+ }
// I want to be able to drag the page with the left mouse
// button, because that will make possible to move the page
@@ -66,7 +71,12 @@
// GdkWindow, so I have to add the event box that will receive
// the mouse events.
m_EventBox = gtk_event_box_new ();
- gtk_container_add (GTK_CONTAINER (m_EventBox), m_PageImage);
+ m_ImageBox = gtk_hbox_new (TRUE, 0);
+ for ( guint pageNum = 0; pageNum < pagesCount ; ++pageNum )
+ {
+ gtk_container_add (GTK_CONTAINER (m_ImageBox), m_PageImage[pageNum]);
+ }
+ gtk_container_add (GTK_CONTAINER (m_EventBox), m_ImageBox);
gtk_scrolled_window_add_with_viewport (
GTK_SCROLLED_WINDOW (m_PageScroll), m_EventBox);
@@ -75,6 +85,7 @@
PageView::~PageView ()
{
+ delete[] m_PageImage;
}
gdouble
@@ -163,7 +174,7 @@
void
PageView::resizePage (gint width, gint height)
{
- GdkPixbuf *originalPage = gtk_image_get_pixbuf (GTK_IMAGE (m_PageImage));
+ GdkPixbuf *originalPage = gtk_image_get_pixbuf (GTK_IMAGE (m_PageImage[0]));
if ( NULL != originalPage )
{
GdkPixbuf *scaledPage = gdk_pixbuf_scale_simple (originalPage,
@@ -171,7 +182,7 @@
GDK_INTERP_NEAREST);
if ( NULL != scaledPage )
{
- gtk_image_set_from_pixbuf (GTK_IMAGE (m_PageImage), scaledPage);
+ gtk_image_set_from_pixbuf (GTK_IMAGE (m_PageImage[0]), scaledPage);
g_object_unref (scaledPage);
}
}
@@ -245,7 +256,7 @@
GtkAdjustment *hAdjustment = gtk_scrolled_window_get_hadjustment (
GTK_SCROLLED_WINDOW (m_PageScroll));
gdouble hAdjValue = hAdjustment->page_size *
- (gdouble)dx / m_PageImage->allocation.width;
+ (gdouble)dx / m_PageImage[0]->allocation.width;
gtk_adjustment_set_value (hAdjustment,
CLAMP (scrollX - hAdjValue,
hAdjustment->lower,
@@ -254,7 +265,7 @@
GtkAdjustment *vAdjustment = gtk_scrolled_window_get_vadjustment (
GTK_SCROLLED_WINDOW (m_PageScroll));
gdouble vAdjValue = vAdjustment->page_size *
- (gdouble)dy / m_PageImage->allocation.height;
+ (gdouble)dy / m_PageImage[0]->allocation.height;
gtk_adjustment_set_value (vAdjustment,
CLAMP (scrollY - vAdjValue,
vAdjustment->lower,
@@ -279,12 +290,14 @@
}
void
-PageView::showPage (DocumentPage *page, PageScroll scroll)
+PageView::showPage (DocumentPage *page, PageScroll scroll, guint index)
{
- gtk_image_set_from_pixbuf (GTK_IMAGE (m_PageImage), NULL);
+ GtkWidget *image = m_PageImage[index];
+ gtk_image_set_from_pixbuf (GTK_IMAGE (image), NULL);
GdkPixbuf *pixbuf = getPixbufFromPage (page);
- gtk_image_set_from_pixbuf (GTK_IMAGE (m_PageImage), pixbuf);
+ gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf);
g_object_unref (pixbuf);
+
// Set the vertical scroll to the specified.
if ( PAGE_SCROLL_NONE != scroll )
{
@@ -302,7 +315,20 @@
}
void
-PageView::showText (const gchar *text)
+PageView::showSecondPage (gboolean show)
+{
+ if ( show )
+ {
+ gtk_widget_show (m_PageImage[1]);
+ }
+ else
+ {
+ gtk_widget_hide (m_PageImage[1]);
+ }
+}
+
+void
+PageView::showText (const gchar *text, guint index)
{
// I need to make the changes to the original Pixbuf that the GtkImage
// controls shows.
@@ -312,14 +338,16 @@
// server-side and therefore drawable, make the modifications
// and set the modified pixbuf again to the GtkImage control.
//
- GdkPixbuf *originalPage = gtk_image_get_pixbuf (GTK_IMAGE (m_PageImage));
+
+ GtkWidget* image = m_PageImage[index];
+ GdkPixbuf *originalPage = gtk_image_get_pixbuf (GTK_IMAGE (image));
if ( NULL != originalPage )
{
gint width = gdk_pixbuf_get_width (originalPage);
gint height = gdk_pixbuf_get_height (originalPage);
PangoLayout *layout =
- gtk_widget_create_pango_layout (m_PageImage, text);
+ gtk_widget_create_pango_layout (image, text);
// I want the text to be half the page's width.
// Since I don't know the font's size I just set the font
@@ -349,7 +377,7 @@
gdk_pixbuf_render_pixmap_and_mask (originalPage,
&pixmap, &mask, 0);
gdk_draw_layout (pixmap,
- m_PageImage->style->black_gc,
+ image->style->black_gc,
(width - logicalRectangle.width) / 2,
height / 4 - logicalRectangle.height / 2,
layout);
@@ -369,7 +397,7 @@
g_object_unref (mask);
}
- gtk_image_set_from_pixbuf (GTK_IMAGE (m_PageImage), modifiedPage);
+ gtk_image_set_from_pixbuf (GTK_IMAGE (image), modifiedPage);
g_object_unref (modifiedPage);
}
}
@@ -385,7 +413,7 @@
}
void
-PageView::getPagePosition (gint widgetX, gint widgetY, gint *pageX, gint *pageY)
+PageView::getPagePosition (gint widgetX, gint widgetY, gint *pageX, gint *pageY, guint index)
{
g_assert ( NULL != pageX && "Tried to save the page's X to NULL.");
g_assert ( NULL != pageY && "Tried to save the page's Y to NULL.");
@@ -395,17 +423,18 @@
// how many widget space is being used for padding.
gint horizontalPadding = PAGE_VIEW_PADDING;
gint verticalPadding = PAGE_VIEW_PADDING;
- GdkPixbuf *page = gtk_image_get_pixbuf (GTK_IMAGE (m_PageImage));
+ GdkPixbuf *page = gtk_image_get_pixbuf (GTK_IMAGE (m_PageImage[index]));
if ( NULL != page )
{
horizontalPadding =
- (m_PageImage->allocation.width - gdk_pixbuf_get_width (page)) / 2;
+ (m_PageImage[index]->allocation.width - gdk_pixbuf_get_width (page)) / 2;
verticalPadding =
- (m_PageImage->allocation.height - gdk_pixbuf_get_height (page)) / 2;
+ (m_PageImage[index]->allocation.height - gdk_pixbuf_get_height (page)) / 2;
}
-
- *pageX = widgetX - horizontalPadding + (gint)getHorizontalScroll ();
- *pageY = widgetY - verticalPadding + (gint)getVerticalScroll ();
+ *pageX = widgetX - horizontalPadding + (gint)getHorizontalScroll () -
+ m_PageImage[index]->allocation.x;
+ *pageY = widgetY - verticalPadding + (gint)getVerticalScroll () -
+ m_PageImage[index]->allocation.y;
}
///
@@ -443,10 +472,7 @@
gint event_x;
gint event_y;
gtk_widget_get_pointer (view->getTopWidget (), &event_x, &event_y);
- gint x;
- gint y;
- view->getPagePosition (event_x, event_y, &x, &y);
- view->getPresenter ()->mouseButtonPressed (event->button, x, y);
+ view->getPresenter ()->mouseButtonPressed (event->button, event_x, event_y);
gtk_widget_grab_focus(view->getTopWidget());
@@ -481,10 +507,7 @@
gint event_x;
gint event_y;
gtk_widget_get_pointer (view->getTopWidget (), &event_x, &event_y);
- gint x;
- gint y;
- view->getPagePosition (event_x, event_y, &x, &y);
- view->getPresenter ()->mouseMoved (x, y);
+ view->getPresenter ()->mouseMoved (event_x, event_y);
return TRUE;
}
diff -ur a/src/gtk/PageView.h b/src/gtk/PageView.h
--- a/src/gtk/PageView.h 2009-10-29 23:45:04.000000000 +0300
+++ b/src/gtk/PageView.h 2009-10-30 01:19:38.000000000 +0300
@@ -29,7 +29,7 @@
gdouble getHorizontalScroll (void);
GtkWidget *getTopWidget (void);
void getPagePosition (gint widgetX, gint widgetY,
- gint *pageX, gint *pageY);
+ gint *pageX, gint *pageY, guint index);
void getSize (gint *width, gint *height);
gdouble getVerticalScroll (void);
void makeRectangleVisible (DocumentRectangle &rect, gdouble scale);
@@ -38,13 +38,15 @@
gint dx, gint dy);
void setCursor (PageCursor cursorType);
void setPresenter (PagePter *pter);
- void showPage (DocumentPage *page, PageScroll scroll);
- void showText (const gchar *text);
+ void showPage (DocumentPage *page, PageScroll scroll, guint index = 0);
+ void showText (const gchar *text, guint index);
+ void showSecondPage (gboolean show);
protected:
PageCursor m_CurrentCursor;
GtkWidget *m_EventBox;
- GtkWidget *m_PageImage;
+ GtkWidget *m_ImageBox;
+ GtkWidget **m_PageImage;
GtkWidget *m_PageScroll;
GdkPixbuf *getPixbufFromPage (DocumentPage *page);
diff -ur a/src/IDocument.cxx b/src/IDocument.cxx
--- a/src/IDocument.cxx 2009-10-29 23:45:04.000000000 +0300
+++ b/src/IDocument.cxx 2009-10-30 01:19:38.000000000 +0300
@@ -31,7 +31,7 @@
static const gdouble ZOOM_IN_MAX = 4.0;
static const gdouble ZOOM_OUT_FACTOR = (1.0 / ZOOM_IN_FACTOR);
static const gdouble ZOOM_OUT_MAX = 0.05409;
-static const guint CACHE_SIZE = 3;
+static const guint CACHE_SIZE = 3 * Config::getPagesCount ();
/// This is the error domain that will be used to report Document's errors.
GQuark IDocument::errorQuark = 0;
@@ -278,11 +278,14 @@
{
// Empty the cache to avoid displaying pages from previous file.
clearCache ();
- // Add the two first pages, if they exists, to the cache.
- addPageToCache (1);
- if ( 1 < getNumPages () )
+
+ // Add the first pages to the cache.
+ guint pageMax = getCountOfVisiblePages () * 2;
+ for ( guint pageNum = 1;
+ pageNum <= pageMax && pageNum <= (guint)getNumPages ();
+ ++pageNum)
{
- addPageToCache (2);
+ addPageToCache (pageNum);
}
for ( GList *item = g_list_first (m_Observers) ; NULL != item ;
@@ -954,16 +957,19 @@
}
///
-/// @brief Gets the document's current page image.
+/// @brief Gets one of the document's current pages.
+///
+/// @param index The index of the desired page in the list of current pages.
+/// Should always be 0 for single page mode.
///
-/// @return The rendered image of the current page or NULL if the image
+/// @return The rendered image of the selected page or NULL if the image
/// is not yet available.
///
DocumentPage *
-IDocument::getCurrentPage ()
+IDocument::getCurrentPage (guint index)
{
- PageCache *cachedPage = getCachedPage (m_CurrentPage);
+ PageCache *cachedPage = getCachedPage (m_CurrentPage + index);
if ( NULL == cachedPage )
{
return NULL;
@@ -976,7 +982,7 @@
if ( NULL != pageImage )
{
/// XXX: Only non rotated documents for now.
- if ( m_FindPage == m_CurrentPage && NULL != m_FindRect &&
+ if ( m_FindPage == m_CurrentPage + (gint)index && NULL != m_FindRect &&
0 == getRotation () )
{
pageImage->setSelection (*m_FindRect, getZoom ());
@@ -1088,7 +1094,7 @@
void
IDocument::goToNextPage ()
{
- goToPage (getCurrentPageNum() + 1);
+ goToPage (getCurrentPageNum() + getCountOfVisiblePages ());
}
///
@@ -1104,18 +1110,49 @@
void
IDocument::goToPage (gint pageNum)
{
- if ( pageNum != m_CurrentPage && 1 <= pageNum && pageNum <= getNumPages ())
+ guint pagesCount = getCountOfVisiblePages ();
+ if ( pageNum <= getNumPages () &&
+ pageNum + pagesCount > 1 )
{
- m_CurrentPage = pageNum;
+ // Check boundaries first
+ if ( pageNum < 1 )
+ {
+ m_CurrentPage = 1;
+ }
+ else if ( pageNum + pagesCount - 1 > (guint)getNumPages () )
+ {
+ m_CurrentPage = getNumPages () - pagesCount + 1;
+ }
+ else if ( m_CurrentPage == pageNum )
+ {
+ return;
+ }
+ else {
+ m_CurrentPage = pageNum;
+ }
+
+ // Process the currently visible pages.
+ for ( gint num = m_CurrentPage ;
+ num < m_CurrentPage + (gint)pagesCount && num <= getNumPages ();
+ ++num )
+ {
+ addPageToCache (num);
+ }
- addPageToCache (m_CurrentPage);
- if ( 1 < m_CurrentPage )
+ // Process a bunch of previous pages.
+ for ( gint num = m_CurrentPage - 1;
+ num >= m_CurrentPage - (gint)pagesCount && num > 0;
+ --num )
{
- addPageToCache (m_CurrentPage - 1);
+ addPageToCache (num);
}
- if ( m_CurrentPage < getNumPages () )
+
+ // Process a bunch of next pages.
+ for ( gint num = m_CurrentPage + pagesCount;
+ num < m_CurrentPage + (gint)pagesCount * 2 && num <= getNumPages ();
+ ++num )
{
- addPageToCache (m_CurrentPage + 1);
+ addPageToCache (num);
}
notifyPageChanged ();
@@ -1131,7 +1168,7 @@
void
IDocument::goToPreviousPage ()
{
- goToPage (getCurrentPageNum () - 1);
+ goToPage (getCurrentPageNum() - getCountOfVisiblePages ());
}
///
@@ -1479,24 +1516,25 @@
}
///
-/// @brief Checks if the current page has a link on a given position.
+/// @brief Checks if one of the current pages has a link on a given position.
///
-/// Checks if under a given position the document's current page have a
-/// link.
+/// Checks if under a given position one of the document's current pages have
+/// a link.
///
/// @param x The X coordinate of the position to check.
/// @param y The Y coordinate of the position to check.
+/// @param index The index of the page to look for a link on.
///
/// @return TRUE if the document's current page has a link under the given
/// position. FALSE otherwise.
///
gboolean
-IDocument::hasLinkAtPosition (gint x, gint y)
+IDocument::hasLinkAtPosition (gint x, gint y, guint index)
{
// XXX For now only non rotated pages.
if ( 0 == getRotation () )
{
- DocumentPage *page = getCurrentPage ();
+ DocumentPage *page = getCurrentPage (index);
if ( NULL != page )
{
return (NULL != page->getLinkAtPosition (x, y));
@@ -1513,11 +1551,12 @@
///
/// @param x The X coordinate of the current page's link to activate.
/// @param y The Y coordinate of the current page's link to activate.
+/// @param index The index of the page containing the link.
///
void
-IDocument::activateLinkAtPosition (gint x, gint y)
+IDocument::activateLinkAtPosition (gint x, gint y, guint index)
{
- DocumentPage *page = getCurrentPage ();
+ DocumentPage *page = getCurrentPage (index);
// XXX For now only non rotated pages.
if ( NULL != page && 0 == getRotation () )
{
@@ -1528,3 +1567,29 @@
}
}
}
+
+///
+/// @brief Gets visibility of a particular page.
+///
+/// @return TRUE if the selected page is currently on the screen.
+/// FALSE otherwise.
+///
+gboolean
+IDocument::isPageVisible (guint pageNum)
+{
+ return ( pageNum >= (guint)m_CurrentPage ) &&
+ ( pageNum < (guint)m_CurrentPage + getCountOfVisiblePages () );
+}
+
+///
+/// @brief Gets count of pages being currently displayed to user.
+///
+/// @return The result depends on current view mode. The value is always 1 for
+/// single-page mode and 2 for dual-pages mode.
+///
+guint
+IDocument::getCountOfVisiblePages ()
+{
+ Config &config = Config::getConfig ();
+ return ( config.dualPages () ) ? Config::getPagesCount () : 1;
+}
diff -ur a/src/IDocument.h b/src/IDocument.h
--- a/src/IDocument.h 2009-10-29 23:45:04.000000000 +0300
+++ b/src/IDocument.h 2009-10-30 01:19:38.000000000 +0300
@@ -265,8 +265,11 @@
virtual gboolean saveFile (const gchar *filename,
GError **error) = 0;
- virtual GdkRegion* getTextRegion (DocumentRectangle *rect) = 0;
- virtual void setTextSelection (DocumentRectangle *rect) = 0;
+ virtual GdkRegion* getTextRegion (DocumentRectangle *rect,
+ guint index ) = 0;
+ virtual gchar *getTextSelection (DocumentRectangle *rect,
+ guint index) = 0;
+ virtual void setTextSelection (gchar *text) = 0;
void attach (const IDocumentObserver *observer);
void detach (const IDocumentObserver *observer);
@@ -318,7 +321,8 @@
void getPageSize (gdouble *width, gdouble *height);
gint getNumPages (void);
void setNumPages (gint numPages);
- DocumentPage *getCurrentPage (void);
+ DocumentPage *getCurrentPage (guint index);
+ DocumentPage *getPairedPage (void);
DocumentPage *getEmptyPage (void);
gint getCurrentPageNum (void);
DocumentOutline *getOutline (void);
@@ -349,8 +353,11 @@
void zoomToFit (gint width, gint height);
void zoomToWidth (gint width);
- gboolean hasLinkAtPosition (gint x, gint y);
- void activateLinkAtPosition (gint x, gint y);
+ gboolean hasLinkAtPosition (gint x, gint y, guint index);
+ void activateLinkAtPosition (gint x, gint y, guint index);
+
+ gboolean isPageVisible (guint pageNum);
+ guint getCountOfVisiblePages (void);
static GQuark getErrorQuark (void);
static gchar *getErrorMessage (DocumentError errorCode);
diff -ur a/src/IMainView.h b/src/IMainView.h
--- a/src/IMainView.h 2009-10-29 23:45:04.000000000 +0300
+++ b/src/IMainView.h 2009-10-30 01:19:38.000000000 +0300
@@ -78,6 +78,17 @@
virtual void activeZoomWidth (gboolean active) = 0;
///
+ /// @brief Actives or deactivates the dual pages option.
+ ///
+ /// The view must change the state of the dual pages option
+ /// to @a active.
+ ///
+ /// @param active TRUE if the option must be activated, FALSE
+ /// otherwise.
+ ///
+ virtual void activeDualPages (gboolean active) = 0;
+
+ ///
/// @brief Tells if the index is shown.
///
/// @return @c TRUE if the index is currently shown, @c FALSE
@@ -355,6 +366,17 @@
///
virtual void sensitiveZoomWidth (gboolean sensitive) = 0;
+ /// @brief Changes the sensitivity of the "Dual Pages" action.
+ ///
+ /// The view must change the sensitivity (it's called enabled or
+ /// disabled on some toolkits) of the "Dual Pages" action.
+ ///
+ /// @param sensitive Set to TRUE if need to make sensitive (enable)
+ /// the action (enable) or FALSE to
+ /// insensitive (disable) it.
+ ///
+ virtual void sensitiveDualPages (gboolean sensitive) = 0;
+
///
/// @brief Sets the page view's cursor.
///
diff -ur a/src/IPageView.h b/src/IPageView.h
--- a/src/IPageView.h 2009-10-29 23:45:04.000000000 +0300
+++ b/src/IPageView.h 2009-10-30 01:19:38.000000000 +0300
@@ -168,7 +168,7 @@
///
/// @brief Shows a document's page.
///
- /// The view must show the @a page the the presenter gives to it.
+ /// The view must show the @a page the presenter gives to it.
/// Of course the view can use scroll bars if the page doesn't fit
/// the current view's size, but MUST NOT change the page's size.
///
@@ -178,23 +178,60 @@
/// @param page The document's page to show.
/// @param scroll Tells the main view how to scroll the
/// new page.
+ /// @param index The index on the page to be displayed in the list
+ /// of current pages. This is only used in dual pages
+ /// and is 0 by default (for single page mode).
///
- virtual void showPage (DocumentPage *page, PageScroll scroll) = 0;
+ virtual void showPage (DocumentPage *page, PageScroll scroll,
+ guint index = 0) = 0;
///
/// @brief Shows text on the page.
///
/// This is only used when the page is still loading but the
/// presenter wants to show something on the user. The presenter
- /// passes a text string to show during the rendering of the
- /// current page. The view should put this string at the middle
- /// of the currently shown page.
+ /// passes a text string to show during the rendering of a page.
+ /// The view should put this string at the middle of one of the
+ /// currently shown pages.
///
/// @param text The text to show on the middle of the page.
+ /// @param index The index of the page to show the text on. Should
+ /// always be 0 for single page mode.
///
- virtual void showText (const gchar *text) = 0;
-
-
+ virtual void showText (const gchar *text, guint index) = 0;
+
+ ///
+ /// @brief Shows the second page widget.
+ ///
+ /// The view must show the paired page or hide it depending
+ /// on the @a show parameter.
+ ///
+ /// The presenter calls this when user toggles the "Dual Pages"
+ /// option.
+ ///
+ /// @param show Set to TRUE if the second page should be shown.
+ /// FALSE otherwise.
+ ///
+ virtual void showSecondPage (gboolean show) = 0;
+
+ ///
+ /// @brief Gets a dot coordinate relative to a page.
+ ///
+ /// The view must provide to the presenter the position of a dot
+ /// relative to one of the current pages.
+ ///
+ /// @param widgetX The X coordinate relative to a widget.
+ /// @param widgetY The Y coordinate relative to a widget.
+ /// @param pageX The location to save the X coordinate relative to
+ /// a page.
+ /// @param pageY The location to save the Y coordinate relative to
+ /// a page.
+ /// @param index The index of the page in the list of current pages.
+ ///
+ virtual void getPagePosition (gint widgetX, gint widgetY,
+ gint *pageX, gint *pageY,
+ guint index) = 0;
+
protected:
///
/// @brief Creates a new IPageView object.
diff -ur a/src/MainPter.cxx b/src/MainPter.cxx
--- a/src/MainPter.cxx 2009-10-29 23:45:04.000000000 +0300
+++ b/src/MainPter.cxx 2009-10-30 01:19:38.000000000 +0300
@@ -136,12 +136,15 @@
view.sensitiveZoomOut (TRUE);
view.sensitiveZoomFit (TRUE);
view.sensitiveZoomWidth (TRUE);
+ view.sensitiveDualPages (TRUE);
view.activeZoomFit (config.zoomToFit ());
view.activeZoomWidth (config.zoomToWidth ());
+ view.activeDualPages (config.dualPages ());
#if defined (HAVE_CUPS)
view.sensitivePrint (TRUE);
#endif // HAVE_CUPS
+ dualPagesActivated (config.dualPages ());
checkZoomSettings ();
// Check if we should see the outlines.
@@ -170,6 +173,7 @@
view.sensitiveZoomOut (FALSE);
view.sensitiveZoomFit (FALSE);
view.sensitiveZoomWidth (FALSE);
+ view.sensitiveDualPages (FALSE);
showSidebar = FALSE;
#if defined (HAVE_CUPS)
view.sensitivePrint (FALSE);
@@ -332,7 +336,7 @@
///
/// @brief The "Full Screen" action was activated.
///
-/// @param show TRUE if Full Screen is active, FALSE otherwise.
+/// @param active TRUE if Full Screen is active, FALSE otherwise.
///
void
MainPter::fullScreenActivated (gboolean active)
@@ -341,6 +345,24 @@
}
///
+/// @brief The "Dual Pages" action was activated.
+///
+/// @param active TRUE if Dual Pages is active, FALSE otherwise.
+///
+void
+MainPter::dualPagesActivated (gboolean active)
+{
+ Config &config = Config::getConfig ();
+ config.setDualPages (active);
+ if (active)
+ {
+ // Need to recheck boundaries
+ m_Document->goToPage (m_Document->getCurrentPageNum ());
+ }
+ m_PagePter->setDualPages (active);
+}
+
+///
/// @brief The "Go To First Page" action was activated.
///
void
diff -ur a/src/MainPter.h b/src/MainPter.h
--- a/src/MainPter.h 2009-10-29 23:45:04.000000000 +0300
+++ b/src/MainPter.h 2009-10-30 01:19:38.000000000 +0300
@@ -50,6 +50,7 @@
void aboutBoxLinkActivated (const gchar *link);
void findActivated (void);
void fullScreenActivated (gboolean active);
+ void dualPagesActivated (gboolean active);
void goToFirstPageActivated (void);
void goToLastPageActivated (void);
void goToNextPageActivated (void);
diff -ur a/src/PagePter.cxx b/src/PagePter.cxx
--- a/src/PagePter.cxx 2009-10-29 23:45:04.000000000 +0300
+++ b/src/PagePter.cxx 2009-10-30 01:19:38.000000000 +0300
@@ -31,6 +31,8 @@
PagePter *pter;
/// The scroll to be used when the page is available.
PageScroll scroll;
+ /// Location of the page to be updated (left, right or both).
+ PageLocation location;
}
PageNotAvailableData;
@@ -54,14 +56,19 @@
};
// Global variables.
-static gboolean g_WaitingForPage = FALSE;
+static const guint g_pagesCount = Config::getPagesCount ();
+static gboolean* g_WaitingForPage = new gboolean[g_pagesCount];
///
/// @brief Constructs a new PagePter object.
///
PagePter::PagePter (IDocument *document)
{
- m_LastSelection = NULL;
+ m_LastSelection = new GdkRegion *[g_pagesCount];
+ for ( guint pageNum = 0; pageNum < g_pagesCount ; ++pageNum )
+ {
+ m_LastSelection[pageNum] = NULL;
+ }
m_Document = document;
m_Document->attach (this);
m_DragInfo = NULL;
@@ -76,6 +83,7 @@
PagePter::~PagePter ()
{
delete m_DragInfo;
+ delete[] m_LastSelection;
m_Document->detach (this);
}
@@ -121,24 +129,33 @@
{
if ( 1 == button )
{
- if ( m_Document->hasLinkAtPosition (x, y) )
+ IPageView &view = getView ();
+
+ // Check for a link first
+ gint maxNum = m_Document->getCountOfVisiblePages ();;
+ for ( gint pageNum = 0; pageNum < maxNum ; ++pageNum )
{
- m_Document->activateLinkAtPosition (x, y);
+ gint pageX = 0;
+ gint pageY = 0;
+ view.getPagePosition (x, y, &pageX, &pageY, pageNum);
+ if ( m_Document->hasLinkAtPosition (pageX, pageY, pageNum) )
+ {
+ m_Document->activateLinkAtPosition (pageX, pageY, pageNum);
+ return;
+ }
}
- else
- {
- m_DragInfo = new DragInfo;
- m_DragInfo->x = x;
- m_DragInfo->y = y;
- IPageView &view = getView ();
- m_DragInfo->startX = x;
- m_DragInfo->startY = y;
- if(m_ScrollMode == PagePterModeScroll)
- view.setCursor (PAGE_VIEW_CURSOR_DRAG);
- else
- view.setCursor (PAGE_VIEW_CURSOR_SELECT_TEXT);
- }
+ // Link is not found
+ m_DragInfo = new DragInfo;
+ m_DragInfo->x = x;
+ m_DragInfo->y = y;
+
+ m_DragInfo->startX = x;
+ m_DragInfo->startY = y;
+ if(m_ScrollMode == PagePterModeScroll)
+ view.setCursor (PAGE_VIEW_CURSOR_DRAG);
+ else
+ view.setCursor (PAGE_VIEW_CURSOR_SELECT_TEXT);
}
}
@@ -155,17 +172,46 @@
{
if ( 1 == button )
{
- if(m_LastSelection)
- gdk_region_destroy(m_LastSelection);
- m_LastSelection = NULL;
+ for ( guint pageNum = 0; pageNum < g_pagesCount ; ++pageNum )
+ {
+ if (m_LastSelection[pageNum])
+ gdk_region_destroy(m_LastSelection[pageNum]);
+ m_LastSelection[pageNum] = NULL;
+ }
if ( m_Document->isLoaded() &&
m_ScrollMode == PagePterModeSelectText &&
NULL != m_DragInfo )
{
- DocumentRectangle rect(m_DragInfo->startX, m_DragInfo->startY,
- m_DragInfo->x, m_DragInfo->y);
- m_Document->setTextSelection(&rect);
+
+ gint maxNum = m_Document->getCountOfVisiblePages ();
+ gchar **selections = new gchar *[maxNum];
+ IPageView &view = getView ();
+ for ( gint pageNum = 0; pageNum < maxNum ; ++pageNum )
+ {
+ gint pageStartX = 0;
+ gint pageStartY = 0;
+ view.getPagePosition (m_DragInfo->startX, m_DragInfo->startY,
+ &pageStartX, &pageStartY, pageNum);
+ gint pageX = 0;
+ gint pageY = 0;
+ view.getPagePosition (m_DragInfo->x, m_DragInfo->y,
+ &pageX, &pageY, pageNum);
+
+ DocumentRectangle rect(pageStartX, pageStartY, pageX, pageY);
+ selections[pageNum] = m_Document->getTextSelection(&rect,
+ pageNum);
+ }
+ GString *selection = g_string_new (NULL);
+ for ( gint pageNum = 0; pageNum < maxNum ; ++pageNum )
+ {
+ if ( selections[pageNum] )
+ {
+ g_string_append (selection, selections[pageNum]);
+ g_free (selections[pageNum]);
+ }
+ }
+ m_Document->setTextSelection (g_string_free(selection, FALSE));
}
delete m_DragInfo;
@@ -192,9 +238,23 @@
PagePter::mouseMoved (gint x, gint y)
{
IPageView &view = getView ();
+ gint maxNum = m_Document->getCountOfVisiblePages ();
+
if ( NULL == m_DragInfo )
{
- if ( m_Document->hasLinkAtPosition (x, y) )
+ gboolean isFound = FALSE;
+ for ( gint pageNum = 0; pageNum < maxNum ; ++pageNum )
+ {
+ gint pageX = 0;
+ gint pageY = 0;
+ view.getPagePosition (x, y, &pageX, &pageY, pageNum);
+ if ( m_Document->hasLinkAtPosition (pageX, pageY, pageNum) )
+ {
+ isFound = TRUE;
+ }
+ }
+
+ if ( isFound )
{
view.setCursor (PAGE_VIEW_CURSOR_LINK);
}
@@ -207,26 +267,39 @@
m_DragInfo->x = x;
m_DragInfo->y = y;
- if(m_ScrollMode == PagePterModeScroll){
- view.scrollPage (view.getHorizontalScroll (), view.getVerticalScroll (),
+ if (m_ScrollMode == PagePterModeScroll){
+ view.scrollPage (view.getHorizontalScroll (),
+ view.getVerticalScroll (),
x - m_DragInfo->startX, y - m_DragInfo->startY);
}
else{
- if(!m_Document->isLoaded())
+ if (!m_Document->isLoaded())
return ;
-
- DocumentRectangle rect(m_DragInfo->startX, m_DragInfo->startY,
- m_DragInfo->x, m_DragInfo->y);
-
- GdkRegion *region = m_Document->getTextRegion (&rect);
-
- if( !m_LastSelection || !gdk_region_equal(m_LastSelection, region)){
- if(m_LastSelection)
- gdk_region_destroy(m_LastSelection);
- m_LastSelection = gdk_region_copy(region);
- DocumentPage *page = m_Document->getCurrentPage();
- if ( NULL != page )
- refreshPage (PAGE_SCROLL_NONE, FALSE);
+
+ for ( gint pageNum = 0; pageNum < maxNum ; ++pageNum )
+ {
+ gint pageStartX = 0;
+ gint pageStartY = 0;
+ view.getPagePosition (m_DragInfo->startX, m_DragInfo->startY,
+ &pageStartX, &pageStartY, pageNum);
+ gint pageX = 0;
+ gint pageY = 0;
+ view.getPagePosition (m_DragInfo->x, m_DragInfo->y,
+ &pageX, &pageY, pageNum);
+
+ DocumentRectangle rect(pageStartX, pageStartY, pageX, pageY);
+ GdkRegion *region = m_Document->getTextRegion (&rect, pageNum);
+
+ if ( !m_LastSelection[pageNum] ||
+ !gdk_region_equal(m_LastSelection[pageNum], region))
+ {
+ if(m_LastSelection[pageNum])
+ gdk_region_destroy(m_LastSelection[pageNum]);
+ m_LastSelection[pageNum] = gdk_region_copy(region);
+ DocumentPage *page = m_Document->getCurrentPage (pageNum);
+ if ( NULL != page )
+ refreshPage (PAGE_SCROLL_NONE, FALSE);
+ }
}
}
}
@@ -245,35 +318,50 @@
void
PagePter::notifyLoad ()
{
- g_WaitingForPage = FALSE;
+ for ( guint pageNum = 0 ; pageNum < g_pagesCount ; ++pageNum )
+ {
+ g_WaitingForPage[pageNum] = FALSE;
+ }
refreshPage (PAGE_SCROLL_START, FALSE);
}
void
PagePter::notifyPageChanged (gint pageNum)
{
- g_WaitingForPage = FALSE;
+ for ( guint pageNum = 0 ; pageNum < g_pagesCount ; ++pageNum )
+ {
+ g_WaitingForPage[pageNum] = FALSE;
+ }
refreshPage (m_NextPageScroll, FALSE);
}
void
PagePter::notifyPageRotated (gint rotation)
{
- g_WaitingForPage = FALSE;
+ for ( guint pageNum = 0 ; pageNum < g_pagesCount ; ++pageNum )
+ {
+ g_WaitingForPage[pageNum] = FALSE;
+ }
refreshPage (PAGE_SCROLL_START, FALSE);
}
void
PagePter::notifyPageZoomed (gdouble zoom)
{
- g_WaitingForPage = FALSE;
+ for ( guint pageNum = 0 ; pageNum < g_pagesCount ; ++pageNum )
+ {
+ g_WaitingForPage[pageNum] = FALSE;
+ }
refreshPage (PAGE_SCROLL_NONE, TRUE);
}
void
PagePter::notifyReload ()
{
- g_WaitingForPage = FALSE;
+ for ( guint pageNum = 0 ; pageNum < g_pagesCount ; ++pageNum )
+ {
+ g_WaitingForPage[pageNum] = FALSE;
+ }
refreshPage (PAGE_SCROLL_NONE, FALSE);
}
@@ -283,9 +371,14 @@
g_assert (NULL != user && "The data parameter in NULL.");
PageNotAvailableData *data = (PageNotAvailableData *)user;
- if ( g_WaitingForPage )
+ gboolean isWaiting = FALSE;
+ for ( guint num = 0 ; num < g_pagesCount ; ++num )
+ {
+ isWaiting |= g_WaitingForPage[num];
+ }
+ if ( isWaiting )
{
- data->pter->refreshPage (data->scroll, FALSE);
+ data->pter->refreshPage (data->scroll, FALSE, data->location);
return TRUE;
}
delete data;
@@ -303,46 +396,63 @@
/// to show the scroll this new page.
/// @param wasZoomed If this is set to TRUE then it means that the page
/// has been refreshed because its scaled has changed.
+/// @param pageLocation This determines location (left, right or both) of the
+/// page to be refreshed.
///
void
-PagePter::refreshPage (PageScroll pageScroll, gboolean wasZoomed)
+PagePter::refreshPage (PageScroll pageScroll, gboolean wasZoomed,
+ PageLocation pageLocation)
{
g_assert (NULL != m_Document &&
"Tried to show a page from a NULL document.");
-
if ( m_Document->isLoaded () )
{
IPageView &view = getView ();
- DocumentPage *documentPage = m_Document->getCurrentPage ();
- if ( NULL != documentPage )
+
+ Config &config = Config::getConfig ();
+ if ( !config.dualPages () )
{
- g_WaitingForPage = FALSE;
- if ( NULL != m_LastSelection )
- documentPage->setSelection(m_LastSelection);
- view.showPage (documentPage, pageScroll);
+ pageLocation = PageLocationLeft;
}
- else
+
+ int pageMin = (pageLocation == PageLocationRight) ? 1 : 0;
+ int pageMax = (pageLocation == PageLocationLeft) ? 0 : 1;
+
+ for (int pageIndex = pageMin ; pageIndex <= pageMax ; ++pageIndex )
{
- if ( !g_WaitingForPage )
+ DocumentPage *documentPage = m_Document->getCurrentPage (pageIndex);
+ if ( NULL != documentPage )
{
- documentPage = m_Document->getEmptyPage ();
- if ( wasZoomed )
- {
- view.resizePage (documentPage->getWidth (),
- documentPage->getHeight ());
- }
- else
+ g_WaitingForPage[pageIndex] = FALSE;
+ if ( NULL != m_LastSelection[pageIndex] )
+ documentPage->setSelection(m_LastSelection[pageIndex]);
+ view.showPage (documentPage, pageScroll, pageIndex);
+ }
+ else
+ {
+ if ( !g_WaitingForPage[pageIndex] )
{
- view.showPage (documentPage, pageScroll);
- delete documentPage;
- view.showText (_("Loading..."));
+ documentPage = m_Document->getEmptyPage ();
+ if ( wasZoomed )
+ {
+ view.resizePage (documentPage->getWidth (),
+ documentPage->getHeight ());
+ }
+ else
+ {
+ view.showPage (documentPage, pageScroll, pageIndex);
+ delete documentPage;
+ view.showText (_("Loading..."), pageIndex);
+ }
+
+ g_WaitingForPage[pageIndex] = TRUE;
+ PageNotAvailableData *data = new PageNotAvailableData;
+ data->pter = this;
+ data->scroll = pageScroll;
+ data->location = (pageIndex == 0) ?
+ PageLocationLeft : PageLocationRight;
+ g_idle_add (PagePter::pageNotAvailable, data);
}
-
- g_WaitingForPage = TRUE;
- PageNotAvailableData *data = new PageNotAvailableData;
- data->pter = this;
- data->scroll = pageScroll;
- g_idle_add (PagePter::pageNotAvailable, data);
}
}
}
@@ -452,3 +562,16 @@
m_Document->zoomToWidth (width);
}
}
+
+///
+/// @brief Sets the view mode: single/dual page.
+///
+/// @param active TRUE if Dual Pages mode should be activated,
+/// FALSE otherwise.
+///
+void
+PagePter::setDualPages (gboolean activate)
+{
+ m_PageView->showSecondPage (activate);
+ refreshPage (PAGE_SCROLL_NONE, FALSE);
+}
diff -ur a/src/PagePter.h b/src/PagePter.h
--- a/src/PagePter.h 2009-10-29 23:45:04.000000000 +0300
+++ b/src/PagePter.h 2009-10-30 01:19:38.000000000 +0300
@@ -28,6 +28,12 @@
PagePterModeSelectText,
};
+ enum PageLocation{
+ PageLocationLeft,
+ PageLocationRight,
+ PageLocationBoth,
+ };
+
///
/// @class PagePter.
/// @brief The page presenter.
@@ -58,7 +64,8 @@
void setNextPageScroll (PageScroll next);
void setView (IMainView &view);
void viewResized (gint width, gint height);
- void setMode(PagePterMode mode);
+ void setMode (PagePterMode mode);
+ void setDualPages (gboolean activate);
protected:
/// The document whose page is shown.
@@ -69,12 +76,13 @@
PageScroll m_NextPageScroll;
/// The page view.
IPageView *m_PageView;
- /// Last text selection
- GdkRegion *m_LastSelection;
+ /// Last text selections
+ GdkRegion **m_LastSelection;
/// What page presenter must do when user move mouse with button pressed.
PagePterMode m_ScrollMode;
- void refreshPage (PageScroll pageScroll, gboolean wasZoomed);
+ void refreshPage (PageScroll pageScroll, gboolean wasZoomed,
+ PageLocation pageLocation = PageLocationBoth);
};
}
diff -ur a/src/PDFDocument.cxx b/src/PDFDocument.cxx
--- a/src/PDFDocument.cxx 2009-10-29 23:45:04.000000000 +0300
+++ b/src/PDFDocument.cxx 2009-10-30 01:19:38.000000000 +0300
@@ -669,13 +669,31 @@
}
void
-PDFDocument::setTextSelection (DocumentRectangle *rect)
+PDFDocument::setTextSelection (gchar *text)
+{
+ g_assert(text);
+
+ for ( GList *obs = g_list_first (m_Observers) ;
+ NULL != obs ;
+ obs = g_list_next (obs) )
+ {
+ IDocumentObserver *observer = (IDocumentObserver*)obs->data;
+ observer->notifyTextSelected(text);
+ }
+
+ g_free(text);
+}
+
+
+gchar *
+PDFDocument::getTextSelection (DocumentRectangle *rect, guint index)
{
g_assert(rect);
- PopplerPage *page = poppler_document_get_page (m_Document, getCurrentPageNum()-1);
+ PopplerPage *page = poppler_document_get_page (m_Document,
+ getCurrentPageNum() + index - 1);
if(!page)
- return;
+ return NULL;
gdouble pageWidth, pageHeight;
poppler_page_get_size(page, &pageWidth, &pageHeight);
@@ -693,29 +711,19 @@
#else // !HAVE_POPPLER_0_6_0
gchar *text = poppler_page_get_text(page, &textRect);
#endif // HAVE_POPPLER_0_6_0
- if(!text)
- goto cleanup;
-
- for ( GList *obs = g_list_first (m_Observers) ;
- NULL != obs ;
- obs = g_list_next (obs) )
- {
- IDocumentObserver *observer = (IDocumentObserver*)obs->data;
- observer->notifyTextSelected(text);
- }
- cleanup:
if(page)
g_object_unref(page);
- if(text)
- g_free(text);
+
+ return text;
}
GdkRegion*
-PDFDocument::getTextRegion (DocumentRectangle *r)
+PDFDocument::getTextRegion (DocumentRectangle *r, guint index)
{
GdkRegion *res = NULL;
- PopplerPage *page = poppler_document_get_page (m_Document, getCurrentPageNum()-1);
+ PopplerPage *page = poppler_document_get_page (m_Document,
+ getCurrentPageNum() + index - 1);
if(!page)
return NULL;
diff -ur a/src/PDFDocument.h b/src/PDFDocument.h
--- a/src/PDFDocument.h 2009-10-29 23:45:04.000000000 +0300
+++ b/src/PDFDocument.h 2009-10-30 01:19:38.000000000 +0300
@@ -54,8 +54,9 @@
DocumentPage *renderPage (gint pageNum);
gboolean saveFile (const gchar *fileName, GError **error);
- GdkRegion* getTextRegion (DocumentRectangle* rect);
- void setTextSelection (DocumentRectangle *rect);
+ GdkRegion* getTextRegion (DocumentRectangle* rect, guint index);
+ void setTextSelection (gchar *text);
+ gchar *getTextSelection (DocumentRectangle *rect, guint index);
protected:
/// The PDF document.