# Written by Arno Bakker, Jie Yang # see LICENSE.txt for license information import wx import os import sys from traceback import print_exc import urllib import webbrowser from Swapper.CacheDB.CacheDBHandler import FriendDBHandler from Swapper.__init__ import myinfo from Swapper.Overlay.permid import permid_for_user from makefriends import MakeFriendsDialog def createImageList(utility, friends): if len(friends) == 0: return None bitmaps = [] height = 0 width = 0 for friend in friends: filename = '' if friend.has_key('icon'): filename = friend['icon'] elif friend['name'] is not None: filename = os.path.join(utility.getConfigPath(), 'icons', friend['name']+'.bmp') if not os.access(filename, os.F_OK): # fallback name, don't use nickname2... here filename = os.path.join(utility.getPath(), 'icons', 'joe32.bmp') bm = wx.Bitmap(filename,wx.BITMAP_TYPE_BMP) if bm.GetWidth() > width: width = bm.GetWidth() if bm.GetHeight() > height: height = bm.GetHeight() bitmaps.append(bm) imgList = wx.ImageList(width,height) for bm in bitmaps: imgList.Add(bm) return imgList ################################################################ # # Class: ManageFriendsPanel # # Panel for managing friends # ################################################################ class ManageFriendsPanel(wx.Panel): def __init__(self, parent, utility, frame): self.utility = utility self.frame = frame style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER pos = wx.DefaultPosition size = wx.Size(530, 420) #size, split = self.getWindowSettings() title = self.utility.lang.get('managefriends') wx.Panel.__init__(self, parent, -1) # 1. Read friends from DB, and figure out who's already helping # for this torrent self.friendsdb = FriendDBHandler() # 2. Build GUI mainbox = wx.BoxSizer(wx.VERTICAL) # 3. Friends in top window #friendsbox_title = wx.StaticBox(self, -1, self.utility.lang.get('friends')) friendsbox = wx.BoxSizer(wx.VERTICAL) self.friendListCtrl = FriendList(self, self.friendsdb) friendsbox.Add(self.friendListCtrl, 1, wx.EXPAND|wx.TOP, 5) # 4. Buttons in lower window botbox = wx.BoxSizer(wx.HORIZONTAL) button = wx.Button(self, -1, self.utility.lang.get('buttons_add'), style = wx.BU_EXACTFIT) wx.EVT_BUTTON(self, button.GetId(), self.addFriend) botbox.Add(button, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 3) button = wx.Button(self, -1, self.utility.lang.get('buttons_edit'), style = wx.BU_EXACTFIT) wx.EVT_BUTTON(self, button.GetId(), self.editFriend) botbox.Add(button, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 3) button = wx.Button(self, -1, self.utility.lang.get('buttons_remove'), style = wx.BU_EXACTFIT) wx.EVT_BUTTON(self, button.GetId(), self.removeFriend) botbox.Add(button, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 3) # 5. Show GUI mainbox.Add(friendsbox, 1, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL, 5) mainbox.Add(botbox, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) self.SetSizerAndFit(mainbox) def addFriend(self, event = None): dialog = MakeFriendsDialog(self) ret = dialog.ShowModal() if ret == wx.ID_OK: self.updateView() dialog.Destroy() def editFriend(self, event = None): selected = self.getSelectedFriends() if not selected: return dialog = MakeFriendsDialog(self, selected[0]) ret = dialog.ShowModal() if ret == wx.ID_OK: self.updateView() dialog.Destroy() def removeFriend(self, event = None): selected = self.getSelectedFriends() if not selected: return to_remove = [] for friend in selected: permid = friend['permid'] to_remove.append(permid) self.friendsdb.deleteFriend(permid) if len(selected) > 0: self.updateView() def show_error(self, err_msg): dlg = wx.MessageDialog(self, err_msg, 'Warning!', wx.OK | wx.ICON_INFORMATION #wx.YES_NO | wx.NO_DEFAULT | wx.CANCEL | wx.ICON_INFORMATION ) dlg.ShowModal() dlg.Destroy() def getSelectedFriends(self): item = -1 itemList = [] while 1: item = self.friendListCtrl.GetNextItem(item,wx.LIST_NEXT_ALL,wx.LIST_STATE_SELECTED) if item == -1: break else: itemList.append(item) friends = self.friendListCtrl.getFriends() selected = [] for item in itemList: selected.append(friends[item]) return selected def close(self, event = None): self.EndModal(wx.ID_OK) def updateView(self, updateBuddyFrame=True): """ Easiest way of keeping the info presented to the user up to date: build a new window """ self.friendListCtrl.updateView() if updateBuddyFrame: self.frame.updateBuddyPanel(self.friendListCtrl.getFriends()) def show_inputerror(self,txt): dlg = wx.MessageDialog(self, txt, 'Invalid Input', wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() ################################################################ # # Class: FriendList # # ListCtrl for managing friends # ################################################################ class FriendList(wx.ListCtrl): def __init__(self, parent, friendsdb): self.parent = parent self.utility = parent.utility self.friendsdb = friendsdb self.type = wx.LC_LIST style = self.type|wx.VSCROLL|wx.SIMPLE_BORDER|wx.LC_VRULES|wx.CLIP_CHILDREN if (sys.platform == 'win32'): style |= wx.LC_ALIGN_TOP wx.ListCtrl.__init__(self, parent, -1, style=style) self.SetMinSize(wx.Size(200, 300)) self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnActivated) self.updateView() def updateView(self): self.friends = self.friendsdb.getFriends() for index in range(len(self.friends)): self.friends[index]['tempiconindex'] = index if not self.friends[index]['name']: self.friends[index]['name'] = self.friends[index]['ip'] self.ClearAll() if self.type != wx.LC_REPORT: try: self.updateImageList() except: print_exc() # disable icons self.type = wx.LC_REPORT self.updateReportList() else: self.updateReportList() self.Refresh() def updateImageList(self): self.SetWindowStyleFlag(self.type) self.imgList = createImageList(self.utility, self.friends) self.AssignImageList(self.imgList, wx.IMAGE_LIST_SMALL) self.loadList() def updateReportList(self): self.SetWindowStyleFlag(self.type) if not hasattr(self, 'fw'): try: # get system font width self.fw = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT).GetPointSize()+1 except: self.fw = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT).GetPointSize()+1 self.InsertColumn(0, self.utility.lang.get('name'), format=wx.LIST_FORMAT_CENTER, width=self.fw*20) self.loadList() def loadList(self): i = 0; for friend in self.friends: if self.type != wx.LC_REPORT: self.InsertImageStringItem(i,friend['name'],friend['tempiconindex']) else: self.InsertStringItem(i, friend['name']) i += 1 def OnActivated(self, event): self.parent.editFriend(event) def getFriends(self): return self.friends ################################################################ # # Class: MyInfoDialog # # Panel with user's info, to give to others to become friends # ################################################################ class MyInfoDialog(wx.Dialog): def __init__(self, parent, utility): self.utility = utility style = wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER pos = wx.DefaultPosition size = wx.Size(530, 420) title = self.utility.lang.get('myinfo') wx.Dialog.__init__(self, parent, -1, title, size = size, style = style) # 1. Build My Info mainbox = wx.BoxSizer(wx.VERTICAL) # my info myinfobox_title = wx.StaticBox(self, -1, self.utility.lang.get('myinfo')) myinfobox = wx.StaticBoxSizer(myinfobox_title, wx.VERTICAL) ip = self.utility.config.Read('bind') if ip is None or ip == '': ip = myinfo['ip'] self.permid_txt = self.utility.lang.get('permid')+": "+permid_for_user(myinfo['permid']) self.ip_txt = self.utility.lang.get('ipaddress')+": "+ip # port = self.utility.controller.listen_port port = self.utility.config.Read('minport', 'int') self.port_txt = self.utility.lang.get('portnumber')+" "+str(port) if True: # Make it copy-and-paste able self.textctrl = wx.TextCtrl(self, -1, size = (640, 100), style = wx.TE_MULTILINE|wx.TE_DONTWRAP|wx.TE_READONLY) self.textctrl.AppendText( self.permid_txt + '\n' ); self.textctrl.AppendText( self.ip_txt + '\n' ); self.textctrl.AppendText( self.port_txt + '\n' ); myinfobox.Add( self.textctrl, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) else: label = wx.StaticText(self, -1, self.permid_txt ) myinfobox.Add( label, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) label = wx.StaticText(self, -1, self.ip_txt ) myinfobox.Add( label, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) label = wx.StaticText(self, -1, self.port_txt ) myinfobox.Add( label, 0, wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) # 1.5 Explanatory text botbox = wx.BoxSizer(wx.VERTICAL) msg = self.utility.lang.get('myinfo_explanation') botbox.Add(wx.StaticText(self, -1, msg), 0, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 5) # 2. Invitation and Close buttons btnbox = wx.BoxSizer(wx.HORIZONTAL) invitation_btn = wx.Button(self, -1, self.utility.lang.get('invitationbtn'), style = wx.BU_EXACTFIT) #button.SetToolTipString(self.utility.lang.get('stopdlhelp_help')) wx.EVT_BUTTON(self, invitation_btn.GetId(), self.emailFriend) btnbox.Add(invitation_btn, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 3) button = wx.Button(self, -1, self.utility.lang.get('close'), style = wx.BU_EXACTFIT) #button.SetToolTipString(self.utility.lang.get('stopdlhelp_help')) wx.EVT_BUTTON(self, button.GetId(), self.close) btnbox.Add(button, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 3) # 3. Show GUI mainbox.Add(myinfobox, 0, wx.EXPAND) mainbox.Add(botbox, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) mainbox.Add(btnbox, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5) self.SetSizerAndFit(mainbox) def close(self, event = None): self.EndModal(wx.ID_OK) def emailFriend(self, event): subject = self.utility.lang.get('invitation_subject') invitation_body = self.utility.lang.get('invitation_body') invitation_body += self.permid_txt + '\r\n' invitation_body += self.ip_txt + '\r\n' invitation_body += self.port_txt + '\r\n\r\n\r\n' if sys.platform == "darwin": body = invitation_body.replace('\\r\\n','\r\n') else: body = urllib.quote(invitation_body) mailToURL = 'mailto:%s?subject=%s&body=%s'%('', subject, body) webbrowser.open(mailToURL)