Пример #1
0
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()
Пример #2
0
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('')
Пример #3
0
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()
Пример #4
0
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()
Пример #5
0
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)
Пример #6
0
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)
Пример #7
0
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))
Пример #8
0
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()
Пример #9
0
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')
Пример #10
0
    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)
Пример #11
0
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()
Пример #12
0
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)
Пример #13
0
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()
Пример #14
0
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)