Beispiel #1
0
    def __init__(self, parent):
        wx.StatusBar.__init__(self, parent, style=wx.ST_SIZEGRIP)

        # On Linux/OS X the resize handle and icons overlap, therefore we add an extra field.
        # On Windows this field is automatically set to 1 when the wx.ST_SIZEGRIP is set.
        self.SetFieldsCount(7)
        self.SetStatusStyles([wx.SB_FLAT] * 7)
        self.SetStatusWidths([-1, 250, 50, 19, 19, 19, 19])

        self._gui_image_manager = GuiImageManager.getInstance()

        self.guiutility = GUIUtility.getInstance()
        self.utility = self.guiutility.utility
        self.library_manager = self.guiutility.library_manager

        self.ff_checkbox = wx.CheckBox(self, -1, 'Family filter', style=wx.ALIGN_RIGHT)
        self.ff_checkbox.Bind(wx.EVT_CHECKBOX, self.OnCheckbox)
        self.ff_checkbox.SetValue(self.guiutility.getFamilyFilter())

        self.speed_down_icon = self._gui_image_manager.getBitmap(self, u"arrow", self.GetBackgroundColour(), state=0)
        self.speed_down_sbmp = wx.StaticBitmap(self, -1, self.speed_down_icon)
        self.speed_down_sbmp.Bind(wx.EVT_RIGHT_UP, self.OnDownloadPopup)
        self.speed_down = wx.StaticText(self, -1, '')
        self.speed_down.Bind(wx.EVT_RIGHT_UP, self.OnDownloadPopup)
        self.speed_up_icon = self.speed_down_icon.ConvertToImage().Rotate90().Rotate90().ConvertToBitmap()
        self.speed_up_sbmp = wx.StaticBitmap(self, -1, self.speed_up_icon)
        self.speed_up_sbmp.Bind(wx.EVT_RIGHT_UP, self.OnUploadPopup)
        self.speed_up = wx.StaticText(self, -1, '')
        self.speed_up.Bind(wx.EVT_RIGHT_UP, self.OnUploadPopup)

        self.free_space_icon = self._gui_image_manager.getImage(u"drive.png")
        self.free_space_sbmp = wx.StaticBitmap(self, -1, self.free_space_icon)
        self.free_space = wx.StaticText(self, -1, '')

        self.searchConnectionImages = [u"progressbarEmpty.png", u"progressbarFull.png"]
        self.searchConnectionImages = [self._gui_image_manager.getImage(image) for image in self.searchConnectionImages]

        self.activityImages = [u"statusbar_activity.png", u"statusbar_noactivity.png"]
        self.activityImages = [self._gui_image_manager.getImage(image) for image in self.activityImages]

        self.connection = HorizontalGauge(self, self.searchConnectionImages[0], self.searchConnectionImages[1])
        self.activity = wx.StaticBitmap(self, -1, self.activityImages[1])
        self.activity_timer = None
        self.channelconnections = 0

        self.bmp_firewall_warning = self._gui_image_manager.getImage(u"statusbar_warning.png")
        self.bmp_firewall_ok = self._gui_image_manager.getImage(u"statusbar_ok.png")
        self.firewallStatus = ActionButton(self, -1, self.bmp_firewall_warning)
        self.firewallStatus.SetSize((16, 16))
        self.firewallStatus.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
        self.firewallStatus.SetToolTipString('Port status unknown')
        self.firewallStatus.Enable(False)
        self.firewallStatus.SetBitmapDisabled(self.bmp_firewall_warning)

        self.SetTransferSpeeds(0, 0)
        self.Bind(wx.EVT_SIZE, self.OnSize)

        self.library_manager.add_download_state_callback(self.RefreshTransferSpeed)
Beispiel #2
0
class SRstatusbar(wx.StatusBar):

    def __init__(self, parent):
        wx.StatusBar.__init__(self, parent, style=wx.ST_SIZEGRIP)

        # On Linux/OS X the resize handle and icons overlap, therefore we add an extra field.
        # On Windows this field is automatically set to 1 when the wx.ST_SIZEGRIP is set.
        self.SetFieldsCount(7)
        self.SetStatusStyles([wx.SB_FLAT] * 7)
        self.SetStatusWidths([-1, 250, 50, 19, 19, 19, 19])

        self._gui_image_manager = GuiImageManager.getInstance()

        self.guiutility = GUIUtility.getInstance()
        self.utility = self.guiutility.utility
        self.library_manager = self.guiutility.library_manager

        self.ff_checkbox = wx.CheckBox(self, -1, 'Family filter', style=wx.ALIGN_RIGHT)
        self.ff_checkbox.Bind(wx.EVT_CHECKBOX, self.OnCheckbox)
        self.ff_checkbox.SetValue(self.guiutility.getFamilyFilter())

        self.speed_down_icon = self._gui_image_manager.getBitmap(self, u"arrow", self.GetBackgroundColour(), state=0)
        self.speed_down_sbmp = wx.StaticBitmap(self, -1, self.speed_down_icon)
        self.speed_down_sbmp.Bind(wx.EVT_RIGHT_UP, self.OnDownloadPopup)
        self.speed_down = wx.StaticText(self, -1, '')
        self.speed_down.Bind(wx.EVT_RIGHT_UP, self.OnDownloadPopup)
        self.speed_up_icon = self.speed_down_icon.ConvertToImage().Rotate90().Rotate90().ConvertToBitmap()
        self.speed_up_sbmp = wx.StaticBitmap(self, -1, self.speed_up_icon)
        self.speed_up_sbmp.Bind(wx.EVT_RIGHT_UP, self.OnUploadPopup)
        self.speed_up = wx.StaticText(self, -1, '')
        self.speed_up.Bind(wx.EVT_RIGHT_UP, self.OnUploadPopup)

        self.free_space_icon = self._gui_image_manager.getImage(u"drive.png")
        self.free_space_sbmp = wx.StaticBitmap(self, -1, self.free_space_icon)
        self.free_space = wx.StaticText(self, -1, '')

        self.searchConnectionImages = [u"progressbarEmpty.png", u"progressbarFull.png"]
        self.searchConnectionImages = [self._gui_image_manager.getImage(image) for image in self.searchConnectionImages]

        self.activityImages = [u"statusbar_activity.png", u"statusbar_noactivity.png"]
        self.activityImages = [self._gui_image_manager.getImage(image) for image in self.activityImages]

        self.connection = HorizontalGauge(self, self.searchConnectionImages[0], self.searchConnectionImages[1])
        self.activity = wx.StaticBitmap(self, -1, self.activityImages[1])
        self.activity_timer = None
        self.channelconnections = 0

        self.bmp_firewall_warning = self._gui_image_manager.getImage(u"statusbar_warning.png")
        self.bmp_firewall_ok = self._gui_image_manager.getImage(u"statusbar_ok.png")
        self.firewallStatus = ActionButton(self, -1, self.bmp_firewall_warning)
        self.firewallStatus.SetSize((16, 16))
        self.firewallStatus.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
        self.firewallStatus.SetToolTipString('Port status unknown')
        self.firewallStatus.Enable(False)
        self.firewallStatus.SetBitmapDisabled(self.bmp_firewall_warning)

        self.SetTransferSpeeds(0, 0)
        self.Bind(wx.EVT_SIZE, self.OnSize)

        self.library_manager.add_download_state_callback(self.RefreshTransferSpeed)

    @forceWxThread
    def RefreshFreeSpace(self, space):
        if space >= 0:
            space_str = size_format(space, truncate=1)
            space_label = space_str.replace(' ', '')
            space_tooltip = 'You currently have %s of disk space available on your default download location.' % space_str
            self.free_space.SetLabel(space_label)
            self.free_space.SetToolTipString(space_tooltip)
            self.free_space.Show(True)
            self.free_space_sbmp.SetToolTipString(space_tooltip)
            self.free_space_sbmp.Show(True)
        else:
            self.free_space.Show(False)
            self.free_space_sbmp.Show(False)
        self.Reposition()

    def RefreshTransferSpeed(self, dslist, magnetlist):
        if not self:
            return

        total_down, total_up = 0.0, 0.0
        for ds in dslist:
            total_down += ds.get_current_speed(DOWNLOAD)
            total_up += ds.get_current_speed(UPLOAD)
        self.SetTransferSpeeds(total_down, total_up)

    @warnWxThread
    def SetTransferSpeeds(self, down, up):
        self.speed_down.SetLabel(speed_format(down))
        self.speed_up.SetLabel(speed_format(up))
        self.Reposition()

    def SetGlobalMaxSpeed(self, direction, value):
        if direction in [UPLOAD, DOWNLOAD]:
            if direction == UPLOAD:
                self.utility.write_config('maxuploadrate', value)
                self.guiutility.utility.session.set_max_upload_speed(value)
            else:
                self.utility.write_config('maxdownloadrate', value)
                self.guiutility.utility.session.set_max_download_speed(value)

    def GetSpeedChoices(self, value):
        values = round_range(max(0, value)) if value != 0 else range(0, 1000, 100)
        values = [value or -1 for value in values]
        if value != 0 and value not in values:
            values.append(value)
            values.sort()
        values.append(0)
        return [('unlimited' if value == 0 else ('0' if value == -1 else str(value)), value) for value in values]

    def OnDownloadPopup(self, event):
        menu = wx.Menu()
        current = self.utility.read_config('maxdownloadrate')
        value_tuples = self.GetSpeedChoices(current)

        for value_str, value in value_tuples:
            itemid = wx.NewId()
            menu.AppendRadioItem(itemid, value_str)
            menu.Bind(wx.EVT_MENU, lambda x, v=value: self.SetGlobalMaxSpeed(DOWNLOAD, v), id=itemid)
            menu.Check(itemid, current == value)

        self.speed_down.PopupMenu(menu, event.GetPosition())
        menu.Destroy()
        self.speed_down.Layout()

    def OnUploadPopup(self, event):
        menu = wx.Menu()
        current = self.utility.read_config('maxuploadrate')
        value_tuples = self.GetSpeedChoices(current)

        for value_str, value in value_tuples:
            itemid = wx.NewId()
            menu.AppendRadioItem(itemid, value_str)
            menu.Bind(wx.EVT_MENU, lambda x, v=value: self.SetGlobalMaxSpeed(UPLOAD, v), id=itemid)
            menu.Check(itemid, current == value)

        self.speed_up.PopupMenu(menu, event.GetPosition())
        menu.Destroy()
        self.speed_up.Layout()

    def OnCheckbox(self, event):
        checkbox = event.GetEventObject()
        checkbox.Enable(False)
        wx.CallLater(1000, checkbox.Enable, True)

        wx.CallLater(100, self.__toggleFF, event.GetEventObject().GetValue())

    @warnWxThread
    def __toggleFF(self, newvalue):
        if newvalue != self.guiutility.getFamilyFilter():
            self.guiutility.toggleFamilyFilter(newvalue)

    @warnWxThread
    def SetConnections(self, connectionPercentage, totalConnections, channelConnections):
        self.connection.SetPercentage(connectionPercentage)
        self.connection.SetToolTipString('Connected to %d peers' % totalConnections)
        self.channelconnections = channelConnections

    def GetConnections(self):
        return self.connection.GetPercentage()

    def GetChannelConnections(self):
        return self.channelconnections

    @warnWxThread
    def onReachable(self, event=None):
        if not self.guiutility.firewall_restart:
            self.firewallStatus.SetBitmapLabel(self.bmp_firewall_ok)
            self.firewallStatus.SetBitmapDisabled(self.bmp_firewall_ok)
            self.firewallStatus.SetToolTipString('Port is working')

    @warnWxThread
    def IsReachable(self):
        if not self.guiutility.firewall_restart:
            return self.firewallStatus.GetBitmapLabel() == self.bmp_firewall_ok
        return False

    @warnWxThread
    def onActivity(self, msg):
        if self.activity_timer:
            self.activity_timer.Stop()

        def revert():
            if not self:
                return
            self.activity.SetBitmap(self.activityImages[1])
            self.activity.Refresh()

        self.activity.SetBitmap(self.activityImages[0])
        self.activity.Refresh()
        self.activity.SetToolTipString(msg)
        self.activity_timer = wx.CallLater(300, revert)

    def OnSize(self, event):
        self.Reposition()

    def Reposition(self):
        self.Freeze()

        rect = self.GetFieldRect(0)
        self.ff_checkbox.SetPosition((rect.x + 2, rect.y + 2))
        self.ff_checkbox.SetSize((-1, rect.height - 4))

        rect = self.GetFieldRect(1)
        x = rect.x + rect.width - 15
        for control in reversed([self.speed_down_sbmp, self.speed_down, self.speed_up_sbmp, self.speed_up]):
            spacer = 10 if not isinstance(control, wx.StaticBitmap) else 7
            x -= control.GetSize()[0] + spacer
            yAdd = (rect.height - control.GetSize()[1]) / 2
            control.SetPosition((x, rect.y + yAdd))

        rect = self.GetFieldRect(2)
        x = rect.x + rect.width
        for control in [self.free_space, self.free_space_sbmp]:
            size = control.GetSize()
            yAdd = (rect.height - size[1]) / 2
            x -= size[0] + 5
            control.SetPosition((x, rect.y + yAdd))

        rect = self.GetFieldRect(3)
        size = self.connection.GetSize()
        yAdd = (rect.height - size[1]) / 2
        xAdd = (rect.width - size[0]) / 2
        self.connection.SetPosition((rect.x + xAdd, rect.y + yAdd))

        rect = self.GetFieldRect(4)
        size = self.activity.GetSize()
        yAdd = (rect.height - size[1]) / 2
        xAdd = (rect.width - size[0]) / 2
        self.activity.SetPosition((rect.x + xAdd, rect.y + yAdd))

        rect = self.GetFieldRect(5)
        size = self.firewallStatus.GetSize()
        yAdd = (rect.height - size[1]) / 2
        xAdd = (rect.width - size[0]) / 2
        self.firewallStatus.SetPosition((rect.x + xAdd, rect.y + yAdd))

        self.sizeChanged = False
        self.Thaw()
