diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
diff --git a/Manatee/Extension/PdfViewer.hs b/Manatee/Extension/PdfViewer.hs
--- a/Manatee/Extension/PdfViewer.hs
+++ b/Manatee/Extension/PdfViewer.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
diff --git a/Manatee/Extension/PdfViewer/PageMode.hs b/Manatee/Extension/PdfViewer/PageMode.hs
--- a/Manatee/Extension/PdfViewer/PageMode.hs
+++ b/Manatee/Extension/PdfViewer/PageMode.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
diff --git a/Manatee/Extension/PdfViewer/PdfBuffer.hs b/Manatee/Extension/PdfViewer/PdfBuffer.hs
--- a/Manatee/Extension/PdfViewer/PdfBuffer.hs
+++ b/Manatee/Extension/PdfViewer/PdfBuffer.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
@@ -17,19 +17,24 @@
 -- along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 {-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE TemplateHaskell #-}
 module Manatee.Extension.PdfViewer.PdfBuffer where
 
 import Control.Applicative
 import Control.Concurrent.STM 
 import Control.Monad
 import DBus.Client hiding (Signal)
+import Data.Binary
 import Data.ByteString.UTF8
+import Data.DeriveTH
 import Data.Maybe
 import Data.Typeable
 import Graphics.UI.Gtk.Poppler.Document hiding (PageMode)
 import Graphics.UI.Gtk.Poppler.Page
+import Manatee.Core.Config
 import Manatee.Core.Types
 import Manatee.Extension.PdfViewer.PageMode
+import Manatee.Toolkit.General.STM
 import Manatee.Toolkit.Gio.Gio
 
 data PdfBuffer =
@@ -40,9 +45,21 @@
               ,pdfBufferDocument            :: Document
               ,pdfBufferNPages              :: Int
               ,pdfBufferPageSize            :: (Double, Double)
+              ,pdfBufferState               :: TVar PdfState
               }
     deriving Typeable
 
+data PdfState =
+    PdfState {pdfStatePageIndex         :: Int
+             ,pdfStateScale             :: Maybe Double
+             ,pdfStatePageSize          :: Maybe (Int, Int)
+             ,pdfStateScrolledPosition  :: (Double, Double)}
+
+-- | Init state.
+pdfInitState :: PdfState
+pdfInitState =
+    PdfState 0 Nothing Nothing (0, 0)
+
 -- | New pdf viewer buffer.
 pdfBufferNew :: String -> [String] -> Client -> PageId -> CustomizeWrap -> IO PdfBuffer
 pdfBufferNew path _ client pageId _ = do
@@ -63,5 +80,21 @@
             <*> pure document
             <*> pure nPages
             <*> pure size
+            <*> newTVarIO pdfInitState
+
       where filepath = filepathGetDisplayName (fromString path)
+
+-- | Write state.
+pdfBufferWriteState :: PdfBuffer -> FilePath -> IO ()
+pdfBufferWriteState buffer path = do
+  state <- readTVarIO $ pdfBufferState buffer
+  writeConfigPath path state
+
+-- | Read state.
+pdfBufferReadState :: PdfBuffer -> FilePath -> IO ()  
+pdfBufferReadState buffer path = do
+  state <- readConfigPath path pdfInitState
+  writeTVarIO (pdfBufferState buffer) state
+  
+$(derive makeBinary ''PdfState)
 
diff --git a/Manatee/Extension/PdfViewer/PdfView.hs b/Manatee/Extension/PdfViewer/PdfView.hs
--- a/Manatee/Extension/PdfViewer/PdfView.hs
+++ b/Manatee/Extension/PdfViewer/PdfView.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
@@ -29,17 +29,18 @@
 import Data.Typeable
 import Graphics.Rendering.Cairo
 import Graphics.UI.Gtk hiding (Statusbar, statusbarNew, get)
-import Graphics.UI.Gtk.Gdk.SerializedEvent
 import Graphics.UI.Gtk.Poppler.Document
 import Graphics.UI.Gtk.Poppler.Page
