2 # -*- coding: ISO-8859-15 -*-
7 sys.path+=["../lib/python"]
16 # gfx.setparameter("wxwindowparams", "1")
18 # gfx.setoption("wxwindowparams", "1")
22 self.simpleviewer_bitmap = wx.BitmapFromImage(wx.ImageFromData(images.simpleviewer_width,images.simpleviewer_height,images.simpleviewer_data))
23 self.raw_bitmap = wx.BitmapFromImage(wx.ImageFromData(images.raw_width,images.raw_height,images.raw_data))
24 self.motionpaper_bitmap = wx.BitmapFromImage(wx.ImageFromData(images.motionpaper_width,images.motionpaper_height,images.motionpaper_data))
25 self.rfxview_bitmap = wx.BitmapFromImage(wx.ImageFromData(images.rfxview_width,images.rfxview_height,images.rfxview_data))
28 HTMLTEMPLATE = """<html>
29 <body style="padding: 0px; margin: 0px">
30 <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
33 codebase="http://active.macromedia.com/flash5/cabs/swflash.cab#version=%(version)d,0,0,0">
34 <param name="MOVIE" value="%(swffilename)s">
35 <param name="PLAY" value="true">
36 <param name="LOOP" value="true">
37 <param name="QUALITY" value="high">
38 <param name="FLASHVARS" value="%(flashvars)s">
39 <embed src="%(swffilename)s" width="%(width)s" height="%(height)s"
40 play="true" ALIGN="" loop="true" quality="high"
41 type="application/x-shockwave-flash"
42 flashvars="%(flashvars)s"
43 pluginspage="http://www.macromedia.com/go/getflashplayer">
51 dlg = wx.MessageDialog(None, msg, "Error", style=wx.OK, pos=wx.DefaultPosition)
55 def savefilestatus(msg):
56 dlg = wx.MessageDialog(None, msg, "Save file status", style=wx.OK, pos=wx.DefaultPosition)
60 def swfcombine(params):
62 if os.path.sep == '/':
63 locations = [os.path.join(basedir, "swfcombine"),
64 "/usr/local/bin/swfcombine",
68 locations = [os.path.join(basedir, "swfcombine.exe"),
69 "c:\\swftools\\swfcombine.exe"]
75 if hasattr(os,"spawnv"):
76 print "spawnv",exe,params
77 ret = os.spawnv(os.P_WAIT, exe, [exe]+params)
81 cmd = exe + " " + (" ".join(params))
85 error("Couldn't execute swfcombine.exe- error code "+str(ret))
93 class ProgressFrame(wx.Dialog):
94 def __init__(self, parent, message=""):
95 wx.Dialog.__init__(self, parent, -1, "Progress", size=(350, 150))
96 panel = wx.Panel(self, -1)
99 self.msg = wx.StaticText(panel, -1, message, (20,25))
100 self.gauge = wx.Gauge(panel, -1, 100, (20, 50), (250, 25))
102 self.gauge.SetBezelFace(3)
103 self.gauge.SetShadowWidth(3)
105 self.Bind(wx.EVT_WINDOW_DESTROY, self.close, id=wx.ID_CLOSE)
107 def setProgress(self, num):
108 self.gauge.SetValue(int(num))
110 def close(self, event):
114 def swapextension(filename,newext):
115 basename,ext = os.path.splitext(filename)
116 return basename + "." + newext
118 def has_different_size_pages(doc):
120 for i in range(1,doc.pages+1):
121 page = doc.getPage(i)
123 width,height = page.width,page.height
125 if abs(width-page.width)>2 or \
126 abs(height-page.height)>2:
135 def __init__(self, parameter, text, options, default, mapping=None):
136 self.parameter = parameter
138 self.options = options
139 self.default = default
140 self.mapping = mapping
145 def generateControl(self, panel):
146 if type(self.options) == type((0,)):
147 control = wx.Choice(panel, -1, choices=self.options)
148 control.SetSelection(self.default)
149 elif self.options == "slider":
150 control = wx.Slider(panel, -1, self.default, 0, 100, size=(100, -1), style=wx.SL_HORIZONTAL|wx.SL_LABELS|wx.SL_TOP)
151 elif self.options == "spinner":
152 control = wx.SpinCtrl(panel, -1, str(self.default))
154 control = wx.Choice(panel, -1, choices=["broken"])
155 control.SetSelection(0)
157 self.control = control
160 def getSettings(self):
162 if type(self.options) == type((0,)):
163 value = self.options[self.control.GetCurrentSelection()]
164 if self.mapping and value in self.mapping:
165 value = str(self.mapping[value])
170 return {self.parameter:value}
171 elif self.options == "slider" or self.options == "spinner":
172 value = str(self.control.GetValue())
173 return {self.parameter:value}
179 class Option2(Option):
181 def __init__(self, parameter, text, options, default, mapping=None):
182 Option.__init__(self, parameter, text, options, default, mapping)
185 def generateControl(self, panel):
186 p = wx.Panel(panel, -1)
187 #p.SetOwnBackgroundColour('#ff0000')
188 h = wx.BoxSizer(wx.HORIZONTAL)
189 control = wx.Choice(p, -1, choices=self.options)
190 control.SetSelection(self.default)
191 text = wx.StaticText(p, -1, self.text)
192 h.Add(text,1,wx.EXPAND|wx.ALIGN_LEFT|wx.TOP, 5)
193 h.Add(control,1,wx.EXPAND|wx.ALIGN_RIGHT|wx.ALIGN_TOP)
194 self.control = control
206 self.control.Disable()
211 self.control.Enable()
213 def getSettings(self):
216 return Option.getSettings(self)
218 class ChooseAndText(Option):
219 def __init__(self, parameter, text, options, default, editselection, textvalue=""):
220 Option.__init__(self, parameter, text, options, default)
221 self.editselection = editselection
222 self.selection = default
223 self.textvalue = textvalue
227 def generateControl(self, panel):
228 p = wx.Panel(panel, -1)
229 h = wx.BoxSizer(wx.HORIZONTAL)
230 control = wx.Choice(p, -1, choices=self.options)
231 p.Bind(wx.EVT_CHOICE, self.OnChoice, control)
232 control.SetSelection(self.default)
233 text = wx.StaticText(p, -1, self.text)
234 if self.selection == self.editselection:
235 edittext = wx.TextCtrl(p, -1, self.textvalue)
238 edittext = wx.TextCtrl(p, -1, "")
240 p.Bind(wx.EVT_TEXT, self.OnText, edittext)
241 h.Add(text,1,wx.EXPAND|wx.ALIGN_LEFT|wx.TOP, 5)
242 h.Add(control,1,wx.EXPAND|wx.ALIGN_RIGHT)
243 h.Add(edittext,1,wx.EXPAND|wx.ALIGN_RIGHT)
244 self.choice = control
245 self.edittext = edittext
254 def OnText(self, event):
255 text = self.edittext.GetValue()
256 text2 = "".join(c for c in text if c.isdigit())
258 self.edittext.SetValue(text2)
260 def OnChoice(self, event):
261 self.selection = self.choice.GetCurrentSelection()
262 if self.selection != self.editselection:
263 if not self.textvalue and self.edittext.GetValue():
264 self.textvalue = self.edittext.GetValue()
265 self.edittext.SetValue("")
266 self.edittext.Disable()
268 if self.textvalue and not self.edittext.GetValue():
269 self.edittext.SetValue(self.textvalue)
271 self.edittext.Enable()
277 self.choice.Disable()
278 self.edittext.Disable()
285 if self.choice.GetCurrentSelection() == self.editselection:
286 if self.textvalue and not self.edittext.GetValue():
287 self.edittext.SetValue(self.textvalue)
289 self.edittext.Enable()
291 self.edittext.Disable()
293 def getSettings(self):
296 if self.choice.GetCurrentSelection() != self.editselection:
297 value = self.options[self.choice.GetCurrentSelection()]
299 value = self.edittext.GetValue().strip()
300 return {self.parameter:value}
303 def __init__(self, parameter, label, default=""):
304 self.parameter = parameter
306 self.default = default
309 def generateControl(self, panel):
310 v = wx.BoxSizer(wx.VERTICAL)
311 self.control = wx.TextCtrl(panel, -1, self.default, size=(250, -1))
315 def getSettings(self):
317 for items in self.control.GetValue().split(" "):
321 settings[l[0]] = l[1]
328 class RadioOption(Option):
329 def __init__(self, text, options):
331 self.options = options
332 self.selected = "==nothing=="
336 def generateControl(self, panel):
337 control = wx.Panel(panel, -1)
338 vsplit = wx.BoxSizer(wx.VERTICAL)
339 for i in range(len(self.options)/2):
340 text = self.options[i*2]
342 c = wx.RadioButton(control, -1, text, style=wx.RB_GROUP)
344 c = wx.RadioButton(control, -1, text)
345 control.Bind(wx.EVT_RADIOBUTTON, self.OnRadio, c)
348 control.SetSizer(vsplit)
350 self.control = control
353 def OnRadio(self, event):
354 self.selected = event.GetEventObject().GetLabel()
356 def getSettings(self):
357 for i in range(len(self.options)/2):
358 if self.options[i*2] == self.selected:
359 return self.options[i*2+1]
360 return self.options[1]
362 class BitmapWindow(wx.Window):
363 def __init__(self, parent, image):
364 wx.Window.__init__(self, parent, -1)
366 self.SetMinSize((image.GetWidth()+2, image.GetHeight()+2))
367 self.SetMaxSize((image.GetWidth()+2, image.GetHeight()+2))
368 self.SetSize((image.GetWidth()+2, image.GetHeight()+2))
369 self.Bind(wx.EVT_PAINT, self.OnPaint)
371 def OnPaint(self, event):
372 dc = wx.PaintDC(self)
374 def Draw(self,dc=None):
376 dc = wx.ClientDC(self)
377 dc.DrawRectangleRect((0, 0, self.image.GetWidth()+2, self.image.GetHeight()+2))
378 dc.DrawBitmap(self.image, 1, 1, False)
380 class ImageRadioOption(Option):
381 def __init__(self, text, options):
383 self.options = options
384 self.selected = "==nothing=="
389 def generateControl(self, panel):
390 control = wx.Panel(panel, -1)
391 vsplit = wx.BoxSizer(wx.VERTICAL)
393 for image,text,params,selected,extraoptions in self.options:
394 hsplit = wx.BoxSizer(wx.HORIZONTAL)
396 v = wx.BoxSizer(wx.VERTICAL)
398 name,text = text.split("- ")
400 c = wx.CheckBox(control, -1, name)
401 control.Bind(wx.EVT_CHECKBOX, self.OnRadio, c)
403 # radio buttons crash windows when clicked on- even without event bindings.
404 # This is caused by the subpanel which is created for extra options
405 # (I tried this with a empty Panel(), and even that crashed)
407 # c = wx.RadioButton(control, -1, name, style=wx.RB_GROUP)
409 # c = wx.RadioButton(control, -1, name)
410 #control.Bind(wx.EVT_RADIOBUTTON, self.OnRadio, c)
412 self.ids += [c.GetId()]
416 if "disable" in text:
419 self.selected = c.GetId()
425 bitmap = BitmapWindow(control, image)
426 t = wx.StaticText(control, -1, text, size=(400,50))
428 v.Add(c, 0, wx.EXPAND)
429 v.Add(t, 0, wx.EXPAND|wx.LEFT, 20)
431 for o in extraoptions:
432 cx = o.generateControl(control)
437 v.Add(cx, 0, wx.EXPAND|wx.LEFT, 20)
439 v.SetMinSize((330,170))
441 hsplit.Add(bitmap, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.ALIGN_TOP, 5)
442 hsplit.Add(v, 0, wx.EXPAND)
443 vsplit.Add(hsplit, 0, wx.EXPAND)
445 control.SetSizer(vsplit)
447 self.control = control
450 def OnRadio(self, event):
451 self.selected = event.GetEventObject().GetId()
452 for c in self.radios:
453 if c.GetId() == self.selected:
458 for image,text,params,selected,extraoptions in self.options:
459 if self.ids[i] == self.selected:
460 for xo in extraoptions:
464 for xo in extraoptions:
468 event.ResumePropagation(0)
470 def getSettings(self):
472 for image,text,params,s,extraoptions in self.options:
475 if id == self.selected:
480 class OptionFrame(wx.Dialog):
482 def __init__(self, parent):
483 wx.Dialog.__init__(self, parent, -1, "Options")
485 #self.nb = wx.Notebook(self, -1)#, wx.Point(0,0), wx.Size(0,0), wxNB_FIXEDWIDTH)
486 self.nb = wx.Notebook(self, -1)
490 options0 = [RadioOption('Rendering mode',
491 ["Convert polygons to polygons and fonts to fonts", {},
492 "Convert fonts to fonts, everything else to bitmaps", {"poly2bitmap":"1"},
493 "Convert everthing to bitmaps", {"poly2bitmap":"1", "bitmapfonts":"1"}
497 sv_options = [Option2('flashversion', 'Flash version:', ('4','5','6','7','8'), 2),
498 Option2('transparent', 'Make SWF file transparent:', ('no','yes'), 0),
501 raw_options = [Option2('flashversion', 'Flash version:', ('4','5','6','7','8','9'), 2),
502 Option2('insertstop', 'Insert stop after each frame:', ('no','yes'), 0),
503 Option2('transparent', 'Make SWF file transparent:', ('no','yes'), 0),
505 rfxview_options = [ChooseAndText('rfxwidth', 'Width:', ('same as PDF','fullscreen','custom'),1,2,"600"),
506 ChooseAndText('rfxheight', 'Height:', ('same as PDF','fullscreen','custom'),1,2,"800"),
507 Option2('rfxzoomtype', 'Initial zoom level:', ('Original resolution','Show all','Maximum width/height'),2),
510 options4 = [ImageRadioOption('Select Paging GUI',
511 [(staticdata.raw_bitmap, "No Viewer- The SWF will be in \"raw\" format, with each page a seperate frame. Use this if you want to add a viewer yourself afterwards.", {}, 0, raw_options),
512 (staticdata.simpleviewer_bitmap, "SimpleViewer- A tiny viewer, which attaches directly to the SWF, and provides small previous/next buttons in the upper left corner", {"simpleviewer":"1", "insertstop":"1"}, 0, sv_options),
513 (staticdata.rfxview_bitmap, "rfxView- A more sophisticated viewer with zooming and scrolling.", {"rfxview":"1", "flashversion":"8"}, 1, rfxview_options),
514 #(staticdata.motionpaper_bitmap, "MotionPaper- A highly sophisticated viewer with page flipping. (disabled in this evaluation version)", {}, 0, mp_options),
515 #(staticdata.motionpaper_bitmap, "Your advertisement here- Are you are company who developed a viewer for pdf2swf, or who offers commercial PDF hosting service? Place your advertisement or demo viewer here, or allow pdf2swf to upload SWFs directly to your site! contact sales@swftools.org for details.", {}, 0, mp_options),
518 options1 = [Option('zoom', 'Resolution (in dpi):', "spinner", 72),
519 Option('fontquality', 'Font quality:', "slider", 20),
520 Option('storeallcharacters', 'Insert full fonts in SWF file:', ('no','yes'), 0),
521 Option('splinequality', 'Polygon quality:', "slider", 100),
522 Option('jpegquality', 'JPEG quality:', "slider", 75),
523 Option('jpegsubpixels', 'JPEG image resolution:', ('same as in PDF', '1x', '2x', '4x'), 0, {"same as in PDF": 0, "1x": 1, "2x": 2, "3x": 3}),
524 Option('ppmsubpixels', 'non-JPEG image resolution:', ('same as in PDF', '1x', '2x', '4x'), 0, {"same as in PDF": 0, "1x": 1, "2x": 2, "3x": 3}),
528 options3 = [TextOption('_additional_', 'Additional options')]
530 panel1 = [('Rendering options', options0,''),
531 ('Quality',options1,'v')]
532 panel3 = [('Select paging GUI', options4,'')]
533 panel4 = [('Additional options', options3,'')]
535 panels = [('Quality', panel1),
537 ('Advanced', panel4)]
539 for name,poptions in panels:
540 panel = wx.Panel(self.nb, -1)
541 self.nb.AddPage(panel, name)
543 vsplit = wx.BoxSizer(wx.VERTICAL)
545 for name,options,align in poptions:
546 optiongroup = wx.StaticBox(panel, -1, name)
547 optiongroupsizer= wx.StaticBoxSizer(optiongroup, wx.VERTICAL)
548 optiongroup.SetSizer(optiongroupsizer)
551 grid = wx.GridSizer(rows=len(options), cols=2, hgap=3, vgap=3)
552 optiongroupsizer.Add(grid, 1, wx.EXPAND, 0)
554 grid = wx.GridSizer(rows=len(options), cols=1, hgap=3, vgap=3)
555 optiongroupsizer.Add(grid, 1, wx.EXPAND, 0)
557 for option in options:
559 t = wx.StaticText(panel, -1, option.text)
560 grid.Add(t, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
561 optionbox = option.generateControl(panel)
562 grid.Add(optionbox, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
564 vsplit.Add(optiongroupsizer, 0, wx.EXPAND, 0)
566 #hs = wx.BoxSizer(wx.HORIZONTAL)
567 #hs.Add(gobutton, 0, wx.ALIGN_CENTER, 0)
568 gobutton = wx.Button(panel, -1, "Apply")
569 self.Bind(wx.EVT_BUTTON, self.Apply, gobutton)
571 vsplit.Add(gobutton, 0, wx.ALIGN_CENTER|wx.ALL, 0)
573 panel.SetSizer(vsplit)
581 def updateOptions(self):
582 global options,gfx_options
585 # FIXME: we clear *our* options- but gfx will still have
586 # stored the old ones. Critical for options in the "imageradio" section.
589 print "----- options ------"
590 for option in options:
591 for k,v in option.getSettings().items():
593 gfx.setparameter(k,v)
597 # TODO: filter out "global" options, and do this only if
598 # pdf layer is affected
600 def Apply(self, event):
611 self.pagebitmap = None
612 self.bitmap_width = 0
613 self.bitmap_height = 0
616 self.status_text = None
617 self.lastsavefile = "output.swf"
618 self.lasthtmlfile = "index.html"
622 def onEvent(self,event_type, function):
623 self.listeners += [(event_type,function)]
624 def loadPDF(self,filename):
625 self.filename = filename
626 self.lastsavefile = swapextension(filename,"swf")
627 self.lasthtmlfile = swapextension(filename,"html")
629 self.pdf = gfx.open("pdf",filename)
630 if(has_different_size_pages(self.pdf)):
631 # just let the user know- for now, we can't handle this properly
632 dlg = wx.MessageDialog(app.frame, """In this PDF, width or height are not the same for each page. This might cause problems if you export pages of different dimensions into the same SWF file.""", "Notice", style=wx.OK, pos=wx.DefaultPosition)
638 for type,f in self.listeners:
639 if type&EVENT_PAGE_CHANGE or type&EVENT_FILE_CHANGE:
641 self.setStatus("File loaded successfully.")
643 def saveSWF(self, filename, progress, pages=None, html=0):
645 basename,ext = os.path.splitext(filename)
647 html = basename + ".html"
648 filename = basename + ".swf"
649 elif ext.lower() != ".swf":
651 filename = basename + ".swf"
653 html = basename + ".html"
656 steps = 100.0 / (self.pdf.pages*2 + 3)
659 self.lastsavefile = filename
661 self.lasthtmlfile = html
664 for k,v in gfx_options.items():
665 swf.setparameter(k,v)
667 pages = range(1,self.pdf.pages+1)
668 pdfwidth,pdfheight=0,0
670 page = self.pdf.getPage(pagenr)
671 pdfwidth = page.width
672 pdfheight = page.height
673 swf.startpage(page.width, page.height)
678 if gfx_options.get("rfxview",None):
679 rfxview = os.path.join(basedir, "rfxview.swf")
680 if not os.path.isfile(rfxview):
681 error("File rfxview.swf not found in working directory")
683 swfcombine([rfxview,"viewport="+filename,"-o",filename])
686 version = int(gfx_options.get("flashversion", "8"))
687 swf = gfx.open("swf", filename)
688 page1 = swf.getPage(1)
690 width,height = str(page1.width),str(page1.height)
693 w = gfx_options.get("rfxwidth","")
694 if w == "fullscreen": width = "100%"
695 elif w == "same as PDF": width = pdfwidth+40
696 elif w.isdigit(): width = w
697 else: width = pdfwidth
699 h = gfx_options.get("rfxheight","")
700 if h == "fullscreen": height = "100%"
701 elif h == "same as PDF": height = pdfheight+70
702 elif h.isdigit(): height = h
703 else: height = pdfwidth
706 zoomtype = gfx_options.get("rfxzoomtype","")
707 if zoomtype=="Original resolution":
708 flashvars = "zoomtype=1"
709 elif zoomtype=="Show all":
710 flashvars = "zoomtype=2"
711 elif zoomtype=="Maximum width/height":
712 flashvars = "zoomtype=3"
714 swffilename = os.path.basename(filename)
715 fi = open(html, "wb")
716 fi.write(HTMLTEMPLATE % locals())
720 def changePage(self,page):
722 self.page = self.pdf.getPage(self.pagenr)
723 for type,f in self.listeners:
724 if type&EVENT_PAGE_CHANGE:
727 def getPageIcon(self,pagenr):
728 page = self.pdf.getPage(pagenr)
729 return wx.BitmapFromImage(wx.ImageFromData(ICON_SIZE,ICON_SIZE,page.asImage(ICON_SIZE,ICON_SIZE)))
730 #return wx.BitmapFromImage(wx.ImageFromData(8,8,"0"*(64*3)))
732 def getPageImage(self, width, height):
733 if self.bitmap_width == width and self.bitmap_height == height and self.bitmap_page == self.pagenr:
734 return self.pagebitmap
736 self.bitmap_width = width
737 self.bitmap_height = height
738 self.bitmap_page = self.pagenr
739 self.pagebitmap = wx.BitmapFromImage(wx.ImageFromData(width,height,self.page.asImage(width,height)))
740 #self.pagebitmap = wx.BitmapFromImage(wx.ImageFromData(8,8,"0"*(64*3)))
741 return self.pagebitmap
743 def setStatus(self,text):
744 self.status_text = text
745 for type,f in self.listeners:
746 if type&EVENT_STATUS_TEXT:
751 class PageListWidget(wx.ListCtrl):
752 def __init__(self,parent):
753 wx.ListCtrl.__init__(self,parent,style=wx.LC_ICON|wx.LC_AUTOARRANGE)
754 #self.SetMinSize((ICON_SIZE+8,-1))
755 #self.SetMaxSize((ICON_SIZE+8,-1))
756 #self.SetSize((ICON_SIZE+8,-1))
757 self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.SelectItem)
758 state.onEvent(EVENT_FILE_CHANGE, self.reload)
759 state.onEvent(EVENT_PAGE_CHANGE, self.switchPage)
762 #self.Bind(wx.EVT_IDLE, self.OnIdle)
765 def processFiles(self):
766 if self.filepos >= 0 and self.filepos < state.pdf.pages:
767 icon = state.getPageIcon(self.filepos+1)
768 self.imglist.Add(icon)
769 self.InsertImageStringItem(self.filepos, str(self.filepos+1), self.filepos)
770 self.filepos = self.filepos + 1
773 def OnIdle(self,event):
775 event.ResumePropagation(0)
779 self.DeleteAllItems()
780 self.imglist = wx.ImageList(ICON_SIZE,ICON_SIZE,mask=False)
781 self.AssignImageList(self.imglist,wx.IMAGE_LIST_NORMAL)
783 while state.pdf and self.filepos < state.pdf.pages:
786 def switchPage(self):
790 for i in range(0,self.GetItemCount()):
791 self.Select(i, False)
792 self.Select(state.pagenr-1, True)
793 self.Focus(state.pagenr-1)
796 def SelectItem(self,event):
797 self.dontcare = 1 #ignore next change event
798 state.changePage(event.GetIndex()+1)
802 This is the SWF preview window.
803 Here, you will see how the SWF file generated from
804 the PDF file will look like. Changing parameters in
805 the configuration which affect the appeareance of
806 the final SWF will affect this preview, too, so you
807 can always evaluate the final output beforehand.
811 class OnePageWidget(wx.Window):
812 def __init__(self,parent):
813 wx.Window.__init__(self, parent)
814 self.SetSize((160,100))
815 self.SetMinSize((160,100))
817 self.Bind(wx.EVT_PAINT, self.OnPaint)
818 self.Bind(wx.EVT_SIZE, self.OnSize)
819 self.Bind(wx.EVT_KEY_DOWN, self.key_down)
820 state.onEvent(EVENT_PAGE_CHANGE, self.OnPageChange)
822 def key_down(self, event):
824 if event.GetKeyCode() == 312 and state.pagenr>1:
825 state.changePage(state.pagenr-1)
826 elif event.GetKeyCode() == 313 and state.pagenr<state.pdf.pages:
827 state.changePage(state.pagenr+1)
829 def OnPageChange(self):
832 def OnSize(self, event):
835 def Draw(self,dc=None):
838 dc = wx.ClientDC(self)
841 window_width,window_height = self.GetSize()
844 if not state.pdf or not state.page:
847 if state.page.width * window_height > state.page.height * window_width:
849 height = window_width * state.page.height / state.page.width
850 posy = (window_height - height) / 2
852 width = window_height * state.page.width / state.page.height
853 height = window_height
854 posx = (window_width - width) / 2
856 dc.DrawBitmap(state.getPageImage(width,height), posx,posy, False)
859 def OnPaint(self, event):
860 dc = wx.PaintDC(self)
863 class Pdf2swfFrame(wx.Frame):
865 #wx.Window.__init__(self, None, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize)
866 def __init__(self,application):
867 wx.Frame.__init__(self, None, -1, style = wx.DEFAULT_FRAME_STYLE)
868 self.application = application
870 self.SetTitle("pdf2swf")
873 self.createStatusBar()
874 self.createMainFrame()
876 self.SetSize((800,600))
878 self.options = OptionFrame(None)
879 self.options.Show(False)
880 self.options.updateOptions()
882 state.onEvent(EVENT_STATUS_TEXT, self.status_change)
885 #self.table = wx.AcceleratorTable([(wx.ACCEL_ALT, ord('X'), 333),])
886 #self.SetAcceleratorTable(self.table)
888 self.Bind(wx.EVT_IDLE, self.OnIdle)
889 self.Bind(wx.EVT_CLOSE, self.menu_exit)
892 def menu_open(self,event):
895 dlg = wx.FileDialog(self, "Choose PDF File:", style = wx.DD_DEFAULT_STYLE, defaultFile = state.filename, wildcard = "PDF files (*.pdf)|*.pdf|all files (*.*)|*.*")
897 dlg = wx.FileDialog(self, "Choose PDF File:", style = wx.DD_DEFAULT_STYLE, wildcard = "PDF files (*.pdf)|*.pdf|all files (*.*)|*.*")
899 if dlg.ShowModal() == wx.ID_OK:
900 self.filename = dlg.GetFilename()
901 state.loadPDF(self.filename)
903 def menu_save(self,event,pages=None):
904 html,self.html = self.html,0
910 defaultFile = state.lastsavefile
912 defaultFile = state.lasthtmlfile
913 dlg = wx.FileDialog(self, "Choose Save Filename:", style = wx.SAVE | wx.OVERWRITE_PROMPT, defaultFile = defaultFile, wildcard = "all files (*.*)|*.*|SWF files (*.swf)|*.swf|HTML template (*.html)|*.html")
915 if dlg.ShowModal() == wx.ID_OK:
916 filename = os.path.join(dlg.GetDirectory(),dlg.GetFilename())
918 #progress = ProgressFrame(self, "Saving %s File '%s'..." % (html and "HTML" or "SWF", filename))
921 state.saveSWF(filename, progress, pages, html)
924 def menu_save_selected(self,event):
928 for i in range(0,self.pagelist.GetItemCount()):
929 if self.pagelist.IsSelected(i):
931 self.menu_save(event, pages=p)
933 def menu_save_html(self,event):
935 return self.menu_save(event)
937 def menu_save_selected_html(self,event):
939 return self.menu_save_selected(event)
941 def menu_exit(self,event):
942 self.application.Exit()
944 def menu_selectall(self,event):
945 for i in range(0,self.pagelist.GetItemCount()):
946 self.pagelist.Select(i, True)
947 def menu_options(self,event):
948 self.options.Show(True)
950 def status_change(self):
951 self.statusbar.SetStatusText(state.status_text)
953 def OnIdle(self,event):
954 if self.options.needreload:
955 self.options.needreload = 0
958 state.loadPDF(state.filename)
960 def createMenu(self):
961 menubar = wx.MenuBar()
963 menu = wx.Menu();menubar.Append(menu, "&File")
964 menu.Append(wx.ID_OPEN, "Open PDF\tCTRL-O");self.Bind(wx.EVT_MENU, self.menu_open, id=wx.ID_OPEN)
965 menu.AppendSeparator()
966 menu.Append(wx.ID_SAVE, "Save SWF (all pages)\tCTRL-W");self.Bind(wx.EVT_MENU, self.menu_save, id=wx.ID_SAVE)
967 menu.Append(wx.ID_SAVEAS, "Save SWF (selected pages)\tCTRL-S");self.Bind(wx.EVT_MENU, self.menu_save_selected, id=wx.ID_SAVEAS)
968 menu.AppendSeparator()
969 menu.Append(2001, "Save HTML template (all pages)\tCTRL-H");self.Bind(wx.EVT_MENU, self.menu_save_html, id=2001)
970 menu.Append(2002, "Save HTML template (selected pages)");self.Bind(wx.EVT_MENU, self.menu_save_selected_html, id=2002)
971 menu.AppendSeparator()
972 menu.Append(wx.ID_EXIT, "Exit\tCTRL-Q");self.Bind(wx.EVT_MENU, self.menu_exit, id=wx.ID_EXIT)
974 menu = wx.Menu();menubar.Append(menu, "&Edit")
975 menu.Append(wx.ID_SELECTALL, "Select All\tCTRL-A");self.Bind(wx.EVT_MENU, self.menu_selectall, id=wx.ID_SELECTALL)
976 menu.AppendSeparator()
977 menu.Append(wx.ID_PREFERENCES, "Options\tCTRL-R");self.Bind(wx.EVT_MENU, self.menu_options, id=wx.ID_PREFERENCES)
979 menu = wx.Menu();menubar.Append(menu, "&Help")
981 self.SetMenuBar(menubar)
984 def createToolbar(self):
987 self.toolbar = self.CreateToolBar(wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT)
989 self.toolbar.AddSimpleTool(wx.ID_OPEN,
990 wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN, wx.ART_TOOLBAR, tsize),
992 self.toolbar.AddSimpleTool(wx.ID_SAVE,
993 wx.ArtProvider.GetBitmap(wx.ART_FILE_SAVE, wx.ART_TOOLBAR, tsize),
994 "Save selected pages")
995 self.toolbar.AddSimpleTool(wx.ID_PREFERENCES,
996 wx.ArtProvider.GetBitmap(wx.ART_LIST_VIEW, wx.ART_TOOLBAR, tsize),
998 #self.toolbar.AddSeparator()
999 self.toolbar.Realize()
1001 def createStatusBar(self):
1002 self.statusbar = self.CreateStatusBar(1)
1004 def createMainFrame(self):
1007 self.pagelist = PageListWidget(self)
1008 self.onepage = OnePageWidget(self)
1009 hsplit = wx.BoxSizer(wx.HORIZONTAL)
1010 pagelistbox = wx.StaticBox(self, -1, "Pages")
1011 pagelistboxsizer= wx.StaticBoxSizer(pagelistbox, wx.VERTICAL)
1012 pagelistboxsizer.Add(self.pagelist, proportion=1, flag=wx.EXPAND)
1013 onepagebox = wx.StaticBox(self, -1, "Page 1")
1014 onepageboxsizer= wx.StaticBoxSizer(onepagebox, wx.VERTICAL)
1015 onepageboxsizer.Add(self.onepage, proportion=1, flag=wx.EXPAND)
1016 hsplit.Add(pagelistboxsizer, 0, wx.EXPAND, 0)
1017 hsplit.Add(onepageboxsizer, 1, wx.EXPAND, 0)
1018 self.SetAutoLayout(True)
1019 self.SetSizer(hsplit)
1021 hsplit.SetSizeHints(self)
1023 hsplit = wx.SplitterWindow(self, style=wx.SP_3D|wx.SP_LIVE_UPDATE)
1024 #p1 = wx.Panel(hsplit,-1, style=wx.SUNKEN_BORDER)
1025 #p2 = wx.Panel(hsplit,-1, style=wx.SUNKEN_BORDER)
1026 self.pagelist = PageListWidget(hsplit)
1027 self.onepage = OnePageWidget(hsplit)
1028 #hsplit.SplitVertically(p1,p2, sashPosition=64)
1029 hsplit.SplitVertically(self.pagelist, self.onepage, sashPosition=ICON_SIZE*3/2)
1030 hsplit.SetMinimumPaneSize(10)
1032 #class TestWindow(wx.SplitterWindow):
1033 # def __init__(self,parent):
1034 # wx.SplitterWindow.__init__(self, parent, -1)
1035 # panel = wx.Panel(self, -1)
1036 # self.txt = wx.StaticText(panel, -1, "bla bla bla", (100,10), (160,-1), wx.ALIGN_CENTER|wx.ALIGN_CENTER_VERTICAL)
1037 # self.SetMinSize((320,200))
1038 # self.txt.SetForegroundColour("blue")
1039 # self.txt.SetBackgroundColour("green")
1041 # self.Initialize(panel)
1043 #class TestFrame(wx.Frame):
1044 # def __init__(self,parent):
1045 # wx.Frame.__init__(self, None, -1)
1046 # panel = wx.Panel(self, -1)
1047 # window = TestWindow(panel)
1050 class MyApp(wx.App):
1052 wx.App.__init__(self, redirect=False, filename=None, useBestVisual=False)
1054 #state.loadPDF("sitis2007.pdf")
1055 #state.loadPDF("wxPython-Advanced-OSCON2004.pdf")
1057 staticdata = StaticData()
1059 self.frame = Pdf2swfFrame(self)
1060 self.SetTopWindow(self.frame)
1061 self.frame.Show(True)
1063 #self.frame = TestFrame(self)
1064 #self.frame.Show(True)