Beispiel #3
0
class TopSearchPanel(FancyPanel):
    def __init__(self, parent):
        self._logger = logging.getLogger(self.__class__.__name__)

        self._logger.debug("TopSearchPanel: __init__")

        self.loaded_bitmap = None

        self.guiutility = GUIUtility.getInstance()
        self.utility = self.guiutility.utility
        self.installdir = self.utility.getPath()
        self.tdb = self.utility.session.open_dbhandler(NTFY_TORRENTS)
        self.collectedTorrents = {}

        FancyPanel.__init__(self, parent, border=wx.BOTTOM)
        self.SetBorderColour(SEPARATOR_GREY)
        self.SetBackgroundColour(GRADIENT_LGREY, GRADIENT_DGREY)
        self.AddComponents()
        self.Bind(wx.EVT_SIZE, self.OnResize)

    def AddComponents(self):
        self.SetForegroundColour(
            wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT))

        self._logger.debug("TopSearchPanel: OnCreate")

        gui_image_manager = GuiImageManager.getInstance()

        # TODO martijn: on OS X, the wx.SearchCtrl element is bugged (doesn't show a placeholder unless focussed).
        # for now, we replaced the occurrences of wx.SearchCtrl with wx.TextCtrl elements.
        if sys.platform == 'darwin':
            self.searchField = wx.TextCtrl(self, -1, style=wx.TE_PROCESS_ENTER)
            self.searchField.Bind(wx.EVT_TEXT_ENTER, self.OnSearchKeyDown)
            self.searchField.SetHint('Search Files or Channels')
            self.searchField.SetMinSize((400, 22))
        else:
            self.searchFieldPanel = FancyPanel(self, radius=5, border=wx.ALL)
            self.searchFieldPanel.SetBorderColour(SEPARATOR_GREY,
                                                  highlight=TRIBLER_RED)
            self.searchField = TextCtrlAutoComplete(
                self.searchFieldPanel,
                style=wx.NO_BORDER,
                entrycallback=self.complete)
            # Since we have set the style to wx.NO_BORDER, the default height will be
            # too large. Therefore, we need to set the correct height.
            _, height = self.GetTextExtent("Gg")
            self.searchField.SetMinSize((-1, height))
            self.searchFieldPanel.SetMinSize((400, 25))
            self.searchFieldPanel.SetBackgroundColour(
                self.searchField.GetBackgroundColour())
            self.searchField.Bind(wx.EVT_KILL_FOCUS,
                                  self.searchFieldPanel.OnKillFocus)
            self.searchField.Bind(wx.EVT_TEXT_ENTER, self.OnSearchKeyDown)

        self.go = ProgressButton(self, -1)
        self.go.SetMinSize((50, 25))
        self.go.Bind(wx.EVT_LEFT_UP, self.OnSearchKeyDown)

        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.SetBackgroundColour(wx.Colour(244, 244, 244))
        self.ag.Hide()

        download_bmp = gui_image_manager.getImage(u"download.png")
        self.download_btn = ActionButton(self, -1, download_bmp)
        self.download_btn.Enable(False)
        upload_bmp = gui_image_manager.getImage(u"upload.png")
        self.upload_btn = ActionButton(self, -1, upload_bmp)
        self.upload_btn.Enable(False)
        stop_bmp = gui_image_manager.getImage(u"pause.png")
        self.stop_btn = ActionButton(self, -1, stop_bmp)
        self.stop_btn.Enable(False)
        delete_bmp = gui_image_manager.getImage(u"delete.png")
        self.delete_btn = ActionButton(self, -1, delete_bmp)
        self.delete_btn.Enable(False)
        play_bmp = gui_image_manager.getImage(u"play.png")
        self.play_btn = ActionButton(self, -1, play_bmp)
        self.play_btn.Enable(False)
        add_bmp = gui_image_manager.getImage(u"add.png")
        self.add_btn = ActionButton(self, -1, add_bmp)
        self.SetButtonHandler(self.add_btn, self.OnAdd,
                              'Download an external torrent.')
        settings_bmp = gui_image_manager.getImage(u"settings.png")
        self.settings_btn = ActionButton(self, -1, settings_bmp)
        self.SetButtonHandler(self.settings_btn, self.OnSettings,
                              'Change settings.')

        mainSizer = wx.BoxSizer(wx.HORIZONTAL)

        if sys.platform != 'darwin':
            vSizer = wx.BoxSizer(wx.VERTICAL)
            vSizer.AddStretchSpacer()
            vSizer.Add(
                self.searchField, 0, wx.EXPAND
                | wx.RESERVE_SPACE_EVEN_IF_HIDDEN | wx.LEFT | wx.RIGHT, 5)
            vSizer.AddStretchSpacer()
            self.searchFieldPanel.SetSizer(vSizer)
            vSizer.Layout()

        # Add searchbox etc.
        self.searchSizer = wx.BoxSizer(wx.VERTICAL)
        searchBoxSizer = wx.BoxSizer(wx.HORIZONTAL)
        if sys.platform == 'darwin':
            searchBoxSizer.Add(self.searchField, 1,
                               wx.CENTER | wx.RESERVE_SPACE_EVEN_IF_HIDDEN)
        else:
            searchBoxSizer.Add(self.searchFieldPanel, 1,
                               wx.CENTER | wx.RESERVE_SPACE_EVEN_IF_HIDDEN)
        searchBoxSizer.Add(self.go, 0, wx.CENTER | wx.LEFT
                           | wx.RESERVE_SPACE_EVEN_IF_HIDDEN,
                           5)  # add searchbutton
        searchBoxSizer.Add(self.ag, 0, wx.CENTER | wx.LEFT
                           | wx.RESERVE_SPACE_EVEN_IF_HIDDEN,
                           5)  # add animation
        self.searchSizer.Add(searchBoxSizer, 1, wx.EXPAND)
        # finished searchSizer, add to mainSizer
        mainSizer.Add(self.searchSizer, 0, wx.EXPAND | wx.LEFT, 10)
        mainSizer.AddSpacer((40, 0))

        # add buttons
        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        buttonSizer.Add(self.download_btn, 0, wx.CENTER | wx.RIGHT, 5)
        buttonSizer.Add(self.upload_btn, 0, wx.CENTER | wx.RIGHT, 5)
        buttonSizer.Add(self.stop_btn, 0, wx.CENTER | wx.RIGHT, 5)
        buttonSizer.Add(self.delete_btn, 0, wx.CENTER | wx.RIGHT, 5)
        buttonSizer.Add(self.play_btn, 0, wx.CENTER | wx.RIGHT, 5)
        buttonSizer.AddSpacer((35, 0))
        buttonSizer.AddStretchSpacer()
        buttonSizer.Add(self.add_btn, 0, wx.CENTER | wx.RIGHT, 5)
        buttonSizer.Add(self.settings_btn, 0, wx.CENTER | wx.RIGHT, 5)
        mainSizer.Add(buttonSizer, 1, wx.EXPAND)

        self.SetSizer(mainSizer)
        self.Layout()

    def OnResize(self, event):
        self.Refresh()
        event.Skip()

    def OnSearchKeyDown(self, event=None):
        if self.go.IsEnabled():
            self._logger.debug("TopSearchPanel: OnSearchKeyDown")

            if getattr(self.searchField, 'ShowDropDown', False):
                self.searchField.ShowDropDown(False)

            self.guiutility.dosearch()

            self.go.Enable(False)
            wx.CallLater(2500, self.go.Enable, True)

    def OnSettings(self, event):
        self.guiutility.ShowPage('settings')

    def OnAdd(self, event):
        dlg = AddTorrent(None, self.guiutility.frame)
        dlg.CenterOnParent()
        dlg.ShowModal()
        dlg.Destroy()

    def OnStats(self, event):
        self.guiutility.ShowPage('stats')

    def StartSearch(self):
        if getattr(self.searchField, 'ShowDropDown', False):
            self.searchField.ShowDropDown(False)
            self.guiutility.frame.searchlist.ResetBottomWindow()

        self.Freeze()
        self.go.SetValue(0)
        self.guiutility.frame.top_bg.ag.Play()
        self.guiutility.frame.top_bg.ag.Show()
        self.Thaw()

    def ShowSearching(self, max):
        if not self or not self.go:
            return
        self.go.SetRange(max + 16)

        cancelWorker(u"FakeResult")
        startWorker(None,
                    self.FakeResult,
                    uId=u"FakeResult",
                    delay=0.25,
                    workerType="ThreadPool")

    @forceWxThread
    def FakeResult(self, times=1):
        if not self:
            return

        newValue = min(self.go.GetValue() + 1, self.go.GetRange())
        if times < 16:
            self.go.SetValue(newValue)

            startWorker(None,
                        self.FakeResult,
                        wargs=(times + 1, ),
                        uId=u"FakeResult",
                        delay=0.25,
                        workerType="ThreadPool")

    def NewResult(self):
        maxValue = self.go.GetRange()
        newValue = min(self.go.GetValue() + 1, maxValue)
        self.guiutility.frame.top_bg.go.SetValue(newValue)

        if newValue == maxValue:
            return True
        return False

    def SetFinished(self):
        self.Freeze()
        self.ag.Stop()
        self.ag.Hide()
        self.go.SetValue(self.go.GetRange())
        self.Layout()
        self.Thaw()

    def complete(self, term):
        ignore_list = ["http://", "https://", "magnet:"]
        for ignore in ignore_list:
            if term.startswith(ignore):
                return []
        """autocompletes term."""
        if len(term) > 1:
            return self.tdb.getAutoCompleteTerms(term, max_terms=7)
        return []

    def SearchFocus(self):
        if self.guiutility.guiPage == 'home':
            if getattr(self.GetParent(), 'home', False):
                self.GetParent().home.SearchFocus()
        else:
            self.searchField.SetFocus()
            self.searchField.SelectAll()

    def AddCollectedTorrent(self, coltorrent):
        self.collectedTorrents[coltorrent.infohash] = coltorrent
        self.TorrentsChanged()

    def GetSelectedTorrents(self):
        torrents = None

        page = self.guiutility.guiPage
        if page in [
                'search_results', 'selectedchannel', 'playlist', 'my_files'
        ]:
            list = self.guiutility.GetSelectedPage()
            items = list.GetExpandedItems()
            torrents = [
                item[1].original_data for item in items
                if isinstance(item[1].original_data, Torrent)
                or isinstance(item[1].original_data, CollectedTorrent)
            ]
        return torrents

    def TorrentsChanged(self):
        self.RefreshTorrents(self.GetSelectedTorrents())

    def RefreshTorrents(self, torrents):
        inDownloads = self.guiutility.guiPage == 'my_files'

        if torrents:
            isMultiple = len(torrents) > 1
            usedCollectedTorrents = set()
            # we have 7 different states, able to resume seeding, resume downloading,
            # download, stop seeding, stop downloading, delete, or play
            # TODO(emilon): This is so ugly. At least we should use a named tuple.
            states = [0, 0, 0, 0, 0, 0, 0]
            for torrent in torrents:
                if 'stopped' in torrent.state:
                    if 'completed' in torrent.state:
                        states[0] += 1
                    else:
                        states[1] += 1

                elif not torrent.state:
                    states[2] += 1

                if 'active' in torrent.state:
                    if 'completed' in torrent.state:
                        states[3] += 1
                    else:
                        states[4] += 1

                if torrent.state or inDownloads:
                    states[5] += 1

                if "metadata" not in torrent.state and torrent.infohash in self.collectedTorrents:
                    coltorrent = self.collectedTorrents[torrent.infohash]
                    if coltorrent.isPlayable():
                        states[6] += 1

                    usedCollectedTorrents.add(torrent.infohash)
                else:
                    # If the torrent isn't collected we assume its playable and let the core cancel the VOD if it isn't.
                    states[6] += 1

            enableDownload = states[1] + states[2]
            if enableDownload:
                if isMultiple:
                    self.SetButtonHandler(
                        self.download_btn, self.OnDownload,
                        'Resume downloading %d torrent(s).' % enableDownload)
                elif states[1]:
                    self.SetButtonHandler(self.download_btn, self.OnResume,
                                          'Resume downloading this torrent.')
                else:
                    self.SetButtonHandler(self.download_btn, self.OnDownload,
                                          'Start downloading this torrent.')
            else:
                self.SetButtonHandler(self.download_btn, None)

            enableUpload = states[0]
            if enableUpload:
                if isMultiple:
                    self.SetButtonHandler(
                        self.upload_btn, self.OnUpload,
                        'Resume seeding %d torrent(s).' % enableUpload)
                else:
                    self.SetButtonHandler(self.upload_btn, self.OnUpload,
                                          'Resume seeding this torrent.')
            else:
                self.SetButtonHandler(self.upload_btn, None)

            enableStop = states[3] + states[4]
            if enableStop:
                if isMultiple:
                    self.SetButtonHandler(self.stop_btn, self.OnStop,
                                          'Stop %d torrent(s).' % enableStop)
                elif states[3]:
                    self.SetButtonHandler(self.stop_btn, self.OnStop,
                                          'Stop seeding this torrent.')
                else:
                    self.SetButtonHandler(self.stop_btn, self.OnStop,
                                          'Stop downloading this torrent.')
            else:
                self.SetButtonHandler(self.stop_btn, None)

            if states[5] > 1:
                self.SetButtonHandler(self.delete_btn, self.OnDelete,
                                      'Delete %d torrent(s).' % states[5])
            elif states[5]:
                self.SetButtonHandler(self.delete_btn, self.OnDelete,
                                      'Delete this torrent.')
            else:
                self.SetButtonHandler(self.delete_btn, None)

            if isMultiple:
                self.SetButtonHandler(
                    self.play_btn, self.OnPlay,
                    'Start playing one of the selected torrents.')
            elif states[6]:
                self.SetButtonHandler(self.play_btn, self.OnPlay,
                                      'Start playing this torrent.')
            else:
                self.SetButtonHandler(self.play_btn, None)

            for infohash in self.collectedTorrents.keys():
                if infohash not in usedCollectedTorrents:
                    del self.collectedTorrents[infohash]
        else:
            self.ClearButtonHandlers()

    def SetButtonHandler(self, button, handler=None, tooltip=None):
        button.Enable(bool(handler))
        if handler:
            button.Bind(wx.EVT_LEFT_UP, handler)
            if tooltip and sys.platform != 'darwin':
                button.SetToolTipString(tooltip)
            else:
                button.SetToolTip(None)
        else:
            button.SetToolTip(None)

    def ClearButtonHandlers(self):
        self.SetButtonHandler(self.download_btn, None)
        self.SetButtonHandler(self.upload_btn, None)
        self.SetButtonHandler(self.play_btn, None)
        self.SetButtonHandler(self.stop_btn, None)
        self.SetButtonHandler(self.delete_btn, None)

    def OnDownload(self, event=None, torrents=None):
        refresh_library = False
        torrents = torrents if torrents is not None else self.GetSelectedTorrents(
        )
        for torrent in torrents:
            if 'stopped' in torrent.state:
                self.guiutility.library_manager.resumeTorrent(torrent)
            else:
                if self.guiutility.frame.selectedchannellist.IsShownOnScreen():
                    self.guiutility.frame.selectedchannellist.StartDownload(
                        torrent)
                else:
                    self.guiutility.torrentsearch_manager.downloadTorrent(
                        torrent)

                refresh_library = True

        if event:
            button = event.GetEventObject()
            button.Enable(False)
            wx.CallLater(3000, button.Enable, True)

        if refresh_library:
            wx.CallLater(
                1000, self.guiutility.frame.librarylist.do_or_schedule_refresh,
                True)

    def OnUpload(self, event):
        for torrent in self.GetSelectedTorrents():
            if 'completed' in torrent.state:
                self.guiutility.library_manager.resumeTorrent(torrent)
        if event:
            button = event.GetEventObject()
            button.Enable(False)

    def OnPlay(self, event):
        # Select the first playable torrent or not collected torrent. Return if none can be found
        torrent = None
        for t in self.GetSelectedTorrents():
            if t.infohash in self.collectedTorrents:
                coltor = self.collectedTorrents[t.infohash]
                if coltor.isPlayable():
                    torrent = coltor
                    break
            else:
                torrent = t
                break

        if not torrent:
            return

        self.guiutility.library_manager.playTorrent(torrent.infohash)

        button = event.GetEventObject()
        button.Enable(False)

    def OnResume(self, event=None):
        for torrent in self.GetSelectedTorrents():
            self.guiutility.library_manager.resumeTorrent(torrent)
        if event:
            button = event.GetEventObject()
            button.Enable(False)

    def OnStop(self, event=None):
        for torrent in self.GetSelectedTorrents():
            self.guiutility.library_manager.stopTorrent(torrent.infohash)
        if event:
            button = event.GetEventObject()
            button.Enable(False)

    def OnDelete(self, event=None, silent=False, delete=False):
        torrents = self.GetSelectedTorrents()
        if not silent:
            dlg = RemoveTorrent(None, torrents)
            button_id = dlg.ShowModal()
        else:
            button_id = wx.ID_DELETE if delete else wx.ID_DEFAULT

        refresh_library = False
        if button_id in [wx.ID_DEFAULT, wx.ID_DELETE]:
            for torrent in torrents:
                self.guiutility.library_manager.deleteTorrent(
                    torrent, button_id == wx.ID_DELETE)
                refresh_library = True

        if not silent:
            if dlg.newName:
                if dlg.newName.IsChanged():
                    dlg2 = wx.MessageDialog(
                        None,
                        'Do you want to save your changes made to this torrent?',
                        'Save changes?',
                        wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
                    if dlg2.ShowModal() == wx.ID_YES:
                        self.guiutility.channelsearch_manager.modifyTorrent(
                            torrent.channel.id, torrent.channeltorrent_id,
                            {'name': dlg.newName.GetValue()})
                    dlg2.Destroy()
            dlg.Destroy()

        if refresh_library:
            wx.CallLater(
                1000, self.guiutility.frame.librarylist.do_or_schedule_refresh,
                True)
Beispiel #4
0
    def AddComponents(self):
        self.SetForegroundColour(
            wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT))

        self._logger.debug("TopSearchPanel: OnCreate")

        gui_image_manager = GuiImageManager.getInstance()

        # TODO martijn: on OS X, the wx.SearchCtrl element is bugged (doesn't show a placeholder unless focussed).
        # for now, we replaced the occurrences of wx.SearchCtrl with wx.TextCtrl elements.
        if sys.platform == 'darwin':
            self.searchField = wx.TextCtrl(self, -1, style=wx.TE_PROCESS_ENTER)
            self.searchField.Bind(wx.EVT_TEXT_ENTER, self.OnSearchKeyDown)
            self.searchField.SetHint('Search Files or Channels')
            self.searchField.SetMinSize((400, 22))
        else:
            self.searchFieldPanel = FancyPanel(self, radius=5, border=wx.ALL)
            self.searchFieldPanel.SetBorderColour(SEPARATOR_GREY,
                                                  highlight=TRIBLER_RED)
            self.searchField = TextCtrlAutoComplete(
                self.searchFieldPanel,
                style=wx.NO_BORDER,
                entrycallback=self.complete)
            # Since we have set the style to wx.NO_BORDER, the default height will be
            # too large. Therefore, we need to set the correct height.
            _, height = self.GetTextExtent("Gg")
            self.searchField.SetMinSize((-1, height))
            self.searchFieldPanel.SetMinSize((400, 25))
            self.searchFieldPanel.SetBackgroundColour(
                self.searchField.GetBackgroundColour())
            self.searchField.Bind(wx.EVT_KILL_FOCUS,
                                  self.searchFieldPanel.OnKillFocus)
            self.searchField.Bind(wx.EVT_TEXT_ENTER, self.OnSearchKeyDown)

        self.go = ProgressButton(self, -1)
        self.go.SetMinSize((50, 25))
        self.go.Bind(wx.EVT_LEFT_UP, self.OnSearchKeyDown)

        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.SetBackgroundColour(wx.Colour(244, 244, 244))
        self.ag.Hide()

        download_bmp = gui_image_manager.getImage(u"download.png")
        self.download_btn = ActionButton(self, -1, download_bmp)
        self.download_btn.Enable(False)
        upload_bmp = gui_image_manager.getImage(u"upload.png")
        self.upload_btn = ActionButton(self, -1, upload_bmp)
        self.upload_btn.Enable(False)
        stop_bmp = gui_image_manager.getImage(u"pause.png")
        self.stop_btn = ActionButton(self, -1, stop_bmp)
        self.stop_btn.Enable(False)
        delete_bmp = gui_image_manager.getImage(u"delete.png")
        self.delete_btn = ActionButton(self, -1, delete_bmp)
        self.delete_btn.Enable(False)
        play_bmp = gui_image_manager.getImage(u"play.png")
        self.play_btn = ActionButton(self, -1, play_bmp)
        self.play_btn.Enable(False)
        add_bmp = gui_image_manager.getImage(u"add.png")
        self.add_btn = ActionButton(self, -1, add_bmp)
        self.SetButtonHandler(self.add_btn, self.OnAdd,
                              'Download an external torrent.')
        settings_bmp = gui_image_manager.getImage(u"settings.png")
        self.settings_btn = ActionButton(self, -1, settings_bmp)
        self.SetButtonHandler(self.settings_btn, self.OnSettings,
                              'Change settings.')

        mainSizer = wx.BoxSizer(wx.HORIZONTAL)

        if sys.platform != 'darwin':
            vSizer = wx.BoxSizer(wx.VERTICAL)
            vSizer.AddStretchSpacer()
            vSizer.Add(
                self.searchField, 0, wx.EXPAND
                | wx.RESERVE_SPACE_EVEN_IF_HIDDEN | wx.LEFT | wx.RIGHT, 5)
            vSizer.AddStretchSpacer()
            self.searchFieldPanel.SetSizer(vSizer)
            vSizer.Layout()

        # Add searchbox etc.
        self.searchSizer = wx.BoxSizer(wx.VERTICAL)
        searchBoxSizer = wx.BoxSizer(wx.HORIZONTAL)
        if sys.platform == 'darwin':
            searchBoxSizer.Add(self.searchField, 1,
                               wx.CENTER | wx.RESERVE_SPACE_EVEN_IF_HIDDEN)
        else:
            searchBoxSizer.Add(self.searchFieldPanel, 1,
                               wx.CENTER | wx.RESERVE_SPACE_EVEN_IF_HIDDEN)
        searchBoxSizer.Add(self.go, 0, wx.CENTER | wx.LEFT
                           | wx.RESERVE_SPACE_EVEN_IF_HIDDEN,
                           5)  # add searchbutton
        searchBoxSizer.Add(self.ag, 0, wx.CENTER | wx.LEFT
                           | wx.RESERVE_SPACE_EVEN_IF_HIDDEN,
                           5)  # add animation
        self.searchSizer.Add(searchBoxSizer, 1, wx.EXPAND)
        # finished searchSizer, add to mainSizer
        mainSizer.Add(self.searchSizer, 0, wx.EXPAND | wx.LEFT, 10)
        mainSizer.AddSpacer((40, 0))

        # add buttons
        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        buttonSizer.Add(self.download_btn, 0, wx.CENTER | wx.RIGHT, 5)
        buttonSizer.Add(self.upload_btn, 0, wx.CENTER | wx.RIGHT, 5)
        buttonSizer.Add(self.stop_btn, 0, wx.CENTER | wx.RIGHT, 5)
        buttonSizer.Add(self.delete_btn, 0, wx.CENTER | wx.RIGHT, 5)
        buttonSizer.Add(self.play_btn, 0, wx.CENTER | wx.RIGHT, 5)
        buttonSizer.AddSpacer((35, 0))
        buttonSizer.AddStretchSpacer()
        buttonSizer.Add(self.add_btn, 0, wx.CENTER | wx.RIGHT, 5)
        buttonSizer.Add(self.settings_btn, 0, wx.CENTER | wx.RIGHT, 5)
        mainSizer.Add(buttonSizer, 1, wx.EXPAND)

        self.SetSizer(mainSizer)
        self.Layout()