+import Manatee.Core.Config
 import Manatee.Core.PageFrame
 import Manatee.Core.PageView 
 import Manatee.Core.Types
 import Manatee.Extension.PdfViewer.PdfBuffer
 import Manatee.Toolkit.General.Basic
+import Manatee.Toolkit.General.Maybe
 import Manatee.Toolkit.General.STM
 import Manatee.Toolkit.Gtk.Event
-import Manatee.Toolkit.Gtk.Gtk
+import Manatee.Toolkit.Gtk.ScrolledWindow
 import Paths_manatee_pdfviewer
 import System.FilePath
 
@@ -64,12 +65,17 @@
   pageBufferPackageName _       = fmap takeFileName getDataDir
 
 instance PageView PdfView where
-    pageViewBuffer              = PageBufferWrap . pdfViewBuffer
-    pageViewPlugId              = pdfViewPlugId
-    pageViewBox                 = pageFrameBox . pdfViewFrame
-    pageViewScrolledWindow      = pdfViewScrolledWindow
-    pageViewFocus               = widgetGrabFocus . pdfViewView
-    pageViewHandleKeyAction     = pdfViewHandleKeyAction
+    pageViewBuffer               = PageBufferWrap . pdfViewBuffer
+    pageViewPlugId               = pdfViewPlugId
+    pageViewFrame                = pdfViewFrame
+    pageViewLocalKeymap _        = pdfViewLocalKeymap
+    pageViewLocalCommandMap _    = pdfViewLocalCommandMap
+    pageViewFocus                = widgetGrabFocus . pdfViewView
+    pageViewPropagateWidget      = castToWidget . pdfViewView
+    pageViewSaveState view       = pdfViewSaveState view Nothing
+    pageViewRestoreState view    = pdfViewRestoreState view Nothing
+    pageViewWriteState view path = pdfViewSaveState view (Just path)
+    pageViewReadState view path  = pdfViewRestoreState view (Just path)
 
 -- | New pdf viewer view.
 pdfViewNew :: PdfBuffer -> PagePlugId -> IO PdfView
@@ -88,32 +94,29 @@
   let viewer = PdfView pId pFrame view buffer pageIndex scale
 
   -- Redraw signal.
-  view `on` exposeEvent $ tryEvent $ pdfViewHandleExpose viewer
+  view `after` exposeEvent $ tryEvent $ pdfViewHandleExpose viewer
 
   return viewer
 
 -- | Handle expose signal.
 pdfViewHandleExpose :: PdfView -> EventM EExpose ()
 pdfViewHandleExpose view@(PdfView {pdfViewBuffer        = buffer
-                                  ,pdfViewScale         = viewScale
+                                  ,pdfViewScale         = scaleTVar
                                   }) = do
   (winWidth, _) <- eventWindowSize                    
   liftIO $ do
     let (pageWidth, pageHeight) = pdfBufferPageSize buffer
         area = pdfViewView view
     -- Init scale and size request.
-    readTVarIO viewScale
-      >>= \ value -> 
-          -- Update scale value and area size request when haven't set.
-          when (value == 0) $ do
-             -- Update scale value.
+    scale <- readTVarIO scaleTVar
+    when (scale == 0) $ do
+             putStrLn "Hello"
              let scaleValue = (winWidth / pageWidth)
-             writeTVarIO viewScale scaleValue
-             -- Update size request.
+             writeTVarIO scaleTVar scaleValue
              widgetSetSizeRequest 
-               area 
-               (truncate winWidth) 
-               (truncate (scaleValue * pageHeight * i2d (pdfBufferNPages buffer)))
+                        area 
+                        (truncate winWidth) 
+                        (truncate (scaleValue * pageHeight * i2d (pdfBufferNPages buffer)))
 
     -- Draw.
     pdfViewDraw view 
@@ -150,38 +153,38 @@
           scale scaleValue scaleValue
           pageRender page
                                         
