def AddComponents(self, leftSpacer, rightSpacer): if leftSpacer > 0: self.hSizer.AddSpacer((leftSpacer, -1)) for i in xrange(len(self.columns)): if self.columns[i]['width'] == wx.LIST_AUTOSIZE: option = 1 size = wx.DefaultSize else: option = 0 size = (self.columns[i]['width'],-1) type = self.columns[i].get('type', 'label') if type == 'label': str_data = self.columns[i].get('fmt', unicode)(self.data[i]) control = StaticText(self, style=self.columns[i].get('style',0)|wx.ST_NO_AUTORESIZE|wx.ST_DOTS_END, size=size) fontWeight = self.columns[i].get('fontWeight', wx.FONTWEIGHT_NORMAL) if fontWeight != wx.FONTWEIGHT_NORMAL: _set_font(control, fontweight = fontWeight) #niels: wx magic prevents us from passing this string with the constructor, ampersands will not work control.SetLabel(str_data.replace('&', "&&")) elif type == 'method': control = self.columns[i]['method'](self, self) if control: control.icon = self._get_icon(i, 'icon') control.icon_right = self._get_icon(i, 'icon_right') self.controls.append(control) if i != 0: self.hSizer.AddSpacer((3, -1)) if control.icon: self.hSizer.Add(control.icon, 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, 3) self.hSizer.Add(control, option, wx.RESERVE_SPACE_EVEN_IF_HIDDEN|wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.BOTTOM, 3) if control.icon_right: self.hSizer.Add(control.icon_right, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT, 3) if self.columns[i]['width'] == wx.LIST_AUTOSIZE: control.SetMinSize((1,-1)) elif self.columns[i]['width'] == LIST_AUTOSIZEHEADER: self.columns[i]['width'] = control.GetSize()[0] if self.parent_list.parent_list.header: self.parent_list.parent_list.header.ResizeColumn(i, self.columns[i]['width']) else: if self.columns[i]['width'] != LIST_AUTOSIZEHEADER: self.hSizer.Add((self.columns[i]['width'], -1), 0, wx.LEFT, 3) if rightSpacer > 0: self.hSizer.AddSpacer((rightSpacer, -1)) self.hSizer.Layout() self.AddEvents(self)
class FamilyFilterHeader(TitleHeader): def __init__(self, *args, **kwargs): self.family_filter = None self.nrfiltered = 0 TitleHeader.__init__(self, *args, **kwargs) @warnWxThread def GetSubTitlePanel(self, parent): hSizer = wx.BoxSizer(wx.HORIZONTAL) self.ff = StaticText(parent) self.ffbutton = LinkStaticText(parent, '', None) self.ffbutton.Bind(wx.EVT_LEFT_UP, self.toggleFamilyFilter) self._SetLabels() hSizer.Add(self.ff) hSizer.Add(self.ffbutton) return hSizer def SetFF(self, family_filter, nrfiltered=0): self.family_filter = family_filter self.nrfiltered = nrfiltered self._SetLabels() def SetFamilyFiltered(self, nr): self.nrfiltered = nr self._SetLabels() @warnWxThread def SetBackgroundColour(self, colour): TitleHeader.SetBackgroundColour(self, colour) if getattr(self, 'ffbutton', False): self.ffbutton.SetBackgroundColour(colour) def toggleFamilyFilter(self, event): self.parent_list.toggleFamilyFilter() @warnWxThread def _SetLabels(self): self.Freeze() if self.family_filter: if self.nrfiltered > 0: self.ff.SetLabel('%d results blocked by Family Filter, ' % self.nrfiltered) else: self.ff.SetLabel('Family Filter is On, ') self.ffbutton.SetLabel('turn off') else: self.ff.SetLabel('Family Filter is Off, ') self.ffbutton.SetLabel('turn on') self.Layout() self.Thaw()
class SubTitleHeader(TitleHeader): @warnWxThread def GetSubTitlePanel(self, parent): self.subtitle = StaticText(parent) return self.subtitle @warnWxThread def SetSubTitle(self, subtitle): if subtitle != self.subtitle.GetLabel(): self.Freeze() self.subtitle.SetLabel(subtitle) self.subtitle.Refresh() self.Thaw()
def GetMidPanel(self, hSizer): hSizer.AddStretchSpacer() self.title = StaticText(self) hSizer.Add(self.title) self.scrollBar = hSizer.AddSpacer((0,0)) self.scrollBar.sizer = hSizer
def _DoInit(self): try: disp = DispersyPanel(self) except: #Dispersy not ready, try again in 5s if self.createTimer is None: self.createTimer = wx.CallLater(5000, self._DoInit) else: self.createTimer.Restart(5000) print_exc() return self.SetBackgroundColour(DEFAULT_BACKGROUND) vSizer = wx.BoxSizer(wx.VERTICAL) self.dowserStatus = StaticText(self, -1, 'Dowser is not running') dowserButton = wx.Button(self, -1, 'Start dowser') dowserButton.Bind(wx.EVT_BUTTON, self.OnDowser) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(self.dowserStatus, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 3) hSizer.Add(dowserButton) vSizer.Add(hSizer, 0, wx.ALIGN_RIGHT | wx.RIGHT | wx.BOTTOM, 10) vSizer.Add(disp, 1, wx.EXPAND | wx.BOTTOM, 10) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(NetworkPanel(self), 1, wx.EXPAND | wx.BOTTOM | wx.RIGHT, 10) self.activity = ActivityPanel(self) hSizer.Add(self.activity, 1, wx.EXPAND | wx.BOTTOM, 10) vSizer.Add(hSizer, 0, wx.EXPAND) # ProxyService 90s Test_ # # hSizer = wx.BoxSizer(wx.HORIZONTAL) # hSizer.Add(NetworkTestPanel(self), 1, wx.EXPAND|wx.BOTTOM|wx.RIGHT, 10) # hSizer.Add(ProxyDiscoveryPanel(self), 1, wx.EXPAND|wx.BOTTOM, 10) # vSizer.Add(hSizer, 0, wx.EXPAND) # # _ProxyService 90s Test hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(NewTorrentPanel(self), 1, wx.EXPAND | wx.RIGHT, 10) hSizer.Add(PopularTorrentPanel(self), 1, wx.EXPAND | wx.RIGHT, 10) # boudewijn: disabled TopContributorsPanel, getTopNPeers is a very expensive call # hSizer.Add(TopContributorsPanel(self), 1, wx.EXPAND) vSizer.Add(hSizer, 0, wx.EXPAND) self.SetSizer(vSizer) self.Layout() self.Bind(wx.EVT_KEY_UP, self.onKey) if sys.platform.startswith('win'): # on Windows, the panel doesn't respond to keypresses self.Bind(wx.EVT_MOUSE_EVENTS, self.onMouse) self.isReady = True
def AddHeader(self): sizer = wx.BoxSizer(wx.HORIZONTAL) self.header = StaticText(self.parent, -1, ' ') self.info_icon = wx.StaticBitmap(self.parent, -1, self.icons['info']) sizer.Add(self.header, 0, wx.RIGHT, 7) sizer.Add(self.info_icon, 0, wx.ALIGN_CENTER_VERTICAL) self.vsizer.Add(sizer, 0, wx.BOTTOM, 3)
def GetSubTitlePanel(self, parent): hSizer = wx.BoxSizer(wx.HORIZONTAL) self.ff = StaticText(parent) self.ffbutton = LinkStaticText(parent, '', None) self.ffbutton.Bind(wx.EVT_LEFT_UP, self.toggleFamilyFilter) self._SetLabels() hSizer.Add(self.ff) hSizer.Add(self.ffbutton) return hSizer
def GetMidPanel(self, hSizer): self.message = StaticText(self) font = self.message.GetFont() font.SetPointSize(font.GetPointSize()+2) font.SetWeight(wx.FONTWEIGHT_BOLD) self.message.SetFont(font) hSizer.Add(self.message, 0, wx.TOP|wx.BOTTOM|wx.ALIGN_BOTTOM, 3) hSizer.AddStretchSpacer() self.channelResults = wx.Button(self, -1, "Channel Results") hSizer.Add(self.channelResults, 0, wx.TOP|wx.BOTTOM, 3)
def GetMidPanel(self, hSizer): self.totals = [] for i in xrange(len(self.columns)): if self.columns[i]['width'] == wx.LIST_AUTOSIZE: option = 1 size = wx.DefaultSize else: option = 0 size = (self.columns[i]['width'],-1) label = StaticText(self, i, '', style = self.columns[i].get('footer_style',0)|wx.ST_NO_AUTORESIZE, size = size) hSizer.Add(label, option, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.TOP|wx.BOTTOM, 3) if self.columns[i]['width'] == wx.LIST_AUTOSIZE: label.SetMinSize((1,-1)) self.totals.append(label) self.scrollBar = hSizer.AddSpacer((3,0)) self.scrollBar.sizer = hSizer
class ChannelResultFooter(ListFooter): def GetMidPanel(self, hSizer): self.message = StaticText(self) font = self.message.GetFont() font.SetPointSize(font.GetPointSize()+2) font.SetWeight(wx.FONTWEIGHT_BOLD) self.message.SetFont(font) hSizer.Add(self.message, 0, wx.TOP|wx.BOTTOM|wx.ALIGN_BOTTOM, 3) hSizer.AddStretchSpacer() self.channelResults = wx.Button(self, -1, "Channel Results") hSizer.Add(self.channelResults, 0, wx.TOP|wx.BOTTOM, 3) def SetLabel(self, label, nr_channels): haveResults = True if nr_channels and nr_channels >= 1 else False if label != self.message.GetLabel(): self.message.SetLabel(label) if haveResults: self.HighLight() self.Layout() self.EnableResults(haveResults) def SetEvents(self, channel): #removing old, binding new eventhandler self.channelResults.Unbind(wx.EVT_BUTTON) self.channelResults.Bind(wx.EVT_BUTTON, channel) def EnableResults(self, state): self.channelResults.Enable(state) def Reset(self): self.EnableResults(False) self.message.SetLabel('')
def AddComponents(self, columns, spacers): vSizer = wx.BoxSizer(wx.VERTICAL) vSizer.AddSpacer((-1, 3)) self.title = StaticText(self) _set_font(self.title, self.font_increment, self.fontweight) titlePanel = self.GetTitlePanel(self) subtitlePanel = self.GetSubTitlePanel(self) righttitlePanel = self.GetRightTitlePanel(self) belowPanel = self.GetBelowPanel(self) if titlePanel: subSizer = wx.BoxSizer(wx.HORIZONTAL) subSizer.Add(self.title) subSizer.Add(titlePanel, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 3) titlePanel = subSizer else: titlePanel = self.title if subtitlePanel: subSizer = wx.BoxSizer(wx.VERTICAL) subSizer.Add(titlePanel, 0, wx.BOTTOM, 3) subSizer.Add(subtitlePanel) subtitlePanel = subSizer else: subtitlePanel = titlePanel subSizer = wx.BoxSizer(wx.HORIZONTAL) subSizer.Add(subtitlePanel) if righttitlePanel: subSizer.Add(righttitlePanel, 1, wx.LEFT, 3) righttitlePanel = subSizer vSizer.Add(righttitlePanel, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, self.radius + spacers[0]) if belowPanel: vSizer.Add(belowPanel, 1, wx.EXPAND | wx.TOP, 3) vSizer.AddSpacer((-1, 3)) if len(columns) > 0: hSizer = wx.BoxSizer(wx.HORIZONTAL) self.AddColumns(hSizer, self, columns) vSizer.Add(hSizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, self.radius + spacers[0]) self.SetSizer(vSizer)
def GetBelowPanel(self, parent): self.descriptionPanel = ImageScrollablePanel(parent) self.descriptionPanel.SetBackgroundColour(DEFAULT_BACKGROUND) self.description = StaticText(self.descriptionPanel) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.description, 1, wx.EXPAND | wx.ALL, 3) self.descriptionPanel.SetSizer(sizer) self.descriptionPanel.Hide() self.descriptionPanel.Bind(wx.EVT_SIZE, self.SetHeight) self.descriptionPanel.Bind(wx.EVT_SHOW, self.SetHeight) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(self.descriptionPanel, 1, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, self.radius + 3) return hSizer
def CreatePanel(self): panel = wx.Panel(self) panel.SetBackgroundColour(DEFAULT_BACKGROUND) vSizer = wx.BoxSizer(wx.VERTICAL) self.nrTorrents = StaticText(panel) self.nrFiles = StaticText(panel) self.totalSize = StaticText(panel) self.queueSize = StaticText(panel) self.nrChannels = StaticText(panel) self.incomplete = StaticText(panel) self.freeMem = None try: if wx.GetFreeMemory() != -1: self.freeMem = StaticText(panel) except: pass gridSizer = wx.FlexGridSizer(0, 2, 3, 10) gridSizer.AddGrowableCol(1) gridSizer.Add(StaticText(panel, -1, 'Number files')) gridSizer.Add(self.nrFiles, 0, wx.EXPAND) gridSizer.Add(StaticText(panel, -1, 'Total size')) gridSizer.Add(self.totalSize, 0, wx.EXPAND) gridSizer.Add(StaticText(panel, -1, 'Torrents collected')) gridSizer.Add(self.nrTorrents, 0, wx.EXPAND) gridSizer.Add(StaticText(panel, -1, 'Torrents in queue')) gridSizer.Add(self.queueSize, 0, wx.EXPAND) gridSizer.Add(StaticText(panel, -1, 'Channels found')) gridSizer.Add(self.nrChannels, 0, wx.EXPAND) gridSizer.Add( StaticText(panel, -1, 'Incomplete limit (cur, max, history, maxhistory)')) gridSizer.Add(self.incomplete, 0, wx.EXPAND) if self.freeMem: gridSizer.Add(StaticText(panel, -1, 'WX:Free memory')) gridSizer.Add(self.freeMem, 0, wx.EXPAND) vSizer.Add(gridSizer, 0, wx.EXPAND | wx.LEFT, 10) panel.SetSizer(vSizer) return panel
def GetMidPanel(self, hSizer): self.hSizer = hSizer self.message = StaticText(self) self.message.SetMinSize((1,-1)) font = self.message.GetFont() font.SetPointSize(font.GetPointSize()+2) font.SetWeight(wx.FONTWEIGHT_BOLD) self.message.SetFont(font) self.subtitle = wx.StaticText(self) self.subtitle.SetMinSize((1,-1)) self.manage = wx.Button(self, -1, 'Edit this Channel') self.spam = wx.Button(self, -1, 'Mark as Spam') self.favorite = wx.Button(self, -1, 'Mark as Favorite') self.ortext = None self.subtitle.Show(False) self.favorite.Show(False) self.spam.Show(False) self.manage.Show(False)
class TitleFooter(ListFooter): def GetMidPanel(self, hSizer): hSizer.AddStretchSpacer() self.title = StaticText(self) hSizer.Add(self.title) self.scrollBar = hSizer.AddSpacer((0,0)) self.scrollBar.sizer = hSizer def SetTitle(self, title): self.Freeze() self.title.SetLabel(title) self.Layout() self.Thaw() def SetSpacerRight(self, right): if self.scrollBar: right = max(3, right + 3) if self.scrollBar.GetSize()[0] != right: self.scrollBar.SetSpacer((right, 0)) self.scrollBar.sizer.Layout()
class Stats(XRCPanel): def __init__(self, parent=None): XRCPanel.__init__(self, parent) self.createTimer = None self.isReady = False def _DoInit(self): try: disp = DispersyPanel(self) except: #Dispersy not ready, try again in 5s if self.createTimer is None: self.createTimer = wx.CallLater(5000, self._DoInit) else: self.createTimer.Restart(5000) print_exc() return self.SetBackgroundColour(DEFAULT_BACKGROUND) vSizer = wx.BoxSizer(wx.VERTICAL) self.dowserStatus = StaticText(self, -1, 'Dowser is not running') dowserButton = wx.Button(self, -1, 'Start dowser') dowserButton.Bind(wx.EVT_BUTTON, self.OnDowser) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(self.dowserStatus, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 3) hSizer.Add(dowserButton) vSizer.Add(hSizer, 0, wx.ALIGN_RIGHT | wx.RIGHT | wx.BOTTOM, 10) vSizer.Add(disp, 1, wx.EXPAND | wx.BOTTOM, 10) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(NetworkPanel(self), 1, wx.EXPAND | wx.BOTTOM | wx.RIGHT, 10) self.activity = ActivityPanel(self) hSizer.Add(self.activity, 1, wx.EXPAND | wx.BOTTOM, 10) vSizer.Add(hSizer, 0, wx.EXPAND) # ProxyService 90s Test_ # # hSizer = wx.BoxSizer(wx.HORIZONTAL) # hSizer.Add(NetworkTestPanel(self), 1, wx.EXPAND|wx.BOTTOM|wx.RIGHT, 10) # hSizer.Add(ProxyDiscoveryPanel(self), 1, wx.EXPAND|wx.BOTTOM, 10) # vSizer.Add(hSizer, 0, wx.EXPAND) # # _ProxyService 90s Test hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(NewTorrentPanel(self), 1, wx.EXPAND | wx.RIGHT, 10) hSizer.Add(PopularTorrentPanel(self), 1, wx.EXPAND | wx.RIGHT, 10) # boudewijn: disabled TopContributorsPanel, getTopNPeers is a very expensive call # hSizer.Add(TopContributorsPanel(self), 1, wx.EXPAND) vSizer.Add(hSizer, 0, wx.EXPAND) self.SetSizer(vSizer) self.Layout() self.Bind(wx.EVT_KEY_UP, self.onKey) if sys.platform.startswith('win'): # on Windows, the panel doesn't respond to keypresses self.Bind(wx.EVT_MOUSE_EVENTS, self.onMouse) self.isReady = True def onActivity(self, msg): if self.isReady: self.activity.onActivity(msg) def onKey(self, event): if event.ControlDown() and (event.GetKeyCode() == 73 or event.GetKeyCode() == 105): #ctrl + i self._showInspectionTool() elif event.ControlDown() and (event.GetKeyCode() == 68 or event.GetKeyCode() == 100): #ctrl + d self._printDBStats() else: event.Skip() def onMouse(self, event): if all([ event.RightUp(), event.ControlDown(), event.AltDown(), event.ShiftDown() ]): self._showInspectionTool() elif all([ event.LeftUp(), event.ControlDown(), event.AltDown(), event.ShiftDown() ]): self._printDBStats() else: event.Skip() def OnDowser(self, event): if not self._startDowser(): dlg = wx.DirDialog( None, "Please select your dowser installation directory", style=wx.wx.DD_DIR_MUST_EXIST) if dlg.ShowModal() == wx.ID_OK and os.path.isdir(dlg.GetPath()): sys.path.append(dlg.GetPath()) self._startDowser() dlg.Destroy() def _startDowser(self): try: import cherrypy import dowser cherrypy.config.update({'server.socket_port': 8080}) cherrypy.tree.mount(dowser.Root()) cherrypy.engine.start() self.dowserStatus.SetLabel('Dowser is running') return True except: print_exc() return False def _showInspectionTool(self): import wx.lib.inspection itool = wx.lib.inspection.InspectionTool() itool.Show() try: frame = itool._frame import Tribler frame.locals['Tribler'] = Tribler from Tribler.Core.Overlay.SecureOverlay import SecureOverlay overlay = SecureOverlay.getInstance() frame.locals['overlay'] = overlay session = Session.get_instance() frame.locals['session'] = session from Tribler.Core.BuddyCast.buddycast import BuddyCastFactory channelcast = BuddyCastFactory.getInstance().channelcast_core frame.locals['channelcast'] = channelcast frame.locals['dispersy'] = Dispersy.get_instance() except Exception: import traceback traceback.print_exc() def _printDBStats(self): torrentdb = TorrentDBHandler.getInstance() tables = torrentdb._db.fetchall( "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name") for table, in tables: print >> sys.stderr, table, torrentdb._db.fetchone( "SELECT COUNT(*) FROM %s" % table) def Show(self, show=True): if show: if not self.isReady: self._DoInit() XRCPanel.Show(self, show)
class CreateTorrent(wx.Dialog): def __init__(self, parent, configfile, fileconfigfile, suggestedTrackers, toChannel=False): wx.Dialog.__init__(self, parent, -1, 'Create a .torrent', size=(600, 200)) self.guiutility = GUIUtility.getInstance() self.toChannel = toChannel vSizer = wx.BoxSizer(wx.VERTICAL) header = wx.StaticText(self, -1, 'Browse for a file or files') _set_font(header, fontweight=wx.FONTWEIGHT_BOLD) vSizer.Add(header, 0, wx.EXPAND | wx.BOTTOM, 3) self.locationText = StaticText(self, -1, '') vSizer.Add(self.locationText, 0, wx.EXPAND | wx.BOTTOM, 3) browseButton = wx.Button(self, -1, 'Browse') browseButton.Bind(wx.EVT_BUTTON, self.OnBrowse) browseDirButton = wx.Button(self, -1, 'Browse for a Directory') browseDirButton.Bind(wx.EVT_BUTTON, self.OnBrowseDir) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(browseButton) hSizer.Add(browseDirButton) vSizer.Add(hSizer, 0, wx.ALIGN_RIGHT | wx.BOTTOM, 3) #self.recursive = wx.CheckBox(self, -1, 'Include all subdirectories') #self.recursive.Bind(wx.EVT_CHECKBOX, self.OnRecursive) #vSizer.Add(self.recursive, 0, wx.ALIGN_RIGHT|wx.BOTTOM, 3) vSizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) header = wx.StaticText(self, -1, '.Torrent details') _set_font(header, fontweight=wx.FONTWEIGHT_BOLD) vSizer.Add(header, 0, wx.EXPAND | wx.BOTTOM, 3) self.foundFilesText = StaticText( self, -1, 'Please select a file or files first') vSizer.Add(self.foundFilesText, 0, wx.EXPAND | wx.BOTTOM, 3) self.combineRadio = wx.RadioButton( self, -1, 'Combine files into a single .torrent', style=wx.RB_GROUP) self.combineRadio.Bind(wx.EVT_RADIOBUTTON, self.OnCombine) self.combineRadio.Enable(False) self.sepRadio = wx.RadioButton( self, -1, 'Create separate .torrent for every file') self.sepRadio.Bind(wx.EVT_RADIOBUTTON, self.OnCombine) self.sepRadio.Enable(False) vSizer.Add(self.combineRadio, 0, wx.EXPAND | wx.BOTTOM, 3) vSizer.Add(self.sepRadio, 0, wx.EXPAND | wx.BOTTOM, 3) self.specifiedName = wx.TextCtrl(self, -1, '') self.specifiedName.Enable(False) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, -1, 'Specify a name'), 0, wx.ALIGN_CENTER_VERTICAL) hSizer.Add(self.specifiedName, 1, wx.EXPAND) vSizer.Add(hSizer, 0, wx.EXPAND | wx.BOTTOM, 3) vSizer.Add(StaticText(self, -1, 'Trackers')) self.trackerList = wx.TextCtrl(self, -1, '', style=wx.TE_MULTILINE) self.trackerList.SetMinSize((500, -1)) self.trackerHistory = wx.FileHistory(10) self.config = wx.FileConfig(appName="Tribler", localFilename=configfile) self.trackerHistory.Load(self.config) if self.trackerHistory.GetCount() > 0: trackers = [ self.trackerHistory.GetHistoryFile(i) for i in range(self.trackerHistory.GetCount()) ] if len(trackers) < len(suggestedTrackers): trackers.extend(suggestedTrackers[:len(suggestedTrackers) - len(trackers)]) else: trackers = suggestedTrackers for tracker in trackers: self.trackerList.AppendText(tracker + "\n") vSizer.Add(self.trackerList, 0, wx.EXPAND | wx.BOTTOM, 3) vSizer.Add(StaticText(self, -1, 'Comment')) self.commentList = wx.TextCtrl(self, -1, '', style=wx.TE_MULTILINE) vSizer.Add(self.commentList, 0, wx.EXPAND, 3) vSizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, 10) header = wx.StaticText(self, -1, 'Advanced options') _set_font(header, fontweight=wx.FONTWEIGHT_BOLD) vSizer.Add(header, 0, wx.EXPAND | wx.BOTTOM | wx.TOP, 3) abbrev_mb = " " + self.guiutility.utility.lang.get('MB') abbrev_kb = " " + self.guiutility.utility.lang.get('KB') piece_choices = [ self.guiutility.utility.lang.get('automatic'), '4' + abbrev_mb, '2' + abbrev_mb, '1' + abbrev_mb, '512' + abbrev_kb, '256' + abbrev_kb, '128' + abbrev_kb, '64' + abbrev_kb, '32' + abbrev_kb ] self.pieceChoice = wx.Choice(self, -1, choices=piece_choices) self.pieceChoice.SetSelection(0) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(StaticText(self, -1, 'Piecesize'), 1) hSizer.Add(self.pieceChoice) vSizer.Add(hSizer, 0, wx.EXPAND | wx.BOTTOM, 3) vSizer.Add(StaticText(self, -1, 'Webseed')) self.webSeed = wx.TextCtrl(self, -1, 'Please select a file or files first') self.webSeed.Enable(False) vSizer.Add(self.webSeed, 0, wx.EXPAND | wx.BOTTOM, 3) cancel = wx.Button(self, wx.ID_CANCEL) cancel.Bind(wx.EVT_BUTTON, self.OnCancel) create = wx.Button(self, wx.ID_OK, 'Create .torrent(s)') create.Bind(wx.EVT_BUTTON, self.OnOk) bSizer = wx.StdDialogButtonSizer() bSizer.AddButton(cancel) bSizer.AddButton(create) bSizer.Realize() vSizer.Add(bSizer, 0, wx.EXPAND) sizer = wx.BoxSizer() sizer.Add(vSizer, 1, wx.EXPAND | wx.ALL, 10) self.SetSizerAndFit(sizer) self.selectedPaths = [] self.createdTorrents = [] self.cancelEvent = Event() self.filehistory = wx.FileHistory(1) self.fileconfig = wx.FileConfig(appName="Tribler", localFilename=fileconfigfile) self.filehistory.Load(self.fileconfig) if self.filehistory.GetCount() > 0: self.latestFile = self.filehistory.GetHistoryFile(0) else: self.latestFile = '' self.paths = None def OnBrowse(self, event): dlg = wx.FileDialog(self, "Please select the file(s).", style=wx.FD_OPEN | wx.FD_MULTIPLE, defaultDir=self.latestFile) if dlg.ShowModal() == wx.ID_OK: filenames = dlg.GetPaths() dlg.Destroy() self._browsePaths(filenames) else: dlg.Destroy() def OnBrowseDir(self, event): dlg = wx.DirDialog(self, "Please a directory.", style=wx.DD_DIR_MUST_EXIST, defaultPath=self.latestFile) if dlg.ShowModal() == wx.ID_OK: filenames = [dlg.GetPath()] dlg.Destroy() self._browsePaths(filenames) else: dlg.Destroy() def OnRecursive(self, event): self._browsePaths() def OnCombine(self, event=None): combine = self.combineRadio.GetValue() self.specifiedName.Enable(False) if combine: path = '' nrFiles = len( [file for file in self.selectedPaths if os.path.isfile(file)]) if nrFiles > 1: self.specifiedName.Enable(True) path = os.path.abspath(os.path.commonprefix( self.selectedPaths)) elif nrFiles > 0: path = self.selectedPaths[0] _, name = os.path.split(path) self.specifiedName.SetValue(name) def OnOk(self, event): # if self.specifyNames.GetValue(): # dlg = wx.Dialog(self, -1, 'Please correct the names for the torrents.', size=(750,450)) # sizer = wx.BoxSizer(wx.VERTICAL) # header = wx.StaticText(dlg, -1, 'Please modify the names for the .torrents.') # # _set_font(header, fontweight=wx.FONTWEIGHT_BOLD) # sizer.Add(header, 0, wx.EXPAND|wx.BOTTOM, 3) # # flexSizer = wx.FlexGridSizer(2,2,3,3) # controls = [] # for name in names: # flexSizer.Add(wx.StaticText(dlg, -1, name), 0, wx.ALIGN_CENTER_VERTICAL) # control = wx.TextCtrl(dlg,-1, name) # control.SetMinSize((300,-1)) # flexSizer.Add(control, 1, wx.EXPAND) # controls.append(control) # # sizer.Add(flexSizer, 1, wx.EXPAND|wx.BOTTOM, 3) # # cancel = wx.Button(dlg, wx.ID_CANCEL) # ok = wx.Button(dlg, wx.ID_OK) # # bSizer = wx.StdDialogButtonSizer() # bSizer.AddButton(cancel) # bSizer.AddButton(ok) # bSizer.Realize() # sizer.Add(bSizer, 0, wx.EXPAND|wx.BOTTOM, 3) # # bsizer = wx.BoxSizer() # bsizer.Add(sizer, 1, wx.EXPAND|wx.ALL, 10) # dlg.SetSizerAndFit(bsizer) # # if dlg.ShowModal() == wx.ID_OK: # for i, control in enumerate(controls): # names[i] = control.GetValue() # dlg.Destroy() # else: # dlg.Destroy() # return max = 1 if self.combineRadio.GetValue() else len(self.selectedPaths) if self.toChannel: dlg = wx.MessageDialog( self, "This will add %d new .torrents to this Channel.\nDo you want to continue?" % max, "Are you sure?", style=wx.YES_NO | wx.ICON_QUESTION) else: dlg = wx.MessageDialog( self, "This will create %d new .torrents.\nDo you want to continue?" % max, "Are you sure?", style=wx.YES_NO | wx.ICON_QUESTION) if dlg.ShowModal() == wx.ID_YES: dlg.Destroy() params = {} params['comment'] = self.commentList.GetValue() params['created by'] = '%s version: %s' % ( self.guiutility.utility.lang.get('title'), self.guiutility.utility.lang.get('version')) trackers = self.trackerList.GetValue() trackers = [tracker for tracker in trackers.split('\n') if tracker] for tracker in trackers: self.trackerHistory.AddFileToHistory(tracker) self.trackerHistory.Save(self.config) self.config.Flush() if len(self.selectedPaths) > 1: basedir = os.path.commonprefix(self.selectedPaths) else: basedir = os.path.dirname(self.selectedPaths[0]) self.filehistory.Save(self.fileconfig) self.fileconfig.Flush() params['announce'] = trackers[0] params['announce-list'] = [trackers] if self.webSeed.GetValue(): params['urllist'] = [self.webSeed.GetValue()] params['nodes'] = False params['httpseeds'] = False params['encoding'] = False params['makehash_md5'] = False params['makehash_crc32'] = False params['makehash_sha1'] = True params['createmerkletorrent'] = False params['torrentsigkeypairfilename'] = False params['thumb'] = False piece_length_list = [ 0, 2**22, 2**21, 2**20, 2**19, 2**18, 2**17, 2**16, 2**15 ] if self.pieceChoice.GetSelection() != wx.NOT_FOUND: params['piece length'] = piece_length_list[ self.pieceChoice.GetSelection()] else: params['piece length'] = 0 def do_gui(): if self.cancelEvent.isSet(): self.OnCancel(event) else: self.EndModal(wx.ID_OK) def create_torrents(): try: if self.combineRadio.GetValue(): params['name'] = self.specifiedName.GetValue() make_meta_file(self.selectedPaths, params, self.cancelEvent, None, self._torrentCreated) else: for path in self.selectedPaths: if os.path.isfile(path): make_meta_file([path], params, self.cancelEvent, None, self._torrentCreated) except: print_exc() wx.CallAfter(do_gui) def start(): if self.combineRadio.GetValue(): self.progressDlg = wx.ProgressDialog( "Creating new .torrents", "Please wait while Tribler is creating your .torrents.\nThis could take a while due to creating the required hashes.", maximum=max, parent=self, style=wx.PD_APP_MODAL | wx.PD_AUTO_HIDE) else: self.progressDlg = wx.ProgressDialog( "Creating new .torrents", "Please wait while Tribler is creating your .torrents.\nThis could take a while due to creating the required hashes.", maximum=max, parent=self, style=wx.PD_CAN_ABORT | wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME | wx.PD_AUTO_HIDE) self.progressDlg.Pulse() self.progressDlg.cur = 0 self.guiserver = GUITaskQueue.getInstance() self.guiserver.add_task(create_torrents) if params['piece length']: total_size = 0 if self.combineRadio.GetValue(): for path in self.selectedPaths: total_size += os.path.getsize(path) else: for path in self.selectedPaths: total_size = max(total_size, os.path.getsize(path)) nrPieces = total_size / params['piece length'] if nrPieces > 2500: dlg2 = wx.MessageDialog( self, "The selected piecesize will cause a torrent to have %d pieces.\nThis is more than the recommended max 2500 pieces.\nDo you want to continue?" % nrPieces, "Are you sure?", style=wx.YES_NO | wx.ICON_QUESTION) if dlg2.ShowModal() == wx.ID_YES: start() dlg2.Destroy() else: start() else: start() else: dlg.Destroy() def OnCancel(self, event): self.EndModal(wx.ID_CANCEL) def _browsePaths(self, paths=None): if paths: self.paths = paths else: paths = self.paths if paths: label = ";".join(paths) self.locationText.SetLabel(label) if os.path.isdir(paths[0]): def addDir(path, recursive=False): paths = [path] for file in os.listdir(path): absfile = os.path.join(path, file) if os.path.isfile(absfile): if file.lower().endswith('.torrent') or file.lower( ).endswith('thumbs.db'): continue paths.append(absfile) elif os.path.isdir(absfile) and recursive: paths.extend(addDir(absfile, recursive)) return paths paths = addDir(paths[0], False) #self.recursive.GetValue()) self.selectedPaths = paths nrFiles = len([file for file in paths if os.path.isfile(file)]) self.foundFilesText.SetLabel('Selected %d files' % nrFiles) if nrFiles == 1: self.webSeed.Enable(True) self.webSeed.SetValue('') else: self.webSeed.SetValue( 'Webseed will only work for a single file.') self.webSeed.Enable(False) self.combineRadio.Enable(nrFiles > 0) self.sepRadio.Enable(nrFiles > 1) self.combineRadio.SetValue(nrFiles == 1) self.sepRadio.SetValue(nrFiles > 1) self.OnCombine() self.Layout() @forceWxThread def _torrentCreated(self, path, correctedfilename, torrentfilename): self.progressDlg.cur += 1 keepGoing, _ = self.progressDlg.Update(self.progressDlg.cur) if not keepGoing: self.cancelEvent.Set() self.createdTorrents.append((path, correctedfilename, torrentfilename))
def __init__(self, parent, configfile, fileconfigfile, suggestedTrackers, toChannel=False): wx.Dialog.__init__(self, parent, -1, 'Create a .torrent', size=(600, 200)) self.guiutility = GUIUtility.getInstance() self.toChannel = toChannel vSizer = wx.BoxSizer(wx.VERTICAL) header = wx.StaticText(self, -1, 'Browse for a file or files') _set_font(header, fontweight=wx.FONTWEIGHT_BOLD) vSizer.Add(header, 0, wx.EXPAND | wx.BOTTOM, 3) self.locationText = StaticText(self, -1, '') vSizer.Add(self.locationText, 0, wx.EXPAND | wx.BOTTOM, 3) browseButton = wx.Button(self, -1, 'Browse') browseButton.Bind(wx.EVT_BUTTON, self.OnBrowse) browseDirButton = wx.Button(self, -1, 'Browse for a Directory') browseDirButton.Bind(wx.EVT_BUTTON, self.OnBrowseDir) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(browseButton) hSizer.Add(browseDirButton) vSizer.Add(hSizer, 0, wx.ALIGN_RIGHT | wx.BOTTOM, 3) #self.recursive = wx.CheckBox(self, -1, 'Include all subdirectories') #self.recursive.Bind(wx.EVT_CHECKBOX, self.OnRecursive) #vSizer.Add(self.recursive, 0, wx.ALIGN_RIGHT|wx.BOTTOM, 3) vSizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10) header = wx.StaticText(self, -1, '.Torrent details') _set_font(header, fontweight=wx.FONTWEIGHT_BOLD) vSizer.Add(header, 0, wx.EXPAND | wx.BOTTOM, 3) self.foundFilesText = StaticText( self, -1, 'Please select a file or files first') vSizer.Add(self.foundFilesText, 0, wx.EXPAND | wx.BOTTOM, 3) self.combineRadio = wx.RadioButton( self, -1, 'Combine files into a single .torrent', style=wx.RB_GROUP) self.combineRadio.Bind(wx.EVT_RADIOBUTTON, self.OnCombine) self.combineRadio.Enable(False) self.sepRadio = wx.RadioButton( self, -1, 'Create separate .torrent for every file') self.sepRadio.Bind(wx.EVT_RADIOBUTTON, self.OnCombine) self.sepRadio.Enable(False) vSizer.Add(self.combineRadio, 0, wx.EXPAND | wx.BOTTOM, 3) vSizer.Add(self.sepRadio, 0, wx.EXPAND | wx.BOTTOM, 3) self.specifiedName = wx.TextCtrl(self, -1, '') self.specifiedName.Enable(False) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, -1, 'Specify a name'), 0, wx.ALIGN_CENTER_VERTICAL) hSizer.Add(self.specifiedName, 1, wx.EXPAND) vSizer.Add(hSizer, 0, wx.EXPAND | wx.BOTTOM, 3) vSizer.Add(StaticText(self, -1, 'Trackers')) self.trackerList = wx.TextCtrl(self, -1, '', style=wx.TE_MULTILINE) self.trackerList.SetMinSize((500, -1)) self.trackerHistory = wx.FileHistory(10) self.config = wx.FileConfig(appName="Tribler", localFilename=configfile) self.trackerHistory.Load(self.config) if self.trackerHistory.GetCount() > 0: trackers = [ self.trackerHistory.GetHistoryFile(i) for i in range(self.trackerHistory.GetCount()) ] if len(trackers) < len(suggestedTrackers): trackers.extend(suggestedTrackers[:len(suggestedTrackers) - len(trackers)]) else: trackers = suggestedTrackers for tracker in trackers: self.trackerList.AppendText(tracker + "\n") vSizer.Add(self.trackerList, 0, wx.EXPAND | wx.BOTTOM, 3) vSizer.Add(StaticText(self, -1, 'Comment')) self.commentList = wx.TextCtrl(self, -1, '', style=wx.TE_MULTILINE) vSizer.Add(self.commentList, 0, wx.EXPAND, 3) vSizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, 10) header = wx.StaticText(self, -1, 'Advanced options') _set_font(header, fontweight=wx.FONTWEIGHT_BOLD) vSizer.Add(header, 0, wx.EXPAND | wx.BOTTOM | wx.TOP, 3) abbrev_mb = " " + self.guiutility.utility.lang.get('MB') abbrev_kb = " " + self.guiutility.utility.lang.get('KB') piece_choices = [ self.guiutility.utility.lang.get('automatic'), '4' + abbrev_mb, '2' + abbrev_mb, '1' + abbrev_mb, '512' + abbrev_kb, '256' + abbrev_kb, '128' + abbrev_kb, '64' + abbrev_kb, '32' + abbrev_kb ] self.pieceChoice = wx.Choice(self, -1, choices=piece_choices) self.pieceChoice.SetSelection(0) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(StaticText(self, -1, 'Piecesize'), 1) hSizer.Add(self.pieceChoice) vSizer.Add(hSizer, 0, wx.EXPAND | wx.BOTTOM, 3) vSizer.Add(StaticText(self, -1, 'Webseed')) self.webSeed = wx.TextCtrl(self, -1, 'Please select a file or files first') self.webSeed.Enable(False) vSizer.Add(self.webSeed, 0, wx.EXPAND | wx.BOTTOM, 3) cancel = wx.Button(self, wx.ID_CANCEL) cancel.Bind(wx.EVT_BUTTON, self.OnCancel) create = wx.Button(self, wx.ID_OK, 'Create .torrent(s)') create.Bind(wx.EVT_BUTTON, self.OnOk) bSizer = wx.StdDialogButtonSizer() bSizer.AddButton(cancel) bSizer.AddButton(create) bSizer.Realize() vSizer.Add(bSizer, 0, wx.EXPAND) sizer = wx.BoxSizer() sizer.Add(vSizer, 1, wx.EXPAND | wx.ALL, 10) self.SetSizerAndFit(sizer) self.selectedPaths = [] self.createdTorrents = [] self.cancelEvent = Event() self.filehistory = wx.FileHistory(1) self.fileconfig = wx.FileConfig(appName="Tribler", localFilename=fileconfigfile) self.filehistory.Load(self.fileconfig) if self.filehistory.GetCount() > 0: self.latestFile = self.filehistory.GetHistoryFile(0) else: self.latestFile = '' self.paths = None
class BundlePanel(wx.BoxSizer): COLLAPSED, PARTIAL, FULL = range(3) icons = None @classmethod def load_icons(cls): if not cls.icons: icons = cls.icons = {} guiUtility = GUIUtility.getInstance() utility = guiUtility.utility base_path = os.path.join(utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images") icons['info'] = wx.Bitmap(os.path.join(base_path, "info.png"), wx.BITMAP_TYPE_ANY) def __init__(self, parent, parent_list, hits, general_description = None, description = None, font_increment=0): wx.BoxSizer.__init__(self, wx.HORIZONTAL) # preload icons self.load_icons() self.parent = parent self.parent_listitem = parent self.parent_list = parent_list listbody_width = parent_list.GetSize()[0] if listbody_width < BUNDLE_GRID_COLLAPSE: self.num_cols = 1 else: self.num_cols = BUNDLE_NUM_COLS # logging self.guiutility = GUIUtility.getInstance() self.uelog = UserEventLogDBHandler.getInstance() self.state = BundlePanel.COLLAPSED self.nrhits = -1 self.bundlelist = None self.font_increment = font_increment self.vsizer = wx.BoxSizer(wx.VERTICAL) self.SetBackgroundColour(DEFAULT_BACKGROUND) self.indent = parent.controls[0].icon.GetSize()[0] + 3 + 3 + self.parent_list.leftSpacer #width of icon + 3px left spacer + 3px right spacer self.AddHeader() self.AddGrid() self.SetHits(hits, noChange = True) self.UpdateHeader(general_description, description) self.AddSpacer((self.indent, -1)) self.Add(self.vsizer, 1, wx.EXPAND|wx.BOTTOM, 7) def AddHeader(self): sizer = wx.BoxSizer(wx.HORIZONTAL) self.header = StaticText(self.parent, -1, ' ') self.info_icon = wx.StaticBitmap(self.parent, -1, self.icons['info']) sizer.Add(self.header, 0, wx.RIGHT, 7) sizer.Add(self.info_icon, 0, wx.ALIGN_CENTER_VERTICAL) self.vsizer.Add(sizer, 0, wx.BOTTOM, 3) def UpdateHeader(self, general_description, description): self.SetGeneralDescription(general_description) self.SetDescription(description) def AddGrid(self): self.grid = wx.FlexGridSizer(0, self.num_cols, 3, 7) self.grid.SetFlexibleDirection(wx.HORIZONTAL) self.grid.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_NONE) self.grid.SetMinSize((1,-1)) for i in xrange(BUNDLE_NUM_ROWS): self.grid.AddGrowableRow(i, 1) for j in xrange(self.num_cols): self.grid.AddGrowableCol(j, 1) self.vsizer.Add(self.grid, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 14 + self.indent) def RebuildGrid(self, new_cols): if self.num_cols != new_cols: self.num_cols = new_cols children = self.grid.GetChildren() children_controls = [] for child in children: children_controls.append(child.GetWindow() or child.GetSizer()) for child in children_controls: self.grid.Detach(child) self.vsizer.Detach(self.grid) self.grid.Destroy() self.grid = wx.FlexGridSizer(0, self.num_cols, 3, 7) for child in children_controls: self.grid.Add(child, 0, wx.EXPAND) for j in xrange(self.num_cols): self.grid.AddGrowableCol(j, 1) self.vsizer.Add(self.grid, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 14 + self.indent) self.Layout() self.parent_listitem.Layout() return True return False def UpdateGrid(self, hits, noChange=False): N = BUNDLE_NUM_ROWS * BUNDLE_NUM_COLS items_to_add = min(N, self.nrhits) if self.nrhits > N: items_to_add -= 1 self.parent.Freeze() children = self.grid.GetChildren() didChange = len(children) < min(N, self.nrhits) if not didChange: if DEBUG: print >> sys.stderr, "*** BundlePanel.UpdateGrid: total nr items did not change, updating labels only" #total nr items did not change for i in range(items_to_add): link_static_text = children[i].GetWindow() or children[i].GetSizer() if link_static_text and getattr(link_static_text, 'SetLabel', False): link_static_text.SetLabel(hits[i].name) link_static_text.action = hits[i] else: didChange = True break if self.nrhits > N: more_caption = '(%s more...)' % (self.nrhits - N + 1) link_static_text = children[i+1].GetWindow() or children[i+1].GetSizer() if link_static_text and getattr(link_static_text, 'SetLabel', False): link_static_text.SetLabel(more_caption) link_static_text.Unbind(wx.EVT_LEFT_UP) link_static_text.Bind(wx.EVT_LEFT_UP, self.OnMoreClick) else: didChange = True if didChange: if DEBUG: print >> sys.stderr, "*** BundlePanel.UpdateGrid: something did change rebuilding grid", len(children),min(N, self.nrhits) curRows = len(children) / BUNDLE_NUM_COLS newRows = min(self.nrhits / BUNDLE_NUM_COLS, BUNDLE_NUM_ROWS) rowsChanged = curRows != newRows self.grid.ShowItems(False) self.grid.Clear(deleteWindows = True) for i in range(items_to_add): hit = hits[i] new_text = LinkStaticText(self.parent, hit.name, icon = False, icon_type = 'tree', icon_align = wx.ALIGN_LEFT, font_increment = self.font_increment, font_colour = BUNDLE_FONT_COLOR) new_text.Bind(wx.EVT_LEFT_UP, self.OnBundleLinkClick) new_text.SetMinSize((1,-1)) new_text.action = hit self.grid.Add(new_text, 0, wx.EXPAND) if self.nrhits > N: caption = '(%s more...)' % (self.nrhits - N + 1) more_label = LinkStaticText(self.parent, caption, icon = False, icon_align = wx.ALIGN_LEFT, font_increment = self.font_increment, font_colour = BUNDLE_FONT_COLOR) more_label.Bind(wx.EVT_LEFT_UP, self.OnMoreClick) self.grid.Add(more_label, 0, wx.EXPAND) self.parent_listitem.AddEvents(self.grid) if self.state != self.COLLAPSED: self.ShowGrid(False) if rowsChanged and not noChange: self.parent_listitem.OnChange() self.parent.Thaw() return didChange def OnEventSize(self, width): if width < BUNDLE_GRID_COLLAPSE: return self.RebuildGrid(1) return self.RebuildGrid(BUNDLE_NUM_COLS) def ShowGrid(self, show): if show: self.grid.ShowItems(True) else: self.grid.ShowItems(False) def UpdateList(self, hits): self.hits = hits if self.bundlelist: self.bundlelist.SetData(hits) if self.state == BundlePanel.FULL: self.bundlelist.OnLoadAll() def ShowList(self, show): if self.bundlelist is None and show: max_list = BUNDLE_NUM_ROWS * BUNDLE_NUM_COLS if len(self.hits) != BUNDLE_NUM_ROWS * BUNDLE_NUM_COLS: max_list -= 1 self.bundlelist = BundleListView(parent = self.parent, list_item_max = max_list) self.vsizer.Add(self.bundlelist, 0, wx.EXPAND|wx.BOTTOM, self.indent - 7) #a 7px spacer is already present # SetData does wx.Yield, which could cause a collapse event to be processed within the setdata # method. Thus we have to do this after the add to the sizer self.bundlelist.SetData(self.hits) elif self.bundlelist is not None and not show: self.vsizer.Detach(self.bundlelist) self.bundlelist.Show(False) self.bundlelist.Destroy() self.bundlelist = None def CollapseExpandedItem(self): if self.state != BundlePanel.COLLAPSED: self.bundlelist.list.OnCollapse() def RefreshDataBundleList(self, key, data): if self.bundlelist is not None: self.bundlelist.RefreshData(key, data) def SetDescription(self, description): self.header.SetToolTipString(description) self.info_icon.SetToolTipString(description) def SetGeneralDescription(self, general_description): if general_description: general_description = unicode(general_description) else: general_description = u'Similar' self.header.SetLabel(u'%s items (%s):' % (general_description, self.nrhits)) def SetHits(self, hits, noChange=False): self.nrhits = len(hits) gridChanged = self.UpdateGrid(hits, noChange) self.UpdateList(hits) self.Layout() return gridChanged def ChangeState(self, new_state, doLayout=True): if self.state != new_state: old_state = self.state self.state = new_state if new_state == BundlePanel.COLLAPSED: self.ShowList(False) self.ShowGrid(True) else: if new_state == BundlePanel.PARTIAL or new_state == BundlePanel.FULL: self.ShowGrid(False) if old_state == BundlePanel.COLLAPSED: self.ShowList(True) if new_state == BundlePanel.FULL and self.bundlelist: self.bundlelist.OnLoadAll() if DEBUG: statestr = lambda st: ['COLLAPSED', 'PARTIAL', 'FULL'][st] print >>sys.stderr, '*** BundlePanel.ChangeState: %s --> %s' % (statestr(old_state), statestr(new_state)) def ExpandHit(self, hit): id = hit.infohash self.bundlelist.ExpandItem(id) self.parent_listitem.ShowSelected() def OnBundleLinkClick(self, event): #do expand self.ExpandAndHideParent() staticText = event.GetEventObject() action = getattr(staticText, 'action', None) if action is not None: # Reason for non-persistence (for now) is least-surprise. # If the user collapses a bundled listitem, the previously # clicked item is still at the same location. if action in self.hits: self.hits.remove(action) self.hits.insert(0, action) self.ChangeState(BundlePanel.PARTIAL) self.ExpandHit(action) def db_callback(): self.uelog.addEvent(message="Bundler GUI: BundleLink click; %s; %s;" % (self.nrhits, self.parent_listitem.general_description), type = 3) self.guiutility.frame.guiserver.add_task(db_callback) def OnMoreClick(self, event): #do expand self.ExpandAndHideParent() self.ChangeState(BundlePanel.FULL) def db_callback(): self.uelog.addEvent(message="Bundler GUI: More click; %s; %s;" % (self.nrhits, self.parent_listitem.general_description), type = 3) self.guiutility.frame.guiserver.add_task(db_callback) def ExpandAndHideParent(self): self.parent.Freeze() if not self.parent_listitem.expanded: # Make sure the listitem is marked as expanded self.parent_listitem.OnClick() # but hide the panel self.parent_listitem.ShowExpandedPanel(False) self.parent.Thaw() #Called from GUI to get expanded torrentdetails panel def GetExpandedPanel(self): if self.bundlelist: item = self.bundlelist.GetExpandedItem() if item: return item.GetExpandedPanel() def SetBackgroundColour(self, colour): self.parent.Freeze() if getattr(self, 'grid', False): for sizeritem in self.grid.GetChildren(): child = sizeritem.GetWindow() or sizeritem.GetSizer() if child and getattr(child, 'SetBackgroundColour', False): child.SetBackgroundColour(colour) self.parent.Thaw()
def GetSubTitlePanel(self, parent): self.subtitle = StaticText(parent) return self.subtitle
def __init__(self, parent_list, columns, leftSpacer=0, rightSpacer=0, singleExpanded=False, showChange=False, list_item_max=None, hasFilter=True, listRateLimit=LIST_RATE_LIMIT): self.columns = columns self.leftSpacer = leftSpacer self.rightSpacer = rightSpacer self.parent_list = parent_list self.singleExpanded = singleExpanded self.showChange = showChange self.list_selected = LIST_SELECTED self.listRateLimit = listRateLimit if not list_item_max: list_item_max = LIST_ITEM_MAX_SIZE self.list_item_max = list_item_max self.list_cur_max = self.list_item_max self.hasFilter = hasFilter hSizer = wx.BoxSizer(wx.HORIZONTAL) self.listpanel = wx.Panel(self, name="LIST") #vertical sizer containing all items self.vSizer = wx.BoxSizer(wx.VERTICAL) self.listpanel.SetSizer(self.vSizer) hSizer.Add(self.listpanel, 1) self.SetSizer(hSizer) #messagePanel text self.messagePanel = wx.Panel(self.listpanel) self.messagePanel.SetBackgroundColour(DEFAULT_BACKGROUND) self.messagePanel.Show(False) messageVSizer = wx.BoxSizer(wx.VERTICAL) self.headerText = StaticText(self.messagePanel) _set_font(self.headerText, fontweight=wx.FONTWEIGHT_BOLD) self.messageText = StaticText(self.messagePanel) self.loadNext = wx.Button(self.messagePanel) self.loadNext.Bind(wx.EVT_BUTTON, self.OnLoadMore) self.loadNext.Hide() messageVSizer.Add(self.headerText, 0, wx.EXPAND) messageVSizer.Add(self.messageText, 0, wx.EXPAND) messageVSizer.Add(self.loadNext, 0, wx.ALIGN_CENTER) self.messageText.sizer = messageVSizer self.messageText.altControl = None messageSizer = wx.BoxSizer(wx.HORIZONTAL) messageSizer.AddStretchSpacer() messageSizer.Add(messageVSizer, 0, wx.TOP | wx.BOTTOM, 7) messageSizer.AddStretchSpacer() self.messagePanel.SetSizer(messageSizer) #vertical scrollrate self.rate = None #states self.cur_expanded = None #quick filter self.filter = None self.filterMessage = None #sorting self.sortcolumn = None #queue lists self.done = True self.lastData = 0 self.dataTimer = None self.data = None self.raw_data = None self.items = {} # Allow list-items to store the most recent mouse left-down events: self.lastMouseLeftDownEvent = None self.curWidth = -1 self.Bind(wx.EVT_SIZE, self.OnEventSize)
class ChannelHeader(SearchHeader): DESCRIPTION_MAX_HEIGTH = 100 @warnWxThread def GetRightTitlePanel(self, parent): hSizer = SearchHeader.GetRightTitlePanel(self, parent) self.back = wx.Button(parent, wx.ID_BACKWARD, "Go back") hSizer.Add(self.back, 0, wx.LEFT, 5) return hSizer @warnWxThread def GetBelowPanel(self, parent): self.descriptionPanel = ImageScrollablePanel(parent) self.descriptionPanel.SetBackgroundColour(DEFAULT_BACKGROUND) self.description = StaticText(self.descriptionPanel) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.description, 1, wx.EXPAND | wx.ALL, 3) self.descriptionPanel.SetSizer(sizer) self.descriptionPanel.Hide() self.descriptionPanel.Bind(wx.EVT_SIZE, self.SetHeight) self.descriptionPanel.Bind(wx.EVT_SHOW, self.SetHeight) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(self.descriptionPanel, 1, wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, self.radius + 3) return hSizer def Reset(self): SearchHeader.Reset(self) self.SetStyle(None) @warnWxThread def SetHeight(self, event): if self.descriptionPanel.IsShown(): dirty = False self.descriptionPanel.SetVirtualSizeHints( -1, -1, maxW=self.descriptionPanel.GetClientSize() [0]) #change to allow for scrollbarwidth self.descriptionPanel.SetupScrolling() bestHeight = self.description.GetVirtualSize()[1] + 6 minHeight = min(self.DESCRIPTION_MAX_HEIGTH, bestHeight) if self.descriptionPanel.GetMinSize()[1] != minHeight: self.descriptionPanel.SetMinSize((-1, minHeight)) dirty = True if dirty: self.Layout() @warnWxThread def SetEvents(self, back): self.back.Bind(wx.EVT_BUTTON, back) @warnWxThread def SetStyle(self, description, font=None, foreground=None, bgImage=None): if description: self.description.SetLabel(description) if font: self.description.SetFont(font) if foreground: self.description.SetForegroundColour(foreground) self.descriptionPanel.SetBitmap(bgImage) self.descriptionPanel.Show() else: self.descriptionPanel.Hide()
class AbstractListBody(): @warnWxThread def __init__(self, parent_list, columns, leftSpacer=0, rightSpacer=0, singleExpanded=False, showChange=False, list_item_max=None, hasFilter=True, listRateLimit=LIST_RATE_LIMIT): self.columns = columns self.leftSpacer = leftSpacer self.rightSpacer = rightSpacer self.parent_list = parent_list self.singleExpanded = singleExpanded self.showChange = showChange self.list_selected = LIST_SELECTED self.listRateLimit = listRateLimit if not list_item_max: list_item_max = LIST_ITEM_MAX_SIZE self.list_item_max = list_item_max self.list_cur_max = self.list_item_max self.hasFilter = hasFilter hSizer = wx.BoxSizer(wx.HORIZONTAL) self.listpanel = wx.Panel(self, name="LIST") #vertical sizer containing all items self.vSizer = wx.BoxSizer(wx.VERTICAL) self.listpanel.SetSizer(self.vSizer) hSizer.Add(self.listpanel, 1) self.SetSizer(hSizer) #messagePanel text self.messagePanel = wx.Panel(self.listpanel) self.messagePanel.SetBackgroundColour(DEFAULT_BACKGROUND) self.messagePanel.Show(False) messageVSizer = wx.BoxSizer(wx.VERTICAL) self.headerText = StaticText(self.messagePanel) _set_font(self.headerText, fontweight=wx.FONTWEIGHT_BOLD) self.messageText = StaticText(self.messagePanel) self.loadNext = wx.Button(self.messagePanel) self.loadNext.Bind(wx.EVT_BUTTON, self.OnLoadMore) self.loadNext.Hide() messageVSizer.Add(self.headerText, 0, wx.EXPAND) messageVSizer.Add(self.messageText, 0, wx.EXPAND) messageVSizer.Add(self.loadNext, 0, wx.ALIGN_CENTER) self.messageText.sizer = messageVSizer self.messageText.altControl = None messageSizer = wx.BoxSizer(wx.HORIZONTAL) messageSizer.AddStretchSpacer() messageSizer.Add(messageVSizer, 0, wx.TOP | wx.BOTTOM, 7) messageSizer.AddStretchSpacer() self.messagePanel.SetSizer(messageSizer) #vertical scrollrate self.rate = None #states self.cur_expanded = None #quick filter self.filter = None self.filterMessage = None #sorting self.sortcolumn = None #queue lists self.done = True self.lastData = 0 self.dataTimer = None self.data = None self.raw_data = None self.items = {} # Allow list-items to store the most recent mouse left-down events: self.lastMouseLeftDownEvent = None self.curWidth = -1 self.Bind(wx.EVT_SIZE, self.OnEventSize) @warnWxThread def SetBackgroundColour(self, colour): wx.Panel.SetBackgroundColour(self, DEFAULT_BACKGROUND) self.listpanel.SetBackgroundColour(colour) @warnWxThread def SetStyle(self, font=None, foregroundcolour=None, list_selected=LIST_SELECTED): if font: self.SetFont(font) if foregroundcolour: self.SetForegroundColour(foregroundcolour) self.list_selected = list_selected @warnWxThread def OnSort(self, column, reverse): self.Scroll(-1, 0) #Niels: translating between -1 and None conventions if column == -1: column = None self.sortcolumn = column self.sortreverse = reverse self.SetData(highlight=False, force=True) def DoSort(self): def sortby(b, a): if a[0] in self.items: a = self.items[a[0]].data[self.sortcolumn] else: a = a[1][self.sortcolumn] if b[0] in self.items: b = self.items[b[0]].data[self.sortcolumn] else: b = b[1][self.sortcolumn] if isinstance(a, basestring): a = a.lower() if isinstance(b, basestring): b = b.lower() return cmp(a, b) if self.sortcolumn != None: self.data = sorted(self.data, cmp=sortby, reverse=self.sortreverse) def SetFilter(self, filter, filterMessage, highlight): self.filterMessage = filterMessage if self.filter is not None or filter is not None: self.filter = filter self.Scroll(-1, 0) self.SetData(highlight=highlight) @warnWxThread def OnExpand(self, item, raise_event=False): self.Freeze() if self.singleExpanded: if self.cur_expanded: self.OnCollapse(self.cur_expanded, False) panel = self.parent_list.OnExpand(item) if panel and not isinstance(panel, bool): item.Expand(panel) self.OnChange() #Niels: Windows 7 needs this refresh otherwise it will show some paint errors self.Refresh() self.cur_expanded = item self.Thaw() return panel @warnWxThread def OnCollapse(self, item=None, onchange=True): self.Freeze() if not item: item = self.cur_expanded if item: panel = item.Collapse() self.parent_list.OnCollapse(item, panel) self.cur_expanded = None if onchange: self.OnChange() #Niels: Windows 7 needs this refresh otherwise it will show some paint errors self.Refresh() self.Thaw() @warnWxThread def OnChange(self, scrollToTop=False): self.Freeze() self.vSizer.Layout() self.listpanel.Layout() self.Layout() #Determine scrollrate if self.rate is None: nritems = len(self.vSizer.GetChildren()) if nritems > 0: height = self.vSizer.GetSize()[1] self.rate = height / nritems if DEBUG: print >> sys.stderr, "ListBody: setting scrollrate to", self.rate self.SetupScrolling(scrollToTop=scrollToTop, rate_y=self.rate) else: if DEBUG: print >> sys.stderr, "ListBody: setting scrollrate to default" self.SetupScrolling(scrollToTop=scrollToTop) else: if DEBUG: print >> sys.stderr, "ListBody: using scrollrate", self.rate self.SetupScrolling(scrollToTop=scrollToTop, rate_y=self.rate) self.Thaw() @warnWxThread def Reset(self): if DEBUG: print >> sys.stderr, "ListBody: reset" self.Freeze() self.filter = None self.filterMessage = None self.sortcolumn = None self.rate = None self.vSizer.ShowItems(False) self.vSizer.Clear() for key in self.items.keys(): self.items[key].Destroy() self.list_cur_max = self.list_item_max self.items = {} self.data = None self.lastData = 0 self.raw_data = None self.ShowLoading() self.OnChange() self.Thaw() def IsEmpty(self): return len(self.items) == 0 def InList(self, key, onlyCreated=True): if onlyCreated or not self.data: return key in self.items if key in self.items: return True return any(curdata[0] == key for curdata in self.data) @warnWxThread def ScrollToEnd(self, scroll_to_end): if scroll_to_end: self.Scroll(-1, self.vSizer.GetSize()[1]) else: self.Scroll(-1, 0) @warnWxThread def ScrollToId(self, id): if id in self.items: sy = self.items[id].GetPosition()[1] / self.GetScrollPixelsPerUnit( )[1] self.Scroll(-1, sy) @warnWxThread def ShowMessage(self, message, header=None, altControl=None): if DEBUG: print >> sys.stderr, "ListBody: ShowMessage", message self.Freeze() if header: self.headerText.SetLabel(header) self.headerText.Show() else: self.headerText.Hide() self.messageText.SetLabel(message) if self.messageText.altControl: self.messageText.sizer.Detach(self.messageText.altControl) if getattr(self.messageText.altControl, 'ShowItems', False): self.messageText.altControl.ShowItems(False) self.messageText.altControl.Clear(True) self.messageText.altControl = None if altControl: self.messageText.altControl = altControl self.messageText.sizer.Insert(2, altControl, 0, wx.EXPAND) self.loadNext.Hide() self.vSizer.ShowItems(False) self.vSizer.Clear() self.vSizer.Add(self.messagePanel, 0, wx.EXPAND | wx.BOTTOM, 1) self.messagePanel.Layout() if not self.messagePanel.IsShown(): self.messagePanel.Show() self.OnChange() self.Thaw() def GetMessage(self): header = message = None if self.headerText.IsShown(): header = self.headerText.GetLabel() if self.messageText.IsShown(): message = self.messageText.GetLabel() return header, message @warnWxThread def ShowLoading(self): self.ShowMessage('Loading, please wait.') @warnWxThread def RefreshData(self, key, data): if key in self.items: if DEBUG: print >> sys.stderr, "ListBody: refresh item", self.items[key] self.items[key].RefreshData(data) #forward update to expandedPanel panel = self.items[key].GetExpandedPanel() if panel and getattr(panel, 'RefreshData', False): if DEBUG: print >> sys.stderr, "ListBody: refresh item (Calling expandedPanel refreshdata)", self.items[ key] panel.RefreshData(data) @warnWxThread def SetData(self, data=None, highlight=None, force=False): if DEBUG: nr_items = 0 if data: nr_items = len(data) print >> sys.stderr, "ListBody: new data", time(), nr_items if data == None: data = self.raw_data else: self.raw_data = data assert len(data[0][1]) == len( self.columns ), 'Data does not have equal amount of columns %d/%d %s' % (len( data[0][1]), len(self.columns), type(self.parent_list)) if highlight is None: highlight = not self.IsEmpty() def doSetData(): self.lastData = time() self.dataTimer = None self.__SetData(highlight) if force: if self.dataTimer: self.dataTimer.Stop() doSetData() else: diff = time() - (self.listRateLimit + self.lastData) call_in = -diff * 1000 if call_in <= 0: doSetData() else: if self.dataTimer == None: self.dataTimer = wx.CallLater(call_in, doSetData) else: self.dataTimer.Restart(call_in) def __SetData(self, highlight=True): if DEBUG: print >> sys.stderr, "ListBody: __SetData", time() if __debug__ and currentThread().getName() != "MainThread": print >> sys.stderr, "ListBody: __SetData thread", currentThread( ).getName(), "is NOT MAIN THREAD" print_stack() self.Freeze() #apply quickfilter if self.filter: data = filter(self.filter, self.raw_data) if len(data) != len(self.raw_data): self.parent_list.SetFilteredResults(len(data)) else: self.parent_list.SetFilteredResults(None) else: self.parent_list.SetFilteredResults(None) data = self.raw_data if not data: data = [] self.highlightSet = set() cur_keys = set(self.items.keys()) for curdata in data[:self.list_cur_max]: key = curdata[0] if key not in cur_keys: if highlight: self.highlightSet.add(key) else: cur_keys.discard(key) #cur_keys now contains all removed items for key in cur_keys: self.items[key].Show(False) self.items[key].Destroy() del self.items[key] self.data = data self.DoSort() self.done = False if len(data) > 0: self.vSizer.ShowItems(False) self.vSizer.Clear() self.CreateItems(nr_items_to_create=3 * LIST_ITEM_BATCH_SIZE) #Try to yield try: wx.Yield() except: pass elif self.filter: self.ShowMessage(self.filterMessage(empty=True) + '.') if self.done: self.Unbind( wx.EVT_IDLE ) #unbinding unnecessary event handler seems to improve visual performance else: self.Bind(wx.EVT_IDLE, self.OnIdle) self.Thaw() def OnIdle(self, event): if not self.done: if self.data and len(self.data) > 0: self.CreateItems() else: self.done = True #idle event also paints search animation, use request more to show this update event.RequestMore(not self.done) if self.done: self.Unbind(wx.EVT_IDLE) def OnLoadMore(self, event): self.loadNext.Disable() self.list_cur_max += LIST_ITEM_MAX_SIZE wx.CallAfter(self.CreateItems) self.Bind(wx.EVT_IDLE, self.OnIdle) def OnLoadAll(self): self.loadNext.Disable() self.list_cur_max = sys.maxint wx.CallAfter(self.CreateItems) self.Bind(wx.EVT_IDLE, self.OnIdle) @warnWxThread def CreateItem(self, key): if not key in self.items and self.data: for curdata in self.data: if len(curdata) > 3: thiskey, item_data, original_data, create_method = curdata else: thiskey, item_data, original_data = curdata create_method = ListItem if key == thiskey: self.items[key] = create_method( self.listpanel, self, self.columns, item_data, original_data, self.leftSpacer, self.rightSpacer, showChange=self.showChange, list_selected=self.list_selected) if self.messagePanel.IsShown(): before = len(self.vSizer.GetChildren()) - 1 self.vSizer.Insert(before, self.items[key], 0, wx.EXPAND | wx.BOTTOM, 1) else: self.vSizer.Add(self.items[key], 0, wx.EXPAND | wx.BOTTOM, 1) self.OnChange() break @warnWxThread def CreateItems(self, nr_items_to_create=LIST_ITEM_BATCH_SIZE, nr_items_to_add=None): if not nr_items_to_add: nr_items_to_add = self.list_cur_max if DEBUG: print >> sys.stderr, "ListBody: Creating items", time() initial_nr_items_to_add = nr_items_to_add done = True if len(self.data) > 0: t1 = time() self.Freeze() #Check if we need to clear vSizer self.messagePanel.Show(False) self.loadNext.Show(False) self.vSizer.Remove(self.messagePanel) if self.filter: message = self.filterMessage() + '.' else: message = '' revertList = [] #Add created/cached items for curdata in self.data: if len(curdata) > 3: key, item_data, original_data, create_method = curdata else: key, item_data, original_data = curdata create_method = ListItem if nr_items_to_add > 0 and nr_items_to_create > 0: if key not in self.items: self.items[key] = create_method( self.listpanel, self, self.columns, item_data, original_data, self.leftSpacer, self.rightSpacer, showChange=self.showChange, list_selected=self.list_selected) nr_items_to_create -= 1 elif getattr(self.items[key], 'should_update', False): self.items[key].RefreshData(curdata) item = self.items[key] sizer = self.vSizer.GetItem(item) if not sizer: self.vSizer.Add(item, 0, wx.EXPAND | wx.BOTTOM, 1) item.Show() if key in self.highlightSet: self.highlightSet.remove(key) if item.Highlight(revert=False): revertList.append(key) nr_items_to_add -= 1 else: done = nr_items_to_add == 0 or initial_nr_items_to_add == sys.maxint if done: if message != '': message = 'Only showing the first %d of %d' % (len( self.vSizer.GetChildren() ), len(self.data)) + message[ 12:] + '\nFurther specify keywords to reduce the number of items, or click the button below.' else: message = 'Only showing the first %d of %d items in this list.' % ( len(self.vSizer.GetChildren()), len(self.data)) if self.hasFilter: message += '\nSearch within results to reduce the number of items, or click the button below.' remainingItems = min( LIST_ITEM_MAX_SIZE, len(self.data) - len(self.vSizer.GetChildren())) self.loadNext.SetLabel("Show next %d items" % remainingItems) self.loadNext.Enable() self.loadNext.Show() break if len(message) > 12: self.messageText.SetLabel(message) self.vSizer.Add(self.messagePanel, 0, wx.EXPAND | wx.BOTTOM, 1) self.messagePanel.Layout() self.messagePanel.Show() self.OnChange() self.Thaw() if len(revertList) > 0: wx.CallLater(1000, self.Revert, revertList) if len(revertList) > 0: wx.CallLater(1000, self.Revert, revertList) self.done = done if DEBUG: print >> sys.stderr, "List created", len( self.vSizer.GetChildren()), "rows of", len( self.data), "took", time() - t1, "done:", self.done def GetItem(self, key): return self.items[key] def GetItemPos(self, key): # Returns the index of the ListItem belonging to this key for i, data in enumerate(self.data): if key == data[0]: return i @warnWxThread def RemoveItem(self, remove): for key, item in self.items.iteritems(): if item == remove: self.RemoveKey(key) break @warnWxThread def RemoveKey(self, key): item = self.items.get(key, None) if item: self.items.pop(key) self.vSizer.Detach(item) item.Destroy() self.OnChange() for i, curdata in enumerate(self.raw_data): if curdata[0] == key: self.raw_data.pop(i) break def GetExpandedItem(self): return self.cur_expanded def GetExpandedItems(self): return [(key, item) for key, item in self.items.iteritems() if item.expanded] @warnWxThread def Select(self, key, raise_event=True): self.DeselectAll() #check if we need to create this item on the spot if not key in self.items: self.CreateItem(key) if key in self.items: if raise_event: self.items[key].OnClick(None) else: self.items[key].expanded = True self.cur_expanded = self.items[key] self.items[key].ShowSelected() @warnWxThread def DeselectAll(self): for _, item in self.items.iteritems(): item.Deselect() def Revert(self, revertList): for key in revertList: if key in self.items: self.items[key].Revert() def OnEventSize(self, event): width = self.GetSize()[0] if width != self.curWidth: doOnChange = False self.Freeze() self.curWidth = width for item in self.items.itervalues(): if item.OnEventSize(width): doOnChange = True if doOnChange: self.OnChange() self.Thaw() event.Skip()
def AddComponents(self, leftSpacer, rightSpacer): if leftSpacer > 0: self.hSizer.AddSpacer((leftSpacer, -1)) for i in xrange(len(self.columns)): if self.columns[i]['width'] == wx.LIST_AUTOSIZE: option = 1 size = wx.DefaultSize else: option = 0 size = (self.columns[i]['width'], -1) type = self.columns[i].get('type', 'label') if type == 'label': str_data = self.columns[i].get('fmt', unicode)(self.data[i]) control = StaticText(self, style=self.columns[i].get('style', 0) | wx.ST_NO_AUTORESIZE | wx.ST_DOTS_END, size=size) fontWeight = self.columns[i].get('fontWeight', wx.FONTWEIGHT_NORMAL) if fontWeight != wx.FONTWEIGHT_NORMAL: _set_font(control, fontweight=fontWeight) #niels: wx magic prevents us from passing this string with the constructor, ampersands will not work control.SetLabel(str_data.replace('&', "&&")) elif type == 'method': control = self.columns[i]['method'](self, self) if control: control.icon = self._get_icon(i, 'icon') control.icon_right = self._get_icon(i, 'icon_right') self.controls.append(control) if i != 0: self.hSizer.AddSpacer((3, -1)) if control.icon: self.hSizer.Add(control.icon, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 3) self.hSizer.Add( control, option, wx.RESERVE_SPACE_EVEN_IF_HIDDEN | wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.BOTTOM, 3) if control.icon_right: self.hSizer.Add(control.icon_right, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 3) if self.columns[i]['width'] == wx.LIST_AUTOSIZE: control.SetMinSize((1, -1)) elif self.columns[i]['width'] == LIST_AUTOSIZEHEADER: self.columns[i]['width'] = control.GetSize()[0] if self.parent_list.parent_list.header: self.parent_list.parent_list.header.ResizeColumn( i, self.columns[i]['width']) else: if self.columns[i]['width'] != LIST_AUTOSIZEHEADER: self.hSizer.Add((self.columns[i]['width'], -1), 0, wx.LEFT, 3) if rightSpacer > 0: self.hSizer.AddSpacer((rightSpacer, -1)) self.hSizer.Layout() self.AddEvents(self)
class ChannelFooter(ListFooter): def GetMidPanel(self, hSizer): self.hSizer = hSizer self.message = StaticText(self) self.message.SetMinSize((1,-1)) font = self.message.GetFont() font.SetPointSize(font.GetPointSize()+2) font.SetWeight(wx.FONTWEIGHT_BOLD) self.message.SetFont(font) self.subtitle = wx.StaticText(self) self.subtitle.SetMinSize((1,-1)) self.manage = wx.Button(self, -1, 'Edit this Channel') self.spam = wx.Button(self, -1, 'Mark as Spam') self.favorite = wx.Button(self, -1, 'Mark as Favorite') self.ortext = None self.subtitle.Show(False) self.favorite.Show(False) self.spam.Show(False) self.manage.Show(False) def SetEvents(self, spam, favorite, remove, manage): self.spam_eventhandler = spam self.favorite_eventhandler = favorite self.remove_eventhandler = remove self.manage.Bind(wx.EVT_BUTTON, manage) def SetStates(self, vote, channelstate, iamModerator): self.Freeze() self.hSizer.Clear() explicit_vote = vote != 0 preview = not explicit_vote and not iamModerator open2edit = channelstate == ChannelCommunity.CHANNEL_CLOSED and iamModerator allow2edit = vote == 2 and channelstate == ChannelCommunity.CHANNEL_OPEN self.favorite.Show(False) self.spam.Show(False) self.manage.Show(False) #clean up old ortext statictext if self.ortext: self.ortext.Destroy() self.ortext = None header = '' msg = '' buttonSizer = None if preview: header = "You are looking at a preview of this Channel." msg = "If you want to see more of it, press the 'Mark as Favorite' button.\nTribler will then more aggressively download updates making sure you always have access to the newest content." self.spam.SetLabel('Mark as Spam') self.spam.Bind(wx.EVT_BUTTON, self.spam_eventhandler) self.spam.Show(True) self.ortext = wx.StaticText(self, -1, 'or') self.favorite.SetLabel('Mark as Favorite') self.favorite.Bind(wx.EVT_BUTTON, self.favorite_eventhandler) self.favorite.Show(True) buttonSizer = wx.BoxSizer(wx.HORIZONTAL) buttonSizer.Add(self.spam) buttonSizer.Add(self.ortext, 0, wx.LEFT|wx.RIGHT|wx.ALIGN_CENTRE_VERTICAL, 3) buttonSizer.Add(self.favorite) else: if open2edit: header = "You can now enable community-features for this Channel." msg = "Allowing other users to comment, modify and improve meta-data will increase the overall community feel. Try it now.\nEdit your channel settings to get started." self.manage.Show(True) buttonSizer = self.manage elif allow2edit: header = "This is an open community. You can modify, comment and add new content. Feel free to do so." self.manage.Show(True) buttonSizer = self.manage if vote == -1: header = '' msg = "You have marked this Channel as Spam." self.spam.SetLabel('This is not Spam') self.spam.Bind(wx.EVT_BUTTON, self.remove_eventhandler) self.spam.Show(True) buttonSizer = self.spam elif vote == 2: if msg == '': msg = "Thank you for marking this Channel as your Favorite." self.favorite.SetLabel('Remove Favorite') self.favorite.Bind(wx.EVT_BUTTON, self.remove_eventhandler) self.favorite.Show(True) if buttonSizer: sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(buttonSizer) sizer.Add(self.favorite) buttonSizer = sizer else: buttonSizer = self.favorite else: if msg == '': msg = "You can edit this channel" self.manage.Show(True) buttonSizer = self.manage if header != '': self.message.SetLabel(header) self.subtitle.SetLabel(msg) self.subtitle.Show(True) vSizer = wx.BoxSizer(wx.VERTICAL) vSizer.Add(self.message, 0, wx.EXPAND) if buttonSizer: if preview: vSizer.Add(self.subtitle, 0, wx.EXPAND) vSizer.Add(buttonSizer, 0, wx.ALIGN_CENTER|wx.TOP|wx.BOTTOM, 10) else: sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.subtitle, 1, wx.EXPAND) sizer.Add(buttonSizer, 0, wx.TOP|wx.BOTTOM|wx.RIGHT, 3) vSizer.Add(sizer, 0, wx.EXPAND) else: vSizer.Add(self.subtitle, 0, wx.EXPAND) self.hSizer.Add(vSizer, 1, wx.EXPAND|wx.TOP|wx.BOTTOM, 7) else: self.message.SetLabel(msg) self.subtitle.Show(False) self.hSizer.Add(self.message, 1, wx.TOP|wx.BOTTOM|wx.ALIGN_BOTTOM|wx.LEFT, 7) self.hSizer.Add(buttonSizer, 0, wx.TOP|wx.BOTTOM|wx.RIGHT, 7) self.hSizer.Layout() self.Layout() self.Thaw() def Reset(self): ListFooter.Reset(self) self.Freeze() self.hSizer.Clear() self.subtitle.Show(False) self.favorite.Show(False) self.spam.Show(False) self.manage.Show(False) self.message.SetLabel('') self.Thaw() def GetStates(self): return (self.spam.GetLabel() == 'This is not Spam', self.favorite.GetLabel() == 'Remove Favorite')
class SearchSideBar(wx.Panel): INDENT = 7 HEADER_FONT_WEIGHT = wx.FONTWEIGHT_NORMAL def __init__(self, parent, parent_list, size): wx.Panel.__init__(self, parent, size = size) self.SetForegroundColour(parent.GetForegroundColour()) self.guiutility = GUIUtility.getInstance() self.torrentsearch_manager = self.guiutility.torrentsearch_manager self.parent = parent self.parent_list = parent_list self.nrfiltered = 0 self.family_filter = True self.bundlestates = [Bundler.ALG_MAGIC, Bundler.ALG_NAME, Bundler.ALG_NUMBERS, Bundler.ALG_SIZE, Bundler.ALG_OFF] self.bundlestates_str = {Bundler.ALG_NAME: 'Name', Bundler.ALG_NUMBERS: 'Numbers', Bundler.ALG_SIZE: 'Size', Bundler.ALG_MAGIC: 'Magic', Bundler.ALG_OFF: 'Off'} self.bundletexts = [] self.bundle_db = BundlerPreferenceDBHandler.getInstance() self.uelog = UserEventLogDBHandler.getInstance() self.vSizer = wx.BoxSizer(wx.VERTICAL) hSizer = wx.BoxSizer(wx.HORIZONTAL) header = StaticText(self, -1, 'Search') if SearchSideBar.HEADER_FONT_WEIGHT != wx.FONTWEIGHT_NORMAL: font = header.GetFont() font.SetWeight(SearchSideBar.HEADER_FONT_WEIGHT) header.SetFont(font) hSizer.Add(header, 0, wx.ALIGN_CENTER_VERTICAL) self.searchState = StaticText(self) hSizer.Add(self.searchState, 1, wx.ALIGN_CENTER_VERTICAL) ag_fname = os.path.join(self.guiutility.utility.getPath(), LIBRARYNAME, 'Main', 'vwxGUI', 'images', 'search_new.gif') self.ag = wx.animate.GIFAnimationCtrl(self, -1, ag_fname) self.ag.UseBackgroundColour(True) self.ag.Hide() hSizer.Add(self.ag, 0, wx.RESERVE_SPACE_EVEN_IF_HIDDEN) self.vSizer.Add(hSizer, 0, wx.EXPAND|wx.BOTTOM, 3) self.vSizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.BOTTOM, 3) self.searchGauge = wx.Gauge(self, size = (-1, 7)) self.vSizer.Add(self.searchGauge, 0, wx.EXPAND|wx.RESERVE_SPACE_EVEN_IF_HIDDEN) self.vSizer.AddSpacer((-1,15)) hSizer = wx.BoxSizer(wx.HORIZONTAL) header = StaticText(self, -1, 'Family Filter') if SearchSideBar.HEADER_FONT_WEIGHT != wx.FONTWEIGHT_NORMAL: font = header.GetFont() font.SetWeight(SearchSideBar.HEADER_FONT_WEIGHT) header.SetFont(font) hSizer.Add(header) self.ffstate = StaticText(self) hSizer.Add(self.ffstate) self.vSizer.Add(hSizer, 0, wx.EXPAND|wx.BOTTOM, 3) self.vSizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.BOTTOM, 3) self.ffblocked = StaticText(self) self.vSizer.Add(self.ffblocked, 0, wx.EXPAND|wx.LEFT, SearchSideBar.INDENT) self.ffbutton = LinkStaticText(self, '', None) self.ffbutton.Bind(wx.EVT_LEFT_UP, self.toggleFamilyFilter) self.vSizer.Add(self.ffbutton, 0, wx.EXPAND|wx.LEFT, SearchSideBar.INDENT) self.vSizer.AddSpacer((-1,15)) hSizer = wx.BoxSizer(wx.HORIZONTAL) header = StaticText(self, -1, 'Bundling') if SearchSideBar.HEADER_FONT_WEIGHT != wx.FONTWEIGHT_NORMAL: font = header.GetFont() font.SetWeight(SearchSideBar.HEADER_FONT_WEIGHT) header.SetFont(font) hSizer.Add(header) #keep longest text in bundlestatetext, to define bestsize (width) for sidepanel self.bundlestatetext = StaticText(self, -1, ' by Numbers') hSizer.Add(self.bundlestatetext) self.vSizer.Add(hSizer, 0, wx.EXPAND|wx.BOTTOM, 3) self.vSizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.BOTTOM, 3) self.bundleSizer = wx.FlexGridSizer(0, 2, 0, 0) self.SetBundleState(None, reset = True) self.vSizer.Add(self.bundleSizer, 0, wx.EXPAND|wx.LEFT, SearchSideBar.INDENT) self.vSizer.AddSpacer((-1,15)) header = StaticText(self, -1, 'Associated Channels') if SearchSideBar.HEADER_FONT_WEIGHT != wx.FONTWEIGHT_NORMAL: font = header.GetFont() font.SetWeight(SearchSideBar.HEADER_FONT_WEIGHT) header.SetFont(font) self.vSizer.Add(header, 0, wx.EXPAND|wx.BOTTOM, 3) self.vSizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.BOTTOM, 3) self.nochannels = StaticText(self, -1, 'None') self.vSizer.Add(self.nochannels, 0, wx.EXPAND|wx.LEFT, SearchSideBar.INDENT) self.channels = [LinkStaticText(self, '', icon = None) for _ in range(3)] for channel in self.channels: self.vSizer.Add(channel, 0, wx.EXPAND|wx.LEFT, SearchSideBar.INDENT) channel.Bind(wx.EVT_LEFT_UP, self.OnChannel) borderSizer = wx.BoxSizer(wx.VERTICAL) borderSizer.AddSpacer((-1, 3)) borderSizer.Add(self.vSizer, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 7) self.SetSizer(borderSizer) self.SetMinSize((self.GetBestSize()[0], -1)) self.Reset() def SetFF(self, family_filter, nrfiltered): self.family_filter = family_filter self.nrfiltered = nrfiltered self._SetLabels() @forceWxThread def SetMaxResults(self, max, remotekeywords): self.Freeze() self.searchGauge.SetRange(max) self.searchGauge.SetValue(0) self.searchGauge.Show() self.searchState.SetLabel(' in progress') wx.CallLater(10000, self.SetFinished, remotekeywords) self.ag.Play() self.ag.Show() self.Thaw() @forceWxThread def NewResult(self): maxValue = self.searchGauge.GetRange() newValue = min(self.searchGauge.GetValue() + 1, maxValue) if newValue == maxValue: self.SetFinished(None) else: self.searchGauge.SetValue(newValue) def SetFinished(self, keywords): curkeywords, hits, filtered = self.guiutility.torrentsearch_manager.getSearchKeywords() if not keywords or curkeywords == keywords: self.Freeze() self.ag.Stop() self.ag.Hide() self.searchGauge.Hide() self.searchState.SetLabel(' completed') self.Layout() self.Thaw() self.guiutility.frame.searchlist.SetFinished() @forceWxThread def SetAssociatedChannels(self, channels): #channels should be a list, of occurrences, name, permid self.Freeze() self.nochannels.Show(len(channels) == 0) for i in range(len(self.channels)): if i < len(channels): tooltip = "Click to go to %s's Channel."%channels[i][-1].name self.channels[i].SetLabel(channels[i][-1].name) self.channels[i].SetToolTipString(tooltip) self.channels[i].channel = channels[i][-1] else: self.channels[i].SetLabel('') self.channels[i].SetToolTipString('') self.Layout() self.Thaw() def toggleFamilyFilter(self, event): self.parent_list.toggleFamilyFilter() def _SetLabels(self): self.Freeze() if self.family_filter: if self.nrfiltered > 0: if self.nrfiltered > 1: self.ffblocked.SetLabel('%d results blocked'%self.nrfiltered) else: self.ffblocked.SetLabel('1 result blocked') self.vSizer.Detach(self.ffblocked) self.vSizer.Insert(6, self.ffblocked, 0, wx.EXPAND|wx.LEFT, 7) else: self.ffblocked.SetLabel('') self.vSizer.Detach(self.ffblocked) self.vSizer.Insert(7, self.ffblocked) self.ffstate.SetLabel(' is On') self.ffbutton.SetLabel('turn off') else: self.ffstate.SetLabel(' is Off') self.ffbutton.SetLabel('turn on') self.ffblocked.SetLabel('') self.Layout() self.Thaw() def Reset(self): self.SetBundleState(None,refresh=False,reset=True) self.nochannels.Show() self.searchState.SetLabel(' in progress') for channel in self.channels: channel.SetLabel('') channel.SetToolTipString('') def OnRebundle(self, event): curstate = self.bundlestate selectedByMagic = -1 for i, text in enumerate(self.bundletexts): if isinstance(text, LinkStaticText) and text.IsIconShown(): selectedByMagic = self.bundlestates[i] break newstate = event.GetEventObject().action self.SetBundleState(newstate) def db_callback(): keywords = self.torrentsearch_manager.getSearchKeywords()[0] self.bundle_db.storePreference(keywords, newstate) query = ' '.join(keywords) selectedByMagicStr = '' if selectedByMagic != -1: selectedByMagicStr = self.bundlestates_str[selectedByMagic] self.uelog.addEvent(message="Bundler GUI: %s -> %s; %s -> %s; selectedByMagic %s (%s); q=%s" % (curstate, newstate, self.bundlestates_str[curstate], self.bundlestates_str[newstate], selectedByMagic, selectedByMagicStr, query), type = 3) self.guiutility.frame.guiserver.add_task(db_callback) def SetBundleState(self, newstate, refresh=True, reset=False): if newstate is None: auto_guess = self.guiutility.utility.config.Read('use_bundle_magic', "boolean") newstate = Bundler.ALG_OFF # default stored_state = None if not reset: keywords = self.torrentsearch_manager.getSearchKeywords()[0] if keywords != '': try: stored_state = self.bundle_db.getPreference(keywords) except: pass #if db interaction fails, ignore local_override = stored_state is not None if local_override: newstate = stored_state elif auto_guess: newstate = Bundler.ALG_MAGIC self.bundlestate = newstate self.selected_bundle_mode = None self.Freeze() if newstate != Bundler.ALG_OFF: self.bundlestatetext.SetLabel(' by %s' % self.bundlestates_str[newstate]) else: self.bundlestatetext.SetLabel(' is %s' % self.bundlestates_str[newstate]) self.torrentsearch_manager.setBundleMode(newstate, refresh) self.bundleSizer.ShowItems(False) self.bundleSizer.Clear(deleteWindows = True) self.bundletexts = [] self.bundleSizer.Add(StaticText(self, -1, 'Bundle by ')) for i, state in enumerate(self.bundlestates): if newstate == state: text = StaticText(self, -1, self.bundlestates_str[state]) self.bundleSizer.Add(text) self.bundletexts.append(text) else: link = LinkStaticText(self, self.bundlestates_str[state], "wand.png") link.ShowIcon(False) link.SetIconToolTipString('Selected by Magic') link.Bind(wx.EVT_LEFT_UP, self.OnRebundle) link.action = state self.bundleSizer.Add(link) self.bundletexts.append(link) if i+1 < len(self.bundlestates): self.bundleSizer.AddSpacer((1, -1)) self.Layout() self.Thaw() def SetSelectedBundleMode(self, selected_bundle_mode): if self.bundlestate == Bundler.ALG_MAGIC: self.Freeze() self.selected_bundle_mode = selected_bundle_mode index = self.bundlestates.index(selected_bundle_mode) for i in range(len(self.bundletexts)): linkStaticText = self.bundletexts[i] if isinstance(linkStaticText, LinkStaticText): if i == index: if not linkStaticText.IsIconShown(): linkStaticText.ShowIcon(True) wx.CallAfter(linkStaticText.Blink) else: linkStaticText.ShowIcon(False) self.Thaw() def OnChannel(self, event): label = event.GetEventObject() channel_name = label.GetLabel() if channel_name != '': channel = label.channel self.guiutility.showChannel(channel) def SetBackgroundColour(self, colour): wx.Panel.SetBackgroundColour(self, colour) self.ffbutton.SetBackgroundColour(colour) self.ag.SetBackgroundColour(colour) for channel in self.channels: channel.SetBackgroundColour(colour) for sizeritem in self.bundleSizer.GetChildren(): if sizeritem.IsWindow(): child = sizeritem.GetWindow() if isinstance(child, wx.Panel): child.SetBackgroundColour(colour)
class TitleHeader(ListHeader): def __init__(self, parent, parent_list, columns, font_increment=2, fontweight=wx.FONTWEIGHT_BOLD, radius=LIST_RADIUS, spacers=[0, 0]): self.font_increment = font_increment self.fontweight = fontweight ListHeader.__init__(self, parent, parent_list, columns, radius=radius, spacers=spacers) @warnWxThread def AddComponents(self, columns, spacers): vSizer = wx.BoxSizer(wx.VERTICAL) vSizer.AddSpacer((-1, 3)) self.title = StaticText(self) _set_font(self.title, self.font_increment, self.fontweight) titlePanel = self.GetTitlePanel(self) subtitlePanel = self.GetSubTitlePanel(self) righttitlePanel = self.GetRightTitlePanel(self) belowPanel = self.GetBelowPanel(self) if titlePanel: subSizer = wx.BoxSizer(wx.HORIZONTAL) subSizer.Add(self.title) subSizer.Add(titlePanel, 0, wx.LEFT | wx.ALIGN_CENTER_VERTICAL, 3) titlePanel = subSizer else: titlePanel = self.title if subtitlePanel: subSizer = wx.BoxSizer(wx.VERTICAL) subSizer.Add(titlePanel, 0, wx.BOTTOM, 3) subSizer.Add(subtitlePanel) subtitlePanel = subSizer else: subtitlePanel = titlePanel subSizer = wx.BoxSizer(wx.HORIZONTAL) subSizer.Add(subtitlePanel) if righttitlePanel: subSizer.Add(righttitlePanel, 1, wx.LEFT, 3) righttitlePanel = subSizer vSizer.Add(righttitlePanel, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, self.radius + spacers[0]) if belowPanel: vSizer.Add(belowPanel, 1, wx.EXPAND | wx.TOP, 3) vSizer.AddSpacer((-1, 3)) if len(columns) > 0: hSizer = wx.BoxSizer(wx.HORIZONTAL) self.AddColumns(hSizer, self, columns) vSizer.Add(hSizer, 0, wx.EXPAND | wx.LEFT | wx.RIGHT, self.radius + spacers[0]) self.SetSizer(vSizer) def GetTitlePanel(self, parent): pass def GetSubTitlePanel(self, parent): pass def GetRightTitlePanel(self, parent): pass def GetBelowPanel(self, parent): pass @warnWxThread def SetTitle(self, title): if title != self.title.GetLabel(): self.Freeze() self.title.SetLabel(title) self.title.Refresh() self.Layout() self.Thaw() @warnWxThread def SetToolTip(self, tooltip): self.title.SetToolTipString(tooltip)
class NetworkPanel(HomePanel): def __init__(self, parent): HomePanel.__init__(self, parent, 'Network info', LIST_BLUE) self.torrentdb = TorrentDBHandler.getInstance() self.channelcastdb = ChannelCastDBHandler.getInstance() self.remotetorrenthandler = RemoteTorrentHandler.getInstance() self.remotequerymsghandler = RemoteQueryMsgHandler.getInstance() self.incompleteCounter = IncompleteCounter.getInstance() self.timer = None session = Session.get_instance() session.add_observer(self.OnNotify, NTFY_TORRENTS, [NTFY_INSERT]) self.UpdateStats() def CreatePanel(self): panel = wx.Panel(self) panel.SetBackgroundColour(DEFAULT_BACKGROUND) vSizer = wx.BoxSizer(wx.VERTICAL) self.nrTorrents = StaticText(panel) self.nrFiles = StaticText(panel) self.totalSize = StaticText(panel) self.queueSize = StaticText(panel) self.nrChannels = StaticText(panel) self.incomplete = StaticText(panel) self.freeMem = None try: if wx.GetFreeMemory() != -1: self.freeMem = StaticText(panel) except: pass gridSizer = wx.FlexGridSizer(0, 2, 3, 10) gridSizer.AddGrowableCol(1) gridSizer.Add(StaticText(panel, -1, 'Number files')) gridSizer.Add(self.nrFiles, 0, wx.EXPAND) gridSizer.Add(StaticText(panel, -1, 'Total size')) gridSizer.Add(self.totalSize, 0, wx.EXPAND) gridSizer.Add(StaticText(panel, -1, 'Torrents collected')) gridSizer.Add(self.nrTorrents, 0, wx.EXPAND) gridSizer.Add(StaticText(panel, -1, 'Torrents in queue')) gridSizer.Add(self.queueSize, 0, wx.EXPAND) gridSizer.Add(StaticText(panel, -1, 'Channels found')) gridSizer.Add(self.nrChannels, 0, wx.EXPAND) gridSizer.Add( StaticText(panel, -1, 'Incomplete limit (cur, max, history, maxhistory)')) gridSizer.Add(self.incomplete, 0, wx.EXPAND) if self.freeMem: gridSizer.Add(StaticText(panel, -1, 'WX:Free memory')) gridSizer.Add(self.freeMem, 0, wx.EXPAND) vSizer.Add(gridSizer, 0, wx.EXPAND | wx.LEFT, 10) panel.SetSizer(vSizer) return panel def OnNotify(self, subject, type, infohash): try: if self.IsShownOnScreen(): self.UpdateStats() except wx.PyDeadObjectError: pass def UpdateStats(self): def db_callback(): stats = self.torrentdb.getTorrentsStats() nr_channels = self.channelcastdb.getNrChannels() self._UpdateStats(stats, nr_channels) startWorker(None, db_callback, uId="NetworkPanel_UpdateStats") @forceWxThread def _UpdateStats(self, stats, nr_channels): self.nrTorrents.SetLabel(str(stats[0])) if stats[1] is None: self.totalSize.SetLabel(str(stats[1])) else: self.totalSize.SetLabel( self.guiutility.utility.size_format(stats[1])) self.nrFiles.SetLabel(str(stats[2])) self.queueSize.SetLabel('%d (%d sources)' % self.remotetorrenthandler.getQueueSize()) self.nrChannels.SetLabel(str(nr_channels)) self.incomplete.SetLabel(", ".join( map(str, self.incompleteCounter.getstats()))) if self.freeMem: self.freeMem.SetLabel( self.guiutility.utility.size_format(wx.GetFreeMemory())) if self.timer: self.timer.Restart(10000) else: self.timer = wx.CallLater(10000, self.UpdateStats)
def __init__(self, parent, parent_list, size): wx.Panel.__init__(self, parent, size = size) self.SetForegroundColour(parent.GetForegroundColour()) self.guiutility = GUIUtility.getInstance() self.torrentsearch_manager = self.guiutility.torrentsearch_manager self.parent = parent self.parent_list = parent_list self.nrfiltered = 0 self.family_filter = True self.bundlestates = [Bundler.ALG_MAGIC, Bundler.ALG_NAME, Bundler.ALG_NUMBERS, Bundler.ALG_SIZE, Bundler.ALG_OFF] self.bundlestates_str = {Bundler.ALG_NAME: 'Name', Bundler.ALG_NUMBERS: 'Numbers', Bundler.ALG_SIZE: 'Size', Bundler.ALG_MAGIC: 'Magic', Bundler.ALG_OFF: 'Off'} self.bundletexts = [] self.bundle_db = BundlerPreferenceDBHandler.getInstance() self.uelog = UserEventLogDBHandler.getInstance() self.vSizer = wx.BoxSizer(wx.VERTICAL) hSizer = wx.BoxSizer(wx.HORIZONTAL) header = StaticText(self, -1, 'Search') if SearchSideBar.HEADER_FONT_WEIGHT != wx.FONTWEIGHT_NORMAL: font = header.GetFont() font.SetWeight(SearchSideBar.HEADER_FONT_WEIGHT) header.SetFont(font) hSizer.Add(header, 0, wx.ALIGN_CENTER_VERTICAL) self.searchState = StaticText(self) hSizer.Add(self.searchState, 1, wx.ALIGN_CENTER_VERTICAL) ag_fname = os.path.join(self.guiutility.utility.getPath(), LIBRARYNAME, 'Main', 'vwxGUI', 'images', 'search_new.gif') self.ag = wx.animate.GIFAnimationCtrl(self, -1, ag_fname) self.ag.UseBackgroundColour(True) self.ag.Hide() hSizer.Add(self.ag, 0, wx.RESERVE_SPACE_EVEN_IF_HIDDEN) self.vSizer.Add(hSizer, 0, wx.EXPAND|wx.BOTTOM, 3) self.vSizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.BOTTOM, 3) self.searchGauge = wx.Gauge(self, size = (-1, 7)) self.vSizer.Add(self.searchGauge, 0, wx.EXPAND|wx.RESERVE_SPACE_EVEN_IF_HIDDEN) self.vSizer.AddSpacer((-1,15)) hSizer = wx.BoxSizer(wx.HORIZONTAL) header = StaticText(self, -1, 'Family Filter') if SearchSideBar.HEADER_FONT_WEIGHT != wx.FONTWEIGHT_NORMAL: font = header.GetFont() font.SetWeight(SearchSideBar.HEADER_FONT_WEIGHT) header.SetFont(font) hSizer.Add(header) self.ffstate = StaticText(self) hSizer.Add(self.ffstate) self.vSizer.Add(hSizer, 0, wx.EXPAND|wx.BOTTOM, 3) self.vSizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.BOTTOM, 3) self.ffblocked = StaticText(self) self.vSizer.Add(self.ffblocked, 0, wx.EXPAND|wx.LEFT, SearchSideBar.INDENT) self.ffbutton = LinkStaticText(self, '', None) self.ffbutton.Bind(wx.EVT_LEFT_UP, self.toggleFamilyFilter) self.vSizer.Add(self.ffbutton, 0, wx.EXPAND|wx.LEFT, SearchSideBar.INDENT) self.vSizer.AddSpacer((-1,15)) hSizer = wx.BoxSizer(wx.HORIZONTAL) header = StaticText(self, -1, 'Bundling') if SearchSideBar.HEADER_FONT_WEIGHT != wx.FONTWEIGHT_NORMAL: font = header.GetFont() font.SetWeight(SearchSideBar.HEADER_FONT_WEIGHT) header.SetFont(font) hSizer.Add(header) #keep longest text in bundlestatetext, to define bestsize (width) for sidepanel self.bundlestatetext = StaticText(self, -1, ' by Numbers') hSizer.Add(self.bundlestatetext) self.vSizer.Add(hSizer, 0, wx.EXPAND|wx.BOTTOM, 3) self.vSizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.BOTTOM, 3) self.bundleSizer = wx.FlexGridSizer(0, 2, 0, 0) self.SetBundleState(None, reset = True) self.vSizer.Add(self.bundleSizer, 0, wx.EXPAND|wx.LEFT, SearchSideBar.INDENT) self.vSizer.AddSpacer((-1,15)) header = StaticText(self, -1, 'Associated Channels') if SearchSideBar.HEADER_FONT_WEIGHT != wx.FONTWEIGHT_NORMAL: font = header.GetFont() font.SetWeight(SearchSideBar.HEADER_FONT_WEIGHT) header.SetFont(font) self.vSizer.Add(header, 0, wx.EXPAND|wx.BOTTOM, 3) self.vSizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.BOTTOM, 3) self.nochannels = StaticText(self, -1, 'None') self.vSizer.Add(self.nochannels, 0, wx.EXPAND|wx.LEFT, SearchSideBar.INDENT) self.channels = [LinkStaticText(self, '', icon = None) for _ in range(3)] for channel in self.channels: self.vSizer.Add(channel, 0, wx.EXPAND|wx.LEFT, SearchSideBar.INDENT) channel.Bind(wx.EVT_LEFT_UP, self.OnChannel) borderSizer = wx.BoxSizer(wx.VERTICAL) borderSizer.AddSpacer((-1, 3)) borderSizer.Add(self.vSizer, 1, wx.EXPAND|wx.LEFT|wx.RIGHT, 7) self.SetSizer(borderSizer) self.SetMinSize((self.GetBestSize()[0], -1)) self.Reset()
def _PostInit(self): self.guiutility = GUIUtility.getInstance() self.SetBackgroundColour(DEFAULT_BACKGROUND) vSizer = wx.BoxSizer(wx.VERTICAL) vSizer.AddStretchSpacer() text = StaticText(self, -1, self.guiutility.utility.lang.get('title')) font = text.GetFont() font.SetPointSize(font.GetPointSize() * 3) font.SetWeight(wx.FONTWEIGHT_BOLD) text.SetForegroundColour((255, 51, 0)) text.SetFont(font) textSizer = wx.FlexGridSizer(2, 2, 3, 7) if sys.platform == 'darwin': # mac self.searchBox = wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER) else: self.searchBox = TextCtrlAutoComplete( self, entrycallback=self.parent.top_bg.complete, selectcallback=self.parent.top_bg.OnAutoComplete) font = self.searchBox.GetFont() font.SetPointSize(font.GetPointSize() * 2) self.searchBox.SetFont(font) self.searchBox.Bind(wx.EVT_TEXT_ENTER, self.OnSearchKeyDown) if sys.platform == 'darwin': # mac self.searchBox.SetMinSize( (450, self.searchBox.GetTextExtent('T')[1] + 5)) else: self.searchBox.SetMinSize((450, -1)) self.searchBox.SetFocus() textSizer.Add(text, 0, wx.EXPAND | wx.RIGHT, 7) scalingSizer = wx.BoxSizer(wx.HORIZONTAL) scalingSizer.Add(self.searchBox) if sys.platform == 'darwin': # mac searchButton = wx.Button(self, -1, '\n') searchButton.SetLabel('Search') else: searchButton = wx.Button(self, -1, 'Search') searchButton.Bind(wx.EVT_BUTTON, self.OnClick) scalingSizer.Add(searchButton, 0, wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 3) textSizer.Add(scalingSizer, 0, wx.ALIGN_CENTER_VERTICAL) textSizer.AddSpacer((1, 1)) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(StaticText(self, -1, "Take me to ")) channelLink = LinkStaticText(self, "channels", icon=None) channelLink.Bind(wx.EVT_LEFT_UP, self.OnChannels) hSizer.Add(channelLink) hSizer.Add(StaticText(self, -1, " to see what others are sharing")) textSizer.Add(hSizer) vSizer.Add(textSizer, 0, wx.ALIGN_CENTER) vSizer.AddStretchSpacer() buzzpanel = BuzzPanel(self) vSizer.Add(buzzpanel, 0, wx.EXPAND) self.SetSizer(vSizer) self.Layout() self.SearchFocus()
def __init__(self, parent, torrent): canEdit = canComment = False if torrent.hasChannel(): state, iamModerator = torrent.channel.getState() canEdit = state >= ChannelCommunity.CHANNEL_OPEN height = 125 if canEdit: height = 200 wx.Dialog.__init__(self, parent, -1, 'Are you sure you want to remove this torrent?', size=(600, height)) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add( wx.StaticBitmap( self, -1, wx.ArtProvider.GetBitmap(wx.ART_QUESTION, wx.ART_MESSAGE_BOX)), 0, wx.RIGHT, 10) vSizer = wx.BoxSizer(wx.VERTICAL) firstLine = StaticText( self, -1, "Delete '%s' from disk, or just remove them from your downloads?" % torrent.name) _set_font(firstLine, fontweight=wx.FONTWEIGHT_BOLD) firstLine.SetMinSize((1, -1)) vSizer.Add(firstLine, 0, wx.EXPAND | wx.BOTTOM, 3) vSizer.Add( StaticText( self, -1, "Removing from disk will move the selected item to your trash." ), 0, wx.EXPAND) vSizer.AddStretchSpacer() self.newName = None if canEdit: vSizer.Add( StaticText( self, -1, "While we're at it, can you improve the name of this torrent?" ), 0, wx.EXPAND | wx.BOTTOM, 3) self.newName = EditText(self, torrent.name) vSizer.Add(self.newName, 0, wx.EXPAND) vSizer.AddStretchSpacer() bSizer = wx.BoxSizer(wx.HORIZONTAL) bSizer.AddStretchSpacer() bSizer.Add(wx.Button(self, wx.ID_CANCEL), 0, wx.RIGHT, 3) bSizer.Add( wx.Button(self, wx.ID_DEFAULT, 'Only delete from downloads'), 0, wx.RIGHT, 3) bSizer.Add(wx.Button(self, wx.ID_DELETE, 'Also delete from disk')) vSizer.Add(bSizer, 0, wx.ALIGN_RIGHT | wx.TOP, 7) hSizer.Add(vSizer, 1, wx.EXPAND) border = wx.BoxSizer() border.Add(hSizer, 1, wx.ALL | wx.EXPAND, 10) self.Bind(wx.EVT_BUTTON, lambda event: self.EndModal(event.GetId())) self.SetSizer(border) self.Layout() self.CenterOnParent()