{-# LANGUAGE CPP, DeriveDataTypeable #-} -- GIMP Toolkit (GTK) Binding for Haskell: binding to poppler -*-haskell-*- -- -- Author : Andy Stewart -- Created: 18-Jun-2010 -- -- Copyright (c) 2010 Andy Stewart -- -- This library is free software: you can redistribute it and/or -- modify it under the terms of the GNU Lesser General Public License -- as published by the Free Software Foundation, either version 3 of -- the License, or (at your option) any later version. -- -- This library is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- Lesser General Public License for more details. -- -- You should have received a copy of the GNU Lesser General Public -- License along with this program. If not, see -- . -- -- POPPLER, the C library which this Haskell library depends on, is -- available under LGPL Version 2. The documentation included with -- this library is based on the original POPPLER documentation. -- -- TODO : -- poppler_font_info_scan -- -- | Maintainer : gtk2hs-devel@lists.sourceforge.net -- Stability : alpha -- Portability : portable (depends on GHC) module Graphics.UI.Gtk.Poppler.Document ( -- * Details -- -- | The 'Document' is an object used to refer to a main document. -- * Types Document, DocumentClass, Page, PageClass, IndexIter, FontsIter, FontsIterClass, FontInfo, FontInfoClass, Dest, FormField, Action, PSFile, PSFileClass, -- * Enums FontType (..), PageLayout (..), PageMode (..), Permissions (..), ViewerPreferences (..), -- * Methods documentNewFromFile, documentNewFromData, documentSave, documentGetNPages, documentGetPage, documentGetPageByLabel, documentFindDest, documentHasAttachments, documentGetAttachments, documentGetFormField, indexIterNew, indexIterCopy, indexIterGetChild, indexIterIsOpen, indexIterNext, indexIterGetAction, fontInfoNew, fontsIterCopy, fontsIterGetName, fontsIterGetFullName, fontsIterGetFontType, fontsIterIsEmbedded, fontsIterIsSubset, fontsIterNext, psFileNew, psFileSetPaperSize, psFileSetDuplex, -- * Attributes documentAuthor, documentCreationDate, documentCreator, documentFormat, documentFormatMajor, documentFormatMinor, documentKeywords, documentLinearized, documentMetadata, documentModDate, documentPageLayout, documentPageMode, documentPermissions, documentProducer, documentSubject, documentTitle, documentViewerPreferences, documentLabel, ) where import Control.Monad import Data.Typeable import System.Glib.Attributes import System.Glib.Properties import System.Glib.FFI import System.Glib.Flags import System.Glib.GList import System.Glib.GError import System.Glib.GObject import System.Glib.UTFString import Graphics.UI.Gtk.Poppler.Enums import Graphics.UI.Gtk.Poppler.Action (Action, Dest, makeNewAction, makeNewDest) {#import Graphics.UI.Gtk.Poppler.Types#} {# context lib="poppler" prefix="poppler" #} -- | Creates a new 'Document'. If 'Nothing' is returned, then error will be set. Possible errors include -- those in the 'Error' and GFileError domains. documentNewFromFile :: String -- ^ @uri@ uri of the file to load -> Maybe String -- ^ @password@ password to unlock the file with, or 'Nothing' -> IO (Maybe Document) -- ^ returns A newly created 'Document', or 'Nothing' documentNewFromFile uri password = maybeNull (wrapNewGObject mkDocument) $ withUTFString uri $ \ uriPtr -> maybeWith withUTFString password $ \ passwordPtr -> propagateGError ({# call poppler_document_new_from_file #} uriPtr passwordPtr) -- | Creates a new 'Document'. If 'Nothing' is returned, then error will be set. Possible errors include -- those in the 'Error' and GFileError domains. documentNewFromData :: String -- ^ @data@ the pdf data contained in a char array -> Maybe String -- ^ @password@ password to unlock the file with, or 'Nothing' -> IO (Maybe Document) -- ^ returns A newly created 'Document', or 'Nothing' documentNewFromData dat password = maybeNull (wrapNewGObject mkDocument) $ withUTFString dat $ \ datPtr -> maybeWith withUTFString password $ \ passwordPtr -> propagateGError ({#call poppler_document_new_from_data #} datPtr (fromIntegral (length dat)) passwordPtr) -- | Saves document. Any change made in the document such as form fields filled by the user will be -- saved. If error is set, 'False' will be returned. Possible errors include those in the GFileError -- domain. documentSave :: DocumentClass doc => doc -> String -- ^ @uri@ uri of file to save -> IO Bool -- ^ returns 'True', if the document was successfully saved documentSave doc uri = liftM toBool $ withUTFString uri $ \ uriPtr -> propagateGError ({#call poppler_document_save #} (toDocument doc) uriPtr) -- | Returns the number of pages in a loaded document. documentGetNPages :: DocumentClass doc => doc -> IO Int -- ^ returns Number of pages documentGetNPages doc = liftM fromIntegral $ {#call poppler_document_get_n_pages #} (toDocument doc) -- | Returns the 'Page' indexed at index. This object is owned by the caller. -- | 'Page's are indexed starting at 0. documentGetPage :: DocumentClass doc => doc -> Int -- ^ @index@ a page index -> IO Page -- ^ returns The 'Page' at index documentGetPage doc index = wrapNewGObject mkPage $ {#call poppler_document_get_page#} (toDocument doc) (fromIntegral index) -- | Returns the 'Page' reference by label. This object is owned by the caller. label is a -- human-readable string representation of the page number, and can be document specific. Typically, it -- is a value such as "iii" or "3". -- -- By default, "1" refers to the first page. documentGetPageByLabel :: DocumentClass doc => doc -> String -- ^ @label@ a page label -> IO Page -- ^ returns The 'Page' referenced by label documentGetPageByLabel doc label = wrapNewGObject mkPage $ withUTFString label $ \ labelPtr -> {#call poppler_document_get_page_by_label #} (toDocument doc) labelPtr -- | Finds named destination @linkName@ in document documentFindDest :: DocumentClass doc => doc -> String -- ^ @linkName@ a named destination -> IO (Maybe Dest) -- ^ returns The 'Dest' destination or 'Nothing' if @linkName@ is not a destination. documentFindDest doc linkName = withUTFString linkName $ \ linkNamePtr -> do destPtr <- {#call poppler_document_find_dest #} (toDocument doc) linkNamePtr if destPtr == nullPtr then return Nothing else liftM Just $ makeNewDest (castPtr destPtr) -- | Returns 'True' of document has any attachments. documentHasAttachments :: DocumentClass doc => doc -> IO Bool -- ^ returns 'True', if document has attachments. documentHasAttachments doc = liftM toBool $ {#call poppler_document_has_attachments #} (toDocument doc) -- | Returns the 'FormField' for the given id. documentGetFormField :: DocumentClass doc => doc -> Int -- ^ @id@ an id of a 'FormField' -> IO (Maybe FormField) documentGetFormField doc id = maybeNull (wrapNewGObject mkFormField) $ {#call poppler_document_get_form_field #} (toDocument doc) (fromIntegral id) -- | Create a new postscript file to render to psFileNew :: DocumentClass doc => doc -> String -- ^ @filename@ the path of the output filename -> Int -- ^ @firstPage@ the first page to print -> Int -- ^ @nPages@ the number of pages to print -> IO PSFile psFileNew doc filename firstPage nPages = wrapNewGObject mkPSFile $ withUTFString filename $ \ filenamePtr -> {#call poppler_ps_file_new #} (toDocument doc) filenamePtr (fromIntegral firstPage) (fromIntegral nPages) -- | Set the output paper size. These values will end up in the DocumentMedia, the BoundingBox DSC -- comments and other places in the generated PostScript. psFileSetPaperSize :: PSFileClass file => file -- ^ @psFile@ a 'PSFile' which was not yet printed to. -> Double -- ^ @width@ the paper width in 1/72 inch -> Double -- ^ @height@ the paper height in 1/72 inch -> IO () psFileSetPaperSize psFile width height = {#call poppler_ps_file_set_paper_size #} (toPSFile psFile) (realToFrac width) (realToFrac height) -- | Enable or disable Duplex printing. psFileSetDuplex :: PSFileClass file => file -- ^ @psFile@ a 'PSFile' which was not yet printed to -> Bool -- ^ @duplex@ whether to force duplex printing (on printers which support this) -> IO () psFileSetDuplex psFile duplex = {#call poppler_ps_file_set_duplex#} (toPSFile psFile) (fromBool duplex) -- | Returns a GList containing 'Attachment's. documentGetAttachments :: DocumentClass doc => doc -> IO [Attachment] documentGetAttachments doc = do glistPtr <- {#call poppler_document_get_attachments #} (toDocument doc) list <- fromGList glistPtr attachs <- mapM (wrapNewGObject mkAttachment . return) list {#call unsafe g_list_free #} glistPtr return attachs -- | Returns the root 'IndexIter' for document, or 'Nothing'. indexIterNew :: DocumentClass doc => doc -> IO (Maybe IndexIter) indexIterNew doc = do iterPtr <- {#call poppler_index_iter_new #} (toDocument doc) if iterPtr == nullPtr then return Nothing else liftM Just (makeNewIndexIter (castPtr iterPtr)) {#pointer *IndexIter foreign newtype #} makeNewIndexIter :: Ptr IndexIter -> IO IndexIter makeNewIndexIter rPtr = do iter <- newForeignPtr rPtr indexIter_free return (IndexIter iter) foreign import ccall unsafe "&poppler_index_iter_free" indexIter_free :: FinalizerPtr IndexIter -- | Creates a new 'IndexIter' as a copy of iter. indexIterCopy :: IndexIter -> IO IndexIter indexIterCopy iter = {#call poppler_index_iter_copy #} iter >>= makeNewIndexIter -- | Returns a newly created child of parent, or 'Nothing' if the iter has no child. See -- 'indexIterNew' for more information on this function. indexIterGetChild :: IndexIter -> IO (Maybe IndexIter) indexIterGetChild iter = do iterPtr <- {#call poppler_index_iter_get_child #} iter if iterPtr == nullPtr then return Nothing else liftM Just (makeNewIndexIter iterPtr) -- | Returns whether this node should be expanded by default to the user. The document can provide a hint -- as to how the document's index should be expanded initially. indexIterIsOpen :: IndexIter -> IO Bool -- ^ returns 'True', if the document wants iter to be expanded indexIterIsOpen iter = liftM toBool $ {#call poppler_index_iter_is_open #} iter -- | Sets iter to point to the next action at the current level, if valid. See 'indexIterNew' -- for more information. indexIterNext :: IndexIter -> IO Bool -- ^ returns 'True', if iter was set to the next action indexIterNext iter = liftM toBool $ {#call poppler_index_iter_next #} iter -- | Returns the 'Action' associated with iter. indexIterGetAction :: IndexIter -> IO Action indexIterGetAction iter = {#call poppler_index_iter_get_action #} iter >>= makeNewAction . castPtr -- | fontInfoNew :: DocumentClass doc => doc -> IO FontInfo fontInfoNew doc = wrapNewGObject mkFontInfo $ {#call poppler_font_info_new#} (toDocument doc) -- | fontsIterCopy :: FontsIterClass iter => iter -> IO FontsIter fontsIterCopy iter = wrapNewGObject mkFontsIter $ {#call poppler_fonts_iter_copy #} (toFontsIter iter) -- | fontsIterGetName :: FontsIterClass iter => iter -> IO String fontsIterGetName iter = {#call poppler_fonts_iter_get_name #} (toFontsIter iter) >>= peekUTFString -- | fontsIterGetFullName :: FontsIterClass iter => iter -> IO String fontsIterGetFullName iter = {#call poppler_fonts_iter_get_full_name #} (toFontsIter iter) >>= peekUTFString -- | fontsIterGetFontType :: FontsIterClass iter => iter -> IO FontType fontsIterGetFontType iter = liftM (toEnum . fromIntegral) $ {#call poppler_fonts_iter_get_font_type #} (toFontsIter iter) -- | fontsIterIsEmbedded :: FontsIterClass iter => iter -> IO Bool fontsIterIsEmbedded iter = liftM toBool $ {#call poppler_fonts_iter_is_embedded #} (toFontsIter iter) -- | fontsIterIsSubset :: FontsIterClass iter => iter -> IO Bool fontsIterIsSubset iter = liftM toBool $ {#call poppler_fonts_iter_is_subset #} (toFontsIter iter) -- | fontsIterNext :: FontsIterClass iter => iter -> IO Bool -- ^ returns 'True', if iter was set to the next action fontsIterNext iter = liftM toBool $ {#call poppler_fonts_iter_next #} (toFontsIter iter) ------------------- -- Attributes -- | The author of the document. -- -- Default value: \"\" documentAuthor :: DocumentClass doc => ReadAttr doc String documentAuthor = readAttrFromStringProperty "author" -- | The date and time the document was created. -- -- Allowed values: >= 0 -- -- Default value: 0 documentCreationDate :: DocumentClass doc => ReadAttr doc Int documentCreationDate = readAttrFromIntProperty "creation-date" -- | The software that created the document. -- -- Default value: \"\" documentCreator :: DocumentClass doc => ReadAttr doc String documentCreator = readAttrFromStringProperty "creator" -- | The PDF version of the document. -- -- Default value: \"\" documentFormat :: DocumentClass doc => ReadAttr doc String documentFormat = readAttrFromStringProperty "format" -- | The PDF major version number of the document. -- -- Default value: 1 documentFormatMajor :: DocumentClass doc => ReadAttr doc String documentFormatMajor = readAttrFromStringProperty "format-major" -- | The PDF minor version number of the document. -- -- Default value: 0 documentFormatMinor :: DocumentClass doc => ReadAttr doc String documentFormatMinor = readAttrFromStringProperty "format-minor" -- | Keywords. -- -- Default value: \"\" documentKeywords :: DocumentClass doc => ReadAttr doc String documentKeywords = readAttrFromStringProperty "keywords" -- | Is the document optimized for web viewing?. -- -- Default value: \"\" documentLinearized :: DocumentClass doc => ReadAttr doc String documentLinearized = readAttrFromStringProperty "linearized" -- | Embedded XML metadata. -- -- Default value: \"\" documentMetadata :: DocumentClass doc => ReadAttr doc String documentMetadata = readAttrFromStringProperty "metadata" -- | The date and time the document was modified. -- -- Allowed values: >= 0 -- -- Default value: 0 documentModDate :: DocumentClass doc => ReadAttr doc Int documentModDate = readAttrFromIntProperty "mod-date" -- | Initial Page Layout. -- -- Default value: 'PageLayoutUnset' documentPageLayout :: DocumentClass doc => ReadAttr doc PageLayout documentPageLayout = readAttrFromEnumProperty "page-layout" {#call pure unsafe poppler_page_layout_get_type #} -- | Page Mode. -- -- Default value: 'PageModeUnset' documentPageMode :: DocumentClass doc => ReadAttr doc PageMode documentPageMode = readAttrFromEnumProperty "page-mode" {#call pure unsafe poppler_page_mode_get_type #} -- | Permissions. -- -- Default value: 'PermissionsFull' documentPermissions :: DocumentClass doc => ReadAttr doc Permissions documentPermissions = readAttrFromEnumProperty "permissions" {#call pure unsafe poppler_permissions_get_type #} -- | The software that converted the document. -- -- Default value: \"\" documentProducer :: DocumentClass doc => ReadAttr doc String documentProducer = readAttrFromStringProperty "producer" -- | Subjects the document touches. -- -- Default value: \"\" documentSubject :: DocumentClass doc => ReadAttr doc String documentSubject = readAttrFromStringProperty "subject" -- | The title of the document. -- -- Default value: \"\" documentTitle :: DocumentClass doc => ReadAttr doc String documentTitle = readAttrFromStringProperty "title" -- | Viewer Preferences. documentViewerPreferences :: DocumentClass doc => ReadAttr doc ViewerPreferences documentViewerPreferences = readAttrFromEnumProperty "viewer-preferences" {#call pure unsafe poppler_viewer_preferences_get_type #} -- | The label of the page. -- -- Default value: \"\" documentLabel :: DocumentClass doc => ReadAttr doc String documentLabel = readAttrFromStringProperty "label"