コード例 #1
0
def BPFSImageFile(fshandler, location, name=None, img=None, width=-1, height=-1, valign="center", bgcolor=None):
    """Handles image files

    If we have to do any conversion on the file then we return PNG
    data.  This used to be a class derived from wx.FSFile, but due to
    various wxPython bugs it instead returns the parameters to make a
    wx.FSFile since a new one has to be made every time.
    """
    # if this is a bad or non-existing image file, use the dummy one!
    if name is None and img is None:
        name=guihelper.getresourcefile('wallpaper.png')
    # special fast path if we aren't resizing or converting image
    if img is None and width<0 and height<0:
        mime=guihelper.getwxmimetype(name)
        # wxPython 2.5.3 has a new bug and fails to read bmp files returned as a stream
        if mime not in (None, "image/x-bmp"):
            return (open(name, "rb"), location, mime, "", wx.DateTime_Now())

    if img is None:
        img=wx.Image(name)

    if width>0 and height>0:
        b=ScaleImageIntoBitmap(img, width, height, bgcolor, valign)
    else:
        b=img.ConvertToBitmap()

    with common.usetempfile('png') as f:
        if not b.SaveFile(f, wx.BITMAP_TYPE_PNG):
            raise Exception, "Saving to png failed"
        data=open(f, "rb").read()
        return (cStringIO.StringIO(data), location, "image/png", "", wx.DateTime_Now())
コード例 #2
0
ファイル: ringers.py プロジェクト: deosai/bitpim
    def GetSections(self):
        # work out section and item sizes
        self.thumbnail=wx.Image(guihelper.getresourcefile('ringer.png')).ConvertToBitmap()
        
        dc=wx.MemoryDC()
        dc.SelectObject(wx.EmptyBitmap(100,100)) # unused bitmap needed to keep wxMac happy
        h=dc.GetTextExtent("I")[1]
        itemsize=self.thumbnail.GetWidth()+160, max(self.thumbnail.GetHeight(), h*4+DisplayItem.PADDING)+DisplayItem.PADDING*2
        
        # get all the items
        items=[DisplayItem(self, key) for key in self._data[self.database_key] if self._data[self.database_key][key].mediadata!=None]

        self.sections=[]
        
        if len(items)==0:
            return self.sections
        
        # get the current sorting type
        for sectionlabel, items in self.organizeby_Origin(items):
            self.media_root.AddMediaNode(sectionlabel, self)
            sh=aggregatedisplay.SectionHeader(sectionlabel)
            sh.itemsize=itemsize
            for item in items:
                item.thumbnailsize=self.thumbnail.GetWidth(), self.thumbnail.GetHeight()
            # sort items by name
            items.sort(self.CompareItems)
            self.sections.append( (sh, items) )
        return [sh for sh,items in self.sections]
コード例 #3
0
 def getwallpapers(self, result):
     self.log('Reading wallpaper index')
     self.setmode(self.MODEMODEM)
     self.charset_ascii()
     self._wallpaper_mode()
     media={}
     media_index=self._get_wallpaper_index()
     self.charset_ascii()
     self._wallpaper_mode()
     res={}
     self._get_image_index(self.protocolclass.MIN_WALLPAPER_INDEX, self.protocolclass.MAX_WALLPAPER_INDEX,
                      res, 0, 'wallpaper')
     _dummy_data=file(guihelper.getresourcefile('wallpaper.png'),'rb').read()
     for e in res.values():
         media[e['name']]=_dummy_data
     self.charset_ascii()
     self._photo_mode()
     res={}
     self._get_image_index(self.protocolclass.MIN_PHOTO_INDEX, self.protocolclass.MAX_PHOTO_INDEX,
                      res, 0, 'camera')
     for e in res.values():
         data=self._get_media_file(e['name'])
         if data != False:
             print "get OK"
             media[e['name']]=data
         else:
             print "get failed"
             media[e['name']]=_dummy_data
     result['wallpapers']=media
     result['wallpaper-index']=media_index
     return result
コード例 #4
0
 def GetSections(self):
     self.thumbnail=wx.Image(guihelper.getresourcefile('ringer.png')).ConvertToBitmap()
     dc=wx.MemoryDC()
     dc.SelectObject(wx.EmptyBitmap(100,100)) # unused bitmap needed to keep wxMac happy
     h=dc.GetTextExtent("I")[1]
     itemsize=self.thumbnail.GetWidth()+160, max(self.thumbnail.GetHeight(), h*4+DisplayItem.PADDING)+DisplayItem.PADDING*2
     items=[DisplayItem(self, key, self.mainwindow.ringerpath) for key in self._data['ringtone-index']]
     items=[item for item in items if os.path.exists(item.filename)]
     self.sections=[]
     if len(items)==0:
         return self.sections
     for i in range(len(self.organizetypes)):
         item=self.organizemenu.FindItemByPosition(i)
         if self.organizemenu.IsChecked(item.GetId()):
             for sectionlabel, items in self.organizeinfo[item.GetId()](items):
                 sh=aggregatedisplay.SectionHeader(sectionlabel)
                 sh.itemsize=itemsize
                 for item in items:
                     item.thumbnailsize=self.thumbnail.GetWidth(), self.thumbnail.GetHeight()
                 items=[(item.name.lower(), item) for item in items]
                 items.sort()
                 items=[item for name,item in items]
                 self.sections.append( (sh, items) )
             return [sh for sh,items in self.sections]
     assert False, "Can't get here"
コード例 #5
0
 def __init__(self, parent, file, convertinfo):
     wx.Dialog.__init__(self, parent, title="Convert Audio File", style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.SYSTEM_MENU|wx.MAXIMIZE_BOX)
     self.file=file
     self.convertinfo=convertinfo
     self.afi=None
     self.temporaryfiles=[]
     self.wavfile=common.gettempfilename("wav")      # full length wav equivalent
     self.clipwavfile=common.gettempfilename("wav")  # used for clips from full length wav
     self.temporaryfiles.extend([self.wavfile, self.clipwavfile])
     getattr(self, self.PARAMETERS[convertinfo.format]['setup'])()
     vbs=wx.BoxSizer(wx.VERTICAL)
     self.create_convert_pane(vbs, file, convertinfo)
     self.create_crop_panel(vbs)
     vbs.Add(self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.HELP), 0, wx.ALL|wx.ALIGN_RIGHT, 5)
     self.SetSizer(vbs)
     vbs.Fit(self)
     self.FindWindowById(wx.ID_OK).Enable(False)
     for i in self.cropids:
         self.FindWindowById(i).Enable(False)
     wx.EVT_BUTTON(self, wx.ID_OK, self.OnOk)
     wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnCancel)
     wx.EVT_TIMER(self, self.ID_TIMER, self.OnTimer)
     wx.EVT_BUTTON(self, wx.ID_HELP, lambda _: wx.GetApp().displayhelpid(helpids.ID_DLG_AUDIOCONVERT))
     self.sound=None
     self.timer=wx.Timer(self, self.ID_TIMER)
     if guihelper.IsMac():
         self.zerolenwav=guihelper.getresourcefile("zerolen.wav")
コード例 #6
0
ファイル: ringers.py プロジェクト: SJLC/portage-overlay
    def GetSections(self):
        # work out section and item sizes
        self.thumbnail=wx.Image(guihelper.getresourcefile('ringer.png')).ConvertToBitmap()
        
        dc=wx.MemoryDC()
        dc.SelectObject(wx.EmptyBitmap(100,100)) # unused bitmap needed to keep wxMac happy
        h=dc.GetTextExtent("I")[1]
        itemsize=self.thumbnail.GetWidth()+160, max(self.thumbnail.GetHeight(), h*4+DisplayItem.PADDING)+DisplayItem.PADDING*2
        
        # get all the items
        items=[DisplayItem(self, key) for key in self._data[self.database_key] if self._data[self.database_key][key].mediadata!=None]

        self.sections=[]
        
        if len(items)==0:
            return self.sections
        
        # get the current sorting type
        for sectionlabel, items in self.organizeby_Origin(items):
            self.media_root.AddMediaNode(sectionlabel, self)
            sh=aggregatedisplay.SectionHeader(sectionlabel)
            sh.itemsize=itemsize
            for item in items:
                item.thumbnailsize=self.thumbnail.GetWidth(), self.thumbnail.GetHeight()
            # sort items by name
            items.sort(self.CompareItems)
            self.sections.append( (sh, items) )
        return [sh for sh,items in self.sections]
コード例 #7
0
 def setuphelp(self):
     """Does all the nonsense to get help working"""
     import wx.html
     from wxPython.htmlhelp import wxHtmlHelpController
     wx.FileSystem_AddHandler(wx.ZipFSHandler())
     self.helpcontroller=wxHtmlHelpController()
     self.helpcontroller.AddBook(guihelper.getresourcefile("bitpim.htb"))
     self.helpcontroller.UseConfig(self.config, "help")
コード例 #8
0
 def windowsinit(self, iconfile):
     bitmap=wx.Bitmap(guihelper.getresourcefile(iconfile), wx.BITMAP_TYPE_PNG)
     icon=wx.EmptyIcon()
     icon.CopyFromBitmap(bitmap)
     self.SetIcon(icon, "BitFling")
     wx.EVT_TASKBAR_RIGHT_UP(self, self.OnRButtonUp)
     wx.EVT_TASKBAR_LEFT_UP(self, self.OnLButtonUp)
     wx.EVT_TASKBAR_LEFT_DOWN(self, self.OnLeftDown)
コード例 #9
0
 def setuphelp(self):
     """Does all the nonsense to get help working"""
     import wx.html
     # Add the Zip filesystem
     wx.FileSystem_AddHandler(wx.ZipFSHandler())
     # Get the help working
     self.helpcontroller=wx.html.HtmlHelpController()
     self.helpcontroller.AddBook(guihelper.getresourcefile("bitpim.htb"))
     self.helpcontroller.UseConfig(self.config, "help")
コード例 #10
0
 def windowsinit(self, iconfile):
     bitmap=wx.Bitmap(guihelper.getresourcefile(iconfile), wx.BITMAP_TYPE_PNG)
     icon=wx.EmptyIcon()
     icon.CopyFromBitmap(bitmap)
     self.SetIcon(icon, "BitFling")
     wx.EVT_TASKBAR_RIGHT_UP(self, self.OnRButtonUp)
     wx.EVT_TASKBAR_LEFT_UP(self, self.OnLButtonUp)
     #wx.EVT_TASKBAR_MOVE(self, self.OnMouseMotion)
     wx.EVT_TASKBAR_LEFT_DOWN(self, self.OnLeftDown)
コード例 #11
0
 def _gen_print_data(self):
     if not self._date_changed and \
        not self._style_changed and \
        self._html is not None:
         return
     self._dt_start=self._start_date.GetValue()
     self._dt_end=self._end_date.GetValue()
     if not self._dt_start.IsValid() or not self._dt_end.IsValid():
         return
     print_data=(
         (self._regular_template, self._regular_style, self._get_list_data),
         (self._monthly_template, self._monthly_style, self._get_monthly_data))
     print_style=self._print_style.GetSelection()
     print_dict=print_data[print_style][2]()
     if self._xcp is None:
         self._xcp=xyaptu.xcopier(None)
         tmpl=file(guihelper.getresourcefile(print_data[print_style][0]),
                   'rt').read()
         self._xcp.setupxcopy(tmpl)
     elif self._style_changed:
         tmpl=file(guihelper.getresourcefile(print_data[print_style][0]),
                   'rt').read()
         self._xcp.setupxcopy(tmpl)
     if self._dns is None:
         self._dns={ 'common': __import__('common') }
         self._dns['guihelper']=__import__('guihelper')
         self._dns['events']=[]
     self._dns['events']=print_dict
     self._dns['date_range']='%s - %s'%\
                               (self._dt_start.FormatDate(),
                                self._dt_end.FormatDate())
     html=self._xcp.xcopywithdns(self._dns.copy())
     sd={'styles': {}, '__builtins__': __builtins__ }
     try:
         execfile(guihelper.getresourcefile(print_data[print_style][1]), sd, sd)
     except UnicodeError:
         common.unicode_execfile(guihelper.getresourcefile(print_data[print_style][1]), sd, sd)
     try:
         self._html=bphtml.applyhtmlstyles(html, sd['styles'])
     except:
         if __debug__:
             file('debug.html', 'wt').write(html)
         raise
     self._date_changed=self._style_change=False
コード例 #12
0
 def GetImageConstructionInformation(self,file):
     file=os.path.join(imagespath, file)
     if file.endswith(".mp4") or not os.path.isfile(file):
         return guihelper.getresourcefile('wallpaper.png'), wx.Image
     if self.isBCI(file):
         return file, lambda name: brewcompressedimage.getimage(brewcompressedimage.FileInputStream(file))
     fi=fileinfo.identify_imagefile(file)
     if fi is not None and fi.format=='LGBIT':
         return file, conversions.convertfilelgbittobmp
     return file, wx.Image
