def __init__(self, parent, id, title): self.taskwin = None # set later wx.Frame.__init__(self, parent, id, title, style=wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION) sys.excepthook = self.excepthook self.authinfo = {} # updated by config panel self.icacache = {} # used by IsConnectionAllowed # Establish config stuff cfgstr = 'bitfling' if guihelper.IsMSWindows(): cfgstr = "BitFling" # nicely capitalized on Windows self.config = wx.Config(cfgstr, style=wx.CONFIG_USE_LOCAL_FILE) # self.config.SetRecordDefaults(True) # for help to save prefs 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) # the notebook pages 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 __init__(self, parent): super(PathPage, self).__init__(parent, 'Select New Storage Dir') if guihelper.IsMSWindows(): shell = client.Dispatch("WScript.Shell") self.defaultdir = os.path.join(shell.SpecialFolders("MyDocuments"), 'Phones') else: self.defaultdir = os.path.expanduser('~/Phones')
def set(self, data): if data.get('currentsettings', False): self.setting.SetSelection(1) else: self.setting.SetSelection(0) if guihelper.IsMSWindows(): self.desktop.SetValue(data.get('desktop', False)) self.startmenu.SetValue(data.get('startmenu', False))
def set(self, data): text = ['Name:\t%s' % data.get('name', '')] text.append('Dir:\t%s' % data.get('path', '')) if data.get('currentsettings', False): text.append('Use current BitPim settings.') else: text.append('Use default BitPim settings.') if guihelper.IsMSWindows(): if data.get('desktop', False): text.append('Create a shortcut on your Desktop.') if data.get('startmenu', False): text.append('Create a shortcut in your Start Menu.') self.summary.SetValue('\n\n'.join(text))
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(): # we want subdir of my documents on windows # nice and painful 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 check_update(update_url=None, current_version=None, platform=None, flavor=''): # get info from current version if current_version is None: current_version = version.version # set flavor to blank for now, should be flavor=version.flavor if platform is None: if guihelper.IsMSWindows(): platform = 'windows' elif guihelper.IsGtk(): platform = 'linux' elif guihelper.IsMac(): platform = 'mac' else: raise ValueError, 'Invalid platform' # todo: need to figure out how to do flavor, comment out for now ## flavor=version.vendor # retrieve and parse update info print 'Checking update for BitPim ', current_version, ' running on ', \ platform, '-', flavor with guihelper.WXDialogWrapper( wx.ProgressDialog('BitPim Update', 'Retrieving BitPim Update Information...', style=wx.PD_AUTO_HIDE)) as dlg: bp_update = BitPimUpdate() s = None try: if update_url is None: bp_update.get_update_info() else: bp_update.get_update_info(update_url) dlg.Update(100) except: s = 'Failed to get BitPim update info.' if s is None: s = bp_update.display_update_info(current_version, platform, flavor) latest_version = bp_update.latest_version else: latest_version = '' if s is not None: # error messages being return, display them guihelper.MessageDialog(None, s, 'BitPim Update', wx.OK | wx.ICON_INFORMATION) return latest_version
def _getdefaults(self): # return the default path & config file name # consistent with the previous BitPim way if guihelper.IsMSWindows( ): # we want subdir of my documents on windows # nice and painful from win32com.shell import shell, shellcon try: path = shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0) except: # it will fail if path doesn't exist. one example was a user # putting my docs on an external usb drive that isn't plugged in # when starting bitpim path = r"c:\My BitPim Files" path = os.path.join(path, "bitpim") else: path = os.path.expanduser("~/.bitpim-files") return path, os.path.join(path, Config._default_config_filename)
def GetMyControls(self): vbs = wx.BoxSizer(wx.VERTICAL) self.setting = wx.RadioBox( self, -1, 'Initial Config Settings:', choices=['Use Default Settings', 'Use Current Settings'], style=wx.RA_SPECIFY_ROWS) vbs.Add(self.setting, 0, wx.EXPAND | wx.ALL, 5) if guihelper.IsMSWindows(): sbs = wx.StaticBoxSizer( wx.StaticBox(self, -1, 'Shortcut Options:'), wx.VERTICAL) self.desktop = wx.CheckBox(self, -1, 'Create a shortcut on your Desktop') sbs.Add(self.desktop, 0, wx.EXPAND | wx.ALL, 5) self.startmenu = wx.CheckBox( self, -1, 'Create a shortcut in your Start Menu') sbs.Add(self.startmenu, 0, wx.EXPAND | wx.ALL, 5) vbs.Add(sbs, 0, wx.EXPAND | wx.ALL, 5) return vbs
def Draw(self, dc, width, height, selected): # uncomment to see exactly what size is given #dc.DrawRectangle(0,0,width,height) us=dc.GetUserScale() dc.SetClippingRegion(0,0,width,height) hdc=wx.html.HtmlDCRenderer() hdc.SetDC(dc, 1) hdc.SetSize(9999, 9999) # width is deliberately wide so that no wrapping happens hdc.SetHtmlText(self.genhtml(selected), '.', True) hdc.Render(0,0) del hdc # restore scale hdc messes dc.SetUserScale(*us) dc.DestroyClippingRegion() # Linux gets bounding box wrong, so we deliberately return actual size if guihelper.IsGtk(): return (0,0,width,height) elif guihelper.IsMSWindows(): return max(0,dc.MinX()), max(0, dc.MinY()), min(width, dc.MaxX()), min(height, dc.MaxY())
def create_new_db(parent, config=None): # Create a new BitPim Storage area with guihelper.WXDialogWrapper(NewDBWizard(parent)) as wz: if wz.RunWizard(): data = wz.get() name = data.get('name', '') # Dir should aleady exist, but check anyway path = data.get('path', '') if not os.path.isdir(path): os.makedirs(path) # create a config file filename = os.path.join(path, '.bitpim') if data.get('currentsettings', False) and config: config.write(file(filename, 'wt')) conf = bp_config.Config(filename) conf.Write('name', name) # and optionally create shortcuts (Windows only) if guihelper.IsMSWindows(): if data.get('desktop', False): create_desktop_shortcut(name, filename) if data.get('startmenu', False): create_startmenu_shortcut(name, filename)
def OnLeftDown(self, evt): if guihelper.IsMSWindows(): self.leftdownpos=0 else: self.leftdownpos=evt.GetPosition() self.motionorigin=self.leftdownpos
import guihelper import xmlrpcstuff import version ID_CONFIG=wx.NewId() ID_LOG=wx.NewId() ID_RESCAN=wx.NewId() ID_EXIT=wx.NewId() XmlServerEvent, EVT_XMLSERVER = wx.lib.newevent.NewEvent() guithreadid=thread.get_ident() # in theory this should also work for GTK, but in practise it doesn't if guihelper.IsMSWindows(): parentclass=wx.TaskBarIcon else: parentclass=wx.Frame class MyTaskBarIcon(parentclass): def __init__(self, mw, menu): self.mw=mw self.menu=menu iconfile="bitfling.png" if parentclass is wx.Frame: parentclass.__init__(self, None, -1, "BitFling Window", size=(32,32), style=wx.FRAME_TOOL_WINDOW) self.genericinit(iconfile) else: parentclass.__init__(self) self.windowsinit(iconfile)
def get(self, data): data['currentsettings'] = self.setting.GetSelection() == 1 if guihelper.IsMSWindows(): data['desktop'] = self.desktop.GetValue() data['startmenu'] = self.startmenu.GetValue()
# system module from __future__ import with_statement import os import os.path # wx modules import wx import wx.wizard as wiz from wx.lib.expando import ExpandoTextCtrl # BitPim modules import bp_config import guihelper import setphone_wizard if guihelper.IsMSWindows(): from win32com import client parentpage = setphone_wizard.MyPage #------------------------------------------------------------------------------- class NamePage(parentpage): def __init__(self, parent): super(NamePage, self).__init__(parent, 'Select BitPim Storage Name') def GetMyControls(self): vbs = wx.BoxSizer(wx.VERTICAL) vbs.Add(wx.StaticText(self, -1, 'Storage Name:'), 0, wx.EXPAND | wx.ALL, 5) self.name = wx.TextCtrl(self, -1, '')
class FileSystemFileView(wx.ListCtrl, listmix.ColumnSorterMixin): def __init__(self, mainwindow, parent, id, style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_SINGLE_SEL): wx.ListCtrl.__init__(self, parent, id, style=style) self.parent=parent self.mainwindow=mainwindow self.datacolumn=False # used for debugging and inspection of values self.InsertColumn(0, "Name", width=300) self.InsertColumn(1, "Size", format=wx.LIST_FORMAT_RIGHT) self.InsertColumn(2, "Date", width=200) self.font=wx.TheFontList.FindOrCreateFont(10, family=wx.SWISS, style=wx.NORMAL, weight=wx.NORMAL) self.ResetView() if self.datacolumn: self.InsertColumn(3, "Extra Stuff", width=400) listmix.ColumnSorterMixin.__init__(self, 4) else: listmix.ColumnSorterMixin.__init__(self, 3) #sort by genre (column 2), A->Z ascending order (1) self.filemenu=wx.Menu() self.filemenu.Append(guihelper.ID_FV_SAVE, "Save ...") self.filemenu.Append(guihelper.ID_FV_HEXVIEW, "Hexdump") self.filemenu.AppendSeparator() self.filemenu.Append(guihelper.ID_FV_DELETE, "Delete") self.filemenu.Append(guihelper.ID_FV_OVERWRITE, "Overwrite ...") # generic menu self.genericmenu=wx.Menu() self.genericmenu.Append(guihelper.ID_FV_NEWFILE, "New File ...") self.genericmenu.AppendSeparator() self.genericmenu.Append(guihelper.ID_FV_OFFLINEPHONE, "Offline Phone") self.genericmenu.Append(guihelper.ID_FV_REBOOTPHONE, "Reboot Phone") self.genericmenu.Append(guihelper.ID_FV_MODEMMODE, "Go to modem mode") wx.EVT_MENU(self.genericmenu, guihelper.ID_FV_NEWFILE, self.OnNewFile) wx.EVT_MENU(self.genericmenu, guihelper.ID_FV_OFFLINEPHONE, parent.OnPhoneOffline) wx.EVT_MENU(self.genericmenu, guihelper.ID_FV_REBOOTPHONE, parent.OnPhoneReboot) wx.EVT_MENU(self.genericmenu, guihelper.ID_FV_MODEMMODE, parent.OnModemMode) wx.EVT_MENU(self.filemenu, guihelper.ID_FV_SAVE, self.OnFileSave) wx.EVT_MENU(self.filemenu, guihelper.ID_FV_HEXVIEW, self.OnHexView) wx.EVT_MENU(self.filemenu, guihelper.ID_FV_DELETE, self.OnFileDelete) wx.EVT_MENU(self.filemenu, guihelper.ID_FV_OVERWRITE, self.OnFileOverwrite) wx.EVT_RIGHT_DOWN(self.GetMainWindow(), self.OnRightDown) wx.EVT_RIGHT_UP(self.GetMainWindow(), self.OnRightUp) wx.EVT_LIST_ITEM_ACTIVATED(self,id, self.OnItemActivated) self.image_list=wx.ImageList(16, 16) a={"sm_up":"GO_UP","sm_dn":"GO_DOWN","w_idx":"WARNING","e_idx":"ERROR","i_idx":"QUESTION"} for k,v in a.items(): s="self.%s= self.image_list.Add(wx.ArtProvider_GetBitmap(wx.ART_%s,wx.ART_TOOLBAR,(16,16)))" % (k,v) exec(s) self.img_file=self.image_list.Add(wx.ArtProvider_GetBitmap(wx.ART_NORMAL_FILE, wx.ART_OTHER, (16, 16))) self.SetImageList(self.image_list, wx.IMAGE_LIST_SMALL) #if guihelper.IsMSWindows(): # turn on drag-and-drag for windows #wx.EVT_MOTION(self, self.OnStartDrag) self.__dragging=False self.add_files=[] self.droptarget=fileview.MyFileDropTarget(self, True, False) self.SetDropTarget(self.droptarget) def OnPaint(self, evt): w,h=self.GetSize() self.Refresh() dc=wx.PaintDC(self) dc.BeginDrawing() dc.SetFont(self.font) x,y= dc.GetTextExtent("There are no items to show in this view") # center the text xx=(w-x)/2 if xx<0: xx=0 dc.DrawText("There are no items to show in this view", xx, h/3) dc.EndDrawing() def OnDropFiles(self, _, dummy, filenames): # There is a bug in that the most recently created tab # in the notebook that accepts filedrop receives these # files, not the most visible one. We find the currently # viewed tab in the notebook and send the files there if self.__dragging: # I'm the drag source, forget 'bout it ! return target=self # fallback t=self.mainwindow.GetCurrentActiveWidget() if isinstance(t, FileSystemFileView): # changing target in dragndrop target=t self.add_files=filenames target.OnAddFiles() def OnDragOver(self, x, y, d): # force copy (instead of move) return wx._misc.DragCopy def OnAddFiles(self): mw=self.mainwindow if not len(self.add_files): return for file in self.add_files: if file is None: continue if len(self.path): path=self.path+"/"+os.path.basename(file) else: path=os.path.basename(file) # you can't create files in root but I won't stop you contents=open(file, "rb").read() mw.MakeCall( gui.Request(mw.wt.writefile, path, contents), gui.Callback(self.OnAddFilesResults, self.path) ) self.add_files.remove(file) # can only add one file at a time break def OnAddFilesResults(self, parentdir, exception, _): mw=self.mainwindow if mw.HandleException(exception): return # add next file if there is one if not len(self.add_files): self.ShowFiles(parentdir, True) else: self.OnAddFiles() if guihelper.IsMSWindows(): # drag-and-drop files only works in Windows def OnStartDrag(self, evt): evt.Skip() if not evt.LeftIsDown(): return path=self.itemtopath(self.GetFirstSelected()) drag_source=wx.DropSource(self) file_names=wx.FileDataObject() file_names.AddFile(path) drag_source.SetData(file_names) self.__dragging=True res=drag_source.DoDragDrop(wx.Drag_CopyOnly) self.__dragging=False def OnRightUp(self, event): pt = event.GetPosition() item, flags = self.HitTest(pt) if item is not -1: self.Select(item) self.PopupMenu(self.filemenu, pt) else: self.PopupMenu(self.genericmenu, pt) def OnRightDown(self,event): # You have to capture right down otherwise it doesn't feed you right up pt = event.GetPosition(); item, flags = self.HitTest(pt) try: self.Select(item) except: pass def OnNewFile(self,_): with guihelper.WXDialogWrapper(wx.FileDialog(self, style=wx.OPEN|wx.HIDE_READONLY|wx.CHANGE_DIR), True) as (dlg, retcode): if retcode==wx.ID_OK: infile=dlg.GetPath() contents=open(infile, "rb").read() if len(self.path): path=self.path+"/"+os.path.basename(dlg.GetPath()) else: path=os.path.basename(dlg.GetPath()) # you can't create files in root but I won't stop you mw=self.mainwindow mw.MakeCall( gui.Request(mw.wt.writefile, path, contents), gui.Callback(self.parent.OnNewFileResults, self.path) ) def OnFileSave(self, _): path=self.itemtopath(self.GetFirstSelected()) mw=self.mainwindow mw.MakeCall( gui.Request(mw.wt.getfile, path), gui.Callback(self.OnFileSaveResults, path) ) def OnFileSaveResults(self, path, exception, contents): mw=self.mainwindow if mw.HandleException(exception): return bn=guihelper.basename(path) ext=guihelper.getextension(bn) if len(ext): ext="%s files (*.%s)|*.%s" % (ext.upper(), ext, ext) else: ext="All files|*" with guihelper.WXDialogWrapper(wx.FileDialog(self, "Save File As", defaultFile=bn, wildcard=ext, style=wx.SAVE|wx.OVERWRITE_PROMPT|wx.CHANGE_DIR), True) as (dlg, retcode): if retcode==wx.ID_OK: file(dlg.GetPath(), "wb").write(contents) def OnItemActivated(self,_): self.OnHexView(self) def OnHexView(self, _): path=self.itemtopath(self.GetFirstSelected()) mw=self.mainwindow mw.MakeCall( gui.Request(mw.wt.getfile, path), gui.Callback(self.OnHexViewResults, path) ) def OnHexViewResults(self, path, exception, result): mw=self.mainwindow if mw.HandleException(exception): return # ::TODO:: make this use HexEditor ## dlg=guiwidgets.MyFixedScrolledMessageDialog(self, common.datatohexstring(result), ## path+" Contents", helpids.ID_HEXVIEW_DIALOG) dlg=hexeditor.HexEditorDialog(self, result, path+" Contents") dlg.Show() def OnFileDelete(self, _): path=self.itemtopath(self.GetFirstSelected()) mw=self.mainwindow mw.MakeCall( gui.Request(mw.wt.rmfile, path), gui.Callback(self.OnFileDeleteResults, guihelper.dirname(path)) ) def OnFileDeleteResults(self, parentdir, exception, _): mw=self.mainwindow if mw.HandleException(exception): return self.ShowFiles(parentdir, True) def OnFileOverwrite(self,_): path=self.itemtopath(self.GetFirstSelected()) with guihelper.WXDialogWrapper(wx.FileDialog(self, style=wx.OPEN|wx.HIDE_READONLY|wx.CHANGE_DIR), True) as (dlg, retcode): if retcode==wx.ID_OK: infile=dlg.GetPath() contents=open(infile, "rb").read() mw=self.mainwindow mw.MakeCall( gui.Request(mw.wt.writefile, path, contents), gui.Callback(self.OnFileOverwriteResults, guihelper.dirname(path)) ) def OnFileOverwriteResults(self, parentdir, exception, _): mw=self.mainwindow if mw.HandleException(exception): return self.ShowFiles(parentdir, True) def ResetView(self): self.DeleteAllItems() self.files={} self.path=None self.itemDataMap = self.files self.itemIndexMap = self.files.keys() self.SetItemCount(0) def ShowFiles(self, path, refresh=False): mw=self.mainwindow if path == self.path and not refresh: return self.path=None mw.MakeCall( gui.Request(mw.wt.getfileonlylist, path), gui.Callback(self.OnShowFilesResults, path) ) def OnShowFilesResults(self, path, exception, result): mw=self.mainwindow if mw.HandleException(exception): return count=self.GetItemCount() self.path=path self.DeleteAllItems() self.files={} index=0 for file in result: index=index+1 f=guihelper.basename(file) if self.datacolumn: self.files[index]=(f, `result[file]['size']`, result[file]['date'][1], result[file]['data'], file) else: self.files[index]=(f, `result[file]['size']`, result[file]['date'][1], file) self.itemDataMap = self.files self.itemIndexMap = self.files.keys() self.SetItemCount(index) self.SortListItems() if count!=0 and index==0: wx.EVT_PAINT(self, self.OnPaint) elif count==0 and index!=0: self.Unbind(wx.EVT_PAINT) def itemtopath(self, item): index=self.itemIndexMap[item] if self.datacolumn: return self.itemDataMap[index][4] return self.itemDataMap[index][3] def SortItems(self,sorter=None): col=self._col sf=self._colSortFlag[col] #creating pairs [column item defined by col, key] items=[] for k,v in self.itemDataMap.items(): if col==1: items.append([int(v[col]),k]) else: items.append([v[col],k]) items.sort() k=[key for value, key in items] # False is descending if sf==False: k.reverse() self.itemIndexMap=k #redrawing the list self.Refresh() def GetListCtrl(self): return self def GetSortImages(self): return (self.sm_dn, self.sm_up) def OnGetItemText(self, item, col): index=self.itemIndexMap[item] s = self.itemDataMap[index][col] return s def OnGetItemImage(self, item): return self.img_file def OnGetItemAttr(self, item): return None