Beispiel #5
0
class EmbeddedPlayerPanel(wx.Panel):
    """
    The Embedded Player consists of a VLCWindow and the media controls such
    as Play/Pause buttons and Volume Control.
    """

    VIDEO_SIZE = (320, 240)

    def __init__(self, parent, utility, vlcwrap, bg):
        wx.Panel.__init__(self, parent, -1)

        self.utility = utility
        self.guiutility = utility.guiUtility
        self.parent = parent
        self.SetBackgroundColour(DEFAULT_BACKGROUND)

        self.volume = 0.48
        self.oldvolume = 0.48
        self.estduration = None
        self.fullscreenwindow = None
        self.download = None
        self.update = True
        self.timeoffset = None

        vSizer = wx.BoxSizer(wx.VERTICAL)

        self.vlcwrap = vlcwrap

        if vlcwrap:
            self.vlcwin = VLCWindow(self, vlcwrap)
            self.vlcwin.SetMinSize(EmbeddedPlayerPanel.VIDEO_SIZE)
            vSizer.Add(self.vlcwin, 1, wx.EXPAND, 0)

            self.logowin = LogoWindow(self)
            self.logowin.SetMinSize(EmbeddedPlayerPanel.VIDEO_SIZE)
            vSizer.Add(self.logowin, 1, wx.EXPAND, 0)

            self.ctrlpanel = FancyPanel(self, border=wx.TOP)
            self.ctrlpanel.SetMinSize((-1, 30))
            self.ctrlpanel.SetBorderColour(SEPARATOR_GREY)
            self.ctrlpanel.SetBackgroundColour(GRADIENT_LGREY, GRADIENT_DGREY)

            self.ctrlsizer = wx.BoxSizer(wx.HORIZONTAL)

            self.slider = VideoSlider(self.ctrlpanel)
            self.slider.Enable(False)
            self.timeposition = TransparentText(self.ctrlpanel, -1, "--:-- / --:--")

            self.bmp_muted = wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_muted.png"))
            self.bmp_unmuted = wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_unmuted.png"))
            self.mute = ActionButton(self.ctrlpanel, -1, self.bmp_unmuted)
            self.mute.Bind(wx.EVT_LEFT_UP, self.MuteClicked)

            self.bmp_pause = wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_pause.png"))
            self.bmp_play = wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_play.png"))
            self.ppbtn = ActionButton(self.ctrlpanel, -1, self.bmp_play)
            self.ppbtn.Bind(wx.EVT_LEFT_UP, self.PlayPause)
            self.ppbtn.Enable(False)

            self.sbtn = ActionButton(self.ctrlpanel, -1, wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_stop.png")))
            self.sbtn.Bind(wx.EVT_LEFT_UP, self.OnStop)
            self.sbtn.Enable(False)

            self.volctrl = VideoVolume(self.ctrlpanel, -1)
            self.volctrl.SetVolumeHandler(self.OnVolumeChanged)
            self.volctrl.SetValue(self.volume)
            self.volctrl.SetMinSize((30, 17))

            self.fsbtn = ActionButton(self.ctrlpanel, -1, wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_fullscreen.png")))
            self.fsbtn.Bind(wx.EVT_LEFT_UP, self.FullScreen)
            self.fsbtn.Enable(False)

            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.ppbtn, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.sbtn, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.slider, 1, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
            self.ctrlsizer.Add(self.timeposition, 0, wx.ALIGN_CENTER_VERTICAL)
            self.ctrlsizer.AddSpacer((10, -1))

            self.ctrlsizer.Add(self.mute, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((5, -1))
            self.ctrlsizer.Add(self.volctrl, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.fsbtn, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((10, -1))

            self.ctrlpanel.SetSizer(self.ctrlsizer)

            vSizer.Add(self.ctrlpanel, 0, wx.ALIGN_BOTTOM | wx.EXPAND)

        self.SetSizer(vSizer)

        self.playtimer = None
        self.timer = None

        if self.vlcwrap:
            self.SetMinSize((EmbeddedPlayerPanel.VIDEO_SIZE[0], -1))
            self.vlcwin.Show(True)
            self.logowin.Show(False)
            self.ctrlsizer.ShowItems(True)
            self.guiutility.frame.Layout()

    def OnVolumeChanged(self, volume):
        if self.mute.GetBitmapLabel() == self.bmp_muted:  # unmute
            self.mute.SetBitmapLabel(self.bmp_unmuted, recreate=True)
        self.volume = volume
        self.oldvolume = self.volume
        self.SetVolume(self.volume)

    def MuteClicked(self, event):
        if self.mute.GetBitmapLabel() == self.bmp_muted:
            self.volume = self.oldvolume
        else:
            self.volume = 0

        self.volctrl.SetValue(self.volume)
        self.SetVolume(self.volume)
        self.mute.SetBitmapLabel(self.bmp_unmuted if self.mute.GetBitmapLabel() == self.bmp_muted else self.bmp_muted, recreate=True)

    @warnWxThread
    def Load(self, url, streaminfo=None):
        if DEBUG:
            print >> sys.stderr, "embedplay: Load:", url, streaminfo, currentThread().getName()

        if streaminfo is not None:
            self.estduration = streaminfo.get('estduration', None)
            self.download = VideoPlayer.getInstance().get_vod_download()

        # 19/02/10 Boudewijn: no self.slider when self.vlcwrap is None
        # 26/05/09 Boudewijn: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            self.slider.Enable(True)

            # Arno, 2009-02-17: If we don't do this VLC gets the wrong playlist somehow
            self.vlcwrap.stop()
            self.vlcwrap.playlist_clear()
            self.vlcwrap.load(url, streaminfo=streaminfo)

            # Enable update of progress slider
            wx.CallAfter(self.slider.SetValue, 0)
            if self.timer is None:
                self.timer = wx.Timer(self)
                self.Bind(wx.EVT_TIMER, self.UpdateSlider)
            self.timer.Start(500)

        self.fsbtn.Enable(True)
        self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True)
        self.ppbtn.Enable(True)
        self.sbtn.Enable(True)

    def StartPlay(self):
        """ Start playing the new item after VLC has stopped playing the old one """
        if DEBUG:
            print >> sys.stderr, "embedplay: PlayWhenStopped"

        self.playtimer = DelayTimer(self)

    @warnWxThread
    def Play(self, evt=None):
        if DEBUG:
            print >> sys.stderr, "embedplay: Play pressed"

        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            if self.GetState() != MEDIASTATE_PLAYING:
                self.HideLoading()
                self.vlcwrap.start()
                self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True)
                self.ppbtn.Enable(True)
            elif DEBUG:
                print >> sys.stderr, "embedplay: Play pressed, already playing"

    @warnWxThread
    def Pause(self, evt=None, gui_vod_event=False):
        if DEBUG:
            print >> sys.stderr, "embedplay: Pause pressed"

        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            if self.GetState() == MEDIASTATE_PLAYING:
                self.vlcwrap.pause()
                self.ppbtn.SetBitmapLabel(self.bmp_play, recreate=True)
                if gui_vod_event:
                    self.ppbtn.Enable(False)
                    self.ShowLoading()
            elif DEBUG:
                print >> sys.stderr, "embedplay: Pause pressed, not playing"

    @warnWxThread
    def Resume(self, evt=None):
        if DEBUG:
            print >> sys.stderr, "embedplay: Resume pressed"

        if self.vlcwrap:
            if self.GetState() != MEDIASTATE_PLAYING:
                self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True)
                self.ppbtn.Enable(True)
                self.HideLoading()
                self.vlcwrap.resume()

    @warnWxThread
    def PlayPause(self, evt=None):
        if DEBUG:
            print >> sys.stderr, "embedplay: PlayPause pressed"

        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            if self.GetState() in [MEDIASTATE_ENDED, MEDIASTATE_STOPPED]:
                # Ensures that the related download also starts
                self.guiutility.library_manager.startLastVODTorrent()
            else:
                self.vlcwrap.resume()
                self.ppbtn.SetBitmapLabel(self.bmp_play if self.ppbtn.GetBitmapLabel() == self.bmp_pause else self.bmp_pause, recreate=True)
                self.ppbtn.Enable(True)

    @warnWxThread
    def Seek(self, evt=None):
        if DEBUG:
            print >> sys.stderr, "embedplay: Seek"

        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True)
            self.ppbtn.Enable(not bool(self.download))
            position = self.slider.GetValue()
            self.update = False

            try:
                if self.download:
                    self.download.pause_vod()
                    self.download.vod_seekpos = None
                    self.ShowLoading()
                self.vlcwrap.set_media_position_relative(position, self.GetState() in [MEDIASTATE_ENDED, MEDIASTATE_STOPPED])

                length = self.vlcwrap.get_stream_information_length()
                length = length / 1000 if length > 0 else (self.estduration or (self.download and self.download.get_vod_duration()))
                time_position = length * position
                self.timeoffset = time_position - (self.vlcwrap.get_media_position() / 1000)

                self.update = True
            except:
                print_exc()
                if DEBUG:
                    print >> sys.stderr, 'embedplay: Could not seek'

    def FullScreen(self, evt=None):
        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap and self.fsbtn.IsEnabled():
            self._ToggleFullScreen()

    def OnFullScreenKey(self, event):
        if event.GetUnicodeKey() == wx.WXK_ESCAPE:
            self._ToggleFullScreen()

        elif event.GetUnicodeKey() == wx.WXK_SPACE:
            self._TogglePause()

    def _TogglePause(self):
        if self.GetState() == MEDIASTATE_PLAYING:
            self.vlcwrap.pause()
        else:
            self.vlcwrap.resume()

    @warnWxThread
    def _ToggleFullScreen(self):
        if isinstance(self.parent, wx.Frame):  # are we shown in popup frame
            if self.ctrlsizer.IsShown(0):  # we are not in fullscreen -> ctrlsizer is showing
                self.parent.ShowFullScreen(True)
                self.ctrlsizer.ShowItems(False)
                self.Layout()

                # Niels: 07-03-2012, only evt_close seems to work :(
                quitId = wx.NewId()
                pauseId = wx.NewId()
                self.parent.Bind(wx.EVT_MENU, lambda event: self._ToggleFullScreen(), id=quitId)
                self.parent.Bind(wx.EVT_MENU, lambda event: self._TogglePause(), id=pauseId)

                self.parent.Bind(wx.EVT_CLOSE, lambda event: self._ToggleFullScreen())
                self.parent.Bind(wx.EVT_LEFT_DCLICK, lambda event: self._ToggleFullScreen())

                accelerators = [(wx.ACCEL_NORMAL, wx.WXK_ESCAPE, quitId), (wx.ACCEL_CTRL, wx.WXK_SPACE, pauseId)]
                self.parent.SetAcceleratorTable(wx.AcceleratorTable(accelerators))
            else:
                self.parent.ShowFullScreen(False)
                self.ctrlsizer.ShowItems(True)
                self.Layout()

                self.parent.SetAcceleratorTable(wx.NullAcceleratorTable)
                self.parent.Unbind(wx.EVT_CLOSE)
        else:
            # saving media player state
            cur_time = self.vlcwrap.get_media_position()
            cur_state = self.vlcwrap.get_our_state()

            self.vlcwrap.stop()
            if not self.fullscreenwindow:
                # create a new top level frame where to attach the vlc widget and
                # render the fullscreen video
                self.fullscreenwindow = wx.Frame(None, title="FullscreenVLC")
                self.fullscreenwindow.SetBackgroundColour("BLACK")

                eventPanel = wx.Panel(self.fullscreenwindow)
                eventPanel.SetBackgroundColour(wx.BLACK)
                eventPanel.Bind(wx.EVT_KEY_DOWN, lambda event: self.OnFullScreenKey(event))
                self.fullscreenwindow.Bind(wx.EVT_CLOSE, lambda event: self._ToggleFullScreen())
                self.fullscreenwindow.ShowFullScreen(True)
                eventPanel.SetFocus()
                self.vlcwrap.set_window(self.fullscreenwindow)
            else:
                self.TellLVCWrapWindow4Playback()
                self.fullscreenwindow.Destroy()
                self.fullscreenwindow = None

            # restoring state
            if cur_state == MEDIASTATE_PLAYING:
                self.vlcwrap.start(cur_time)

            elif cur_state == MEDIASTATE_PAUSED:
                self.vlcwrap.start(cur_time)

                def doPause(cur_time):
                    self.vlcwrap.pause()
                    self.vlcwrap.set_media_position(cur_time)
                wx.CallLater(500, doPause, cur_time)

    def Save(self, evt=None):
        # save media content in different directory
        if self.save_button.isToggled():
            self.save_callback()

    def SetVolume(self, volume, evt=None):
        if DEBUG:
            print >> sys.stderr, "embedplay: SetVolume:", self.volume

        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            self.vlcwrap.sound_set_volume(volume)

    def OnStop(self, event=None):
        if self.vlcwrap and self.sbtn.IsEnabled():
            self.Stop()
            self.ppbtn.Enable(True)
            # Ensures that the related download also stops.
            self.guiutility.library_manager.stopLastVODTorrent()

    @forceWxThread
    def Stop(self):
        if DEBUG:
            print >> sys.stderr, "embedplay: Stop"

        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            self.vlcwrap.stop()
            self.timeposition.SetLabel('--:-- / --:--')
            self.slider.SetValue(0)
            self.fsbtn.Enable(False)
            self.sbtn.Enable(False)
            self.ppbtn.SetBitmapLabel(self.bmp_play, recreate=True)
            self.slider.Enable(False)
            self.HideLoading()

            if self.timer is not None:
                self.timer.Stop()

    def GetState(self):
        """ Returns the state of VLC as summarized by Fabian:
        MEDIASTATE_PLAYING, MEDIASTATE_PAUSED, MEDIASTATE_ENDED, MEDIASTATE_STOPPED """

        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            status = self.vlcwrap.get_our_state()
            if DEBUG:
                print >> sys.stderr, "embedplay: GetState", status

            return status

        # catchall
        return MEDIASTATE_STOPPED

    def Reset(self):
        self.Stop()
        self.slider.SetPieces([])

    @forceWxThread
    def UpdateStatus(self, progress, progress_consec, pieces_complete):
        self.logowin.loading.SetValue(progress)
        if self.vlcwrap:
            self.slider.SetPieces(pieces_complete)

    @warnWxThread
    def UpdateSlider(self, evt):
        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap and self.update:
            if self.GetState() not in [MEDIASTATE_ENDED, MEDIASTATE_STOPPED]:

                length = self.vlcwrap.get_stream_information_length()
                length = length / 1000 if length > 0 else (self.estduration or (self.download and self.download.get_vod_duration()))
                cur = self.vlcwrap.get_media_position() / 1000
                if length and self.timeoffset:
                    cur += self.timeoffset

                if cur >= 0 and length:
                    self.slider.SetValue(float(cur) / length)

                cur_str = self.FormatTime(float(cur)) if cur >= 0 else '--:--'
                length_str = self.FormatTime(length) if length else '--:--'
                self.timeposition.SetLabel('%s / %s' % (cur_str, length_str))
                self.ctrlsizer.Layout()
            elif self.GetState() == MEDIASTATE_ENDED:
                self.OnStop(None)

    def FormatTime(self, s):
        longformat = time.strftime('%d:%H:%M:%S', time.gmtime(s))
        if longformat.startswith('01:'):
            longformat = longformat[3:]
        while longformat.startswith('00:') and len(longformat) > len('00:00'):
            longformat = longformat[3:]
        return longformat

    def TellLVCWrapWindow4Playback(self):
        if self.vlcwrap:
            self.vlcwin.tell_vclwrap_window_for_playback()

    def ShowLoading(self):
        if self.vlcwrap:
            self.logowin.loading.SetValue(0.0)
            self.logowin.show_loading()
            self.logowin.Show(True)
            self.vlcwin.Show(False)
            self.Layout()

    def HideLoading(self):
        if self.vlcwrap:
            self.logowin.hide_loading()
            self.logowin.Show(False)
            self.vlcwin.Show(True)
            self.Layout()