コード例 #13
0
 def genericinit(self, iconfile):
     self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))
     bitmap=wx.Bitmap(guihelper.getresourcefile(iconfile), wx.BITMAP_TYPE_PNG)
     bit=wx.StaticBitmap(self, -1, bitmap)
     self.Show(True)
     wx.EVT_RIGHT_UP(bit, self.OnRButtonUp)
     wx.EVT_LEFT_UP(bit, self.OnLButtonUp)
     wx.EVT_MOTION(bit, self.OnMouseMotion)
     wx.EVT_LEFT_DOWN(bit, self.OnLeftDown)
     self.bit=bit
コード例 #14
0
ファイル: wallpaper.py プロジェクト: deosai/bitpim
 def OpenBPImageFile(self, location, name, **kwargs):
     f = guihelper.getresourcefile(name)
     if not os.path.isfile(f):
         print f, "doesn't exist"
         return None
     si = statinfo(f)
     res = self._GetCache(location, si)
     if res is not None: return res
     res = BPFSImageFile(self, location, name=f, **kwargs)
     self._AddCache(location, si, res)
     return res
コード例 #15
0
 def OpenBPImageFile(self, location, name, **kwargs):
     f=guihelper.getresourcefile(name)
     if not os.path.isfile(f):
         print f,"doesn't exist"
         return None
     si=statinfo(f)
     res=self._GetCache(location, si)
     if res is not None: return res
     res=BPFSImageFile(self, location, name=f, **kwargs)
     self._AddCache(location, si, res)
     return res
コード例 #16
0
 def GetImageConstructionInformation(self,file):
     file=os.path.join(imagespath, file)
     
     if file.endswith(".mp4") or not os.path.isfile(file):
         return guihelper.getresourcefile('wallpaper.png'), wx.Image
     if self.isBCI(file):
         return file, lambda name: brewcompressedimage.getimage(brewcompressedimage.FileInputStream(file))
     # LG phones may return a proprietary wallpaper media file, LGBIT
     fi=fileinfo.identify_imagefile(file)
     if fi is not None and fi.format=='LGBIT':
         return file, conversions.convertfilelgbittobmp
     return file, wx.Image
コード例 #17
0
 def GetItemThumbnail(self, data, width, height, fileinfo=None):
     img=self.GetImageFromString(data, fileinfo)
     if img is None or not img.Ok():
         img=wx.Image(guihelper.getresourcefile('wallpaper.png'))
     if width!=img.GetWidth() or height!=img.GetHeight():
         sfactorw=float(width)/img.GetWidth()
         sfactorh=float(height)/img.GetHeight()
         sfactor=min(sfactorw,sfactorh) # preserve aspect ratio
         newwidth=int(img.GetWidth()*sfactor)
         newheight=int(img.GetHeight()*sfactor)
         img.Rescale(newwidth, newheight)
     return img.ConvertToBitmap()
コード例 #18
0
 def GetItemThumbnail(self, name, width, height):
     img,_=self.GetImage(name.encode(guiwidgets.media_codec))
     if img is None or not img.Ok():
         img=wx.Image(guihelper.getresourcefile('wallpaper.png'))
     if width!=img.GetWidth() or height!=img.GetHeight():
         sfactorw=float(width)/img.GetWidth()
         sfactorh=float(height)/img.GetHeight()
         sfactor=min(sfactorw,sfactorh) # preserve aspect ratio
         newwidth=int(img.GetWidth()*sfactor)
         newheight=int(img.GetHeight()*sfactor)
         img.Rescale(newwidth, newheight)
     bitmap=img.ConvertToBitmap()
     return bitmap
コード例 #19
0
 def getwallpapers(self, result):
     self.log('Reading wallpaper index')
     self.setmode(self.MODEMODEM)
     self.charset_ascii()
     self._wallpaper_mode()
     media={}
     media_index=self._get_wallpaper_index()
     _dummy_data=file(guihelper.getresourcefile('wallpaper.png'),'rb').read()
     for e in media_index.values():
         media[e['name']]=_dummy_data
     result['wallpapers']=media
     result['wallpaper-index']=media_index
     return result
コード例 #20
0
    def getwallpapers(self, result):
        self.log('Reading wallpaper index')
        self.setmode(self.MODEMODEM)
        self.charset_ascii()
        self._wallpaper_mode()

        media = {}
        media_index = self._get_wallpaper_index()
        _dummy_data = file(guihelper.getresourcefile('wallpaper.png'),
                           'rb').read()
        for e in media_index.values():
            media[e['name']] = _dummy_data
        result['wallpapers'] = media
        result['wallpaper-index'] = media_index
        return result
コード例 #21
0
 def GetImageConstructionInformation(self, file):
     """Gets information for constructing an Image from the file
     @return: (filename to use, function to call that returns wxImage)
     """
     fi=self.GetFileInfo(file)
     if file.endswith(".mp4") or not os.path.isfile(file):
         return guihelper.getresourcefile('wallpaper.png'), wx.Image
     if fi:
         if fi.format=='AVI':
             return file, conversions.convertfileavitobmp
         if fi.format=='LGBIT':
             return file, conversions.convertfilelgbittobmp
         if fi.format=='3GPP2':
             return file, lambda name: None
     return file, wx.Image
コード例 #22
0
    def getwallpapers(self, result):
        self.log('Reading wallpaper index')
        self.setmode(self.MODEMODEM)
        self.charset_ascii()
        self._wallpaper_mode()
        media = {}
        media_index = self._get_wallpaper_index()

        # Set the media type to be pic (wallpaper)
        self.charset_ascii()
        self._wallpaper_mode()
        # and read the list
        res = {}
        self._get_image_index(self.protocolclass.MIN_WALLPAPER_INDEX,
                              self.protocolclass.MAX_WALLPAPER_INDEX, res, 0,
                              'wallpaper')

        # dummy data for wallpaper
        _dummy_data = file(guihelper.getresourcefile('wallpaper.png'),
                           'rb').read()
        for e in res.values():
            media[e['name']] = _dummy_data

        # Set the media type to be photo
        self.charset_ascii()
        self._photo_mode()
        # and read the list
        res = {}
        self._get_image_index(self.protocolclass.MIN_PHOTO_INDEX,
                              self.protocolclass.MAX_PHOTO_INDEX, res, 0,
                              'camera')
        # read the files out of the phone
        for e in res.values():
            data = self._get_media_file(e['name'])
            if data != False:
                print "get OK"
                media[e['name']] = data
            else:
                print "get failed"
                media[e['name']] = _dummy_data

        result['wallpapers'] = media
        result['wallpaper-index'] = media_index
        return result
コード例 #23
0
ファイル: ringers.py プロジェクト: deosai/bitpim
    def __init__(self, parent, file, convertinfo):
        wx.Dialog.__init__(self, parent, title="Convert Audio File", style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.SYSTEM_MENU|wx.MAXIMIZE_BOX)
        self.file=file
        self.convertinfo=convertinfo
        self.afi=None
        self.temporaryfiles=[]
        self.wavfile=common.gettempfilename("wav")      # full length wav equivalent
        self.clipwavfile=common.gettempfilename("wav")  # used for clips from full length wav
        self.temporaryfiles.extend([self.wavfile, self.clipwavfile])

        getattr(self, self.PARAMETERS[convertinfo.format]['setup'])()
        
        vbs=wx.BoxSizer(wx.VERTICAL)
        # create the covert controls
        self.create_convert_pane(vbs, file, convertinfo)
        # and the crop controls
        self.create_crop_panel(vbs)

        vbs.Add(self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.HELP), 0, wx.ALL|wx.ALIGN_RIGHT, 5)

        self.SetSizer(vbs)
        vbs.Fit(self)

        # diable various things
        self.FindWindowById(wx.ID_OK).Enable(False)
        for i in self.cropids:
            self.FindWindowById(i).Enable(False)
        

        # Events
        wx.EVT_BUTTON(self, wx.ID_OK, self.OnOk)
        wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnCancel)
        wx.EVT_TIMER(self, self.ID_TIMER, self.OnTimer)
        wx.EVT_BUTTON(self, wx.ID_HELP, lambda _: wx.GetApp().displayhelpid(helpids.ID_DLG_AUDIOCONVERT))

        # timers and sounds
        self.sound=None
        self.timer=wx.Timer(self, self.ID_TIMER)

        # wxPython wrapper on Mac raises NotImplemented for wx.Sound.Stop() so
        # we hack around that by supplying a zero length wav to play instead
        if guihelper.IsMac():
            self.zerolenwav=guihelper.getresourcefile("zerolen.wav")
コード例 #24
0
    def getwallpapers(self, result):
        self.log("Reading wallpaper index")
        self.setmode(self.MODEMODEM)
        self.charset_ascii()
        self._wallpaper_mode()
        media = {}
        media_index = self._get_wallpaper_index()

        # Set the media type to be pic (wallpaper)
        self.charset_ascii()
        self._wallpaper_mode()
        # and read the list
        res = {}
        self._get_image_index(
            self.protocolclass.MIN_WALLPAPER_INDEX, self.protocolclass.MAX_WALLPAPER_INDEX, res, 0, "wallpaper"
        )

        # dummy data for wallpaper
        _dummy_data = file(guihelper.getresourcefile("wallpaper.png"), "rb").read()
        for e in res.values():
            media[e["name"]] = _dummy_data

        # Set the media type to be photo
        self.charset_ascii()
        self._photo_mode()
        # and read the list
        res = {}
        self._get_image_index(self.protocolclass.MIN_PHOTO_INDEX, self.protocolclass.MAX_PHOTO_INDEX, res, 0, "camera")
        # read the files out of the phone
        for e in res.values():
            data = self._get_media_file(e["name"])
            if data != False:
                print "get OK"
                media[e["name"]] = data
            else:
                print "get failed"
                media[e["name"]] = _dummy_data

        result["wallpapers"] = media
        result["wallpaper-index"] = media_index
        return result
コード例 #25
0
ファイル: wallpaper.py プロジェクト: deosai/bitpim
    def __init__(self, mainwindow, parent, media_root):
        global thewallpapermanager
        thewallpapermanager = self
        self.mainwindow = mainwindow
        self.usewidth = 10
        self.useheight = 10
        self._dummy_image_filename = guihelper.getresourcefile('wallpaper.png')
        wx.FileSystem_AddHandler(BPFSHandler(self))
        self._data = {self.database_key: {}}
        fileview.FileView.__init__(self, mainwindow, parent, media_root,
                                   "wallpaper-watermark")
        self.thedir = self.mainwindow.wallpaperpath
        self.wildcard="Image files|*.bmp;*.jpg;*.jpeg;*.png;*.gif;*.pnm;*.tiff;*.ico;*.bci;*.bit"\
                       "|Video files|*.3g2|All files|*.*"

        ##        self.bgmenu.Insert(1,guihelper.ID_FV_PASTE, "Paste")
        ##        wx.EVT_MENU(self.bgmenu, guihelper.ID_FV_PASTE, self.OnPaste)

        self.modified = False
        pubsub.subscribe(self.OnListRequest, pubsub.REQUEST_WALLPAPERS)
        self._raw_image = self._shift_down = False
コード例 #26
0
ファイル: wallpaper.py プロジェクト: SJLC/portage-overlay
    def __init__(self, mainwindow, parent, media_root):
        global thewallpapermanager
        thewallpapermanager=self
        self.mainwindow=mainwindow
        self.usewidth=10
        self.useheight=10
        self._dummy_image_filename=guihelper.getresourcefile('wallpaper.png')
        wx.FileSystem_AddHandler(BPFSHandler(self))
        self._data={self.database_key: {}}
        fileview.FileView.__init__(self, mainwindow, parent, media_root, "wallpaper-watermark")
        self.thedir=self.mainwindow.wallpaperpath
        self.wildcard="Image files|*.bmp;*.jpg;*.jpeg;*.png;*.gif;*.pnm;*.tiff;*.ico;*.bci;*.bit"\
                       "|Video files|*.3g2|All files|*.*"


##        self.bgmenu.Insert(1,guihelper.ID_FV_PASTE, "Paste")
##        wx.EVT_MENU(self.bgmenu, guihelper.ID_FV_PASTE, self.OnPaste)

        self.modified=False
        pubsub.subscribe(self.OnListRequest, pubsub.REQUEST_WALLPAPERS)
        self._raw_image=self._shift_down=False