--- | Handle key action. 
-pdfViewHandleKeyAction :: PdfView -> Text -> SerializedEvent -> IO ()
-pdfViewHandleKeyAction view keystoke sEvent = 
-  case M.lookup keystoke pdfViewKeymap of
-    Just action -> action view
-    Nothing -> widgetPropagateEvent (pdfViewView view) sEvent
-
--- | Update adjustment.
-pdfViewUpdateAdjustment :: PdfView -> (Double, Double) -> IO ()
-pdfViewUpdateAdjustment view (width, height) = do
-  let sWin = pdfViewScrolledWindow view
-  hAdj <- scrolledWindowGetHAdjustment sWin
-  vAdj <- scrolledWindowGetVAdjustment sWin
-  adjustmentSetUpper hAdj width
-  adjustmentSetUpper vAdj height
+-- | Keymap.
+pdfViewLocalKeymap :: Map Text Text
+pdfViewLocalKeymap = 
+  M.fromList [("j",        "Scroll step up")
+             ,("k",        "Scroll step down")
+             ,("Down",     "Scroll step up")
+             ,("Up",       "Scroll step down")
+             ,(" ",        "Scroll page up")
+             ,("b",        "Scroll page down")
+             ,("J",        "Scroll to bottom")
+             ,("K",        "Scroll to top")
+             ,("n",        "Next page")
+             ,("p",        "Previous page")
+             ,("N",        "Last page")
+             ,("P",        "First page")
+             ,("g",        "Goto page")
+             ]
 
 -- | Keymap.