Beispiel #6
0
    def __init__(self, parent, utility, vlcwrap, bg):
        wx.Panel.__init__(self, parent, -1)

        self.utility = utility
        self.guiutility = utility.guiUtility
        self.parent = parent
        self.SetBackgroundColour(DEFAULT_BACKGROUND)

        self.volume = 0.48
        self.oldvolume = 0.48
        self.estduration = None
        self.fullscreenwindow = None
        self.download = None
        self.update = True
        self.timeoffset = None

        vSizer = wx.BoxSizer(wx.VERTICAL)

        self.vlcwrap = vlcwrap

        if vlcwrap:
            self.vlcwin = VLCWindow(self, vlcwrap)
            self.vlcwin.SetMinSize(EmbeddedPlayerPanel.VIDEO_SIZE)
            vSizer.Add(self.vlcwin, 1, wx.EXPAND, 0)

            self.logowin = LogoWindow(self)
            self.logowin.SetMinSize(EmbeddedPlayerPanel.VIDEO_SIZE)
            vSizer.Add(self.logowin, 1, wx.EXPAND, 0)

            self.ctrlpanel = FancyPanel(self, border=wx.TOP)
            self.ctrlpanel.SetMinSize((-1, 30))
            self.ctrlpanel.SetBorderColour(SEPARATOR_GREY)
            self.ctrlpanel.SetBackgroundColour(GRADIENT_LGREY, GRADIENT_DGREY)

            self.ctrlsizer = wx.BoxSizer(wx.HORIZONTAL)

            self.slider = VideoSlider(self.ctrlpanel)
            self.slider.Enable(False)
            self.timeposition = TransparentText(self.ctrlpanel, -1, "--:-- / --:--")

            self.bmp_muted = wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_muted.png"))
            self.bmp_unmuted = wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_unmuted.png"))
            self.mute = ActionButton(self.ctrlpanel, -1, self.bmp_unmuted)
            self.mute.Bind(wx.EVT_LEFT_UP, self.MuteClicked)

            self.bmp_pause = wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_pause.png"))
            self.bmp_play = wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_play.png"))
            self.ppbtn = ActionButton(self.ctrlpanel, -1, self.bmp_play)
            self.ppbtn.Bind(wx.EVT_LEFT_UP, self.PlayPause)
            self.ppbtn.Enable(False)

            self.sbtn = ActionButton(self.ctrlpanel, -1, wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_stop.png")))
            self.sbtn.Bind(wx.EVT_LEFT_UP, self.OnStop)
            self.sbtn.Enable(False)

            self.volctrl = VideoVolume(self.ctrlpanel, -1)
            self.volctrl.SetVolumeHandler(self.OnVolumeChanged)
            self.volctrl.SetValue(self.volume)
            self.volctrl.SetMinSize((30, 17))

            self.fsbtn = ActionButton(self.ctrlpanel, -1, wx.Bitmap(os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI", "images", "video_fullscreen.png")))
            self.fsbtn.Bind(wx.EVT_LEFT_UP, self.FullScreen)
            self.fsbtn.Enable(False)

            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.ppbtn, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.sbtn, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.slider, 1, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
            self.ctrlsizer.Add(self.timeposition, 0, wx.ALIGN_CENTER_VERTICAL)
            self.ctrlsizer.AddSpacer((10, -1))

            self.ctrlsizer.Add(self.mute, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((5, -1))
            self.ctrlsizer.Add(self.volctrl, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.fsbtn, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((10, -1))

            self.ctrlpanel.SetSizer(self.ctrlsizer)

            vSizer.Add(self.ctrlpanel, 0, wx.ALIGN_BOTTOM | wx.EXPAND)

        self.SetSizer(vSizer)

        self.playtimer = None
        self.timer = None

        if self.vlcwrap:
            self.SetMinSize((EmbeddedPlayerPanel.VIDEO_SIZE[0], -1))
            self.vlcwin.Show(True)
            self.logowin.Show(False)
            self.ctrlsizer.ShowItems(True)
            self.guiutility.frame.Layout()
Beispiel #7
0
    def __init__(self, parent):
        wx.StatusBar.__init__(self, parent, style=wx.ST_SIZEGRIP)

        # On Linux/OS X the resize handle and icons overlap, therefore we add an extra field.
        # On Windows this field is automatically set to 1 when the wx.ST_SIZEGRIP is set.
        self.SetFieldsCount(6)
        self.SetStatusStyles([wx.SB_FLAT] * 6)
        self.SetStatusWidths([-1, 250, 19, 19, 19, 19])

        self.guiutility = GUIUtility.getInstance()
        self.utility = self.guiutility.utility
        self.library_manager = self.guiutility.library_manager
        self.uelog = UserEventLogDBHandler.getInstance()

        self.ff_checkbox = wx.CheckBox(self,
                                       -1,
                                       'Family filter',
                                       style=wx.ALIGN_RIGHT)
        self.ff_checkbox.Bind(wx.EVT_CHECKBOX, self.OnCheckbox)
        self.ff_checkbox.SetValue(self.guiutility.getFamilyFilter())

        self.speed_down_icon = NativeIcon.getInstance().getBitmap(
            self, 'arrow', self.GetBackgroundColour(), state=0)
        self.speed_down_sbmp = wx.StaticBitmap(self, -1, self.speed_down_icon)
        self.speed_down_sbmp.Bind(wx.EVT_RIGHT_UP, self.OnDownloadPopup)
        self.speed_down = StaticText(self, -1, '', style=wx.ST_NO_AUTORESIZE)
        self.speed_down.Bind(wx.EVT_RIGHT_UP, self.OnDownloadPopup)
        self.speed_up_icon = self.speed_down_icon.ConvertToImage().Rotate90(
        ).Rotate90().ConvertToBitmap()
        self.speed_up_sbmp = wx.StaticBitmap(self, -1, self.speed_up_icon)
        self.speed_up_sbmp.Bind(wx.EVT_RIGHT_UP, self.OnUploadPopup)
        self.speed_up = StaticText(self, -1, '', style=wx.ST_NO_AUTORESIZE)
        self.speed_up.Bind(wx.EVT_RIGHT_UP, self.OnUploadPopup)

        self.searchConnectionImages = [
            'progressbarEmpty.png', 'progressbarFull.png'
        ]
        self.searchConnectionImages = [
            os.path.join(self.guiutility.vwxGUI_path, 'images', image)
            for image in self.searchConnectionImages
        ]
        self.searchConnectionImages = [
            wx.Bitmap(image, wx.BITMAP_TYPE_ANY)
            for image in self.searchConnectionImages
        ]

        self.activityImages = [
            'statusbar_activity.png', 'statusbar_noactivity.png'
        ]
        self.activityImages = [
            os.path.join(self.guiutility.vwxGUI_path, 'images', image)
            for image in self.activityImages
        ]
        self.activityImages = [
            wx.Bitmap(image, wx.BITMAP_TYPE_ANY)
            for image in self.activityImages
        ]

        self.connection = HorizontalGauge(self, self.searchConnectionImages[0],
                                          self.searchConnectionImages[1])
        self.activity = wx.StaticBitmap(self, -1, self.activityImages[1])
        self.activity_timer = None
        self.channelconnections = 0

        self.bmp_firewall_warning = wx.Bitmap(
            os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI",
                         "images", "statusbar_warning.png"))
        self.bmp_firewall_ok = wx.Bitmap(
            os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI",
                         "images", "statusbar_ok.png"))
        self.firewallStatus = ActionButton(self, -1, self.bmp_firewall_warning)
        self.firewallStatus.SetSize((16, 16))
        self.firewallStatus.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
        self.firewallStatus.SetToolTipString('Port status unknown')
        self.firewallStatus.Enable(False)
        self.firewallStatus.SetBitmapDisabled(self.bmp_firewall_warning)

        self.SetTransferSpeeds(0, 0)
        self.Bind(wx.EVT_SIZE, self.OnSize)

        self.library_manager.add_download_state_callback(
            self.RefreshTransferSpeed)
Beispiel #8
0
class SRstatusbar(wx.StatusBar):
    def __init__(self, parent):
        wx.StatusBar.__init__(self, parent, style=wx.ST_SIZEGRIP)

        # On Linux/OS X the resize handle and icons overlap, therefore we add an extra field.
        # On Windows this field is automatically set to 1 when the wx.ST_SIZEGRIP is set.
        self.SetFieldsCount(6)
        self.SetStatusStyles([wx.SB_FLAT] * 6)
        self.SetStatusWidths([-1, 250, 19, 19, 19, 19])

        self.guiutility = GUIUtility.getInstance()
        self.utility = self.guiutility.utility
        self.library_manager = self.guiutility.library_manager
        self.uelog = UserEventLogDBHandler.getInstance()

        self.ff_checkbox = wx.CheckBox(self,
                                       -1,
                                       'Family filter',
                                       style=wx.ALIGN_RIGHT)
        self.ff_checkbox.Bind(wx.EVT_CHECKBOX, self.OnCheckbox)
        self.ff_checkbox.SetValue(self.guiutility.getFamilyFilter())

        self.speed_down_icon = NativeIcon.getInstance().getBitmap(
            self, 'arrow', self.GetBackgroundColour(), state=0)
        self.speed_down_sbmp = wx.StaticBitmap(self, -1, self.speed_down_icon)
        self.speed_down_sbmp.Bind(wx.EVT_RIGHT_UP, self.OnDownloadPopup)
        self.speed_down = StaticText(self, -1, '', style=wx.ST_NO_AUTORESIZE)
        self.speed_down.Bind(wx.EVT_RIGHT_UP, self.OnDownloadPopup)
        self.speed_up_icon = self.speed_down_icon.ConvertToImage().Rotate90(
        ).Rotate90().ConvertToBitmap()
        self.speed_up_sbmp = wx.StaticBitmap(self, -1, self.speed_up_icon)
        self.speed_up_sbmp.Bind(wx.EVT_RIGHT_UP, self.OnUploadPopup)
        self.speed_up = StaticText(self, -1, '', style=wx.ST_NO_AUTORESIZE)
        self.speed_up.Bind(wx.EVT_RIGHT_UP, self.OnUploadPopup)

        self.searchConnectionImages = [
            'progressbarEmpty.png', 'progressbarFull.png'
        ]
        self.searchConnectionImages = [
            os.path.join(self.guiutility.vwxGUI_path, 'images', image)
            for image in self.searchConnectionImages
        ]
        self.searchConnectionImages = [
            wx.Bitmap(image, wx.BITMAP_TYPE_ANY)
            for image in self.searchConnectionImages
        ]

        self.activityImages = [
            'statusbar_activity.png', 'statusbar_noactivity.png'
        ]
        self.activityImages = [
            os.path.join(self.guiutility.vwxGUI_path, 'images', image)
            for image in self.activityImages
        ]
        self.activityImages = [
            wx.Bitmap(image, wx.BITMAP_TYPE_ANY)
            for image in self.activityImages
        ]

        self.connection = HorizontalGauge(self, self.searchConnectionImages[0],
                                          self.searchConnectionImages[1])
        self.activity = wx.StaticBitmap(self, -1, self.activityImages[1])
        self.activity_timer = None
        self.channelconnections = 0

        self.bmp_firewall_warning = wx.Bitmap(
            os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI",
                         "images", "statusbar_warning.png"))
        self.bmp_firewall_ok = wx.Bitmap(
            os.path.join(self.utility.getPath(), LIBRARYNAME, "Main", "vwxGUI",
                         "images", "statusbar_ok.png"))
        self.firewallStatus = ActionButton(self, -1, self.bmp_firewall_warning)
        self.firewallStatus.SetSize((16, 16))
        self.firewallStatus.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
        self.firewallStatus.SetToolTipString('Port status unknown')
        self.firewallStatus.Enable(False)
        self.firewallStatus.SetBitmapDisabled(self.bmp_firewall_warning)

        self.SetTransferSpeeds(0, 0)
        self.Bind(wx.EVT_SIZE, self.OnSize)

        self.library_manager.add_download_state_callback(
            self.RefreshTransferSpeed)

    def RefreshTransferSpeed(self, dslist, magnetlist):
        total_down, total_up = 0.0, 0.0
        for ds in dslist:
            total_down += ds.get_current_speed(DOWNLOAD)
            total_up += ds.get_current_speed(UPLOAD)
        self.SetTransferSpeeds(total_down * 1024, total_up * 1024)

    def SetTransferSpeeds(self, down, up):
        self.speed_down.SetLabel(self.utility.speed_format_new(down))
        self.speed_up.SetLabel(self.utility.speed_format_new(up))
        self.Reposition()

    def SetGlobalMaxSpeed(self, direction, value):
        if direction in [UPLOAD, DOWNLOAD]:
            if direction == UPLOAD:
                self.utility.setMaxUp(value)
            else:
                self.utility.setMaxDown(value)
            value = 0 if value == 'unlimited' else (
                -1 if int(value) == 0 else int(value))
            self.guiutility.app.ratelimiter.set_global_max_speed(
                direction, value)

    def OnDownloadPopup(self, event):
        menu = wx.Menu()
        curr_valdown = self.utility.getMaxDown()

        # values = ['75', '300', '600']
        values = self.utility.round_range(
            int(curr_valdown)) if curr_valdown.isdigit() else range(
                0, 1000, 100)
        values = map(str, values)
        if curr_valdown.isdigit() and curr_valdown not in values:
            values.append(curr_valdown)
            values.sort(cmp=lambda x, y: cmp(int(x), int(y)))
        values.append('unlimited')

        for valdown in values:
            itemid = wx.NewId()
            menu.AppendRadioItem(itemid, str(valdown))
            menu.Bind(wx.EVT_MENU,
                      lambda x, valdown=valdown: self.SetGlobalMaxSpeed(
                          DOWNLOAD, valdown),
                      id=itemid)
            menu.Check(itemid, curr_valdown == str(valdown))

        self.speed_down.PopupMenu(menu, event.GetPosition())
        menu.Destroy()
        self.speed_down.Layout()

    def OnUploadPopup(self, event):
        menu = wx.Menu()
        curr_valup = self.utility.getMaxUp()

        # values = ['0', '50', '100']
        values = self.utility.round_range(
            int(curr_valup)) if curr_valup.isdigit() else range(0, 1000, 100)
        values = map(str, values)
        if curr_valup.isdigit() and curr_valup not in values:
            values.append(curr_valup)
            values.sort(cmp=lambda x, y: cmp(int(x), int(y)))
        values.append('unlimited')

        for valup in values:
            itemid = wx.NewId()
            menu.AppendRadioItem(itemid, str(valup))
            menu.Bind(
                wx.EVT_MENU,
                lambda x, valup=valup: self.SetGlobalMaxSpeed(UPLOAD, valup),
                id=itemid)
            menu.Check(itemid, curr_valup == str(valup))

        self.speed_up.PopupMenu(menu, event.GetPosition())
        menu.Destroy()
        self.speed_up.Layout()

    def OnCheckbox(self, event):
        checkbox = event.GetEventObject()
        checkbox.Enable(False)
        wx.CallLater(1000, checkbox.Enable, True)

        wx.CallLater(100, self.__toggleFF, event.GetEventObject().GetValue())

    def __toggleFF(self, newvalue):
        if newvalue != self.guiutility.getFamilyFilter():
            self.guiutility.toggleFamilyFilter(newvalue)

            def db_callback():
                self.uelog.addEvent(
                    message="SRstatusbar: user toggled family filter", type=2)

            startWorker(None, db_callback, retryOnBusy=True)

    def SetConnections(self, connectionPercentage, totalConnections,
                       channelConnections):
        self.connection.SetPercentage(connectionPercentage)
        self.connection.SetToolTipString('Connected to %d peers' %
                                         totalConnections)
        self.channelconnections = channelConnections

    def GetConnections(self):
        return self.connection.GetPercentage()

    def GetChannelConnections(self):
        return self.channelconnections

    def onReachable(self, event=None):
        if not self.guiutility.firewall_restart:
            self.firewallStatus.SetBitmapLabel(self.bmp_firewall_ok)
            self.firewallStatus.SetBitmapDisabled(self.bmp_firewall_ok)
            self.firewallStatus.SetToolTipString('Port is working')

    def IsReachable(self):
        if not self.guiutility.firewall_restart:
            return self.firewallStatus.GetBitmapLabel() == self.bmp_firewall_ok
        return False

    def onActivity(self, msg):
        if self.activity_timer:
            self.activity_timer.Stop()

        def revert():
            self.activity.SetBitmap(self.activityImages[1])
            self.activity.Refresh()

        self.activity.SetBitmap(self.activityImages[0])
        self.activity.Refresh()
        self.activity.SetToolTipString(msg)
        self.activity_timer = wx.CallLater(300, revert)

    def format_bytes(self, bytes):
        if bytes < 1000:
            return '%d B' % bytes
        if bytes < 1024:
            return '%1.1f KB' % (bytes / 1024.0)
        if bytes < 1022796:
            return '%d KB' % (bytes // 1024)
        if bytes < 1048576:
            return '%1.1f MB' % (bytes // 1048576.0)
        if bytes < 1047527425:
            return '%d MB' % (bytes // 1048576)
        if bytes < 1073741824:
            return '%1.1f GB' % (bytes // 1073741824.0)
        return '%d GB' % (bytes // 1073741824)

    def OnSize(self, event):
        self.Reposition()

    def Reposition(self):
        self.Freeze()

        rect = self.GetFieldRect(0)
        self.ff_checkbox.SetPosition((rect.x + 2, rect.y + 2))
        self.ff_checkbox.SetSize((-1, rect.height - 4))

        rect = self.GetFieldRect(1)
        x = rect.x + rect.width - 15
        for control in reversed([
                self.speed_down_sbmp, self.speed_down, self.speed_up_sbmp,
                self.speed_up
        ]):
            spacer = 10 if not isinstance(control, wx.StaticBitmap) else 7
            x -= control.GetSize()[0] + spacer
            yAdd = (rect.height - control.GetSize()[1]) / 2
            control.SetPosition((x, rect.y + yAdd))

        rect = self.GetFieldRect(2)
        size = self.connection.GetSize()
        yAdd = (rect.height - size[1]) / 2
        xAdd = (rect.width - size[0]) / 2
        self.connection.SetPosition((rect.x + xAdd, rect.y + yAdd))

        rect = self.GetFieldRect(3)
        size = self.activity.GetSize()
        yAdd = (rect.height - size[1]) / 2
        xAdd = (rect.width - size[0]) / 2
        self.activity.SetPosition((rect.x + xAdd, rect.y + yAdd))

        rect = self.GetFieldRect(4)
        size = self.firewallStatus.GetSize()
        yAdd = (rect.height - size[1]) / 2
        xAdd = (rect.width - size[0]) / 2
        self.firewallStatus.SetPosition((rect.x + xAdd, rect.y + yAdd))

        self.sizeChanged = False
        self.Thaw()
Beispiel #9
0
    def __init__(self, parent, utility, vlcwrap, bg_color):
        wx.Panel.__init__(self, parent, -1)

        self._logger = logging.getLogger(self.__class__.__name__)

        self._gui_image_manager = GuiImageManager.getInstance()

        self.utility = utility
        self.guiutility = utility.guiUtility
        self.videoplayer = self.guiutility.videoplayer
        self.parent = parent
        self.SetBackgroundColour(bg_color)

        self.fullscreenwindow = None
        self.download = None
        self.download_hash = None
        self.update = True
        self.timeoffset = None
        self.oldvolume = 0

        vSizer = wx.BoxSizer(wx.VERTICAL)

        self.vlcwrap = vlcwrap

        if vlcwrap:
            self.vlcwin = VLCWindow(self, vlcwrap)
            self.vlcwin.SetMinSize(EmbeddedPlayerPanel.VIDEO_SIZE)
            vSizer.Add(self.vlcwin, 1, wx.EXPAND, 0)

            self.logowin = LogoWindow(self)
            self.logowin.SetMinSize(EmbeddedPlayerPanel.VIDEO_SIZE)
            vSizer.Add(self.logowin, 1, wx.EXPAND, 0)

            self.ctrlpanel = FancyPanel(self, border=wx.TOP)
            self.ctrlpanel.SetMinSize((-1, 30))
            self.ctrlpanel.SetBorderColour(SEPARATOR_GREY)
            self.ctrlpanel.SetBackgroundColour(GRADIENT_LGREY, GRADIENT_DGREY)

            self.ctrlsizer = wx.BoxSizer(wx.HORIZONTAL)

            self.slider = VideoSlider(self.ctrlpanel)
            self.slider.Enable(False)
            self.timeposition = TransparentText(self.ctrlpanel, -1,
                                                "--:-- / --:--")

            self.bmp_muted = self._gui_image_manager.getImage(
                u"video_muted.png")
            self.bmp_unmuted = self._gui_image_manager.getImage(
                u"video_unmuted.png")
            self.mute = ActionButton(self.ctrlpanel, -1, self.bmp_unmuted)
            self.mute.Bind(wx.EVT_LEFT_UP, self.MuteClicked)

            self.bmp_pause = self._gui_image_manager.getImage(
                u"video_pause.png")
            self.bmp_play = self._gui_image_manager.getImage(u"video_play.png")
            self.ppbtn = ActionButton(self.ctrlpanel, -1, self.bmp_play)
            self.ppbtn.Bind(wx.EVT_LEFT_UP, self.PlayPause)
            self.ppbtn.Enable(False)

            self.sbtn = ActionButton(
                self.ctrlpanel, -1,
                self._gui_image_manager.getImage(u"video_stop.png"))
            self.sbtn.Bind(wx.EVT_LEFT_UP, self.OnStop)
            self.sbtn.Enable(False)

            self.volctrl = VideoVolume(self.ctrlpanel, -1)
            self.volctrl.SetVolumeHandler(self.OnVolumeChanged)
            self.volctrl.SetMinSize((30, 17))
            self.volctrl.Enable(False)

            self.fsbtn = ActionButton(
                self.ctrlpanel, -1,
                self._gui_image_manager.getImage(u"video_fullscreen.png"))
            self.fsbtn.Bind(wx.EVT_LEFT_UP, self.FullScreen)
            self.fsbtn.Enable(False)

            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.ppbtn, 0,
                               wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.sbtn, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP,
                               1)
            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.slider, 1,
                               wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
            self.ctrlsizer.Add(self.timeposition, 0, wx.ALIGN_CENTER_VERTICAL)
            self.ctrlsizer.AddSpacer((10, -1))

            self.ctrlsizer.Add(self.mute, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP,
                               1)
            self.ctrlsizer.AddSpacer((5, -1))
            self.ctrlsizer.Add(self.volctrl, 0,
                               wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.fsbtn, 0,
                               wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((10, -1))

            self.ctrlpanel.SetSizer(self.ctrlsizer)

            vSizer.Add(self.ctrlpanel, 0, wx.ALIGN_BOTTOM | wx.EXPAND)

            self.notifier = self.guiutility.utility.session.notifier

        self.SetSizer(vSizer)

        self.playtimer = None
        self.timer = None

        if self.vlcwrap:
            self.SetMinSize((EmbeddedPlayerPanel.VIDEO_SIZE[0], -1))
            self.vlcwin.Show(True)
            self.logowin.Show(False)
            self.ctrlsizer.ShowItems(True)
            self.guiutility.frame.Layout()

            self.guiutility.library_manager.add_download_state_callback(
                self.OnStatesCallback)

            self.guiutility.utility.session.add_observer(
                self.OnVideoBuffering, NTFY_TORRENTS, [NTFY_VIDEO_BUFFERING])

            self.videoplayer.set_internalplayer_callback(self.LoadAndStartPlay)
Beispiel #10
0
class EmbeddedPlayerPanel(wx.Panel):
    """
    The Embedded Player consists of a VLCWindow and the media controls such
    as Play/Pause buttons and Volume Control.
    """

    VIDEO_SIZE = (320, 240)

    def __init__(self, parent, utility, vlcwrap, bg_color):
        wx.Panel.__init__(self, parent, -1)

        self._logger = logging.getLogger(self.__class__.__name__)

        self._gui_image_manager = GuiImageManager.getInstance()

        self.utility = utility
        self.guiutility = utility.guiUtility
        self.videoplayer = self.guiutility.videoplayer
        self.parent = parent
        self.SetBackgroundColour(bg_color)

        self.fullscreenwindow = None
        self.download = None
        self.download_hash = None
        self.update = True
        self.timeoffset = None
        self.oldvolume = 0

        vSizer = wx.BoxSizer(wx.VERTICAL)

        self.vlcwrap = vlcwrap

        if vlcwrap:
            self.vlcwin = VLCWindow(self, vlcwrap)
            self.vlcwin.SetMinSize(EmbeddedPlayerPanel.VIDEO_SIZE)
            vSizer.Add(self.vlcwin, 1, wx.EXPAND, 0)

            self.logowin = LogoWindow(self)
            self.logowin.SetMinSize(EmbeddedPlayerPanel.VIDEO_SIZE)
            vSizer.Add(self.logowin, 1, wx.EXPAND, 0)

            self.ctrlpanel = FancyPanel(self, border=wx.TOP)
            self.ctrlpanel.SetMinSize((-1, 30))
            self.ctrlpanel.SetBorderColour(SEPARATOR_GREY)
            self.ctrlpanel.SetBackgroundColour(GRADIENT_LGREY, GRADIENT_DGREY)

            self.ctrlsizer = wx.BoxSizer(wx.HORIZONTAL)

            self.slider = VideoSlider(self.ctrlpanel)
            self.slider.Enable(False)
            self.timeposition = TransparentText(self.ctrlpanel, -1,
                                                "--:-- / --:--")

            self.bmp_muted = self._gui_image_manager.getImage(
                u"video_muted.png")
            self.bmp_unmuted = self._gui_image_manager.getImage(
                u"video_unmuted.png")
            self.mute = ActionButton(self.ctrlpanel, -1, self.bmp_unmuted)
            self.mute.Bind(wx.EVT_LEFT_UP, self.MuteClicked)

            self.bmp_pause = self._gui_image_manager.getImage(
                u"video_pause.png")
            self.bmp_play = self._gui_image_manager.getImage(u"video_play.png")
            self.ppbtn = ActionButton(self.ctrlpanel, -1, self.bmp_play)
            self.ppbtn.Bind(wx.EVT_LEFT_UP, self.PlayPause)
            self.ppbtn.Enable(False)

            self.sbtn = ActionButton(
                self.ctrlpanel, -1,
                self._gui_image_manager.getImage(u"video_stop.png"))
            self.sbtn.Bind(wx.EVT_LEFT_UP, self.OnStop)
            self.sbtn.Enable(False)

            self.volctrl = VideoVolume(self.ctrlpanel, -1)
            self.volctrl.SetVolumeHandler(self.OnVolumeChanged)
            self.volctrl.SetMinSize((30, 17))
            self.volctrl.Enable(False)

            self.fsbtn = ActionButton(
                self.ctrlpanel, -1,
                self._gui_image_manager.getImage(u"video_fullscreen.png"))
            self.fsbtn.Bind(wx.EVT_LEFT_UP, self.FullScreen)
            self.fsbtn.Enable(False)

            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.ppbtn, 0,
                               wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.sbtn, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP,
                               1)
            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.slider, 1,
                               wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
            self.ctrlsizer.Add(self.timeposition, 0, wx.ALIGN_CENTER_VERTICAL)
            self.ctrlsizer.AddSpacer((10, -1))

            self.ctrlsizer.Add(self.mute, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP,
                               1)
            self.ctrlsizer.AddSpacer((5, -1))
            self.ctrlsizer.Add(self.volctrl, 0,
                               wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((10, -1))
            self.ctrlsizer.Add(self.fsbtn, 0,
                               wx.ALIGN_CENTER_VERTICAL | wx.TOP, 1)
            self.ctrlsizer.AddSpacer((10, -1))

            self.ctrlpanel.SetSizer(self.ctrlsizer)

            vSizer.Add(self.ctrlpanel, 0, wx.ALIGN_BOTTOM | wx.EXPAND)

            self.notifier = self.guiutility.utility.session.notifier

        self.SetSizer(vSizer)

        self.playtimer = None
        self.timer = None

        if self.vlcwrap:
            self.SetMinSize((EmbeddedPlayerPanel.VIDEO_SIZE[0], -1))
            self.vlcwin.Show(True)
            self.logowin.Show(False)
            self.ctrlsizer.ShowItems(True)
            self.guiutility.frame.Layout()

            self.guiutility.library_manager.add_download_state_callback(
                self.OnStatesCallback)

            self.guiutility.utility.session.add_observer(
                self.OnVideoBuffering, NTFY_TORRENTS, [NTFY_VIDEO_BUFFERING])

            self.videoplayer.set_internalplayer_callback(self.LoadAndStartPlay)

    def OnVideoBuffering(self, subject, changeType, torrent_tuple):
        if not self:
            return

        download_hash, _, is_buffering = torrent_tuple
        if self.download and self.download.get_def().get_infohash(
        ) == download_hash:

            @forceWxThread
            def do_gui():
                if is_buffering:
                    self.Pause(gui_vod_event=True)
                else:
                    self.Resume()

            do_gui()

    def OnStatesCallback(self, dslist, magnetlist):
        if not self or not self.download:
            return

        for ds in dslist:
            if ds.get_download() == self.download and self.download.get_mode(
            ) == DLMODE_VOD:
                if ds.get_status() == DLSTATUS_HASHCHECKING:
                    progress = ds.get_progress()
                    label = 'Checking\n%d%%' % (progress * 100)
                elif ds.get_status() == DLSTATUS_STOPPED_ON_ERROR:
                    progress = 0
                    label = 'Loading\nfailed'
                else:
                    progress = ds.get_vod_prebuffering_progress()
                    label = 'Loading\n%d%%' % (progress * 100)

                pieces_complete = ds.get_pieces_complete(
                ) if ds.get_progress() < 1.0 else [True]
                self.UpdateStatus(label, progress, pieces_complete)

    def OnVolumeChanged(self, volume):
        if self.mute.GetBitmapLabel() == self.bmp_muted:  # unmute
            self.mute.SetBitmapLabel(self.bmp_unmuted, recreate=True)
        self.volume = volume
        self.oldvolume = self.volume
        self.SetVolume(self.volume)

    def MuteClicked(self, event):
        if self.mute.GetBitmapLabel() == self.bmp_muted:
            self.volume = self.oldvolume
        else:
            self.volume = 0

        self.volctrl.SetValue(self.volume)
        self.SetVolume(self.volume)
        self.mute.SetBitmapLabel(
            self.bmp_unmuted if self.mute.GetBitmapLabel() == self.bmp_muted
            else self.bmp_muted,
            recreate=True)

    @forceWxThread
    def LoadAndStartPlay(self, url, download):
        self.Load(url, download)
        self.StartPlay()

    @warnWxThread
    def Load(self, url, download):
        self._logger.debug("embedplay: Load: %s %s", url,
                           currentThread().getName())

        self.download = download
        self.download_hash = download.get_def().get_infohash()

        # 19/02/10 Boudewijn: no self.slider when self.vlcwrap is None
        # 26/05/09 Boudewijn: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            self.slider.Enable(False)

            # Arno, 2009-02-17: If we don't do this VLC gets the wrong playlist somehow
            self.vlcwrap.stop()
            self.vlcwrap.load(url)

            # Enable update of progress slider
            wx.CallAfter(self.slider.SetValue, 0)
            if self.timer is None:
                self.timer = wx.Timer(self)
                self.Bind(wx.EVT_TIMER, self.UpdateSlider)
            self.timer.Start(500)

            self.volume = self.vlcwrap.sound_get_volume()
            self.oldvolume = self.vlcwrap.sound_get_volume()
            self.volctrl.SetValue(self.volume)
            self.volctrl.Enable(True)

        self.fsbtn.Enable(True)
        self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True)
        self.ppbtn.Enable(True)
        self.sbtn.Enable(True)

    def StartPlay(self):
        """ Start playing the new item after VLC has stopped playing the old one """
        self._logger.debug("embedplay: PlayWhenStopped")

        self.playtimer = DelayTimer(self)

    @warnWxThread
    def Play(self, evt=None):
        self._logger.debug("embedplay: Play pressed")

        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            if self.GetState() != MEDIASTATE_PLAYING:
                self.vlcwrap.start()
                self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True)
                self.ppbtn.Enable(True)
            else:
                self._logger.debug("embedplay: Play pressed, already playing")

    @warnWxThread
    def Pause(self, evt=None, gui_vod_event=False):
        self._logger.debug("embedplay: Pause pressed")

        if self.vlcwrap:
            if self.GetState() == MEDIASTATE_PLAYING:
                self.vlcwrap.pause()
            self.ppbtn.SetBitmapLabel(self.bmp_play, recreate=True)
            if gui_vod_event:
                self.ppbtn.Enable(False)
                self.ShowLoading()

    @warnWxThread
    def Resume(self, evt=None):
        self._logger.debug("embedplay: Resume pressed")

        if self.vlcwrap:
            if self.GetState() != MEDIASTATE_PLAYING:
                self.vlcwrap.resume()
            self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True)
            self.ppbtn.Enable(True)
            self.slider.Enable(True)
            self.HideLoading()

    @warnWxThread
    def PlayPause(self, evt=None):
        self._logger.debug("embedplay: PlayPause pressed")

        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            if self.GetState() in [MEDIASTATE_ENDED, MEDIASTATE_STOPPED]:
                # Ensures that the related download also starts
                self.guiutility.library_manager.startLastVODTorrent()
            else:
                self.vlcwrap.resume()
                self.ppbtn.SetBitmapLabel(
                    self.bmp_play if self.ppbtn.GetBitmapLabel()
                    == self.bmp_pause else self.bmp_pause,
                    recreate=True)
                self.ppbtn.Enable(True)

    @warnWxThread
    def Seek(self, evt=None):
        self._logger.debug("embedplay: Seek")

        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            self.ppbtn.SetBitmapLabel(self.bmp_pause, recreate=True)
            self.ppbtn.Enable(self.download.get_progress() == 1.0)
            position = self.slider.GetValue()
            self.update = False

            try:
                self.Pause(gui_vod_event=True)
                self.videoplayer.seek(position)
                self.vlcwrap.set_media_position_relative(
                    position,
                    self.GetState() in [MEDIASTATE_ENDED, MEDIASTATE_STOPPED])

                length = self.vlcwrap.get_stream_information_length()
                length = length / 1000 if length > 0 else self.videoplayer.get_vod_duration(
                    self.download_hash)
                time_position = length * position
                self.timeoffset = time_position - (
                    self.vlcwrap.get_media_position() / 1000)

                self.update = True
            except:
                print_exc()
                self._logger.debug('embedplay: Could not seek')

    def FullScreen(self, evt=None):
        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap and self.fsbtn.IsEnabled():
            self._ToggleFullScreen()

    def OnFullScreenKey(self, event):
        if event.GetUnicodeKey() == wx.WXK_ESCAPE:
            self._ToggleFullScreen()

        elif event.GetUnicodeKey() == wx.WXK_SPACE:
            self._TogglePause()

    def _TogglePause(self):
        if self.GetState() == MEDIASTATE_PLAYING:
            self.vlcwrap.pause()
        else:
            self.vlcwrap.resume()

    @warnWxThread
    def _ToggleFullScreen(self):
        # saving media player state
        cur_time = self.vlcwrap.get_media_position()
        cur_state = self.vlcwrap.get_our_state()

        self.vlcwrap.stop()
        if not self.fullscreenwindow:
            # create a new top level frame where to attach the vlc widget and
            # render the fullscreen video
            self.fullscreenwindow = wx.Frame(None, title="FullscreenVLC")
            self.fullscreenwindow.SetBackgroundColour("BLACK")

            eventPanel = wx.Panel(self.fullscreenwindow)
            eventPanel.SetBackgroundColour(wx.BLACK)
            eventPanel.Bind(wx.EVT_KEY_DOWN,
                            lambda event: self.OnFullScreenKey(event))
            self.fullscreenwindow.Bind(wx.EVT_CLOSE,
                                       lambda event: self._ToggleFullScreen())
            self.fullscreenwindow.Show()
            self.fullscreenwindow.ShowFullScreen(True)
            eventPanel.SetFocus()
            self.vlcwrap.set_window(self.fullscreenwindow)
        else:
            self.vlcwrap.set_window(self.vlcwin)
            self.fullscreenwindow.Destroy()
            self.fullscreenwindow = None

        # restoring state
        if cur_state == MEDIASTATE_PLAYING:
            self.vlcwrap.start(cur_time)

        elif cur_state == MEDIASTATE_PAUSED:
            self.vlcwrap.start(cur_time)

            def doPause(cur_time):
                self.vlcwrap.pause()
                self.vlcwrap.set_media_position(cur_time)

            wx.CallLater(500, doPause, cur_time)

    def SetVolume(self, volume, evt=None):
        self._logger.debug("embedplay: SetVolume: %s", self.volume)

        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            self.vlcwrap.sound_set_volume(volume)

    def OnStop(self, event=None):
        if self.vlcwrap and self.sbtn.IsEnabled():
            self.Stop()
            self.ppbtn.Enable(True)
            # Ensures that the related download also stops.
            self.guiutility.library_manager.stopLastVODTorrent()

    @forceWxThread
    def Stop(self):
        self._logger.debug("embedplay: Stop")

        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            self.vlcwrap.stop()
            self.timeposition.SetLabel('--:-- / --:--')
            self.slider.SetValue(0)
            self.timeoffset = None
            self.fsbtn.Enable(False)
            self.sbtn.Enable(False)
            self.ppbtn.SetBitmapLabel(self.bmp_play, recreate=True)
            self.slider.Enable(False)
            self.HideLoading()

            if self.timer is not None:
                self.timer.Stop()

    def GetState(self):
        """ Returns the state of VLC as summarized by Fabian:
        MEDIASTATE_PLAYING, MEDIASTATE_PAUSED, MEDIASTATE_ENDED, MEDIASTATE_STOPPED """

        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap:
            status = self.vlcwrap.get_our_state()
            self._logger.debug("embedplay: GetState %s", status)

            return status

        # catchall
        return MEDIASTATE_STOPPED

    def Reset(self):
        self.Stop()
        self.slider.SetPieces([])

    @forceWxThread
    def UpdateStatus(self, label, progress, pieces_complete):
        self.logowin.loading.SetValue(progress)
        self.logowin.loading.SetLabel(label)

        if self.vlcwrap:
            self.slider.SetPieces(pieces_complete)

    @warnWxThread
    def UpdateSlider(self, evt):
        # Boudewijn, 26/05/09: when using the external player we do not have a vlcwrap
        if self.vlcwrap and self.update:
            if self.GetState() not in [MEDIASTATE_ENDED, MEDIASTATE_STOPPED]:

                length = self.vlcwrap.get_stream_information_length()
                length = length / 1000 if length > 0 else self.videoplayer.get_vod_duration(
                    self.download_hash)
                cur = self.vlcwrap.get_media_position() / 1000
                if length and self.timeoffset:
                    cur += self.timeoffset

                if cur >= 0 and length:
                    self.slider.SetValue(float(cur) / length)

                cur_str = self.FormatTime(float(cur)) if cur >= 0 else '--:--'
                length_str = self.FormatTime(length) if length else '--:--'
                self.timeposition.SetLabel('%s / %s' % (cur_str, length_str))
                self.ctrlsizer.Layout()
            elif self.GetState() == MEDIASTATE_ENDED:
                download, fileindex = (self.videoplayer.get_vod_download(),
                                       self.videoplayer.get_vod_fileindex())
                self.OnStop(None)
                if download:
                    self.notifier.notify(
                        NTFY_TORRENTS, NTFY_VIDEO_ENDED,
                        (download.get_def().get_infohash(), fileindex))
                if self.fullscreenwindow:
                    self._ToggleFullScreen()

    def FormatTime(self, s):
        longformat = time.strftime('%d:%H:%M:%S', time.gmtime(s))
        if longformat.startswith('01:'):
            longformat = longformat[3:]
        while longformat.startswith('00:') and len(longformat) > len('00:00'):
            longformat = longformat[3:]
        return longformat

    def ShowLoading(self):
        if self.vlcwrap:
            self.logowin.loading.SetValue(0.0)
            self.logowin.show_loading()
            self.logowin.Show(True)
            self.vlcwin.Show(False)
            self.Layout()

    def HideLoading(self):
        if self.vlcwrap:
            self.logowin.hide_loading()
            self.logowin.Show(False)
            self.vlcwin.Show(True)
            self.Layout()

    def RecreateVLCWindow(self):
        if self.vlcwrap:
            vlcwin = VLCWindow(self, self.vlcwrap)
            vlcwin.SetMinSize(EmbeddedPlayerPanel.VIDEO_SIZE)
            vlcwin.Show(self.vlcwin.IsShown())
            self.GetSizer().Replace(self.vlcwin, vlcwin)
            self.vlcwin.Destroy()
            self.vlcwin = vlcwin
Beispiel #11
0
class SRstatusbar(wx.StatusBar):
    def __init__(self, parent):
        wx.StatusBar.__init__(self, parent, style=wx.ST_SIZEGRIP)

        self._gui_image_manager = GuiImageManager.getInstance()

        self.guiutility = GUIUtility.getInstance()
        self.utility = self.guiutility.utility
        self.library_manager = self.guiutility.library_manager

        self.ff_checkbox = wx.CheckBox(self,
                                       -1,
                                       'Family filter',
                                       style=wx.ALIGN_RIGHT)
        self.ff_checkbox.Bind(wx.EVT_CHECKBOX, self.OnCheckbox)
        self.ff_checkbox.SetValue(self.guiutility.getFamilyFilter())

        self.tunnel_contrib = wx.StaticText(self, -1, '')
        self.tunnel_contrib.SetToolTipString('Total Anonymity Contribution')
        self.tunnel_contribNet = wx.StaticText(self, -1, '')
        self.tunnel_contribNet.SetToolTipString(
            'Anonymity Contribution Balance')

        self.speed_down_icon = self._gui_image_manager.getBitmap(
            self, u"arrow", self.GetBackgroundColour(), state=0)
        self.speed_down_sbmp = wx.StaticBitmap(self, -1, self.speed_down_icon)
        self.speed_down_sbmp.Bind(wx.EVT_RIGHT_UP, self.OnDownloadPopup)
        self.speed_down = wx.StaticText(self, -1, '')
        self.speed_down.Bind(wx.EVT_RIGHT_UP, self.OnDownloadPopup)

        self.speed_up_icon = self.speed_down_icon.ConvertToImage().Rotate90(
        ).Rotate90().ConvertToBitmap()
        self.speed_up_sbmp = wx.StaticBitmap(self, -1, self.speed_up_icon)
        self.speed_up_sbmp.Bind(wx.EVT_RIGHT_UP, self.OnUploadPopup)
        self.speed_up = wx.StaticText(self, -1, '')
        self.speed_up.Bind(wx.EVT_RIGHT_UP, self.OnUploadPopup)

        self.free_space_icon = self._gui_image_manager.getImage(u"drive.png")
        self.free_space_sbmp = wx.StaticBitmap(self, -1, self.free_space_icon)
        self.free_space = wx.StaticText(self, -1, '')

        self.searchConnectionImages = [
            u"progressbarEmpty.png", u"progressbarFull.png"
        ]
        self.searchConnectionImages = [
            self._gui_image_manager.getImage(image)
            for image in self.searchConnectionImages
        ]

        self.activityImages = [
            u"statusbar_activity.png", u"statusbar_noactivity.png"
        ]
        self.activityImages = [
            self._gui_image_manager.getImage(image)
            for image in self.activityImages
        ]

        self.connection = HorizontalGauge(self, self.searchConnectionImages[0],
                                          self.searchConnectionImages[1])
        self.connection.SetBackgroundColour(self.GetBackgroundColour())
        self.activity = wx.StaticBitmap(self, -1, self.activityImages[1])
        self.activity_timer = None
        self.channelconnections = 0

        self.bmp_firewall_warning = self._gui_image_manager.getImage(
            u"statusbar_warning.png")
        self.bmp_firewall_ok = self._gui_image_manager.getImage(
            u"statusbar_ok.png")
        self.firewallStatus = ActionButton(self, -1, self.bmp_firewall_warning)
        self.firewallStatus.SetSize((16, 16))
        self.firewallStatus.SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
        self.firewallStatus.SetToolTipString('Port status unknown')
        self.firewallStatus.Enable(False)
        self.firewallStatus.SetBitmapDisabled(self.bmp_firewall_warning)

        # On Linux/OS X the resize handle and icons overlap, therefore we add an extra field.
        # On Windows this field is automatically set to 1 when the wx.ST_SIZEGRIP (parent class constructor) is set.
        self.fields = [
            (-1, wx.SB_FLAT, [self.ff_checkbox]),
            (100, wx.SB_FLAT, [self.tunnel_contrib, self.tunnel_contribNet]),
            (200, wx.SB_FLAT, [
                self.speed_down_sbmp, self.speed_down, self.speed_up_sbmp,
                self.speed_up
            ]), (75, wx.SB_FLAT, [self.free_space_sbmp, self.free_space]),
            (19, wx.SB_FLAT, [self.connection]),
            (19, wx.SB_FLAT, [self.activity]),
            (19, wx.SB_FLAT, [self.firewallStatus])
        ]

        if sys.platform != "win32":
            self.fields.append((19, wx.SB_FLAT, []))

        self.SetFieldsCount(len(self.fields))
        self.SetStatusWidths([field[0] for field in self.fields])
        self.SetStatusStyles([field[1] for field in self.fields])

        self.SetTransferSpeeds(speed_format(0), speed_format(0))
        self.Bind(wx.EVT_SIZE, self.OnSize)
        self.library_manager.add_download_state_callback(
            self.RefreshTransferSpeed)

    def UpdateTunnelContrib(self):
        totalup = (
            sum(_barter_statistics.bartercast[
                BartercastStatisticTypes.TUNNELS_BYTES_SENT].values()) +
            sum(_barter_statistics.bartercast[
                BartercastStatisticTypes.TUNNELS_RELAY_BYTES_SENT].values()) +
            sum(_barter_statistics.bartercast[
                BartercastStatisticTypes.TUNNELS_EXIT_BYTES_SENT].values()))
        totaldown = (
            sum(_barter_statistics.bartercast[
                BartercastStatisticTypes.TUNNELS_BYTES_RECEIVED].values()) +
            sum(_barter_statistics.bartercast[
                BartercastStatisticTypes.TUNNELS_RELAY_BYTES_RECEIVED].values(
                )) +
            sum(_barter_statistics.bartercast[
                BartercastStatisticTypes.TUNNELS_EXIT_BYTES_RECEIVED].values())
        )
        self.SetTunnelContrib(totalup + totaldown, totalup - totaldown)

    @warnWxThread
    def SetTunnelContrib(self, totalcontrib, netcontrib):
        self.tunnel_contrib.SetLabel('Total: %s' %
                                     size_format(totalcontrib, truncate=2))
        self.tunnel_contribNet.SetLabel('Balance: %s' %
                                        size_format(netcontrib, truncate=2))
        self.Reposition()

    @forceWxThread
    def RefreshFreeSpace(self, space):
        if space >= 0:
            space_str = size_format(space, truncate=1)
            space_label = space_str.replace(' ', '')
            space_tooltip = 'You currently have %s of disk space available on your default download location.' % space_str
            self.free_space.SetLabel(space_label)
            self.free_space.Show(True)
            self.free_space_sbmp.Show(True)
            # TODO martijn: we disabled some tooltips that are periodically updated on OS X.
            # There seems to be a bug (in wx3) where the tooltip would always show when being updated.
            if sys.platform != 'darwin':
                self.free_space_sbmp.SetToolTipString(space_tooltip)
                self.free_space.SetToolTipString(space_tooltip)
        else:
            self.free_space.Show(False)
            self.free_space_sbmp.Show(False)
        self.Reposition()

    def RefreshTransferSpeed(self, dslist, magnetlist):
        if not self:
            return

        self.UpdateTunnelContrib()
        total_down, total_up = get_download_upload_speed(dslist)
        self.SetTransferSpeeds(speed_format(total_down),
                               speed_format(total_up))

    @warnWxThread
    def SetTransferSpeeds(self, down, up):
        self.speed_down.SetLabel(down)
        self.speed_up.SetLabel(up)
        self.Reposition()

    def SetGlobalMaxSpeed(self, direction, value):
        if direction in [UPLOAD, DOWNLOAD]:
            if direction == UPLOAD:
                self.utility.write_config('maxuploadrate', value)
                self.guiutility.utility.session.set_max_upload_speed(value)
            else:
                self.utility.write_config('maxdownloadrate', value)
                self.guiutility.utility.session.set_max_download_speed(value)

    def GetSpeedChoices(self, value):
        values = round_range(max(0, value)) if value != 0 else range(
            0, 1000, 100)
        values = [value or -1 for value in values]
        if value != 0 and value not in values:
            values.append(value)
            values.sort()
        values.append(0)
        return [('unlimited' if value == 0 else
                 ('0' if value == -1 else str(value)), value)
                for value in values]

    def OnDownloadPopup(self, event):
        menu = wx.Menu()
        current = self.utility.read_config('maxdownloadrate')
        value_tuples = self.GetSpeedChoices(current)

        for value_str, value in value_tuples:
            itemid = wx.NewId()
            menu.AppendRadioItem(itemid, value_str)
            menu.Bind(wx.EVT_MENU,
                      lambda x, v=value: self.SetGlobalMaxSpeed(DOWNLOAD, v),
                      id=itemid)
            menu.Check(itemid, current == value)

        self.speed_down.PopupMenu(menu, event.GetPosition())
        menu.Destroy()
        self.speed_down.Layout()

    def OnUploadPopup(self, event):
        menu = wx.Menu()
        current = self.utility.read_config('maxuploadrate')
        value_tuples = self.GetSpeedChoices(current)

        for value_str, value in value_tuples:
            itemid = wx.NewId()
            menu.AppendRadioItem(itemid, value_str)
            menu.Bind(wx.EVT_MENU,
                      lambda x, v=value: self.SetGlobalMaxSpeed(UPLOAD, v),
                      id=itemid)
            menu.Check(itemid, current == value)

        self.speed_up.PopupMenu(menu, event.GetPosition())
        menu.Destroy()
        self.speed_up.Layout()

    def OnCheckbox(self, event):
        checkbox = event.GetEventObject()
        checkbox.Enable(False)
        wx.CallLater(1000, checkbox.Enable, True)

        wx.CallLater(100, self.__toggleFF, event.GetEventObject().GetValue())

    @warnWxThread
    def __toggleFF(self, newvalue):
        if newvalue != self.guiutility.getFamilyFilter():
            self.guiutility.toggleFamilyFilter(newvalue)

    @warnWxThread
    def SetConnections(self, connectionPercentage, totalConnections,
                       channelConnections):
        self.connection.SetPercentage(connectionPercentage)
        if sys.platform != 'darwin':
            self.connection.SetToolTipString('Connected to %d peers' %
                                             totalConnections)
        self.channelconnections = channelConnections

    def GetConnections(self):
        return self.connection.GetPercentage()

    def GetChannelConnections(self):
        return self.channelconnections

    @warnWxThread
    def onReachable(self, event=None):
        if not self.guiutility.firewall_restart:
            self.firewallStatus.SetBitmapLabel(self.bmp_firewall_ok)
            self.firewallStatus.SetBitmapDisabled(self.bmp_firewall_ok)
            self.firewallStatus.SetToolTipString('Port is working')

    @warnWxThread
    def IsReachable(self):
        if not self.guiutility.firewall_restart:
            return self.firewallStatus.GetBitmapLabel() == self.bmp_firewall_ok
        return False

    @warnWxThread
    def onActivity(self, msg):
        if self.activity_timer:
            self.activity_timer.Stop()

        def revert():
            if not self:
                return
            self.activity.SetBitmap(self.activityImages[1])
            self.activity.Refresh()

        self.activity.SetBitmap(self.activityImages[0])
        self.activity.Refresh()
        if sys.platform != 'darwin':
            self.activity.SetToolTipString(msg)
        self.activity_timer = wx.CallLater(300, revert)

    def OnSize(self, event):
        self.Reposition()

    def Reposition(self):
        self.Freeze()

        # default spacing rules
        #  - field has 1 control, center it
        #  - field has -1 width (fill), skip it
        #  - starting from the right align all controls with 10 spacing between them, or 7 if it it a bitmap
        for field_index, field in enumerate(self.fields):
            if field[0] == -1:
                continue
            rect = self.GetFieldRect(field_index)
            if len(field[2]) == 1:
                control = field[2][0]
                control.SetPosition(
                    (rect.x + (rect.width - control.GetSize()[0]) / 2,
                     rect.y + (rect.height - control.GetSize()[1]) / 2))
            else:
                x = rect.x + rect.width
                for control in reversed(field[2]):
                    spacer = 10 if not isinstance(control,
                                                  wx.StaticBitmap) else 7
                    x -= control.GetSize()[0] + spacer
                    control.SetPosition(
                        (x, rect.y + (rect.height - control.GetSize()[1]) / 2))

        # any other layout work not covered by the default rules should happen here.
        rect = self.GetFieldRect(0)
        self.ff_checkbox.SetPosition((rect.x + 2, rect.y + 2))
        self.ff_checkbox.SetSize((-1, rect.height - 4))

        self.sizeChanged = False
        self.Thaw()