コード例 #27
0
	def setuphelp(self):

        """Does all the nonsense to get help working"""

        import wx.html

        from wxPython.htmlhelp import wxHtmlHelpController

        wx.FileSystem_AddHandler(wx.ZipFSHandler())

        self.helpcontroller=wxHtmlHelpController()

        self.helpcontroller.AddBook(guihelper.getresourcefile("bitpim.htb"))

        self.helpcontroller.UseConfig(self.config, "help")

	def IsConnectionAllowed(self, peeraddr, username=None, password=None):

        """Verifies if a connection is allowed
        If username and password are supplied (as should be the case if calling this method
        before executing some code) then they are checked as being from a valid address
        as well.
        If username and password are not supplied then this method checks if any
        of the authentication rules allow a connection from the peeraddr.  This form
        is used immediately after calling accept() on a socket, but before doing
        anything else."""

        v=(peeraddr[0], username, password)

        if username is not None and password is None:

            self.Log("%s: No password supplied for user %s" % (peeraddr, `username`))

            assert False, "No password supplied"

            return False 

        print "ica of "+`v`

        val=self.icacache.get(v, None)

        if val is not None:

            allowed, expires = val

            if allowed:

                if self._has_expired(expires):

                    msg="Connection from %s no longer allowed due to expiry" % (peeraddr[0],)

                    if username is not None:

                        msg+=".  Username "+`username`

                    self.Log(msg)

                    return False

                return True

            return False

        ret_allowed=False

        ret_expiry=0  

        for uname, pwd, expires, addresses in self.authinfo.values():  

            if not self._does_address_match(peeraddr[0], addresses):

                continue

            if username is not None:

                if  username!=uname:

                    continue

                if not self._verify_password(password, pwd):

                    self.Log("Wrong password supplied for user %s from %s" % (`username`, peeraddr[0]))

                    continue

            ret_expiry=max(ret_expiry, expires)

            ret_allowed=True

        if not ret_allowed:

            if username is not None:

                self.Log("No valid credentials for user %s from %s" % (username, peeraddr[0]))

            else:

                self.Log("No defined users for address "+`peeraddr`)

        self.icacache[v]=ret_allowed, ret_expiry

        return self.IsConnectionAllowed(peeraddr, username, password)

	def _verify_password(self, password, pwd):

        """Returns True if password matches pwd
        @param password: password supplied by user
        @param pwd:  password as we store it (salt $ hash)"""

        salt,hash=pwd.split("$", 1)

        x=""

        for i in range(0, len(salt), 2):

            x+=chr(int(salt[i:i+2], 16))

        salt=x

        str=[]

        str.extend([ord(x) for x in salt])

        str.extend([ord(x) for x in password])

        val=sha.new("".join([chr(x) for x in str]))

        print password, pwd, val.hexdigest(), val.hexdigest()==hash

        return val.hexdigest()==hash

	def _does_address_match(self, peeraddr, addresses):

        """Returns if the peeraddr matches any of the supplied addresses"""

        for addr in addresses:

            if peeraddr==addr: return True

            if '*' in addr or '?' in addr or '[' in addr:

                if fnmatch.fnmatch(peeraddr, addr):

                    return True

            ips=[]

            try:

                ips=socket.getaddrinfo(addr, None)

            except:

                pass

            for _, _, _, _, ip in ips:

                if peeraddr==ip[0]:

                    return True

        return False

	def _has_expired(self, expires):

        if expires==0:

            return False

        if time.time()>expires:

            return True

        return False

	def CloseRequested(self, evt):

        if evt.CanVeto():

            self.Show(False)

            evt.Veto()

            return

        self.taskwin.GoAway()

        evt.Skip()

        sys.excepthook=sys.__excepthook__

	def OnXmlServerEvent(self, msg):

        if msg.cmd=="log":

            self.Log(msg.data)

        elif msg.cmd=="logexception":

            self.LogException(msg.data)

        else:

            assert False, "bad message "+`msg`

            pass

	def OnExitButton(self, _):

        self.Close(True)

	def OnHideButton(self, _):

        self.Show(False)

	def OnHelpButton(self, _):

        import helpids

        self.helpcontroller.Display(helpids.ID_BITFLING)

	def Log(self, text):

        if thread.get_ident()!=guithreadid:

            wx.PostEvent(self, XmlServerEvent(cmd="log", data=text))

        else:

            self.lw.log(text)

	def LogException(self, exc):

        if thread.get_ident()!=guithreadid:

            wx.PostEvent(self, XmlServerEvent(cmd="log", data="Exception in thread "+threading.currentThread().getName()))

            wx.PostEvent(self, XmlServerEvent(cmd="logexception", data=exc))

        else:

            self.lw.logexception(exc)

	def excepthook(self, *args):

        """Replacement exception handler that sends stuff to our log window"""

        self.LogException(args)

	def GetCertificateFilename(self):

        """Return certificate filename
        By default $HOME (or My Documents) / .bitfling.key
        but can be overridden with "certificatefile" config key"""

        if guihelper.IsMSWindows(): 

            from win32com.shell import shell, shellcon

            path=shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0)

            path=os.path.join(path, ".bitfling.key")

        else:

            path=os.path.expanduser("~/.bitfling.key")

        return self.config.Read("certificatefile", path)

	def StartIfICan(self):

        certfile=self.GetCertificateFilename()

        if not os.path.isfile(certfile):

            wx.BeginBusyCursor(wx.StockCursor(wx.CURSOR_ARROWWAIT))

            bi=wx.BusyInfo("Creating BitFling host certificate and keys")

            try:

                generate_certificate(certfile)

                if not os.path.isfile(certfile):

                    certfile=None

            finally:

                del bi

                wx.EndBusyCursor()

        port=self.config.ReadInt("port", 12652)

        if port<1 or port>65535: port=None

        host=self.config.Read("bindaddress", "")

        if certfile is None or port is None:

            return

        self.Log("Starting on port "+`port`)

        key=paramiko.DSSKey.from_private_key_file(certfile)

        fp=paramiko.util.hexify(key.get_fingerprint())

        self.configpanel.fingerprint.SetValue(fp)

        self.configpanel.porttext.SetLabel(`port`)

        self.configpanel.GetSizer().Layout()

        self.xmlrpcserver=BitFlingService(self, host, port, key)

        self.xmlrpcserver.setDaemon(True)

        self.xmlrpcserver.start()


def generate_certificate(outfile):

    key=paramiko.DSSKey.generate()

    key.write_private_key_file(outfile, None)

class  XMLRPCService (xmlrpcstuff.Server) :
	def __init__(self, mainwin, host, port, servercert):

        self.mainwin=mainwin

        xmlrpcstuff.Server.__init__(self, host, port, servercert)

	def OnLog(self, msg):

        wx.PostEvent(self.mainwin, XmlServerEvent(cmd="log", data=msg))

	def OnLogException(self, exc):

        wx.PostEvent(self.mainwin, XmlServerEvent(cmd="logexception", data=exc))

	def OnNewAccept(self, clientaddr):

        return self.mainwin.IsConnectionAllowed(clientaddr)

	def OnNewUser(self, clientaddr, username, password):

        return self.mainwin.IsConnectionAllowed(clientaddr, username, password)

	def OnMethodDispatch(self, method, params, username, clientaddr):

        method="exp_"+method

        if not hasattr(self, method):

            raise Fault(3, "No such method")

        context={ 'username': username, 'clientaddr': clientaddr }

        return getattr(self, method)(*params, **{'context': context})


class  BitFlingService (XMLRPCService) :
	def __init__(self, mainwin, host, port, servercert):

        XMLRPCService.__init__(self, mainwin, host, port, servercert)

        self.handles={}

	def stashhandle(self, context, comm):

        for i in range(10000):

            if i not in self.handles:

                self.handles[i]=[context, comm]

                return i

	def gethandle(self, context, num):

        return self.handles[num][1]

	def exp_scan(self, context):

        if usb is None:

            return comscan.comscan()

        else:

            return usbscan.usbscan()+comscan.comscan()

	def exp_getversion(self, context):

        return version.description

	def exp_deviceopen(self, port, baud, timeout, hardwareflow, softwareflow, context):

        return self.stashhandle(context, commport.CommConnection(None, port, baud, timeout,
                                                                 hardwareflow, softwareflow))

	def exp_deviceclose(self, handle, context):

        comm=self.gethandle(context, handle)

        comm.close()

        del self.handles[handle]

        return True

	def exp_devicesetbaudrate(self, handle, rate, context):

        return self.gethandle(context, handle).setbaudrate(rate)

	def exp_devicesetdtr(self, handle, dtr, context):

        return self.gethandle(context, handle).setdtr(dtr)

	def exp_devicesetrts(self, handle, rts, context):

        return self.gethandle(context, handle).setrts(rts)

	def exp_devicewrite(self, handle, data, context):

        self.gethandle(context, handle).write(data.data)

        return len(data.data)

	def exp_devicesendatcommand(self, handle, atcommand, ignoreerror, context):

        "Special handling for empty lists and exceptions"

        try:

            res=self.gethandle(context, handle).sendatcommand(atcommand.data, ignoreerror=ignoreerror)

            if len(res)==0:

                res=1

        except:

            res=0

        return res

	def exp_devicereaduntil(self, handle, char, numfailures, context):

        return Binary(self.gethandle(context, handle).readuntil(char.data, numfailures=numfailures))

	def exp_deviceread(self, handle, numchars, context):

        return Binary(self.gethandle(context, handle).read(numchars))

	def exp_devicereadsome(self, handle, numchars, context):

        if numchars==-1:

            numchars=None

        return Binary(self.gethandle(context, handle).readsome(log=True,numchars=numchars))

	def exp_devicewritethenreaduntil(self, handle, data, char, numfailures, context):

        return Binary(self.gethandle(context, handle).writethenreaduntil(data.data, False, char.data, False, False, numfailures))


def run(args):

    theApp=wx.PySimpleApp()

    menu=wx.Menu()

    menu.Append(ID_EXIT, "Exit")

    mw=MainWindow(None, -1, "BitFling")

    taskwin=MyTaskBarIcon(mw, menu)

    mw.taskwin=taskwin

    theApp.MainLoop()

if __name__ == '__main__':

    run()


try:

    import native.usb as usb

except ImportError:

    usb=None


if guihelper.IsMSWindows(): parentclass=wx.TaskBarIcon

else: parentclass=wx.Frame


if __name__ == '__main__':

    run()
コード例 #28
0
ファイル: usbscan.py プロジェクト: SJLC/portage-overlay
def usbscan(*args, **kwargs):

    if usb is None:
        return []

    global ids
    if ids is None:
        ids=usb_ids.usb_ids()
        ids.add_data(guihelper.getresourcefile("usb.ids"))
        ids.add_data(guihelper.getresourcefile("bitpim_usb.ids"))
    global needdriver
    if needdriver is None:
        needdriver=[]
        for line in open(guihelper.getresourcefile("usb_needdriver.ids"), "rt"):
            line=line.strip()
            if line.startswith("#") or len(line)==0:
                continue
            prod,vend,iface=[int(x, 16) for x in line.split()]
            needdriver.append( (prod,vend,iface) )

    res=[]
    usb.UpdateLists()
    for bus in usb.AllBusses():
        for device in bus.devices():
            for iface in device.interfaces():
                seenin=False
                seenout=False
                for ep in iface.endpoints():
                    if ep.isbulk():
                        if ep.direction()==ep.IN:
                            seenin=True
                        else:
                            seenout=True
                if seenin and seenout:
                    # we now have a device/interface that has bidirectional bulk endpoints
                    name="usb::%s::%s::%d" % (bus.name(), device.name(), iface.number())
                    active=True
                    available=False
                    try:
                        iface.openbulk().close()
                        available=True
                    except:
                        pass
                    v={'name': name, 'active': active, 'available': available,
                       'libusb': True,
                       'usb-vendor#': device.vendor(), 'usb-product#': device.product(),
                       'usb-interface#': iface.number(),
                       'VID': '0x%04X'%device.vendor(),
                       'PID': '0x%04X'%device.product() }

                    if ( device.vendor(), device.product(), iface.number() ) in needdriver:
                        v["available"]=False
                        v['driver-required']=True
                    
                    vend,prod,i=ids.lookupdevice(device.vendor(), device.product(), iface.number())
                    if vend is None:
                        vend="#%04X" % (device.vendor(),)
                    else:
                        v['usb-vendor']=vend
                    if prod is None:
                        prod="#%04X" % (device.product(),)
                    else:
                        v['usb-product']=prod
                    if i is None:
                        i="#%02X" % (iface.number(),)
                    else:
                        v['usb-interface']=i
                    hwinstance="USB Device - Vendor %s, Product %s, (Interface %s)" % \
                                (vend, prod, i)
                    v['description']=hwinstance

                    prot=" / ".join([val for val in ids.lookupclass(*(iface.classdetails())) if val is not None])
                    if len(prot):
                        v["protocol"]=prot
                        
                    for n,i in ("usb-vendorstring", device.vendorstring), \
                        ("usb-productstring", device.productstring), \
                        ("usb-serialnumber", device.serialnumber):
                        try:
                            x=i()
                            if x is not None:
                                v[n]=x
                        except:
                            pass
                    res.append(v)
    return res
