+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-#
-# gpdf2swf.py
-# graphical user interface for pdf2swf
-#
-# Part of the swftools package.
-#
-# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-from __future__ import division
-import os
-import wx
-import time
-import pickle
-
-from wx.lib.wordwrap import wordwrap
-from wx.lib.pubsub import Publisher
-
-from document import Document
-from gui import (PdfFrame, ProgressDialog, OptionsDialog, AboutDialog,
- ID_INVERT_SELECTION, ID_SELECT_ODD, ID_SELECT_EVEN)
-
-
-def GetDataDir():
- """
- Return the standard location on this platform for application data
- """
- sp = wx.StandardPaths.Get()
- return sp.GetUserDataDir()
-
-def GetConfig():
- if not os.path.exists(GetDataDir()):
- os.makedirs(GetDataDir())
-
- config = wx.FileConfig(
- localFilename=os.path.join(GetDataDir(), "options"))
- return config
-
-
-class Pdf2Swf:
- def __init__(self):
- self.__doc = Document()
-
- self.__threads = {}
-
- self.__busy = None
- self.__progress = None
-
- self.__can_save = False
-
- self.view = PdfFrame()
- wx.GetApp().SetTopWindow(self.view)
- # Call Show after the current and pending event
- # handlers have been completed. Otherwise on MSW
- # we see the frame been draw and after that we saw
- # the menubar appear
- wx.CallAfter(self.view.Show)
-
- self.options = OptionsDialog(self.view)
- self.__ReadConfigurationFile()
-
- Publisher.subscribe(self.OnPageChanged, "PAGE_CHANGED")
- Publisher.subscribe(self.OnFileLoaded, "FILE_LOADED")
- Publisher.subscribe(self.OnDiffSizes, "DIFF_SIZES")
- Publisher.subscribe(self.OnThumbnailAdded, "THUMBNAIL_ADDED")
- Publisher.subscribe(self.OnThumbnailDone, "THUMBNAIL_DONE")
- Publisher.subscribe(self.OnProgressBegin, "SWF_BEGIN_SAVE")
- Publisher.subscribe(self.OnProgressUpdate, "SWF_PAGE_SAVED")
- Publisher.subscribe(self.OnProgressDone, "SWF_FILE_SAVED")
- Publisher.subscribe(self.OnCombineError, "SWF_COMBINE_ERROR")
- Publisher.subscribe(self.OnFileDroped, "FILE_DROPED")
- Publisher.subscribe(self.OnFilesDroped, "FILES_DROPED")
-
- self.view.Bind(wx.EVT_MENU, self.OnMenuOpen, id=wx.ID_OPEN)
- self.view.Bind(wx.EVT_MENU, self.OnMenuSave, id=wx.ID_SAVE)
- self.view.Bind(wx.EVT_MENU, self.OnMenuSaveSelected, id=wx.ID_SAVEAS)
- self.view.Bind(wx.EVT_MENU, self.OnMenuExit, id=wx.ID_EXIT)
- self.view.Bind(wx.EVT_MENU_RANGE, self.OnFileHistory,
- id=wx.ID_FILE1, id2=wx.ID_FILE9)
-
- self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=wx.ID_SAVE)
- self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=wx.ID_SAVEAS)
-
- self.view.Bind(wx.EVT_MENU, self.OnMenuSelectAll, id=wx.ID_SELECTALL)
- self.view.Bind(wx.EVT_MENU,
- self.OnMenuInvertSelection, id=ID_INVERT_SELECTION)
- self.view.Bind(wx.EVT_MENU, self.OnMenuSelectOdd, id=ID_SELECT_ODD)
- self.view.Bind(wx.EVT_MENU, self.OnMenuSelectEven, id=ID_SELECT_EVEN)
- self.view.Bind(wx.EVT_MENU, self.OnMenuOptions, id=wx.ID_PREFERENCES)
-
- self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=wx.ID_SELECTALL)
- self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=ID_INVERT_SELECTION)
- self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=ID_SELECT_ODD)
- self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=ID_SELECT_EVEN)
-
- self.view.Bind(wx.EVT_MENU, self.OnAbout, id=wx.ID_ABOUT)
-
- self.view.Bind(wx.EVT_MENU, self.OnZoom, id=wx.ID_ZOOM_IN)
- self.view.Bind(wx.EVT_MENU, self.OnZoom, id=wx.ID_ZOOM_OUT)
- self.view.Bind(wx.EVT_MENU, self.OnZoom, id=wx.ID_ZOOM_100)
- self.view.Bind(wx.EVT_MENU, self.OnFit, id=wx.ID_ZOOM_FIT)
-
- self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=wx.ID_ZOOM_IN)
- self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=wx.ID_ZOOM_OUT)
- self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=wx.ID_ZOOM_100)
- self.view.Bind(wx.EVT_UPDATE_UI, self.OnUpdateUI, id=wx.ID_ZOOM_FIT)
-
- self.view.page_list.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnSelectItem)
- self.view.Bind(wx.EVT_CLOSE, self.OnMenuExit)
-
- # statusbar cancel thumbanails generation button
- self.view.statusbar.btn_cancel.Bind(wx.EVT_BUTTON,
- self.OnThumbnailCancel)
-
- def OnFilesDroped(self, evt):
- dlg = wx.MessageDialog(self.view,
- u"You must drop only one file.",
- u"Notice",
- style=wx.OK, pos=wx.DefaultPosition)
- dlg.ShowModal()
- dlg.Destroy()
-
- def OnFileDroped(self, message):
- self.__Load(message.data["filename"])
-
- def OnFileHistory(self, evt):
- # get the file based on the menu ID
- fileNum = evt.GetId() - wx.ID_FILE1
- filename = self.view.filehistory.GetHistoryFile(fileNum)
-
- self.__Load(filename)
-
- def OnProgressBegin(self, message):
- if self.__progress:
- self.__progress.Destroy()
- pages = message.data["pages"]
- style = (
- wx.PD_APP_MODAL|wx.PD_ELAPSED_TIME|
- wx.PD_REMAINING_TIME|wx.PD_CAN_ABORT|
- wx.PD_AUTO_HIDE
- )
- self.__progress = ProgressDialog(u"Saving...",
- u"Start saving SWF pages",
- maximum=pages-1,
- parent=self.view, style=style)
- self.__progress.Show()
- self.view.SetStatusText(u"Saving document...")
-
- def OnProgressUpdate(self, message):
- pagenr = message.data["pagenr"]
- pagenr0 = pagenr - 1 # 0 based
- pages = message.data["pages"]
-
- keep_running, skip = self.__progress.Update(
- pagenr0,
- u"Saving SWF page %d of %d" % (pagenr, pages)
- )
- if not keep_running and self.__threads.has_key("progress"):
- self.view.SetStatusText(u"Cancelling...")
- self.__threads.pop("progress").Stop()
-
- # Send size events to resize the progress dialog,
- # this will allow the progress message label to resize accordingly.
- # Here we minimize that events every 10 times.
- if pagenr0 % 10 == 0:
- self.__progress.SendSizeEvent()
-
- def OnProgressDone(self, message):
- self.__progress.Hide()
- if self.__threads.has_key("progress"): # it goes all the way?
- self.__threads.pop("progress")
- self.view.SetStatusText(u"SWF document saved successfully.")
- else:
- self.view.SetStatusText(u"")
-
- def OnCombineError(self, message):
- from wx.lib.dialogs import ScrolledMessageDialog
- ScrolledMessageDialog(self.view, message.data, u"Notice").ShowModal()
-
-
- def OnThumbnailAdded(self, message):
- self.view.statusbar.SetGaugeValue(message.data['pagenr'])
- tot = self.view.page_list.GetItemCount()
- self.view.SetStatusText(u"Generating thumbnails %s/%d" %
- (message.data['pagenr'], tot), 0)
-
- def OnThumbnailDone(self, message):
- self.view.statusbar.SetGaugeValue(0)
- self.view.SetStatusText(u"", 0)
- if self.__threads.has_key("thumbnails"):
- self.__threads.pop("thumbnails")
-
- def OnThumbnailCancel(self, event):
- if self.__threads.has_key("thumbnails"):
- self.__threads["thumbnails"].Stop()
-
- def OnSelectItem(self, event):
- self.__doc.ChangePage(event.GetIndex() + 1)
-
- def OnPageChanged(self, message):
- # ignore if we have more than one item selected
- if self.view.page_list.GetSelectedItemCount() > 1:
- return
-
- self.view.page_preview.DisplayPage(message.data)
-
- def OnFileLoaded(self, message):
- if self.__progress:
- self.__progress.Destroy()
- self.__progress = None
-
- self.view.SetStatusText(u"Document loaded successfully.")
- self.view.page_list.DisplayEmptyThumbnails(message.data["pages"])
- thumbs = self.__doc.GetThumbnails()
- t = self.view.page_list.DisplayThumbnails(thumbs)
- self.__threads["thumbnails"] = t
- self.view.statusbar.SetGaugeRange(message.data["pages"])
- del self.__busy
-
- def OnDiffSizes(self, message):
- # just let the user know- for now, we can't handle this properly
- self.Message(
- u"In this PDF, width or height are not the same for "
- u"each page. This might cause problems if you export "
- u"pages of different dimensions into the same SWF file."
- )
-
- def OnMenuOpen(self, event):
- dlg = wx.FileDialog(self.view, u"Choose PDF File:",
- style = wx.FD_CHANGE_DIR|wx.FD_OPEN,
- wildcard = u"PDF files (*.pdf)|*.pdf|all files (*.*)|*.*")
-
- if dlg.ShowModal() == wx.ID_OK:
- filename = dlg.GetPath()
- self.__Load(filename)
-
- def OnMenuSave(self, event, pages=None):
- defaultFile = self.__doc.lastsavefile
- allFiles = "*.*" if "wxMSW" in wx.PlatformInfo else "*"
- self.view.SetStatusText(u"")
- dlg = wx.FileDialog(self.view, u"Choose Save Filename:",
- style = wx.SAVE | wx.OVERWRITE_PROMPT,
- defaultFile=defaultFile,
- wildcard=u"SWF files (*.swf)|*.swf"
- "|all files (%s)|%s" % (allFiles, allFiles))
-
- if dlg.ShowModal() == wx.ID_OK:
- self.__threads["progress"] = self.__doc.SaveSWF(dlg.GetPath(),
- pages, self.options)
-
- def OnUpdateUI(self, event):
- menubar = self.view.GetMenuBar()
- menubar.Enable(event.GetId(), self.__can_save)
-
- self.view.GetToolBar().EnableTool(event.GetId(), self.__can_save)
-
- def OnMenuSaveSelected(self, event):
- pages = []
- page = self.view.page_list.GetFirstSelected()
- pages.append(page+1)
-
- while True:
- page = self.view.page_list.GetNextSelected(page)
- if page == -1:
- break
- pages.append(page+1)
-
- self.OnMenuSave(event, pages)
-
- def OnMenuExit(self, event):
- self.view.SetStatusText(u"Cleaning up...")
-
- # Stop any running thread
- self.__StopThreads()
-
- config = GetConfig()
- self.view.filehistory.Save(config)
- config.Flush()
- # A little extra cleanup is required for the FileHistory control
- del self.view.filehistory
-
- # Save quality options
- dirpath = GetDataDir()
- data = self.options.quality_panel.pickle()
- try:
- f = file(os.path.join(dirpath, 'quality.pkl'), 'wb')
- pickle.dump(data, f)
- f.close()
- except IOError:
- pass
-
- # Save viewer options
- try:
- f = file(os.path.join(dirpath, 'viewers.pkl'), 'wb')
- data = self.options.viewers_panel.pickle()
- pickle.dump(data, f)
- f.close()
- except Exception, e:
- pass
-
- self.view.Destroy()
-
- def OnMenuSelectAll(self, event):
- for i in range(0, self.view.page_list.GetItemCount()):
- self.view.page_list.Select(i, True)
-
- def OnMenuInvertSelection(self, event):
- for i in range(0, self.view.page_list.GetItemCount()):
- self.view.page_list.Select(i, not self.view.page_list.IsSelected(i))
-
- def OnMenuSelectOdd(self, event):
- for i in range(0, self.view.page_list.GetItemCount()):
- self.view.page_list.Select(i, not bool(i%2))
-
- def OnMenuSelectEven(self, event):
- for i in range(0, self.view.page_list.GetItemCount()):
- self.view.page_list.Select(i, bool(i%2))
-
- def OnMenuOptions(self, event):
- self.options.ShowModal()
-
- def OnFit(self, event):
- self.__doc.Fit(self.view.page_preview.GetClientSize())
-
- def OnZoom(self, event):
- zoom = {
- wx.ID_ZOOM_IN: .1,
- wx.ID_ZOOM_OUT: -.1,
- wx.ID_ZOOM_100: 1,
- }
- self.__doc.Zoom(zoom[event.GetId()])
-
- def OnAbout(self, evt):
- AboutDialog(self.view)
-
- def __Load(self, filename):
- self.__can_save = True
- self.__StopThreads()
- self.view.SetStatusText(u"Loading document...")
- self.__busy = wx.BusyInfo(u"One moment please, "
- u"opening pdf document...")
-
- self.view.filehistory.AddFileToHistory(filename)
-
- # Need to delay the file load a little bit
- # for the BusyInfo get a change to repaint itself
- wx.FutureCall(150, self.__doc.Load, filename)
-
- def __StopThreads(self):
- for n, t in self.__threads.items():
- t.Stop()
-
- running = True
- while running:
- running = False
- for n, t in self.__threads.items():
- running = running + t.IsRunning()
- time.sleep(0.1)
-
- def __ReadConfigurationFile(self):
- config = GetConfig()
- self.view.filehistory.Load(config)
-
- dirpath = GetDataDir()
- try:
- f = file(os.path.join(dirpath, 'quality.pkl'), 'rb')
- try:
- data = pickle.load(f)
- self.options.quality_panel.unpickle(data)
- except:
- self.Message(
- u"Error loading quality settings. "
- u"They will be reset to defaults. ")
- f.close()
- except IOError:
- pass
-
- try:
- f = file(os.path.join(dirpath, 'viewers.pkl'), 'rb')
- try:
- data = pickle.load(f)
- self.options.viewers_panel.unpickle(data)
- except:
- self.Message(
- u"Error loading viewers settings. "
- u"They will be reset to defaults. ")
- f.close()
- except IOError:
- pass
- #d = pickle.load(f)
-
- def Message(self, message):
- dlg = wx.MessageDialog(self.view,
- message,
- style=wx.OK, pos=wx.DefaultPosition)
- dlg.ShowModal()
- dlg.Destroy()
-
+++ /dev/null
-#!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-#
-# gpdf2swf.py
-# graphical user interface for pdf2swf
-#
-# Part of the swftools package.
-#
-# Copyright (c) 2008,2009 Matthias Kramm <kramm@quiss.org>
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-from __future__ import division
-import os
-import time
-import thread
-import gfx
-import wx
-from wx.lib.pubsub import Publisher
-from subprocess import Popen, PIPE
-
-class _SaveSWFThread:
- def __init__(self, filename, doc, pages, options):
- self.__doc = doc
- self.__filename = filename
- self.__pages = pages or range(1, doc.pages+1)
- self.__options = options
-
- def Start(self):
- self.__keep_running = self.__running = True
- thread.start_new_thread(self.Run, ())
- #self.Run()
-
- def Stop(self):
- self.__keep_running = False
-
- def IsRunning(self):
- return self.__running
-
- def Run(self):
- pages = len(self.__pages)
- wx.CallAfter(Publisher.sendMessage, "SWF_BEGIN_SAVE",
- {'pages': pages,})
-
- time.sleep(0.05)
-
- swf = gfx.SWF()
- self.set_swf_parameters(swf)
-
- plugin = self.__options.viewers.init(swf, self.__filename)
-
- plugin.before_render()
- for i, pagenr in enumerate(self.__pages):
- page = self.__doc.getPage(pagenr)
- swf.startpage(page.width, page.height)
- page.render(swf)
- swf.endpage()
- wx.CallAfter(Publisher.sendMessage, "SWF_PAGE_SAVED",
- {'pagenr': i+1,
- 'pages': pages,})
- time.sleep(0.05)
- if not self.__keep_running:
- break
- else:
- # This will not run if we break the for loop
- plugin.before_save(page)
- swf.save(self.__filename)
- plugin.after_save(page)
-
- # No need. But to be sure that it's clean up
- # as soon as possible
- del swf
-
- wx.CallAfter(Publisher.sendMessage, "SWF_FILE_SAVED")
- time.sleep(0.05)
-
- self.__running = False
-
- def set_swf_parameters(self, swf):
- for opt in self.__options.quality:
- if type(opt.name) in (tuple, list):
- for name, value in (
- # Example to better understand the list comprehension:
- # opt.name = ['a', 'b', 'c']
- # opt.value = [1, 2, 3]
- # zip them = [('a',1), ('b', 2), ('c', 3)]
- # pair will be in this example ('a', 1) due to
- # the if pair[1] condition
- pair for pair in zip(opt.name, opt.value) if pair[1] == 1
- ):
- #print "1.swf.setparameter(%s, %s)" % (name, value)
- swf.setparameter(str(name), str(value))
- else:
- #print "2.swf.setparameter(%s, %s)" % (opt.name, str(opt.value))
- swf.setparameter(opt.name, str(opt.value))
-
-
-class Document:
- def __init__(self):
- self.__page = None
- self.__zoom = 1
- self.__lastsavefile = "output.swf"
-
- def __get_lastsavefile(self):
- return self.__lastsavefile
- def __set_lastsavefile(self, lastsavefile):
- self.__lastsavefile = lastsavefile
- lastsavefile = property(__get_lastsavefile, __set_lastsavefile)
-
- def __SwapExtension(self, filename, newext):
- basename, ext = os.path.splitext(filename)
- return "%s.%s" % (basename, newext)
-
- def __Reload(self):
- Publisher.sendMessage("PAGE_CHANGED",
- {'page': self.__page,
- 'width': int(self.__page.width * self.__zoom),
- 'height': int(self.__page.height * self.__zoom)})
-
- def Load(self, filename):
- self.__lastsavefile = self.__SwapExtension(filename, "swf")
- #self.__htmlfilename = self.__SwapExtension(filename, "html")
- self.__pdf = gfx.open("pdf", filename)
- Publisher.sendMessage("FILE_LOADED", {'pages': self.__pdf.pages})
-
- def ChangePage(self, pagenr=1, size=None):
- self.__page = page = self.__pdf.getPage(pagenr)
- self.__Reload()
-
- def Fit(self, size):
- w = size[0] / self.__page.width
- h = size[1] / self.__page.height
- self.__zoom = min(w, h)
- self.__Reload()
-
- def Zoom(self, zoom):
- self.__zoom = 1 if zoom == 1 else self.__zoom + zoom
- self.__Reload()
-
- def GetThumbnails(self):
- for pagenr in range(1, self.__pdf.pages + 1):
- page = self.__pdf.getPage(pagenr)
- yield page
-
- def SaveSWF(self, filename, pages, options):
- self.__lastsavefile = filename
- t = _SaveSWFThread(filename, self.__pdf, pages, options)
- t.Start()
- return t
-
-