-pdfViewKeymap :: Map Text (PdfView -> IO ())
-pdfViewKeymap = 
-  M.fromList [("j",        pageViewScrollVerticalStep True)
-             ,("k",        pageViewScrollVerticalStep False)
-             ,("Down",     pageViewScrollVerticalStep True)
-             ,("Up",       pageViewScrollVerticalStep False)
-             ,(" ",        pageViewScrollVerticalPage True)
-             ,("b",        pageViewScrollVerticalPage False)
-             ,("J",        pageViewScrollToBottom)
-             ,("K",        pageViewScrollToTop)
-             ,("n",        pdfViewNextPage)
-             ,("p",        pdfViewPrevPage)
-             ,("N",        pdfViewLastPage)
-             ,("P",        pdfViewFirstPage)
-             ,("g",        pdfViewGotoPage)
+pdfViewLocalCommandMap :: Map Text (PdfView -> IO ())
+pdfViewLocalCommandMap = 
+  M.fromList [("Scroll step up",        pageViewScrollVerticalStep True)
+             ,("Scroll step down",      pageViewScrollVerticalStep False)
+             ,("Scroll page up",        pageViewScrollVerticalPage True)
+             ,("Scroll page down",      pageViewScrollVerticalPage False)
+             ,("Scroll to bottom",      pageViewScrollToBottom)
+             ,("Scroll to top",         pageViewScrollToTop)
+             ,("Next page",             pdfViewNextPage)
+             ,("Previous page",         pdfViewPrevPage)
+             ,("Last page",             pdfViewLastPage)
+             ,("First page",            pdfViewFirstPage)
+             ,("Goto page",             pdfViewGotoPage)
              ]
 
 -- | Get index range to render visible are.
@@ -218,11 +221,11 @@
   destIndex <-
     if page < minIndex
        then do
-         pageFrameShowOutputbar (pdfViewFrame view) "Out of bound, goto first page." Nothing 
+         pageViewShowOutputbar view "Out of bound, goto first page." Nothing 
          return minIndex
     else if page > maxIndex
        then do
-         pageFrameShowOutputbar (pdfViewFrame view) "Out of bound, goto last page." Nothing
+         pageViewShowOutputbar view "Out of bound, goto last page." Nothing
          return maxIndex
        else return page
   vAdj <- scrolledWindowGetVAdjustment $ pdfViewScrolledWindow view
@@ -255,7 +258,7 @@
 pdfViewGotoPage :: PdfView -> IO ()
 pdfViewGotoPage view@(PdfView {pdfViewBuffer = buffer}) = do
   let maxPage = pdfBufferNPages buffer
-  localInteractive view ("nGoto page (1 - " ++ show maxPage ++ ") : ") $ \ [page] -> do
+  interactive view [(INum, "Goto page (1 - " ++ show maxPage ++ ") : ", "")] $ \ [page] -> do
     let pageNumber = read page :: Int
     pdfViewSetPage view (pageNumber - 1)
 
@@ -263,3 +266,55 @@
 pdfViewScrolledWindow :: PdfView -> ScrolledWindow    
 pdfViewScrolledWindow =
     pageFrameScrolledWindow . pdfViewFrame
+
+-- | Save state.
+pdfViewSaveState :: PdfView -> Maybe FilePath -> IO ()
+pdfViewSaveState view@(PdfView {pdfViewBuffer     = buffer
+                               ,pdfViewView       = area}) 
+                 statePath = do
+  -- Get page index.
+  pageIndex <- readTVarIO (pdfViewPageIndex view)
+
+  -- Get scale.
+  scale <- readTVarIO (pdfViewScale view)
+
+  -- Get page size.
+  (Rectangle _ _ w h) <- widgetGetAllocation area
+
+  -- Get scroll position.
+  scrolledWindowPosition <- scrolledWindowGetValue (pdfViewScrolledWindow view)
+
+  -- Save state.
+  let state = PdfState pageIndex (Just scale) (Just (w, h)) scrolledWindowPosition
+  case statePath of
+    Nothing   -> writeTVarIO (pdfBufferState buffer) state
+    Just path -> writeConfigPath path state
+
+-- | Restore state.
+pdfViewRestoreState :: PdfView -> Maybe FilePath -> IO ()
+pdfViewRestoreState view@(PdfView {pdfViewBuffer                = buffer
+                                  ,pdfViewView                  = area})
+                    statePath = do
+  let scrolledWindow = pdfViewScrolledWindow view
+
+  bufferState <- readTVarIO (pdfBufferState buffer)
+  (PdfState pageIndex scale size scrolledWindowPosition) <- 
+      case statePath of
+        Just path -> readConfigPath path bufferState
+        Nothing   -> return bufferState
+
+  -- Restore page index.
+  writeTVarIO (pdfViewPageIndex view) pageIndex
+
+  -- Restore scale.
+  scale ?>= (writeTVarIO (pdfViewScale view))
+
+  -- Restore page size.
+  size ?>= \ (w, h) -> do
+    widgetSetSizeRequest area w h
+    scrolledWindowSetUpper scrolledWindow (i2d w, i2d h)
+
+  -- Restore scroll position.
+  scrolledWindowSetValue scrolledWindow scrolledWindowPosition
+
+  return ()
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,7 +1,7 @@
 -- Author:     Andy Stewart <lazycat.manatee@gmail.com>
 -- Maintainer: Andy Stewart <lazycat.manatee@gmail.com>
 -- 
--- Copyright (C) 2010 Andy Stewart, all rights reserved.
+-- Copyright (C) 2010 ~ 2011 Andy Stewart, all rights reserved.
 -- 
 -- This program is free software: you can redistribute it and/or modify
 -- it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
 import Distribution.Simple
 import Manatee.Core.Config
 import Manatee.Core.Types
+import Manatee.Toolkit.Cabal.Utils
 import Manatee.Toolkit.General.List
 import Manatee.Toolkit.General.Map
 import Manatee.Extension.PdfViewer.PageMode
@@ -28,7 +29,7 @@
 main = defaultMainWithHooks 
        -- Update Rule after install successful.
        simpleUserHooks {
-         postInst = \ _ _ _ _ -> do
+         postInst = \ _ _ pack_des lbi -> do
              -- Update PageTypeRule.
              (PageTypeRule rule) <- readConfig pageTypeRulePath (PageTypeRule M.empty)
              writeConfig pageTypeRulePath (PageTypeRule (M.insert "PagePDF" "manatee-pdfviewer" rule))
@@ -46,4 +47,13 @@
              (PageModeRule modeRule) <- readConfig pageModeRulePath (PageModeRule M.empty)
              writeConfig pageModeRulePath (PageModeRule 
                                                 (M.insert "PagePDF" (Left $ pageModeName pdfMode) modeRule))
+             -- Update Application info.
+             let snapshotPath = getDataFilePath pack_des lbi "data/welcome/snapshot.png"
+                 rwhPdf = getDataFilePath pack_des lbi "data/welcome/LearnYouAHaskell.pdf"
+             (WelcomeApplication apps) <- readConfig welcomeApplicationPath (WelcomeApplication M.empty)
+             writeConfig welcomeApplicationPath (WelcomeApplication
+                                                 (M.insert 
+                                                       ("Pdf Viewer", snapshotPath)
+                                                       ("PagePDF", rwhPdf, [])
+                                                       apps))
        }
diff --git a/data/welcome/LearnYouAHaskell.pdf b/data/welcome/LearnYouAHaskell.pdf
new file mode 100644
Binary files /dev/null and b/data/welcome/LearnYouAHaskell.pdf differ
diff --git a/data/welcome/snapshot.png b/data/welcome/snapshot.png
new file mode 100644
Binary files /dev/null and b/data/welcome/snapshot.png differ
diff --git a/manatee-pdfviewer.cabal b/manatee-pdfviewer.cabal
--- a/manatee-pdfviewer.cabal
+++ b/manatee-pdfviewer.cabal
@@ -1,9 +1,9 @@
 name:			manatee-pdfviewer
-version:		0.0.8
+version:		0.1.0
 Cabal-Version:	>= 1.6
 license:		GPL-3
 license-file:	LICENSE
-copyright:		(c) 2009 ~ 2010 Andy Stewart
+copyright:		(c) 2010 ~ 2011 Andy Stewart
 synopsis:		PDF viewer extension for Manatee.
 description:    manatee-pdfviewer is PDF viewer extension for Manatee (Haskell/Gtk+ Integrated Live Environment)
  .
@@ -15,7 +15,7 @@
  .
  And replace Chinese font string in file `/etc/fonts/conf.d/49-sansserif.conf'
  .
- Video at (Select 720p HD) at : <http://www.youtube.com/watch?v=weS6zys3U8k> <http://www.youtube.com/watch?v=A3DgKDVkyeM> <http://v.youku.com/v_show/id_XMjI2MDMzODI4.html>
+ Video (Select 720p HD) at : <http://www.youtube.com/watch?v=weS6zys3U8k> <http://www.youtube.com/watch?v=A3DgKDVkyeM> <http://v.youku.com/v_show/id_XMjI2MDMzODI4.html>
  .
  Screenshots at : <http://goo.gl/MkVw>
  .
@@ -30,16 +30,20 @@
 stability:		provisional
 category:		Manatee, PDF Viewer, PDF
 
-tested-with:	GHC==6.12.3
+tested-with:	GHC==7.0.2
 build-type:		Custom
 
+data-dir: ""
+data-files: data/welcome/snapshot.png
+            data/welcome/LearnYouAHaskell.pdf
+
 Source-Repository head
   type:         darcs
   location:     http://patch-tag.com/r/AndyStewart/manatee-pdfviewer
   
 Library
-     build-depends: base >= 4 && < 5, manatee-core >= 0.0.8, dbus-client >= 0.3 && < 0.4, stm >= 2.1.2.0,
-                    containers >= 0.3.0.0, gtk-serialized-event >= 0.12.0, poppler >= 0.12.1, gtk >= 0.12.0,
+     build-depends: base >= 4 && < 5, manatee-core >= 0.1.0, dbus-client >= 0.3 && < 0.4, stm >= 2.1.2.0,
+                    containers >= 0.3.0.0, poppler >= 0.12.1, gtk >= 0.12.0, derive, binary,
                     cairo >= 0.12.0, text >= 0.7.1.0, mtl >= 1.1.0.2, utf8-string, filepath
      exposed-modules:
          Manatee.Extension.PdfViewer