コード例 #29
0
	def getwallpapers(self, result):

        self.log('Reading wallpaper index')

        self.setmode(self.MODEMODEM)

        self.charset_ascii()

        self._wallpaper_mode()

        media={}

        media_index=self._get_wallpaper_index()

        _dummy_data=file(guihelper.getresourcefile('wallpaper.png'),'rb').read()

        for e in media_index.values():

            media[e['name']]=_dummy_data

        result['wallpapers']=media

        result['wallpaper-index']=media_index

        return result

	def _add_wallpapers(self, names, name_dict, media):

        self.charset_base64()

        for n in names:

            _media_key=name_dict[n]

            if not self._add_media_file(n, common.stripext(n), 12,
                                      media[_media_key].get('data', '')):

                self.log('Failed to send wallpaper %s'%n)

        self.charset_ascii()

	def savewallpapers(self, result, merge):

        self.log('Saving wallpapers')

        self.setmode(self.MODEMODEM)

        self.charset_ascii()

        self._wallpaper_mode()

        media=result.get('wallpapers', {})

        media_index=result.get('wallpaper-index', {})

        media_names=[x['name'] for x in media.values()]

        index_names=[x['name'] for x in media_index.values()]

        del_names=[x for x in index_names if x not in media_names]

        new_names=[x for x in media_names if x not in index_names]

        self._del_media_files(del_names)

        names_to_keys={}

        for k,e in media.items():

            names_to_keys[e['name']]=k

        self._add_wallpapers(new_names, names_to_keys, media)

        return result

	def getmemo(self, result):

        self.log('Reading Memo')

        self.setmode(self.MODEMODEM)

        self.charset_ascii()

        _req=self.protocolclass.memo_read_req()

        _res=self.sendATcommand(_req, self.protocolclass.memo_read_resp)

        res={}

        for e in _res:

            _memo=memo.MemoEntry()

            _memo.text=e.text

            res[_memo.id]=_memo

        result['memo']=res

        return res

	def savememo(self, result, merge):

        self.log('Writing Memo')

        self.setmode(self.MODEMODEM)

        self.charset_ascii()

        _req=self.protocolclass.memo_del_req()

        for i in range(self.protocolclass.MEMO_MIN_INDEX,
                       self.protocolclass.MEMO_MAX_INDEX+1):

            _req.index=i

            try:

                self.sendATcommand(_req, None)

            except:

                pass

        _memo_dict=result.get('memo', {})

        _keys=_memo_dict.keys()

        _keys.sort()

        _req=self.protocolclass.memo_write_req()

        for k in _keys:

            _req.text=_memo_dict[k].text

            try:

                self.sendATcommand(_req, None)

            except:

                self.log('Failed to write memo %s'%_req.text)

        return _memo_dict

	def _process_sms(self, _resp, res):

        for i in range(0, len(_resp), 2):

            try:

                _entry=self.protocolclass.sms_msg_list_header()

                _buf=prototypes.buffer(_resp[i])

                _entry.readfrombuffer(_buf)

                _sms=sms.SMSEntry()

                if _entry.msg_type==self.protocolclass.SMS_MSG_REC_UNREAD or \
                   _entry.msg_type==self.protocolclass.SMS_MSG_REC_READ:

                    _sms._from=_entry.address

                    _sms.folder=sms.SMSEntry.Folder_Inbox

                    _sms.read=_entry.msg_type==self.protocolclass.SMS_MSG_REC_READ

                elif _entry.msg_type==self.protocolclass.SMS_MSG_STO_SENT:

                    _sms.add_recipient(_entry.address)

                    _sms.folder=sms.SMSEntry.Folder_Sent

                elif _entry.msg_type==self.protocolclass.SMS_MSG_STO_UNSENT:

                    _sms.folder=sms.SMSEntry.Folder_Saved

                    _sms.add_recipient(_entry.address)

                else:

                    self.log('Unknown message type: %s'%_entry.msg_type)

                    _sms=None

                if _sms:

                    if _entry.timestamp:

                        _sms.datetime=_entry.timestamp

                    _sms.text=_resp[i+1]

                    res[_sms.id]=_sms

            except:

                if __debug__:

                    raise

        return res

	def getsms(self, result):

        self.log('Getting SMS Messages')

        self.setmode(self.MODEMODEM)

        self.charset_ascii()

        res={}

        _req=self.protocolclass.sms_format_req()

        self.sendATcommand(_req, None)

        self.log('Getting SMS messages from the phone memory')

        _sms_mem=self.protocolclass.sms_memory_select_req()

        _sms_mem.list_memory=self.protocolclass.SMS_MEMORY_PHONE

        self.sendATcommand(_sms_mem, None)

        _list_sms=self.protocolclass.sms_msg_list_req()

        _resp=self.sendATcommand(_list_sms, None)

        self._process_sms(_resp, res)

        self.log('Getting SMS message from the SIM card')

        _sms_mem.list_memory=self.protocolclass.SMS_MEMORY_SIM

        self.sendATcommand(_sms_mem, None)

        _resp=self.sendATcommand(_list_sms, None)

        self._process_sms(_resp, res)

        try:

            self.sendATcommand(_sms_mem, None)

        except commport.ATError:

            pass

        result['sms']=res

        return result

	def _get_history_calls(self, log_str, call_type, min_idx, max_idx):

        self.log(log_str)

        _sel_mem=self.protocolclass.select_storage_req()

        _sel_mem.storage=call_type

        self.sendATcommand(_sel_mem, None)

        _list_pb=self.protocolclass.read_phonebook_req()

        _list_pb.start_index=min_idx

        _list_pb.end_index=max_idx

        self.sendATcommand(_list_pb, None)

	def getcallhistory(self, result):

        self.log('Getting Call History')

        self.setmode(self.MODEMODEM)

        self.charset_ascii()

        res={}

        for l in self.protocolclass.PB_CALL_HISTORY_INFO:

            self._get_history_calls(*l)

        result['call_history']=res

        return result

	""" Talk to the LG G4015 Phone"""
parent_profile=com_gsm.Profile
class  Profile (parent_profile) :
	serialsname=Phone.serialsname
	    WALLPAPER_WIDTH=128
	    WALLPAPER_HEIGHT=128
	    MAX_WALLPAPER_BASENAME_LENGTH=19
	    WALLPAPER_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789_ ."
	    WALLPAPER_CONVERT_FORMAT="jpg"
	    MAX_RINGTONE_BASENAME_LENGTH=19
	    RINGTONE_FILENAME_CHARS="abcdefghijklmnopqrstuvwxyz0123456789_ ."
	    RINGTONE_LIMITS= {
        'MAXSIZE': 20480
    }
	    phone_manufacturer='LGE'
	    phone_model='G4015'
	    usbids=( ( 0x10AB, 0x10C5, 1),
        )
	    deviceclasses=("serial",)
	    imageorigins={}
	    imageorigins.update(common.getkv(parent_profile.stockimageorigins, "images"))
	    imagetargets={}
	    imagetargets.update(common.getkv(parent_profile.stockimagetargets, "wallpaper",
                                      {'width': 128, 'height': 128, 'format': "JPEG"}))
	    def GetImageOrigins(self):

        return self.imageorigins

	def GetTargetsForImageOrigin(self, origin):

        if origin=='images':

            return self.imagetargets

	def __init__(self):

        parent_profile.__init__(self)

	_supportedsyncs=(
        ('phonebook', 'read', None),  
        ('phonebook', 'write', 'OVERWRITE'),  
        ('calendar', 'read', None),   
        ('calendar', 'write', 'OVERWRITE'),   
        ('ringtone', 'read', None),   
        ('ringtone', 'write', 'OVERWRITE'),
        ('wallpaper', 'read', None),  
        ('wallpaper', 'write', 'OVERWRITE'),
        ('memo', 'read', None),     
        ('memo', 'write', 'OVERWRITE'),  
        ('sms', 'read', None),     
        ('call_history', 'read', None),
        )
	    def convertphonebooktophone(self, helper, data):

        return data

	    imageorigins.update(common.getkv(parent_profile.stockimageorigins, "images"))
	    imagetargets.update(common.getkv(parent_profile.stockimagetargets, "wallpaper",
                                      {'width': 128, 'height': 128, 'format': "JPEG"}))
コード例 #30
0
	def GetImageConstructionInformation(self, file):

        """Gets information for constructing an Image from the file
        @return: (filename to use, function to call that returns wxImage)
        """

        file=os.path.join(self.mainwindow.wallpaperpath, file)

        fi=self.GetFileInfo(file)

        if file.endswith(".mp4") or not os.path.isfile(file):

            return guihelper.getresourcefile('wallpaper.png'), wx.Image

        if fi:

            if fi.format=='AVI':

                return file, conversions.convertavitobmp

            if fi.format=='LGBIT':

                return file, conversions.convertfilelgbittobmp

            if fi.format=='3GPP2':

                return file, lambda name: None

        return file, wx.Image

	def GetFileInfo(self, filename):

        return fileinfo.identify_imagefile(filename)

	def GetImageStatInformation(self, file):

        """Returns the statinfo for file"""

        file=os.path.join(self.mainwindow.wallpaperpath, file)

        return statinfo(file)

	def updateindex(self, index):

        if index!=self._data['wallpaper-index']:

            self._data['wallpaper-index']=index.copy()

            self.modified=True

	def populate(self, dict):

        if self._data['wallpaper-index']!=dict['wallpaper-index']:

            self._data['wallpaper-index']=dict['wallpaper-index'].copy()

            self.modified=True

        self.OnRefresh()

	def OnPaste(self, evt=None):

        super(WallpaperView, self).OnPaste(evt)

        if not wx.TheClipboard.Open():

            return

        if wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_BITMAP)):

            do=wx.BitmapDataObject()

            success=wx.TheClipboard.GetData(do)

        else:

            success=False

        wx.TheClipboard.Close()

        if success:

            self.OnAddImage(wx.ImageFromBitmap(do.GetBitmap()), None)

	def CanPaste(self):

        """ Return True if can accept clipboard data, False otherwise
        """

        if not wx.TheClipboard.Open():

            return False

        r=wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_FILENAME)) or\
           wx.TheClipboard.IsSupported(wx.DataFormat(wx.DF_BITMAP))

        wx.TheClipboard.Close()

        return r

	def AddToIndex(self, file, origin):

        for i in self._data['wallpaper-index']:

            if self._data['wallpaper-index'][i]['name']==file:

                self._data['wallpaper-index'][i]['origin']=origin

                return

        keys=self._data['wallpaper-index'].keys()

        idx=10000

        while idx in keys:

            idx+=1

        self._data['wallpaper-index'][idx]={'name': file, 'origin': origin}

        self.modified=True

	def OnAddFiles(self, filenames):

        for file in filenames:

            if self._raw_image:

                decoded_file=self.decodefilename(file)

                targetfilename=self.getshortenedbasename(decoded_file)

                open(targetfilename, 'wb').write(open(file, 'rb').read())

                self.AddToIndex(str(os.path.basename(targetfilename)).decode(fileview.media_codec),
                                'images')

            else:

                fi=self.GetFileInfo(file)

                if fi is not None and fi.format=='LGBIT':

                    img=conversions.convertfilelgbittobmp(file)

                else:

                    img=wx.Image(file)

                if not img.Ok():

                    dlg=wx.MessageDialog(self, "Failed to understand the image in '"+file+"'",
                                        "Image not understood", style=wx.OK|wx.ICON_ERROR)

                    dlg.ShowModal()

                    continue

                self.OnAddImage(img,file,refresh=False)

        self.OnRefresh()

	def OnAddImage(self, img, file, refresh=True):

        dlg=ImagePreviewDialog(self, img, file, self.mainwindow.phoneprofile)

        if dlg.ShowModal()!=wx.ID_OK:

            dlg.Destroy()

            return

        img=dlg.GetResultImage()

        imgparams=dlg.GetResultParams()

        origin=dlg.GetResultOrigin()

        extension={'BMP': 'bmp', 'JPEG': 'jpg', 'PNG': 'png'}[imgparams['format']]

        decoded_file=self.decodefilename(file)

        targetfilename=self.getshortenedbasename(decoded_file, extension)

        res=getattr(self, "saveimage_"+imgparams['format'])(
            img,
            targetfilename, imgparams)

        if not res:

            try:    os.remove(targetfilename)

            except: pass

            dlg=wx.MessageDialog(self, "Failed to convert the image in '"+file+"'",
                                "Image not converted", style=wx.OK|wx.ICON_ERROR)

            dlg.ShowModal()

            return

        self.AddToIndex(str(os.path.basename(targetfilename)).decode(fileview.media_codec), origin)

        if refresh:

            self.OnRefresh()

	def saveimage_BMP(self, img, targetfilename, imgparams):

        if img.ComputeHistogram(wx.ImageHistogram())<=236: 

            img.SetOptionInt(wx.IMAGE_OPTION_BMP_FORMAT, wx.BMP_8BPP)

        return img.SaveFile(targetfilename, wx.BITMAP_TYPE_BMP)

	def saveimage_JPEG(self, img, targetfilename, imgparams):

        img.SetOptionInt("quality", 100)        

        return img.SaveFile(targetfilename, wx.BITMAP_TYPE_JPEG)

	def saveimage_PNG(self, img, targetfilename, imgparams):

        return img.SaveFile(targetfilename, wx.BITMAP_TYPE_PNG)

	def populatefs(self, dict):

        self.thedir=self.mainwindow.wallpaperpath

        return self.genericpopulatefs(dict, 'wallpapers', 'wallpaper-index', self.CURRENTFILEVERSION)

	def getfromfs(self, result):

        self.thedir=self.mainwindow.wallpaperpath

        return self.genericgetfromfs(result, None, 'wallpaper-index', self.CURRENTFILEVERSION)

	def versionupgrade(self, dict, version):

        """Upgrade old data format read from disk
        @param dict:  The dict that was read in
        @param version: version number of the data on disk
        """

        if version==0:

            version=1  

        if version==1:

            print "converting to version 2"

            version=2

            d={}

            input=dict.get('wallpaper-index', {})

            for i in input:

                d[i]={'name': input[i]}

            dict['wallpaper-index']=d

        return dict

	def getdata(self,dict,want=fileview.FileView.NONE):

        return self.genericgetdata(dict, want, self.mainwindow.wallpaperpath, 'wallpapers', 'wallpaper-index')

    

