diff options
| -rw-r--r-- | backend/epub/epub-document.c | 148 | ||||
| -rw-r--r-- | backend/epub/epubdocument.atril-backend.in | 2 | ||||
| -rw-r--r-- | libdocument/ev-document.c | 28 | ||||
| -rw-r--r-- | libdocument/ev-document.h | 5 | ||||
| -rw-r--r-- | shell/ev-window.c | 67 | 
5 files changed, 196 insertions, 54 deletions
| diff --git a/backend/epub/epub-document.c b/backend/epub/epub-document.c index 39c114e3..b61d2eac 100644 --- a/backend/epub/epub-document.c +++ b/backend/epub/epub-document.c @@ -23,6 +23,7 @@ typedef enum _xmlParseReturnType  typedef struct _contentListNode {        gchar* key ;      gchar* value ; +	gint index ;  }contentListNode;  typedef struct _EpubDocumentClass EpubDocumentClass; @@ -65,14 +66,6 @@ epub_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document,  }  static void -epub_document_get_page_size (EvDocument *document, -			       EvPage     *page, -			       double     *width, -			       double     *height) -{ -} - -static void  epub_document_thumbnails_get_dimensions (EvDocumentThumbnails *document,  					   EvRenderContext      *rc,  					   gint                 *width, @@ -80,9 +73,10 @@ epub_document_thumbnails_get_dimensions (EvDocumentThumbnails *document,  {  	gdouble page_width, page_height; -	epub_document_get_page_size (EV_DOCUMENT (document), rc->page, -				       &page_width, &page_height); - +	/*epub_document_get_page_size (EV_DOCUMENT (document), rc->page, +				       &page_width, &page_height);*/ +	page_width = 800 ; +	page_width = 600 ;  	if (rc->rotation == 90 || rc->rotation == 270) {  		*width = (gint) (page_height * rc->scale);  		*height = (gint) (page_width * rc->scale); @@ -486,7 +480,7 @@ extract_one_file(EpubDocument* epub_document,GError ** error)      g_string_free(gfilepath,TRUE);      g_free(currentfilename);      g_free(buffer); -         +    return TRUE;  }  static gboolean  @@ -585,7 +579,7 @@ get_uri_to_content(const gchar* uri,GError ** error,gchar* tmp_archive_dir)  {      GError *   err = NULL ;       gchar*     containerpath = g_filename_from_uri(uri,NULL,&err); -    GString*   absolutepath = g_string_new(NULL); +    GString*   absolutepath ;      gchar*     content_uri ;      xmlNodePtr rootfileNode ;      xmlChar*   relativepath; @@ -613,7 +607,7 @@ get_uri_to_content(const gchar* uri,GError ** error,gchar* tmp_archive_dir)          return NULL ;      } -    if ( set_xml_root_node("container") == FALSE)  { +    if ( set_xml_root_node((xmlChar*)"container") == FALSE)  {          g_set_error_literal(error,                              EV_DOCUMENT_ERROR, @@ -622,7 +616,7 @@ get_uri_to_content(const gchar* uri,GError ** error,gchar* tmp_archive_dir)          return NULL ;      } -    if ( (rootfileNode = xml_get_pointer_to_node("rootfile","media-type","application/oebps-package+xml")) == NULL) +    if ( (rootfileNode = xml_get_pointer_to_node((xmlChar*)"rootfile",(xmlChar*)"media-type",(xmlChar*)"application/oebps-package+xml")) == NULL)      {          g_set_error_literal(error,                              EV_DOCUMENT_ERROR, @@ -640,8 +634,8 @@ get_uri_to_content(const gchar* uri,GError ** error,gchar* tmp_archive_dir)                              _("epub file is corrupt,no container"));          return NULL ;      } -    g_string_printf(absolutepath,"%s/%s",tmp_archive_dir,relativepath); - +	absolutepath = g_string_new(tmp_archive_dir); +    g_string_append_printf(absolutepath,"/%s",relativepath);      content_uri = g_filename_to_uri(absolutepath->str,NULL,&err);      if ( !content_uri )  {      if (err) { @@ -655,7 +649,7 @@ get_uri_to_content(const gchar* uri,GError ** error,gchar* tmp_archive_dir)          }          return NULL ;      } -    free(absolutepath); +    g_string_free(absolutepath,TRUE);      return content_uri ;   } @@ -665,7 +659,7 @@ setup_document_content_list(const gchar* content_uri, GError** error,gchar *tmp_  {      GList* newlist = NULL ;      GError *   err = NULL ;  -     +    gint indexcounter= 1;      xmlNodePtr manifest,spine,itemrefptr,itemptr ;      gboolean errorflag = FALSE; @@ -681,7 +675,7 @@ setup_document_content_list(const gchar* content_uri, GError** error,gchar *tmp_          return FALSE ;      } -    if ( set_xml_root_node("package") == FALSE)  { +    if ( set_xml_root_node((xmlChar*)"package") == FALSE)  {          g_set_error_literal(error,                              EV_DOCUMENT_ERROR, @@ -690,7 +684,7 @@ setup_document_content_list(const gchar* content_uri, GError** error,gchar *tmp_          return FALSE ;      } -    if ( ( spine = xml_get_pointer_to_node("spine",NULL,NULL) )== NULL )   +    if ( ( spine = xml_get_pointer_to_node((xmlChar*)"spine",NULL,NULL) )== NULL )        {           g_set_error_literal(error,                              EV_DOCUMENT_ERROR, @@ -699,7 +693,7 @@ setup_document_content_list(const gchar* content_uri, GError** error,gchar *tmp_          return FALSE ;      } -    if ( ( manifest = xml_get_pointer_to_node("manifest",NULL,NULL) )== NULL )   +    if ( ( manifest = xml_get_pointer_to_node((xmlChar*)"manifest",NULL,NULL) )== NULL )        {           g_set_error_literal(error,                              EV_DOCUMENT_ERROR, @@ -711,7 +705,7 @@ setup_document_content_list(const gchar* content_uri, GError** error,gchar *tmp_      xmlretval = NULL ;      /*Get first instance of itemref from the spine*/ -    xml_parse_children_of_node(spine,"itemref",NULL,NULL); +    xml_parse_children_of_node(spine,(xmlChar*)"itemref",NULL,NULL);      if ( xmlretval != NULL )          itemrefptr = xmlretval ; @@ -730,7 +724,7 @@ setup_document_content_list(const gchar* content_uri, GError** error,gchar *tmp_          if ( xmlStrcmp(itemrefptr->name,(xmlChar*)"itemref") == 0)          {                  contentListNode* newnode = g_malloc0(sizeof(newnode));     -            newnode->key = xml_get_data_from_node(itemrefptr,XML_ATTRIBUTE,(xmlChar*)"idref"); +            newnode->key = (gchar*)xml_get_data_from_node(itemrefptr,XML_ATTRIBUTE,(xmlChar*)"idref");                     if ( newnode->key == NULL )              {                  errorflag =TRUE;     @@ -748,7 +742,7 @@ setup_document_content_list(const gchar* content_uri, GError** error,gchar *tmp_                  errorflag=TRUE;                  break;              } -            relativepath = xml_get_data_from_node(itemptr,XML_ATTRIBUTE,(xmlChar*)"href"); +            relativepath = (gchar*)xml_get_data_from_node(itemptr,XML_ATTRIBUTE,(xmlChar*)"href");              g_string_assign(absolutepath,tmp_archive_dir);              g_string_append_printf(absolutepath,"/%s",relativepath);              newnode->value = g_filename_to_uri(absolutepath->str,NULL,&err); @@ -757,6 +751,8 @@ setup_document_content_list(const gchar* content_uri, GError** error,gchar *tmp_                  errorflag =TRUE;                      break;              } + +			newnode->index = indexcounter++ ;              newlist = g_list_prepend(newlist,newnode);          }          itemrefptr = itemrefptr->next ; @@ -781,7 +777,7 @@ setup_document_content_list(const gchar* content_uri, GError** error,gchar *tmp_          g_list_free_full(newlist,(GDestroyNotify)free_tree_nodes);          return NULL ;      } - +	newlist = g_list_reverse(newlist);      g_string_free(absolutepath,TRUE);      return newlist ; @@ -823,6 +819,13 @@ epub_document_load (EvDocument* document,  		return FALSE;  	} +	extract_epub_from_container (uri,epub_document,&err); + +	if ( err ) +	{ +		g_propagate_error( error,err ); +		return FALSE; +	}  	/*FIXME : can this be different, ever?*/  	containerpath = g_string_new(epub_document->tmp_archive_dir);  	g_string_append_printf(containerpath,"/META-INF/container.xml"); @@ -841,8 +844,13 @@ epub_document_load (EvDocument* document,  		return FALSE;  	} +	xml_free_doc() ; +	  	epub_document->contentList = setup_document_content_list (contentOpfUri,&err,epub_document->tmp_archive_dir); +	if ( xmldocument != NULL ) +		xml_free_doc (); +	  	if ( epub_document->contentList == NULL )  	{  		g_propagate_error(error,err); @@ -875,6 +883,91 @@ epub_document_finalize (GObject *object)  	G_OBJECT_CLASS (epub_document_parent_class)->finalize (object);  } +static EvDocumentInfo* +epub_document_get_info(EvDocument *document) +{ +	EpubDocument *epub_document = EPUB_DOCUMENT(document); +	GError *error = NULL ; +	gchar* infofile ; +	xmlNodePtr metanode ; +	GString* buffer ; +	gchar* archive_dir = epub_document->tmp_archive_dir; +	GString* containerpath = g_string_new(epub_document->tmp_archive_dir); +	g_string_append_printf(containerpath,"/META-INF/container.xml"); +	gchar* containeruri = g_filename_to_uri(containerpath->str,NULL,&error); +	if ( error ) +	{ +		return NULL ; +	} +	gchar* uri = get_uri_to_content (containeruri,&error,archive_dir); +	if ( error ) +	{ +		return NULL ; +	} +	EvDocumentInfo* epubinfo = g_new0 (EvDocumentInfo, 1); +	 +	if ( xmldocument != NULL ) +		xml_free_doc(); +	 +	infofile = g_filename_from_uri(uri,NULL,&error); +	if ( error ) +		return epubinfo; +	 +	open_xml_document(infofile); + +	set_xml_root_node((xmlChar*)"package"); + +	metanode = xml_get_pointer_to_node((xmlChar*)"title",NULL,NULL); +	if ( metanode == NULL ) +	  epubinfo->title = NULL ; +	else +	  epubinfo->title = (char*)xml_get_data_from_node(metanode,XML_KEYWORD,NULL); +	 +	metanode = xml_get_pointer_to_node((xmlChar*)"creator",NULL,NULL); +	if ( metanode == NULL ) +	  epubinfo->author = g_strdup("unknown"); +	else +	  epubinfo->author = xml_get_data_from_node(metanode,XML_KEYWORD,NULL); + +	metanode = xml_get_pointer_to_node((xmlChar*)"subject",NULL,NULL); +	if ( metanode == NULL ) +	   epubinfo->subject = g_strdup("unknown"); +	else +	   epubinfo->subject = xml_get_data_from_node(metanode,XML_KEYWORD,NULL); + +	buffer = g_string_new(xml_get_data_from_node (xmlroot,XML_ATTRIBUTE,(xmlChar*)"version")); +	g_string_prepend(buffer,"epub "); +	epubinfo->format = g_strdup(buffer->str); +	 +	/*FIXME: Add more of these as you write the corresponding modules*/ +	epubinfo->permissions = EV_DOCUMENT_PERMISSIONS_OK_TO_ADD_NOTES; + +	epubinfo->layout = EV_DOCUMENT_LAYOUT_SINGLE_PAGE; + +	metanode = xml_get_pointer_to_node((xmlChar*)"publisher",NULL,NULL); +	if ( metanode == NULL ) +	   epubinfo->creator = g_strdup("unknown"); +	else +	   epubinfo->creator = xml_get_data_from_node(metanode,XML_KEYWORD,NULL); + +	/*TODO : Add a function to get date*/ +	g_free(uri); +	g_string_free(containerpath,TRUE); +	g_string_free(buffer,TRUE); +	return epubinfo ; +} + +static EvPage* +epub_document_get_page(EvDocument *document, +                       gint index) +{ +	EpubDocument *epub_document = EPUB_DOCUMENT(document); +	EvPage* page = ev_page_new(index); +	contentListNode *listptr = g_list_nth_data (epub_document->contentList,--index); +	page->backend_page = g_strdup(listptr->value); +	return page ; +} +  static void  epub_document_class_init (EpubDocumentClass *klass)  { @@ -886,6 +979,7 @@ epub_document_class_init (EpubDocumentClass *klass)  	ev_document_class->load = epub_document_load;  	ev_document_class->save = epub_document_save;  	ev_document_class->get_n_pages = epub_document_get_n_pages; -	ev_document_class->get_page_size = epub_document_get_page_size;  	ev_document_class->render = epub_document_render; +	ev_document_class->get_info = epub_document_get_info;  +	ev_document_class->get_page = epub_document_get_page;  } diff --git a/backend/epub/epubdocument.atril-backend.in b/backend/epub/epubdocument.atril-backend.in index fe97354b..ef7767eb 100644 --- a/backend/epub/epubdocument.atril-backend.in +++ b/backend/epub/epubdocument.atril-backend.in @@ -1,4 +1,4 @@  [Atril Backend]  Module=epubdocument -_TypeDescription=ePub Documents +_TypeDescription=epub Documents  MimeType=application/epub+zip; diff --git a/libdocument/ev-document.c b/libdocument/ev-document.c index 19d51d9b..588d0d89 100644 --- a/libdocument/ev-document.c +++ b/libdocument/ev-document.c @@ -26,6 +26,7 @@  #include "ev-document.h"  #include "synctex_parser.h" +#include "ev-file-helpers.h"  #define EV_DOCUMENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EV_TYPE_DOCUMENT, EvDocumentPrivate)) @@ -141,6 +142,8 @@ ev_document_init (EvDocument *document)  	/* Assume all pages are the same size until proven otherwise */  	document->priv->uniform = TRUE; +	/* Assume that the document is not a web document*/ +	document->iswebdocument = FALSE ;  }  static void @@ -237,6 +240,14 @@ ev_document_load (EvDocument  *document,  	gboolean retval;  	GError *err = NULL; +	/* +	 * Hardcoding a check for ePub documents, cause it needs a web document DOM +	 * and webkit, support for any other web document types can be added similarly. +	 */ + +	if ( !g_strcmp0 (ev_file_get_mime_type(uri,TRUE,&err),"application/epub+zip") ) +		document->iswebdocument=TRUE ; +		  	retval = klass->load (document, uri, &err);  	if (!retval) {  		if (err) { @@ -258,16 +269,28 @@ ev_document_load (EvDocument  *document,  		/* Cache some info about the document to avoid  		 * going to the backends since it requires locks  		 */ +  		priv->uri = g_strdup (uri); -		priv->n_pages = _ev_document_get_n_pages (document); +		priv->n_pages = _ev_document_get_n_pages (document); +		  		for (i = 0; i < priv->n_pages; i++) { + +			/* +			 * Since there is no sense of paging in an ePub,it makes no sense to have pages sizes. +			 * We are however geeneralising the scenario by considering epub as a type of web document. +			 * FIXME: Labels, or bookmarks though, can be done. +			 */ +			if ( document->iswebdocument == TRUE ) +				break; +			  			EvPage     *page = ev_document_get_page (document, i);  			gdouble     page_width = 0;  			gdouble     page_height = 0;  			EvPageSize *page_size;  			gchar      *page_label; - +			 +			  			_ev_document_get_page_size (document, page, &page_width, &page_height);  			if (i == 0) { @@ -277,6 +300,7 @@ ev_document_load (EvDocument  *document,  				priv->max_height = priv->uniform_height;  				priv->min_width = priv->uniform_width;  				priv->min_height = priv->uniform_height; +				  			} else if (priv->uniform &&  				   (priv->uniform_width != page_width ||  				    priv->uniform_height != page_height)) { diff --git a/libdocument/ev-document.h b/libdocument/ev-document.h index d10d261a..940c7c80 100644 --- a/libdocument/ev-document.h +++ b/libdocument/ev-document.h @@ -85,6 +85,11 @@ struct _EvDocument  	GObject base;  	EvDocumentPrivate *priv; +		/* +	 * Since we can only access the members of this structure from the window frontend, +	 * we need a flag to detemine whether to replace the atril-view with a web-view. +	 */ +	gboolean	iswebdocument;  };  struct _EvDocumentClass diff --git a/shell/ev-window.c b/shell/ev-window.c index 9219a7cb..a423da98 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -1369,8 +1369,8 @@ ev_window_setup_document (EvWindow *ev_window)  	ev_window->priv->setup_document_idle = 0;  	ev_window_refresh_window_thumbnail (ev_window); - -	ev_window_set_page_mode (ev_window, PAGE_MODE_DOCUMENT); +	if ( document->iswebdocument == FALSE ) +		ev_window_set_page_mode (ev_window, PAGE_MODE_DOCUMENT);  	ev_window_title_set_document (ev_window->priv->title, document);  	ev_window_title_set_uri (ev_window->priv->title, ev_window->priv->uri); @@ -1405,12 +1405,15 @@ ev_window_setup_document (EvWindow *ev_window)  	info = ev_document_get_info (document);  	update_document_mode (ev_window, info->mode); - -	if (EV_WINDOW_IS_PRESENTATION (ev_window)) +	/*FIXME*/ +	if (EV_WINDOW_IS_PRESENTATION (ev_window) && document->iswebdocument == FALSE)  		gtk_widget_grab_focus (ev_window->priv->presentation_view); -	else -		gtk_widget_grab_focus (ev_window->priv->view); - +	else { +		if ( gtk_widget_get_parent(ev_window->priv->view) != NULL ) +			gtk_widget_grab_focus (ev_window->priv->view); +		else +			gtk_widget_grab_focus (ev_window->priv->web_view); +	}  	return FALSE;  } @@ -1431,15 +1434,28 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document)  	if (ev_document_get_n_pages (document) <= 0) {  		ev_window_warning_message (ev_window, "%s",  					   _("The document contains no pages")); -	} else if (!ev_document_check_dimensions (document)) { +	} else if (!ev_document_check_dimensions (document) && document->iswebdocument == FALSE) {  		ev_window_warning_message (ev_window, "%s",  					   _("The document contains only empty pages"));  	} +#ifdef ENABLE_EPUB +	else if (document->iswebdocument == TRUE){ -	if (EV_WINDOW_IS_PRESENTATION (ev_window)) { +		/*We have encountered a web document, replace the atril view with a web view.*/ +		gtk_container_remove (GTK_CONTAINER(ev_window->priv->scrolled_window),ev_window->priv->view); +		gtk_container_add (GTK_CONTAINER (ev_window->priv->scrolled_window), +				   ev_window->priv->web_view); +		gtk_widget_show(ev_window->priv->web_view); +	} +#endif +	if (EV_WINDOW_IS_PRESENTATION (ev_window) && document->iswebdocument == FALSE) {  		gtk_widget_destroy (ev_window->priv->presentation_view);  		ev_window->priv->presentation_view = NULL;  		ev_window_run_presentation (ev_window); +	} else if ( EV_WINDOW_IS_PRESENTATION (ev_window) && document->iswebdocument == TRUE ) +	{ +		ev_window_warning_message (ev_window, "%s", +					   _("Presentation mode is currently not supported for Web documents."));  	}  	if (ev_window->priv->setup_document_idle > 0) @@ -1539,7 +1555,7 @@ ev_window_load_job_cb (EvJob *job,  	ev_view_set_loading (EV_VIEW (ev_window->priv->view), FALSE);  	/* Success! */ -	if (!ev_job_is_failed (job)) { +	if (!ev_job_is_failed (job)) {    		ev_document_model_set_document (ev_window->priv->model, document);  #ifdef ENABLE_DBUS @@ -5295,13 +5311,24 @@ ev_window_dispose (GObject *object)  	}  	if (priv->view) { -		g_object_unref (priv->view); +		if ( gtk_widget_get_parent (priv->view) == NULL ) +		{ +			g_object_ref_sink (priv->view); +		} +		else +		{ +			g_object_unref (priv->view); +		}  		priv->view = NULL;  	}  #ifdef ENABLE_EPUB  	if ( priv->web_view ) { -		g_object_unref (priv->web_view); +		if (gtk_widget_get_parent(priv->web_view) == NULL )    { +			g_object_ref_sink (priv->web_view); +		}else { +			g_object_unref (priv->web_view); +		}  		priv->web_view = NULL ;  	}  #endif @@ -7079,18 +7106,10 @@ ev_window_init (EvWindow *ev_window)  	/* We own a ref on these widgets, as we can swap them in and out */  	g_object_ref (ev_window->priv->view);  	g_object_ref (ev_window->priv->password_view); -#ifdef ENABLE_EPUB -	if (0) -	{ -		gtk_container_add (GTK_CONTAINER (ev_window->priv->scrolled_window), -			   ev_window->priv->web_view); -	} -	else -#endif -	{ -		gtk_container_add (GTK_CONTAINER (ev_window->priv->scrolled_window), -			   ev_window->priv->view); -	} +	 +	gtk_container_add (GTK_CONTAINER (ev_window->priv->scrolled_window), +		   ev_window->priv->view); +  	/* Connect to model signals */  	g_signal_connect_swapped (ev_window->priv->model,  				  "page-changed", | 