class  WallpaperPreview (wx.PyWindow) :
	def __init__(self, parent, image=None, id=1, size=wx.DefaultSize, pos=wx.DefaultPosition, style=0):

        wx.PyWindow.__init__(self, parent, id=id, size=size, pos=pos, style=style|wx.FULL_REPAINT_ON_RESIZE)

        self.bg=wx.Brush(parent.GetBackgroundColour())

        self._bufbmp=None

        wx.EVT_ERASE_BACKGROUND(self, lambda evt: None)

        wx.EVT_PAINT(self, self.OnPaint)

        self.SetImage(image)

	def SetImage(self, name):

        if name is None:

            self.theimage=None

        else:

            self.theimage, _=thewallpapermanager.GetImage(name)

        self.thesizedbitmap=None

        self.Refresh(False)

	def OnPaint(self, _):

        sz=self.GetClientSize()

        if self._bufbmp is None or sz.width>self._bufbmp.GetWidth() or sz.height>self._bufbmp.GetHeight():

            self._bufbmp=wx.EmptyBitmap((sz.width+64)&~8, (sz.height+64)&~8)

        dc=wx.BufferedPaintDC(self, self._bufbmp, style=wx.BUFFER_VIRTUAL_AREA)

        dc.SetBackground(self.bg)

        dc.Clear()

        if self.theimage is None: return

        sfactorw=float(sz.width)/self.theimage.GetWidth()

        sfactorh=float(sz.height)/self.theimage.GetHeight()

        sfactor=min(sfactorw,sfactorh)

        newwidth=int(self.theimage.GetWidth()*sfactor)

        newheight=int(self.theimage.GetHeight()*sfactor)

        if self.thesizedbitmap is None or self.thesizedbitmap.GetWidth()!=newwidth or \
           self.thesizedbitmap.GetHeight()!=newheight:

            self.thesizedbitmap=self.theimage.Scale(newwidth, newheight).ConvertToBitmap()

        dc.DrawBitmap(self.thesizedbitmap, sz.width/2-newwidth/2, sz.height/2-newheight/2, True)


def ScaleImageIntoBitmap(img, usewidth, useheight, bgcolor=None, valign="center"):

    """Scales the image and returns a bitmap
    @param usewidth: the width of the new image
    @param useheight: the height of the new image
    @param bgcolor: the background colour as a string ("ff0000" is red etc).  If this
                    is none then the background is made transparent"""

    if bgcolor is None:

        bitmap=wx.EmptyBitmap(usewidth, useheight, 24) 

    else:

        bitmap=wx.EmptyBitmap(usewidth, useheight)

    mdc=wx.MemoryDC()

    mdc.SelectObject(bitmap)

    sfactorw=usewidth*1.0/img.GetWidth()

    sfactorh=useheight*1.0/img.GetHeight()

    sfactor=min(sfactorw,sfactorh) 

    newwidth=int(img.GetWidth()*sfactor/1.0)

    newheight=int(img.GetHeight()*sfactor/1.0)

    img.Rescale(newwidth, newheight)

    if bgcolor is not None:

        transparent=None

        assert len(bgcolor)==6

        red=int(bgcolor[0:2],16)

        green=int(bgcolor[2:4],16)

        blue=int(bgcolor[4:6],16)

        mdc.SetBackground(wx.TheBrushList.FindOrCreateBrush(wx.Colour(red,green,blue), wx.SOLID))

    else:

        transparent=wx.Colour(*(img.FindFirstUnusedColour()[1:]))

        mdc.SetBackground(wx.TheBrushList.FindOrCreateBrush(transparent, wx.SOLID))

    mdc.Clear()

    mdc.SelectObject(bitmap)

    posx=usewidth-(usewidth+newwidth)/2

    if valign in ("top", "clip"):

        posy=0

    elif valign=="center":

        posy=useheight-(useheight+newheight)/2

    else:

        assert False, "bad valign "+valign

        posy=0

    mdc.DrawBitmap(img.ConvertToBitmap(), posx, posy, True)

    mdc.SelectObject(wx.NullBitmap)

    if transparent is not None:

            mask=wx.Mask(bitmap, transparent)

            bitmap.SetMask(mask)

    if valign=="clip" and newheight!=useheight:

        return bitmap.GetSubBitmap( (0,0,usewidth,newheight) )

    return bitmap

statinfo=common.statinfo

class  BPFSHandler (wx.FileSystemHandler) :
	CACHELOWWATER=80
	    CACHEHIGHWATER=100
	    def __init__(self, wallpapermanager):

        wx.FileSystemHandler.__init__(self)

        self.wpm=wallpapermanager

        self.cache={}

	def _GetCache(self, location, statinfo):

        """Return the cached item, or None
        Note that the location value includes the filename and the parameters such as width/height
        """

        if statinfo is None:

            print "bad location",location

            return None

        return self.cache.get( (location, statinfo), None)

	def _AddCache(self, location, statinfo, value):

        "Add the item to the cache"

        if len(self.cache)>=self.CACHEHIGHWATER:

            print "BPFSHandler cache flush"

            while len(self.cache)>self.CACHELOWWATER:

                del self.cache[random.choice(self.cache.keys())]

        self.cache[(location, statinfo)]=value

	def CanOpen(self, location):

        if location.startswith("/"):

            return False

        proto=self.GetProtocol(location)

        if proto=="bpimage" or proto=="bpuserimage":

            return True

        return False

	def OpenFile(self,filesystem,location):

        try:

            res=self._OpenFile(filesystem,location)

        except:

            res=None

            print "Exception in getting image file - you can't do that!"

            print common.formatexception()

        if res is not None:

            res[0].seek(0)

            args=(wx.InputStream(res[0]),)+res[1:]

            res=wx.FSFile(*args)

        return res

	def _OpenFile(self, filesystem, location):

        proto=self.GetProtocol(location)

        r=self.GetRightLocation(location)

        params=r.split(';')

        r=params[0]

        params=params[1:]

        p={}

        for param in params:

            x=param.find('=')

            key=str(param[:x])

            value=param[x+1:]

            if key=='width' or key=='height':

                p[key]=int(value)

            else:

                p[key]=value

        if proto=="bpimage":

            return self.OpenBPImageFile(location, r, **p)

        elif proto=="bpuserimage":

            return self.OpenBPUserImageFile(location, r, **p)

        return None

	def OpenBPUserImageFile(self, location, name, **kwargs):

        si=self.wpm.GetImageStatInformation(name)

        res=self._GetCache(location, si)

        if res is not None: return res

        file,cons=self.wpm.GetImageConstructionInformation(name)

        if cons == wx.Image:

            res=BPFSImageFile(self, location, file, **kwargs)

        else:

            res=BPFSImageFile(self, location, img=cons(file), **kwargs)

        self._AddCache(location, si, res)

        return res

	def OpenBPImageFile(self, location, name, **kwargs):

        f=guihelper.getresourcefile(name)

        if not os.path.isfile(f):

            print f,"doesn't exist"

            return None

        si=statinfo(f)

        res=self._GetCache(location, si)

        if res is not None: return res

        res=BPFSImageFile(self, location, name=f, **kwargs)

        self._AddCache(location, si, res)

        return res


def BPFSImageFile(fshandler, location, name=None, img=None, width=-1, height=-1, valign="center", bgcolor=None):

    """Handles image files
    If we have to do any conversion on the file then we return PNG
    data.  This used to be a class derived from wx.FSFile, but due to
    various wxPython bugs it instead returns the parameters to make a
    wx.FSFile since a new one has to be made every time.
    """

    if img is None and width<0 and height<0:

        mime=guihelper.getwxmimetype(name)

        if mime not in (None, "image/x-bmp"):

            return (open(name, "rb"), location, mime, "", wx.DateTime_Now())

    if img is None:

        img=wx.Image(name)

    if width>0 and height>0:

        b=ScaleImageIntoBitmap(img, width, height, bgcolor, valign)

    else:

        b=img.ConvertToBitmap()

    f=common.gettempfilename("png")

    if not b.SaveFile(f, wx.BITMAP_TYPE_PNG):

        raise Exception, "Saving to png failed"

    data=open(f, "rb").read()

    os.remove(f)

    return (cStringIO.StringIO(data), location, "image/png", "", wx.DateTime_Now())

class  ImageCropSelect (wx.ScrolledWindow) :
	def __init__(self, parent, image, previewwindow=None, id=1, resultsize=(100,100), size=wx.DefaultSize, pos=wx.DefaultPosition, style=0):

        wx.ScrolledWindow.__init__(self, parent, id=id, size=size, pos=pos, style=style|wx.FULL_REPAINT_ON_RESIZE)

        self.previewwindow=previewwindow

        self.bg=wx.Brush(wx.WHITE)

        self.parentbg=wx.Brush(parent.GetBackgroundColour())

        self._bufbmp=None

        self.anchors=None

        wx.EVT_ERASE_BACKGROUND(self, lambda evt: None)

        wx.EVT_PAINT(self, self.OnPaint)

        self.image=image

        self.origimage=image

        self.setresultsize(resultsize)

        self.cursors=[wx.StockCursor(c) for c in (wx.CURSOR_ARROW, wx.CURSOR_HAND, wx.CURSOR_SIZING, wx.CURSOR_NO_ENTRY)]

        self.clickpoint=None 

        wx.EVT_MOTION(self, self.OnMotion)

        wx.EVT_LEFT_DOWN(self, self.OnLeftDown)

        wx.EVT_LEFT_UP(self, self.OnLeftUp)

	def SetPreviewWindow(self, previewwindow):

        self.previewwindow=previewwindow

	def OnPaint(self, _):

        sz=self.thebmp.GetWidth(), self.thebmp.GetHeight()

        sz2=self.GetClientSize()

        sz=max(sz[0],sz2[0])+32,max(sz[1],sz2[1])+32

        if self._bufbmp is None or self._bufbmp.GetWidth()<sz[0] or self._bufbmp.GetHeight()<sz[1]:

            self._bufbmp=wx.EmptyBitmap((sz[0]+64)&~8, (sz[1]+64)&~8)

        dc=wx.BufferedPaintDC(self, self._bufbmp, style=wx.BUFFER_VIRTUAL_AREA)

        if sz2[0]<sz[0] or sz2[1]<sz[1]:

            dc.SetBackground(self.parentbg)

            dc.Clear()

        dc.DrawBitmap(self.thebmp, 0, 0, False)

        l,t,r,b=self.anchors

        points=(l,t), (r,t), (r,b), (l,b)

        dc.DrawLines( points+(points[0],) )

        for x,y in points:

            dc.DrawRectangle(x-5, y-5, 10, 10)

	OUTSIDE=0
	    INSIDE=1
	    HANDLE_LT=2
	    HANDLE_RT=3
	    HANDLE_RB=4
	    HANDLE_LB=5
	    def _hittest(self, evt):

        l,t,r,b=self.anchors

        within=lambda x,y,l,t,r,b:  l<=x<=r and t<=y<=b

        x,y=self.CalcUnscrolledPosition(evt.GetX(), evt.GetY())

        for i,(ptx,pty) in enumerate(((l,t), (r,t), (r,b), (l,b))):

            if within(x,y,ptx-5, pty-5, ptx+5,pty+5):

                return self.HANDLE_LT+i

        if within(x,y,l,t,r,b):

            return self.INSIDE

        return self.OUTSIDE

	def OnMotion(self, evt):

        if evt.Dragging():

            return self.OnMotionDragging(evt)

        self.UpdateCursor(evt)

	def UpdateCursor(self, evt):

        ht=self._hittest(evt)

        self.SetCursor(self.cursors[min(2,ht)])

	def OnMotionDragging(self, evt):

        if not evt.LeftIsDown() or self.clickpoint is None:

            self.SetCursor(self.cursors[3])

            return

        xx,yy=self.CalcUnscrolledPosition(evt.GetX(), evt.GetY())

        deltax=xx-self.origevtpos[0]

        deltay=yy-self.origevtpos[1]

        if self.clickpoint==self.INSIDE:

            newanchors=self.origanchors[0]+deltax, self.origanchors[1]+deltay, \
                        self.origanchors[2]+deltax, self.origanchors[3]+deltay

            iw=self.dimensions[0]

            ih=self.dimensions[1]

            if newanchors[0]<0:

                newanchors=0,newanchors[1], self.origanchors[2]-self.origanchors[0], newanchors[3]

            if newanchors[1]<0:

                newanchors=newanchors[0], 0, newanchors[2], self.origanchors[3]-self.origanchors[1]

            if newanchors[2]>iw:

                newanchors=iw-(self.origanchors[2]-self.origanchors[0]),newanchors[1],iw, newanchors[3]

            if newanchors[3]>ih:

                newanchors=newanchors[0],ih-(self.origanchors[3]-self.origanchors[1]), newanchors[2],ih

            self.anchors=newanchors

            self.Refresh(False)

            self.updatepreview()

            return

        if self.clickpoint==self.HANDLE_LT:

            aa=0,1,-1,-1

        elif self.clickpoint==self.HANDLE_RT:

            aa=2,1,+1,-1

        elif self.clickpoint==self.HANDLE_RB:

            aa=2,3,+1,+1

        elif self.clickpoint==self.HANDLE_LB:

            aa=0,3,-1,+1

        else:

            assert False, "can't get here"

        na=[self.origanchors[0],self.origanchors[1],self.origanchors[2],self.origanchors[3]]

        na[aa[0]]=na[aa[0]]+deltax

        na[aa[1]]=na[aa[1]]+deltay

        neww=na[2]-na[0]

        newh=na[3]-na[1]

        ar=float(neww)/newh

        if ar<self.aspectratio:

            na[aa[0]]=na[aa[0]]+(self.aspectratio*newh-neww)*aa[2]

        elif ar>self.aspectratio:

            na[aa[1]]=na[aa[1]]+(neww/self.aspectratio-newh)*aa[3]

        if neww<10 or newh<10:

            return

        if na[0]<0:

            xdiff=-na[0]

            ydiff=xdiff/self.aspectratio

            na[0]=0

            na[1]+=ydiff

        if na[1]<0:

            ydiff=-na[1]

            xdiff=ydiff*self.aspectratio

            na[1]=0

            na[0]-=xdiff

        if na[2]>self.dimensions[0]:

            xdiff=na[2]-self.dimensions[0]

            ydiff=xdiff/self.aspectratio

            na[2]=na[2]-xdiff

            na[3]=na[3]-ydiff

        if na[3]>self.dimensions[1]:

            ydiff=na[3]-self.dimensions[1]

            xdiff=ydiff*self.aspectratio

            na[2]=na[2]-xdiff

            na[3]=na[3]-ydiff

        if na[0]<0 or na[1]<0 or na[2]>self.dimensions[0] or na[3]>self.dimensions[1]:

            print "offscreen fixup not written yet"

            return

        self.anchors=na

        self.Refresh(False)

        self.updatepreview()

        return

	def OnLeftDown(self, evt):

        ht=self._hittest(evt)

        if ht==self.OUTSIDE:

            self.SetCursor(self.cursors[3])

            return

        self.clickpoint=ht

        xx,yy=self.CalcUnscrolledPosition(evt.GetX(), evt.GetY())

        self.origevtpos=xx,yy

        self.origanchors=self.anchors

	def OnLeftUp(self, evt):

        self.clickpoint=None

        self.UpdateCursor(evt)

	def setlbcolour(self, colour):

        self.bg=wx.Brush(colour)

        self.remakebitmap()

	def SetZoom(self, factor):

        curzoom=float(self.image.GetWidth())/self.origimage.GetWidth()

        self.anchors=[a*factor/curzoom for a in self.anchors]

        self.image=self.origimage.Scale(self.origimage.GetWidth()*factor, self.origimage.GetHeight()*factor)

        self.setresultsize(self.resultsize)

	def setresultsize(self, (w,h)):

        self.resultsize=w,h

        self.aspectratio=ratio=float(w)/h

        imgratio=float(self.image.GetWidth())/self.image.GetHeight()

        neww=self.image.GetWidth()

        newh=self.image.GetHeight()

        if imgratio<ratio:

            neww*=ratio/imgratio

        elif imgratio>ratio:

            newh*=imgratio/ratio

        neww=max(neww, 50)

        newh=max(newh, 50)

        if self.anchors==None:

            self.anchors=0.1 * neww, 0.1 * newh, 0.9 * neww, 0.9 * newh

        l,t,r,b=self.anchors

        l=min(neww-40, l)

        r=min(neww-10, r)

        if r-l<20: r=40

        t=min(newh-40, t)

        b=min(newh-10, b)

        if b-t<20: b=40

        aratio=float(r-l)/(b-t)

        if aratio<ratio:

            b=t+(r-l)/ratio

        elif aratio>ratio:

            r=l+(b-t)*ratio

        self.anchors=l,t,r,b

        self.dimensions=neww,newh

        self.thebmp=wx.EmptyBitmap(neww, newh)

        self.remakebitmap()

	def remakebitmap(self):

        w,h=self.dimensions

        dc=wx.MemoryDC()

        dc.SelectObject(self.thebmp)

        dc.SetBackground(self.bg)

        dc.Clear()

        dc.DrawBitmap(self.image.ConvertToBitmap(), w/2-self.image.GetWidth()/2, h/2-self.image.GetHeight()/2, True)

        dc.SelectObject(wx.NullBitmap)

        self.imageofthebmp=None

        self.SetVirtualSize( (w, h) )

        self.SetScrollRate(1,1)

        self.updatepreview()

        self.Refresh(False)

	def updatepreview(self):

        if self.previewwindow:

            self.previewwindow.SetUpdated(self.GetPreview)

	def GetPreview(self):

        w,h=self.resultsize

        l,t,r,b=self.anchors

        scale=max(float(w+0.99999)/(r-l), float(h+0.99999)/(b-t))

        if True and scale<1:

            sub=wx.EmptyBitmap(w,h)

            mdcsub=wx.MemoryDC()

            mdcsub.SelectObject(sub)

            mdcsub.SetUserScale(scale, scale)

            mdc=wx.MemoryDC()

            mdc.SelectObject(self.thebmp)

            mdcsub.Blit(0,0,r-l,b-t,mdc,l,t)

            mdc.SelectObject(wx.NullBitmap)

            mdcsub.SelectObject(wx.NullBitmap)

            return sub

        sub=self.thebmp.GetSubBitmap( (l,t,(r-l),(b-t)) )

        sub=sub.ConvertToImage()

        sub.Rescale(w,h)

        return sub.ConvertToBitmap()


class  ImagePreview (wx.PyWindow) :
	def __init__(self, parent):

        wx.PyWindow.__init__(self, parent)

        wx.EVT_ERASE_BACKGROUND(self, lambda evt: None)

        wx.EVT_PAINT(self, self.OnPaint)

        self.bmp=wx.EmptyBitmap(1,1)

        self.updater=None

	def SetUpdated(self, updater):

        self.updater=updater

        self.Refresh(True)

	def OnPaint(self, _):

        if self.updater is not None:

            self.bmp=self.updater()

            self.updater=None

        dc=wx.PaintDC(self)

        dc.DrawBitmap(self.bmp, 0, 0, False)


class  ImagePreviewDialog (wx.Dialog) :
	SCALES=[ (0.25, "1/4"),
             (0.5,  "1/2"),
             (1, "1"),
             (2, "2"),
             (4, "4")]
	    def __init__(self, parent, image, filename, phoneprofile):

        wx.Dialog.__init__(self, parent, -1, "Image Preview", style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.SYSTEM_MENU|wx.MAXIMIZE_BOX|wx.MINIMIZE_BOX)

        self.phoneprofile=phoneprofile

        self.filename=filename

        self.image=image

        vbsouter=wx.BoxSizer(wx.VERTICAL)

        hbs=wx.BoxSizer(wx.HORIZONTAL)

        self.cropselect=ImageCropSelect(self, image)

        vbs=wx.BoxSizer(wx.VERTICAL)

        self.colourselect=wx.lib.colourselect.ColourSelect(self, wx.NewId(), "Background ...", (255,255,255))

        vbs.Add(self.colourselect, 0, wx.ALL|wx.EXPAND, 5)

        wx.lib.colourselect.EVT_COLOURSELECT(self, self.colourselect.GetId(), self.OnBackgroundColour)

        vbs.Add(wx.StaticText(self, -1, "Origin"), 0, wx.ALL, 5)

        self.originbox=wx.ListBox(self, size=(-1, 100))

        vbs.Add(self.originbox, 0, wx.ALL|wx.EXPAND, 5)

        vbs.Add(wx.StaticText(self, -1, "Target"), 0, wx.ALL, 5)

        self.targetbox=wx.ListBox(self, size=(-1,100))

        vbs.Add(self.targetbox, 0, wx.EXPAND|wx.ALL, 5)

        vbs.Add(wx.StaticText(self, -1, "Scale"), 0, wx.ALL, 5)

        for one,(s,_) in enumerate(self.SCALES):

            if s==1: break

        self.slider=wx.Slider(self, -1, one, 0, len(self.SCALES)-1, style=wx.HORIZONTAL|wx.SL_AUTOTICKS)

        wx.EVT_SCROLL(self, self.SetZoom)

        vbs.Add(self.slider, 0, wx.ALL|wx.EXPAND, 5)

        self.zoomlabel=wx.StaticText(self, -1, self.SCALES[one][1])

        vbs.Add(self.zoomlabel, 0, wx.ALL|wx.ALIGN_CENTRE_HORIZONTAL, 5)

        vbs.Add(wx.StaticText(self, -1, "Preview"), 0, wx.ALL, 5)

        self.imagepreview=ImagePreview(self)

        self.cropselect.SetPreviewWindow(self.imagepreview)

        vbs.Add(self.imagepreview, 0, wx.ALL, 5)

        hbs.Add(vbs, 0, wx.ALL, 5)

        hbs.Add(self.cropselect, 1, wx.ALL|wx.EXPAND, 5)

        vbsouter.Add(hbs, 1, wx.EXPAND|wx.ALL, 5)

        vbsouter.Add(wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL), 0, wx.EXPAND|wx.ALL, 5)

        vbsouter.Add(self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.HELP), 0, wx.ALIGN_CENTRE|wx.ALL, 5)

        wx.EVT_LISTBOX(self, self.originbox.GetId(), self.OnOriginSelect)

        wx.EVT_LISTBOX_DCLICK(self, self.originbox.GetId(), self.OnOriginSelect)

        wx.EVT_LISTBOX(self, self.targetbox.GetId(), self.OnTargetSelect)

        wx.EVT_LISTBOX_DCLICK(self, self.targetbox.GetId(), self.OnTargetSelect)

        wx.EVT_BUTTON(self, wx.ID_HELP, lambda _:
                      wx.GetApp().displayhelpid(helpids.ID_DLG_IMAGEPREVIEW))

        self.originbox.Set(phoneprofile.GetImageOrigins().keys())

        self.originbox.SetSelection(0)

        self.OnOriginSelect(None)

        self.SetSizer(vbsouter)

        vbsouter.Fit(self)

        import guiwidgets

        guiwidgets.set_size("wallpaperpreview", self, 80, 1.0)

	def ShowModal(self):

        res=wx.Dialog.ShowModal(self)

        import guiwidgets

        guiwidgets.save_size("wallpaperpreview", self.GetRect())

        return res

	def SetZoom(self, evt):

        self.cropselect.SetZoom(self.SCALES[evt.GetPosition()][0])

        self.zoomlabel.SetLabel(self.SCALES[evt.GetPosition()][1])

        return

	def OnBackgroundColour(self, evt):

        self.cropselect.setlbcolour(evt.GetValue())

	def OnOriginSelect(self, _):

        v=self.originbox.GetStringSelection()

        assert v is not None

        t=self.targetbox.GetStringSelection()

        self.targets=self.phoneprofile.GetTargetsForImageOrigin(v)

        keys=self.targets.keys()

        keys.sort()

        self.targetbox.Set(keys)

        if t in keys:

            self.targetbox.SetSelection(keys.index(t))

        else:

            self.targetbox.SetSelection(0)

        self.OnTargetSelect(None)

	def OnTargetSelect(self, _):

        v=self.targetbox.GetStringSelection()

        print "target is",v

        w,h=self.targets[v]['width'],self.targets[v]['height']

        self.imagepreview.SetSize( (w,h) )

        self.cropselect.setresultsize( (w, h) )

        sz=self.GetSizer()

        if sz is not None:

            sz.Layout()

            self.Refresh(True)

	def GetResultImage(self):

        return self.imagepreview.bmp.ConvertToImage()

	def GetResultParams(self):

        return self.targets[self.targetbox.GetStringSelection()]

	def GetResultOrigin(self):

        return self.originbox.GetStringSelection()


if __name__=='__main__':

    if __debug__:

        def profile(filename, command):

            import hotshot, hotshot.stats, os

            file=os.path.abspath(filename)

            profile=hotshot.Profile(file)

            profile.run(command)

            profile.close()

            del profile

            howmany=100

            stats=hotshot.stats.load(file)

            stats.strip_dirs()

            stats.sort_stats('time', 'calls')

            stats.print_stats(100)

            stats.sort_stats('cum', 'calls')

            stats.print_stats(100)

            stats.sort_stats('calls', 'time')

            stats.print_stats(100)

            sys.exit(0)

    class FakeProfile:

        def GetImageOrigins(self):

            return {"images": {'description': 'General images'},
                    "mms": {'description': 'Multimedia Messages'},
                    "camera": {'description': 'Camera images'}}

        def GetTargetsForImageOrigin(self, origin):

            return {"wallpaper": {'width': 100, 'height': 200, 'description': 'Display as wallpaper'},
                    "photoid": {'width': 100, 'height': 150, 'description': 'Display as photo id'},
                    "outsidelcd": {'width': 90, 'height': 80, 'description': 'Display on outside screen'}}

    def run():

        app=wx.PySimpleApp()

        dlg=ImagePreviewDialog(None, wx.Image("test.jpg"), "foobar.png", FakeProfile())

        dlg.ShowModal()

    if __debug__ and True:

        profile("wp.prof", "run()")

    run()


import fileview

if __name__=='__main__':

    if __debug__:

        def profile(filename, command):

            import hotshot, hotshot.stats, os

            file=os.path.abspath(filename)

            profile=hotshot.Profile(file)

            profile.run(command)

            profile.close()

            del profile

            howmany=100

            stats=hotshot.stats.load(file)

            stats.strip_dirs()

            stats.sort_stats('time', 'calls')

            stats.print_stats(100)

            stats.sort_stats('cum', 'calls')

            stats.print_stats(100)

            stats.sort_stats('calls', 'time')

            stats.print_stats(100)

            sys.exit(0)

    class FakeProfile:

        def GetImageOrigins(self):

            return {"images": {'description': 'General images'},
                    "mms": {'description': 'Multimedia Messages'},
                    "camera": {'description': 'Camera images'}}

        def GetTargetsForImageOrigin(self, origin):

            return {"wallpaper": {'width': 100, 'height': 200, 'description': 'Display as wallpaper'},
                    "photoid": {'width': 100, 'height': 150, 'description': 'Display as photo id'},
                    "outsidelcd": {'width': 90, 'height': 80, 'description': 'Display on outside screen'}}

    def run():

        app=wx.PySimpleApp()

        dlg=ImagePreviewDialog(None, wx.Image("test.jpg"), "foobar.png", FakeProfile())

        dlg.ShowModal()

    if __debug__ and True:

        profile("wp.prof", "run()")

    run()
コード例 #31
0
	def windowsinit(self, iconfile):

        bitmap=wx.Bitmap(guihelper.getresourcefile(iconfile), wx.BITMAP_TYPE_PNG)

        icon=wx.EmptyIcon()

        icon.CopyFromBitmap(bitmap)

        self.SetIcon(icon, "BitFling")

        wx.EVT_TASKBAR_RIGHT_UP(self, self.OnRButtonUp)

        wx.EVT_TASKBAR_LEFT_UP(self, self.OnLButtonUp)

        wx.EVT_TASKBAR_LEFT_DOWN(self, self.OnLeftDown)

	def genericinit(self, iconfile):

        self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))

        bitmap=wx.Bitmap(guihelper.getresourcefile(iconfile), wx.BITMAP_TYPE_PNG)

        bit=wx.StaticBitmap(self, -1, bitmap)

        self.Show(True)

        wx.EVT_RIGHT_UP(bit, self.OnRButtonUp)

        wx.EVT_LEFT_UP(bit, self.OnLButtonUp)

        wx.EVT_MOTION(bit, self.OnMouseMotion)

        wx.EVT_LEFT_DOWN(bit, self.OnLeftDown)

        self.bit=bit


class  ConfigPanel (wx.Panel, wx.lib.mixins.listctrl.ColumnSorterMixin) :
	def __init__(self, mw, parent, id=-1):

        wx.Panel.__init__(self, parent, id)

        self.mw=mw

        vbs=wx.BoxSizer(wx.VERTICAL)

        bs=wx.StaticBoxSizer(wx.StaticBox(self, -1, "General"), wx.HORIZONTAL)

        bs.Add(wx.StaticText(self, -1, "Fingerprint"), 0, wx.ALL|wx.ALIGN_CENTRE_VERTICAL, 5)

        self.fingerprint=wx.TextCtrl(self, -1, "a", style=wx.TE_READONLY,  size=(300,-1))

        bs.Add(self.fingerprint, 0, wx.EXPAND|wx.ALL|wx.ALIGN_CENTRE_VERTICAL, 5)

        bs.Add(wx.StaticText(self, -1, ""), 0, wx.ALL, 5) 

        bs.Add(wx.StaticText(self, -1, "Port"), 0, wx.ALL|wx.ALIGN_CENTRE_VERTICAL, 5)

        self.porttext=wx.StaticText(self, -1, "<No Port>")

        bs.Add(self.porttext, 0, wx.ALL|wx.ALIGN_CENTRE_VERTICAL, 5)

        vbs.Add(bs, 0, wx.EXPAND|wx.ALL, 5)

        bs=wx.StaticBoxSizer(wx.StaticBox(self, -1, "Authorization"), wx.VERTICAL)

        hbs=wx.BoxSizer(wx.HORIZONTAL)

        butadd=wx.Button(self, wx.NewId(), "Add ...")

        hbs.Add(butadd, 0, wx.ALL|wx.ALIGN_CENTRE_VERTICAL, 5)

        hbs.Add(wx.StaticText(self, -1, ""), 0, wx.ALL, 5) 

        self.butedit=wx.Button(self, wx.NewId(), "Edit ...")

        self.butedit.Enable(False)

        hbs.Add(self.butedit, 0, wx.ALL|wx.ALIGN_CENTRE_VERTICAL, 5)

        hbs.Add(wx.StaticText(self, -1, ""), 0, wx.ALL, 5) 

        self.butdelete=wx.Button(self, wx.NewId(), "Delete")

        self.butdelete.Enable(False)

        hbs.Add(self.butdelete, 0, wx.ALL|wx.ALIGN_CENTRE_VERTICAL, 5)

        bs.Add(hbs, 0, wx.EXPAND|wx.ALL, 5)

        wx.EVT_BUTTON(self, butadd.GetId(), self.OnAddAuth)

        wx.EVT_BUTTON(self, self.butedit.GetId(), self.OnEditAuth)

        wx.EVT_BUTTON(self, self.butdelete.GetId(), self.OnDeleteAuth)

        self.authlist=wx.ListCtrl(self, wx.NewId(), style=wx.LC_REPORT|wx.LC_SINGLE_SEL)

        self.authlist.InsertColumn(0, "User")

        self.authlist.InsertColumn(1, "Allowed Addresses")

        self.authlist.InsertColumn(2, "Expires")

        self.authlist.SetColumnWidth(0, 300)

        self.authlist.SetColumnWidth(1, 300)

        self.authlist.SetColumnWidth(2, 100)

        bs.Add(self.authlist, 1, wx.EXPAND|wx.ALL, 5)

        vbs.Add(bs, 1, wx.EXPAND|wx.ALL, 5)

        self.itemDataMap={}

        wx.lib.mixins.listctrl.ColumnSorterMixin.__init__(self,3)

        wx.EVT_LIST_ITEM_ACTIVATED(self.authlist, self.authlist.GetId(), self.OnEditAuth)

        wx.EVT_LIST_ITEM_SELECTED(self.authlist, self.authlist.GetId(), self.OnAuthListItemFondled)

        wx.EVT_LIST_ITEM_DESELECTED(self.authlist, self.authlist.GetId(), self.OnAuthListItemFondled)

        wx.EVT_LIST_ITEM_FOCUSED(self.authlist, self.authlist.GetId(), self.OnAuthListItemFondled)

        bs=wx.StaticBoxSizer(wx.StaticBox(self, -1, "Devices"), wx.VERTICAL)

        buttoggle=wx.Button(self, wx.NewId(), "Toggle Allowed")

        bs.Add(buttoggle, 0, wx.ALL, 5)

        self.devicelist=wx.ListCtrl(self, wx.NewId(), style=wx.LC_REPORT|wx.LC_SINGLE_SEL)

        self.devicelist.InsertColumn(0, "Allowed")

        self.devicelist.InsertColumn(1, "Name")

        self.devicelist.InsertColumn(2, "Available")

        self.devicelist.InsertColumn(3, "Description")

        self.devicelist.SetColumnWidth(0, 100)

        self.devicelist.SetColumnWidth(1, 300)

        self.devicelist.SetColumnWidth(2, 100)

        self.devicelist.SetColumnWidth(3, 300)

        bs.Add(self.devicelist, 1, wx.EXPAND|wx.ALL, 5)

        vbs.Add(bs, 1, wx.EXPAND|wx.ALL, 5)

        self.setupauthorization()

        self.SortListItems()

        self.SetSizer(vbs)

        self.SetAutoLayout(True)

	def _updateauthitemmap(self, itemnum):

        pos=-1

        if itemnum in self.itemDataMap:

            for i in range(self.authlist.GetItemCount()):

                if self.authlist.GetItemData(i)==itemnum:

                    pos=i

                    break

            assert pos!=-1

        self.mw.icacache={}

        v=self.mw.authinfo[itemnum]

        username=v[0]

        expires=v[2]

        addresses=" ".join(v[3])

        if pos<0:

            pos=self.authlist.GetItemCount()

            self.authlist.InsertStringItem(pos, username)

        else:

            self.authlist.SetStringItem(pos, 0, username)

        self.authlist.SetStringItem(pos, 2, `expires`)

        self.authlist.SetStringItem(pos, 1, addresses)

        self.authlist.SetItemData(pos, itemnum)

        self.itemDataMap[itemnum]=(username, addresses, expires)

	def GetListCtrl(self):

        "Used by the ColumnSorter mixin"

        return self.authlist

	def setupauthorization(self):

        dict={}

        items=[]

        for i in range(1000):

            if self.mw.config.HasEntry("user-"+`i`):

                username,password,expires,addresses=self.mw.config.Read("user-"+`i`).split(":")

                expires=int(expires)

                addresses=addresses.split()

                dict[i]=username,password,expires,addresses

                items.append(i)

        self.mw.authinfo=dict

        for i in items:

            self._updateauthitemmap(i)

	def OnAddAuth(self,_):

        dlg=AuthItemDialog(self, "Add Entry")

        if dlg.ShowModal()==wx.ID_OK:

            username,password,expires,addresses=dlg.GetValue()

            for i in range(1000):

                if i not in self.mw.authinfo:

                    self.mw.config.Write("user-"+`i`, "%s:%s:%d:%s" % (username, password, expires, " ".join(addresses)))

                    self.mw.config.Flush()

                    self.mw.authinfo[i]=username,password,expires,addresses

                    self._updateauthitemmap(i)

                    self.SortListItems()

                    break

        dlg.Destroy()

	def OnDeleteAuth(self, _):

        item=self._getselectedlistitem(self.authlist)

        key=self.authlist.GetItemData(item)

        del self.mw.authinfo[key]

        self.authlist.DeleteItem(item)

        self.mw.config.DeleteEntry("user-"+`key`)

        self.mw.config.Flush()

	def _getselectedlistitem(self, listctrl):

        "Finds the selected item in a listctrl since the wx methods don't actually work"

        i=-1

        while True:

            nexti=listctrl.GetNextItem(i, state=wx.LIST_STATE_SELECTED)

            if nexti<0:

                break

            i=nexti

            return i

        return None

	def OnAuthListItemFondled(self, _):

        "Called whenever list items are selected, unselectected or similar fondling"

        selitem=self._getselectedlistitem(self.authlist)

        self.butedit.Enable(selitem is not None)

        self.butdelete.Enable(selitem is not None)

	def OnEditAuth(self, _):

        "Called to edit the currently selected entry"

        item=self._getselectedlistitem(self.authlist)

        key=self.authlist.GetItemData(item)

        username,password,expires,addresses=self.mw.authinfo[key]

        dlg=AuthItemDialog(self, "Edit Entry", username=username, password=password, expires=expires, addresses=addresses)

        if dlg.ShowModal()==wx.ID_OK:

            username,password,expires,addresses=dlg.GetValue()

            self.mw.authinfo[key]=username,password,expires,addresses

            self._updateauthitemmap(key)

        dlg.Destroy()


class  AuthItemDialog (wx.Dialog) :
	_password_sentinel="\x01\x02\x03\x04\x05\x06\x07\x08"
	    def __init__(self, parent, title, username="******", password="", expires=0, addresses=[]):

        wx.Dialog.__init__(self, parent, -1, title, style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER)

        p=self

        gs=wx.FlexGridSizer(4, 2, 5, 5)

        gs.AddGrowableCol(1)

        gs.AddGrowableRow(3)

        gs.Add(wx.StaticText(p, -1, "Username/Email"))

        self.username=wx.TextCtrl(self, -1, username)

        gs.Add(self.username,0, wx.EXPAND)

        gs.Add(wx.StaticText(p, -1, "Password"))

        self.password=wx.TextCtrl(self, -1, "", style=wx.TE_PASSWORD)

        self.origpassword=password

        if len(password): self.password.SetValue(self._password_sentinel)

        gs.Add(self.password, 0, wx.EXPAND)

        gs.Add(wx.StaticText(p, -1, "Expires"))

        self.expires=wx.lib.masked.textctrl.TextCtrl(p, -1, "", autoformat="EUDATETIMEYYYYMMDD.HHMM")

        gs.Add(self.expires)

        gs.Add(wx.StaticText(p, -1, "Allowed Addresses"))

        self.addresses=wx.TextCtrl(self, -1, "\n".join(addresses), style=wx.TE_MULTILINE)

        gs.Add(self.addresses, 1, wx.EXPAND)

        vbs=wx.BoxSizer(wx.VERTICAL)

        vbs.Add(gs,1, wx.EXPAND|wx.ALL, 5)

        vbs.Add(wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL), 0, wx.EXPAND|wx.ALL, 5)

        vbs.Add(self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.HELP), 0, wx.ALIGN_CENTER|wx.ALL, 5)

        self.SetSizer(vbs)

        vbs.Fit(self)

	def GenPassword(self, string):

        salt="".join([chr(random.randint(0,127)) for x in range(8)])

        saltstr="".join(["%02x" % (ord(x),) for x in salt])

        val=sha.new(salt+string)

        return "$".join([saltstr, val.hexdigest()])

	def GetValue(self):

        if self.password.GetValue()!=self._password_sentinel:

            password=self.GenPassword(self.password.GetValue())

        else:

            password=self.origpassword

        return [self.username.GetValue(), password, 0, self.addresses.GetValue().split()]


class  MainWindow (wx.Frame) :
	def __init__(self, parent, id, title):

        self.taskwin=None 

        wx.Frame.__init__(self, parent, id, title, style=wx.RESIZE_BORDER|wx.SYSTEM_MENU|wx.CAPTION)

        sys.excepthook=self.excepthook

        self.authinfo={}  

        self.icacache={}  

        cfgstr='bitfling'

        if guihelper.IsMSWindows():

            cfgstr="BitFling"  

        self.config=wx.Config(cfgstr, style=wx.CONFIG_USE_LOCAL_FILE)

        wx.GetApp().SetAppName(cfgstr)

        wx.GetApp().SetVendorName(cfgstr)

        self.setuphelp()

        wx.EVT_CLOSE(self, self.CloseRequested)

        panel=wx.Panel(self, -1)

        bs=wx.BoxSizer(wx.VERTICAL)

        self.nb=wx.Notebook(panel, -1)

        bs.Add(self.nb, 1, wx.EXPAND|wx.ALL, 5)

        bs.Add(wx.StaticLine(panel, -1), 0, wx.EXPAND|wx.TOP|wx.BOTTOM, 5)

        gs=wx.GridSizer(1,4, 5, 5)

        for name in ("Rescan", "Hide", "Help", "Exit" ):

            but=wx.Button(panel, wx.NewId(), name)

            setattr(self, name.lower(), but)

            gs.Add(but)

        bs.Add(gs,0,wx.ALIGN_CENTRE|wx.ALL, 5)

        panel.SetSizer(bs)

        panel.SetAutoLayout(True)

        self.configpanel=ConfigPanel(self, self.nb)

        self.nb.AddPage(self.configpanel, "Configuration")

        self.lw=guihelper.LogWindow(self.nb)

        self.nb.AddPage(self.lw, "Log")

        wx.EVT_BUTTON(self, self.hide.GetId(), self.OnHideButton)

        wx.EVT_BUTTON(self, self.help.GetId(), self.OnHelpButton)

        wx.EVT_BUTTON(self, self.exit.GetId(), self.OnExitButton)

        EVT_XMLSERVER(self, self.OnXmlServerEvent)

        self.xmlrpcserver=None

        wx.CallAfter(self.StartIfICan)

	def setuphelp(self):

        """Does all the nonsense to get help working"""

        import wx.html

        from wxPython.htmlhelp import wxHtmlHelpController

        wx.FileSystem_AddHandler(wx.ZipFSHandler())

        self.helpcontroller=wxHtmlHelpController()

        self.helpcontroller.AddBook(guihelper.getresourcefile("bitpim.htb"))

        self.helpcontroller.UseConfig(self.config, "help")

	def IsConnectionAllowed(self, peeraddr, username=None, password=None):

        """Verifies if a connection is allowed
        If username and password are supplied (as should be the case if calling this method
        before executing some code) then they are checked as being from a valid address
        as well.
        If username and password are not supplied then this method checks if any
        of the authentication rules allow a connection from the peeraddr.  This form
        is used immediately after calling accept() on a socket, but before doing
        anything else."""

        v=(peeraddr[0], username, password)

        if username is not None and password is None:

            self.Log("%s: No password supplied for user %s" % (peeraddr, `username`))

            assert False, "No password supplied"

            return False 

        print "ica of "+`v`

        val=self.icacache.get(v, None)

        if val is not None:

            allowed, expires = val

            if allowed:

                if self._has_expired(expires):

                    msg="Connection from %s no longer allowed due to expiry" % (peeraddr[0],)

                    if username is not None:

                        msg+=".  Username "+`username`

                    self.Log(msg)

                    return False

                return True

            return False

        ret_allowed=False

        ret_expiry=0  

        for uname, pwd, expires, addresses in self.authinfo.values():  

            if not self._does_address_match(peeraddr[0], addresses):

                continue

            if username is not None:

                if  username!=uname:

                    continue

                if not self._verify_password(password, pwd):

                    self.Log("Wrong password supplied for user %s from %s" % (`username`, peeraddr[0]))

                    continue

            ret_expiry=max(ret_expiry, expires)

            ret_allowed=True

        if not ret_allowed:

            if username is not None:

                self.Log("No valid credentials for user %s from %s" % (username, peeraddr[0]))

            else:

                self.Log("No defined users for address "+`peeraddr`)

        self.icacache[v]=ret_allowed, ret_expiry

        return self.IsConnectionAllowed(peeraddr, username, password)

	def _verify_password(self, password, pwd):

        """Returns True if password matches pwd
        @param password: password supplied by user
        @param pwd:  password as we store it (salt $ hash)"""

        salt,hash=pwd.split("$", 1)

        x=""

        for i in range(0, len(salt), 2):

            x+=chr(int(salt[i:i+2], 16))

        salt=x

        str=[]

        str.extend([ord(x) for x in salt])

        str.extend([ord(x) for x in password])

        val=sha.new("".join([chr(x) for x in str]))

        print password, pwd, val.hexdigest(), val.hexdigest()==hash

        return val.hexdigest()==hash

	def _does_address_match(self, peeraddr, addresses):

        """Returns if the peeraddr matches any of the supplied addresses"""

        for addr in addresses:

            if peeraddr==addr: return True

            if '*' in addr or '?' in addr or '[' in addr:

                if fnmatch.fnmatch(peeraddr, addr):

                    return True

            ips=[]

            try:

                ips=socket.getaddrinfo(addr, None)

            except:

                pass

            for _, _, _, _, ip in ips:

                if peeraddr==ip[0]:

                    return True

        return False

	def _has_expired(self, expires):

        if expires==0:

            return False

        if time.time()>expires:

            return True

        return False

	def CloseRequested(self, evt):

        if evt.CanVeto():

            self.Show(False)

            evt.Veto()

            return

        self.taskwin.GoAway()

        evt.Skip()

        sys.excepthook=sys.__excepthook__

	def OnXmlServerEvent(self, msg):

        if msg.cmd=="log":

            self.Log(msg.data)

        elif msg.cmd=="logexception":

            self.LogException(msg.data)

        else:

            assert False, "bad message "+`msg`

            pass

	def OnExitButton(self, _):

        self.Close(True)

	def OnHideButton(self, _):

        self.Show(False)

	def OnHelpButton(self, _):

        import helpids

        self.helpcontroller.Display(helpids.ID_BITFLING)

	def Log(self, text):

        if thread.get_ident()!=guithreadid:

            wx.PostEvent(self, XmlServerEvent(cmd="log", data=text))

        else:

            self.lw.log(text)

	def LogException(self, exc):

        if thread.get_ident()!=guithreadid:

            wx.PostEvent(self, XmlServerEvent(cmd="log", data="Exception in thread "+threading.currentThread().getName()))

            wx.PostEvent(self, XmlServerEvent(cmd="logexception", data=exc))

        else:

            self.lw.logexception(exc)

	def excepthook(self, *args):

        """Replacement exception handler that sends stuff to our log window"""

        self.LogException(args)

	def GetCertificateFilename(self):

        """Return certificate filename
        By default $HOME (or My Documents) / .bitfling.key
        but can be overridden with "certificatefile" config key"""

        if guihelper.IsMSWindows(): 

            from win32com.shell import shell, shellcon

            path=shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0)

            path=os.path.join(path, ".bitfling.key")

        else:

            path=os.path.expanduser("~/.bitfling.key")

        return self.config.Read("certificatefile", path)

	def StartIfICan(self):

        certfile=self.GetCertificateFilename()

        if not os.path.isfile(certfile):

            wx.BeginBusyCursor(wx.StockCursor(wx.CURSOR_ARROWWAIT))

            bi=wx.BusyInfo("Creating BitFling host certificate and keys")

            try:

                generate_certificate(certfile)

                if not os.path.isfile(certfile):

                    certfile=None

            finally:

                del bi

                wx.EndBusyCursor()

        port=self.config.ReadInt("port", 12652)

        if port<1 or port>65535: port=None

        host=self.config.Read("bindaddress", "")

        if certfile is None or port is None:

            return

        self.Log("Starting on port "+`port`)

        key=paramiko.DSSKey.from_private_key_file(certfile)

        fp=paramiko.util.hexify(key.get_fingerprint())

        self.configpanel.fingerprint.SetValue(fp)

        self.configpanel.porttext.SetLabel(`port`)

        self.configpanel.GetSizer().Layout()

        self.xmlrpcserver=BitFlingService(self, host, port, key)

        self.xmlrpcserver.setDaemon(True)

        self.xmlrpcserver.start()


def generate_certificate(outfile):

    key=paramiko.DSSKey.generate()

    key.write_private_key_file(outfile, None)

class  XMLRPCService (xmlrpcstuff.Server) :
	def __init__(self, mainwin, host, port, servercert):

        self.mainwin=mainwin

        xmlrpcstuff.Server.__init__(self, host, port, servercert)

	def OnLog(self, msg):

        wx.PostEvent(self.mainwin, XmlServerEvent(cmd="log", data=msg))

	def OnLogException(self, exc):

        wx.PostEvent(self.mainwin, XmlServerEvent(cmd="logexception", data=exc))

	def OnNewAccept(self, clientaddr):

        return self.mainwin.IsConnectionAllowed(clientaddr)

	def OnNewUser(self, clientaddr, username, password):

        return self.mainwin.IsConnectionAllowed(clientaddr, username, password)

	def OnMethodDispatch(self, method, params, username, clientaddr):

        method="exp_"+method

        if not hasattr(self, method):

            raise Fault(3, "No such method")

        context={ 'username': username, 'clientaddr': clientaddr }

        return getattr(self, method)(*params, **{'context': context})


class  BitFlingService (XMLRPCService) :
	def __init__(self, mainwin, host, port, servercert):

        XMLRPCService.__init__(self, mainwin, host, port, servercert)

        self.handles={}

	def stashhandle(self, context, comm):

        for i in range(10000):

            if i not in self.handles:

                self.handles[i]=[context, comm]

                return i

	def gethandle(self, context, num):

        return self.handles[num][1]

	def exp_scan(self, context):

        if usb is None:

            return comscan.comscan()

        else:

            return usbscan.usbscan()+comscan.comscan()

	def exp_getversion(self, context):

        return version.description

	def exp_deviceopen(self, port, baud, timeout, hardwareflow, softwareflow, context):

        return self.stashhandle(context, commport.CommConnection(None, port, baud, timeout,
                                                                 hardwareflow, softwareflow))

	def exp_deviceclose(self, handle, context):

        comm=self.gethandle(context, handle)

        comm.close()

        del self.handles[handle]

        return True

	def exp_devicesetbaudrate(self, handle, rate, context):

        return self.gethandle(context, handle).setbaudrate(rate)

	def exp_devicesetdtr(self, handle, dtr, context):

        return self.gethandle(context, handle).setdtr(dtr)

	def exp_devicesetrts(self, handle, rts, context):

        return self.gethandle(context, handle).setrts(rts)

	def exp_devicewrite(self, handle, data, context):

        self.gethandle(context, handle).write(data.data)

        return len(data.data)

	def exp_devicesendatcommand(self, handle, atcommand, ignoreerror, context):

        "Special handling for empty lists and exceptions"

        try:

            res=self.gethandle(context, handle).sendatcommand(atcommand.data, ignoreerror=ignoreerror)

            if len(res)==0:

                res=1

        except:

            res=0

        return res

	def exp_devicereaduntil(self, handle, char, numfailures, context):

        return Binary(self.gethandle(context, handle).readuntil(char.data, numfailures=numfailures))

	def exp_deviceread(self, handle, numchars, context):

        return Binary(self.gethandle(context, handle).read(numchars))

	def exp_devicereadsome(self, handle, numchars, context):

        if numchars==-1:

            numchars=None

        return Binary(self.gethandle(context, handle).readsome(log=True,numchars=numchars))

	def exp_devicewritethenreaduntil(self, handle, data, char, numfailures, context):

        return Binary(self.gethandle(context, handle).writethenreaduntil(data.data, False, char.data, False, False, numfailures))


def run(args):

    theApp=wx.PySimpleApp()

    menu=wx.Menu()

    menu.Append(ID_EXIT, "Exit")

    mw=MainWindow(None, -1, "BitFling")

    taskwin=MyTaskBarIcon(mw, menu)

    mw.taskwin=taskwin

    theApp.MainLoop()

if __name__ == '__main__':

    run()


try:

    import native.usb as usb

except ImportError:

    usb=None


if guihelper.IsMSWindows(): parentclass=wx.TaskBarIcon

else: parentclass=wx.Frame


if __name__ == '__main__':

    run()