Beispiel #1
0
 def __init__(self, url, dl_url, dest_file, after_complete=0, parent=None):
     self.url = url
     self.dest_file = dest_file
     self.new_path = None  #is used when saving a video from the player
     self.dl_url = dl_url
     self.after_complete = after_complete
     self.completed = False
     self._abort = self.aborted = False
     self._stop = False
     self.init_date = datetime.now()
     self.stop_date = None
     self.time_passed = timedelta(seconds=0)
     self.time_left_str = "00:00:00"
     self.time_stopped = timedelta(seconds=0)
     self.downloaded = 0
     self.local_size_ant = 0
     self.timeout = 0
     self.speed = 0.0
     self.check_download = QTimer()
     self.check_download.timeout.connect(self.checkDownloadState)
     self.speed_unit = "KiB/s"
     self.size_kib = 0
     
     #set unit size
     self.size, self.size_unit = self.setSize(0)
 
     super(DownloadItem, self).__init__(parent)
Beispiel #2
0
    def __init__(self, parent = None, orientation=Qt.Horizontal):
        QSlider.__init__(self, orientation, parent)
        self.setPageStep(1)
        self.paused = False
        self.setEnabled(False)
        self.max = 0
        self.value_when_pressed = 0
        self.progress_max = 0
        self.progress = 0
        self.setValue(0)
        self.last_value = 0
        self.lastSeeked = 0
        self.time_when_paused = 0
        self.is_sliderMoving = False
        self.MediaPlayer = None
        self.last_valid_value = 0
        self.progressBarHeight = 0
        self.ignoreHandle = False

        self.timer_update_slider = QTimer()
        self.timer_update_slider.timeout.connect(self.update_slider)
        
        self.sliderPressed.connect(self.on_slider_press)
        self.sliderReleased.connect(self.on_slider_release)
        self.sliderMoved.connect(self.on_slider_move)
        
        self.setSetStyleSheet()
Beispiel #3
0
class DownloadItem(QThread):
    def __init__(self, url, dl_url, dest_file, after_complete=0, parent=None):
        self.url = url
        self.dest_file = dest_file
        self.new_path = None  #is used when saving a video from the player
        self.dl_url = dl_url
        self.after_complete = after_complete
        self.completed = False
        self._abort = self.aborted = False
        self._stop = False
        self.init_date = datetime.now()
        self.stop_date = None
        self.time_passed = timedelta(seconds=0)
        self.time_left_str = "00:00:00"
        self.time_stopped = timedelta(seconds=0)
        self.downloaded = 0
        self.local_size_ant = 0
        self.timeout = 0
        self.speed = 0.0
        self.check_download = QTimer()
        self.check_download.timeout.connect(self.checkDownloadState)
        self.speed_unit = "KiB/s"
        self.size_kib = 0
        
        #set unit size
        self.size, self.size_unit = self.setSize(0)
    
        super(DownloadItem, self).__init__(parent)
        
    def run(self):
        self.threadDl = Download(self.dl_url, self.dest_file)
        self.threadDl.start()
        self.check_download.start(1000)
        
    def checkDownloadState(self):
        if self.size_kib == 0 and self.threadDl.remote_size > 0:
            self.size, self.size_unit = self.setSize(self.threadDl.remote_size)
            self.size_kib = self.threadDl.remote_size_kb 
        
        self.timeout += 1
        self.threadDl.stop = self._stop
        self.threadDl.abort = self._abort
        
        if self._abort:
            if not self.threadDl.isAlive():
                self.check_download.stop()
                if os.path.exists(self.dest_file):
                    os.remove(self.dest_file)
                self.aborted = True
            return
            
        self.time_passed = datetime.now() - self.init_date
        
        if self._stop and self.stop_date is None: #if stopped
            self.stop_date = datetime.now()
        
        if self.stop_date and not self._stop: #if restarted 
            self.time_stopped += datetime.now() - self.stop_date
            self.stop_date = None
            
        self.calcTimeLeft()
            
        #timeout
        if self.timeout == 20 and self.threadDl.local_size == 0:
            self._abort = True
            return

        #if finished
        if self.threadDl.isDone():
            if self.new_path:
                shutil.copy(self.dest_file, self.new_path)
            self.completed = True
            self.check_download.stop()
        #else update 
        elif self.local_size_ant < self.threadDl.local_size:
            self.speed = self.threadDl.local_size - self.local_size_ant
            self.speed, self.speed_unit = self.setSize(self.speed * 1024)
            self.speed_unit += "/s"
            self.local_size_ant = self.downloaded = self.threadDl.local_size #in KiB
        

    def calcTimeLeft(self):
        sec = float(str(self.time_passed-self.time_stopped).split(':')[2])
        min = float(str(self.time_passed-self.time_stopped).split(':')[1]) * 60
        hour = float(str(self.time_passed-self.time_stopped).split(':')[0]) * 3600
        
        time_passed_sec = sec + min + hour
        
        try:
            time_left_sec = ((self.size_kib - self.downloaded) * time_passed_sec) / self.downloaded
            self.time_left_str = time.strftime('%H:%M:%S', time.gmtime(time_left_sec))
        except ZeroDivisionError:
            pass
        
    def setSize(self, size):
        """receives size in bytes"""
        unit = "???"
        for unit in ("B", "KiB", "MiB", "GiB", "TiB", "PiB"):
            if size < 2**10:
                return size, unit
            else: 
                size /= 2**10
                
        return size, unit
        
    def copyAfterComplete(self, path, name):
        new_dest = get_new_file(path, name)
        if self.completed:
            shutil.copy(self.dest_file, new_dest)
        else:
            self.new_path = new_dest
            
            
    def abort(self):
        self._abort = True

    def stop(self):
        self._stop = True
    
    def isStopped(self):
        return self._stop
    
    def isActive(self):
        return not self.completed and not self.aborted
        
    def resume(self):
        self._stop = False
Beispiel #4
0
class Slider(QSlider):
    def __init__(self, parent = None, orientation=Qt.Horizontal):
        QSlider.__init__(self, orientation, parent)
        self.setPageStep(1)
        self.paused = False
        self.setEnabled(False)
        self.max = 0
        self.value_when_pressed = 0
        self.progress_max = 0
        self.progress = 0
        self.setValue(0)
        self.last_value = 0
        self.lastSeeked = 0
        self.time_when_paused = 0
        self.is_sliderMoving = False
        self.MediaPlayer = None
        self.last_valid_value = 0
        self.progressBarHeight = 0
        self.ignoreHandle = False

        self.timer_update_slider = QTimer()
        self.timer_update_slider.timeout.connect(self.update_slider)
        
        self.sliderPressed.connect(self.on_slider_press)
        self.sliderReleased.connect(self.on_slider_release)
        self.sliderMoved.connect(self.on_slider_move)
        
        self.setSetStyleSheet()
        
        
    def setSetStyleSheet(self):
        #Modified version of this one:
        #http://thesmithfam.org/blog/2010/03/10/fancy-qslider-stylesheet/
        if self.progressBarHeight == 0:
          height = 17
        else:
          height = self.progressBarHeight
        
        self.setStyleSheet('''\

                    QSlider::groove:horizontal {
                    border: 1px solid #bbb;
                    background: white;
                    height: %spx;
                    border-radius: 4px;
                    }

                    QSlider::sub-page:horizontal {
                    background: qlineargradient(x1: 0, y1: 0,    x2: 0, y2: 1,
                        stop: 0 #66e, stop: 1 #bbf);
                    background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,
                        stop: 0 #bbf, stop: 1 #55f);
                    border: 1px solid #777;
                    height: 10px;
                    border-radius: 4px;
                    }


                    QSlider::handle:horizontal {
                    background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                        stop:0 #eee, stop:1 #ccc);
                    border: 1px solid #777;
                    width: 13px;
                    margin-top: -2px;
                    margin-bottom: -2px;
                    border-radius: 4px;
                    }

                    QSlider::handle:horizontal:hover {
                    background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                        stop:0 #fff, stop:1 #ddd);
                    border: 1px solid #444;
                    border-radius: 4px;
                    }

                    QSlider::sub-page:horizontal:disabled {
                    background: #bbb;
                    border-color: #999;
                    }

                    QSlider::handle:horizontal:disabled {
                    background: #eee;
                    border: 1px solid #aaa;
                    border-radius: 4px;
                    }

        ''' % height)
        
    def add_player(self, player):
        self.MediaPlayer = player

    def start(self):
        self.paused = False
    
    def pause(self):
        self.paused = not self.paused
        self.time_when_paused = self.MediaPlayer.get_position() * 1000
        
        
    def reset(self, progress_bar=True):
        if self.timer_update_slider.isActive():
            self.timer_update_slider.stop()
        self.setValue(0)
        self.last_valid_value = self.last_value = self.lastSeeked = 0
        if progress_bar:
            self.progress = self.progress_max = 0
        self.update()
        self.ignoreHandle = False
        
    def complete(self):
        self.reset(progress_bar=False)
        
    def startProgressBar(self):
        self.setEnabled(True)
        self.paused = True
        self.ignoreHandle = True
        self.setMaximum(1000)
        self.progress_max = 1000
        if not self.timer_update_slider.isActive():
            self.timer_update_slider.start(1000)
        
    def loadfile(self, filepath, position=0.0):
        self.setEnabled(True)
        self.paused = False
        self.filepath = filepath
        self.MediaPlayer.set_position( position )
        self.time_when_paused = self.last_valid_value = self.last_value = 0
        if not self.timer_update_slider.isActive():
            self.timer_update_slider.start(1000)
        self.ignoreHandle = False
    
    
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            newEvent = QMouseEvent( event.type(), event.pos(), event.globalPos(),
                Qt.MouseButton( event.button() ^ Qt.LeftButton ^ Qt.MidButton ),
                Qt.MouseButtons( event.buttons() ^ Qt.LeftButton ^ Qt.MidButton ),
                event.modifiers() )
            QSlider.mousePressEvent(self, newEvent )
        else:
            QSlider.mousePressEvent(self, event )

        
    def seekTick(self):
        if self.value() != self.lastSeeked:
            lastSeeked = self.value()
            f_pos = (float)(self.lastSeeked)/1000.0
            self.emit (sliderDragged( f_pos ))

    
    def on_slider_press(self):
        self.value_when_pressed = self.value()
    
    def on_slider_move(self):
        self.is_sliderMoving = True
    
    
    def on_slider_release(self):
        if self.ignoreHandle: 
            self.setValue(self.last_value)
            return
            
        if self.value() < self.max:
            self.last_valid_value = self.last_value
            self.MediaPlayer.set_position( self.value() / 1000.0)
        elif self.is_sliderMoving:
            self.setValue(self.value_when_pressed)
        else:
            self.setValue(self.last_value)
            
        self.is_sliderMoving = False
    
    def update_slider(self):
        if self.paused: 
            #keep updating the progress bar
            self.update()
            return
        
        if self.MediaPlayer.get_position() is not None:
            self.setValue(self.MediaPlayer.get_position() * 1000)
            self.last_value = self.MediaPlayer.get_position() * 1000
            
            
    def paintEvent(self, ev):
        p = QPainter (self)
        opt = QStyleOptionSlider()
        self.initStyleOption(opt)
        opt2 = QStyleOptionProgressBar()
        opt2.initFrom(self)
        if self.progress_max > 0:
            opt2.maximum = self.progress_max
            opt2.progress = self.progress
        else:
            opt2.maximum = -1
            opt2.progress = -1
        
        if self.progressBarHeight == 0:
          self.progressBarHeight = opt2.rect.height() - 3
          self.setSetStyleSheet()
        
        sp = QStylePainter(self)
        sp.drawControl(QStyle.CE_ProgressBar, opt2)
        
        opt.subControls = QStyle.SC_SliderHandle
        self.style().drawComplexControl(QStyle.CC_Slider, opt, p, self)
    def __init__(self, app=None, options=None, args=None):
        """Initialize the GUI and many variables and load the configuration."""
        
        
        super(Gui, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.playlistWidget.hide()
        
        self.app = app
        
        # Load settings
        self.settings = Settings()
        
        self.download_urls = {}
        self.download_folder = c.HOME_FOLDER
        self.convert_thread = None
        self.active_download_items = []
        self.downloads_trash = []
        self.match_url = None
        self.action = ""
        self.namelabel = None
        self.menu_active = None
        self.show_confirm_dialog = True
        self.active_tree_widget = None
        self.ignoreMovement = 0
        self.quality_options = ["custom", "ask", "low", "high"]
        #the user can use different temporary quality
        self.global_quality = self.settings.global_quality 
        self.clipboard = QtGui.QApplication.clipboard()
        self.visited_urls = []
        self.searchIconSize = QSize(0, 0)
        
        #create actions for downloads, search and player's right click menu
        self.start = QAction(QIcon(c.PATH_MEDIA + "start.png"), self.tr("Start"), self)
        self.stop = QAction(QIcon(c.PATH_MEDIA + "stop.png"), self.tr("Stop"), self)
        self.remove = QAction(QIcon(c.ICON_REMOVE), self.tr("Remove"), self)
        self.remove_delete = QAction(QIcon(c.ICON_DELETE), self.tr("Remove and delete file"), self)
        self.opendir = QAction(QIcon(c.ICON_OPEN_FOLDER), self.tr("Open Folder"), self)
        self.copyurl = QAction(QIcon(c.ICON_COPY), self.tr("Copy original URL"), self)
        self.a_play_local = QAction(self.tr("Play local file"), self)
        self.a_download = QAction(QIcon(c.ICON_DOWNLOAD), self.tr("Download"), self)
        
        
        if HAS_PLAYER and c.HAS_FFMPEG:
          self.player = Player(self)
          #self.ui.horizontalLayout.addWidget(self.player.slider)
          self.ui.videoWidget.installEventFilter(self)
          self.ui.playlistWidget.installEventFilter(self)
          self.videoWidgetParent = self.ui.videoWidget.parentWidget()
          

          #player's right click menu
          self.ui.videoWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
          self.menu_player = QMenu(self)
          self.menu_player.addAction(self.copyurl)
          self.menu_player.addAction(self.a_download)
          self.ui.videoWidget.customContextMenuRequested.connect(self.showPlayerRightClickMenu)
          
          
          self.ui.nameLabel.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
          #repeat button
          self.disabled_replay_icon = gui_utils.getGreyedIcon(c.ICON_REPEAT)
          self.enabled_replay_icon = QIcon(c.ICON_REPEAT)
          self.ui.btn_replay.setFlat(True)
          self.onReplayClicked(next=False)#update button's icon
        else:
          self.ui.tab_widget.removeTab(0)
          self.player = None
        
        #cancel button
        self.b_cancelSearch = QPushButton("Cancel", self.ui.statusbar)
        self.b_cancelSearch.clicked.connect(self.cancelSearch)
        self.b_cancelSearch.hide()
        
        #quality button
        self.btn_quality = QPushButton(self.ui.statusbar)
        self.btn_quality.setFlat(True)
        self.ui.statusbar.addPermanentWidget(self.btn_quality)
        self.switchQuality(next=False)
        
        #create tray icon
        self.trayicon = QSystemTrayIcon(QIcon(c.ICON_WATCHVIDEO), self.app)
        self.trayicon.show()
        
        self.notification = Notification(self.trayicon, self.settings)
        

        self.dialogs = {
            'about': None,        # The instance of the "About..." window will be stored here
            'preferences': None,        # The instance of the "Preferences" window will be stored here
            'add_videos': None,
            }

        
        if c.FIREFOX_SESSION is None:
            self.ui.a_searchBrowser.setDisabled(True)
        
        
        self.ui.tree_downloads.setColumnCount(5)
        self.ui.tree_downloads.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.menu = QMenu(self)
        
        #Timers
        self.timer_check_downloads = QTimer(self)
        self.timer_check_downloads.timeout.connect(self.updateDownloads)
        self.convert_timer = QTimer(self)
        self.convert_timer.timeout.connect(self.isConversionDone)
        self.timer_match_urls = QTimer(self)
        self.timer_match_urls.timeout.connect(self.isCheckingDone)
        self.close_timer = QTimer(self)
        self.close_timer.timeout.connect(self.close_window)
        self.close_timer.setSingleShot(True)
        
        #stuff related to the search
        self.search = None
        self.ui.searchLine.addResultsWidget(self.ui.resultsWidget)
        self.ui.resultsWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.ui.searchLine.setFocus(QtCore.Qt.MouseFocusReason)
        self.ui.dockWidget.addAction(self.ui.a_viewSearch)
        self.abort_search_timer = QTimer(self)
        self.abort_search_timer.timeout.connect(self.searchYoutube)
        self.abort_search_timer.setSingleShot(True)
        
        #add actions to the search's right click menu
        self.search_menu = QMenu(self)
        self.search_menu.addAction(self.copyurl)
        self.search_menu.addAction(self.a_download)
        
        #add actions to the download's right click menu
        self.menu.addAction(self.start)
        self.menu.addAction(self.stop)
        self.menu.addSeparator()
        self.menu.addAction(self.remove)
        self.menu.addAction(self.remove_delete)
        self.menu.addSeparator()
        self.menu.addAction(self.opendir)
        self.menu.addAction(self.copyurl)
        self.menu.addAction(self.a_play_local)

        
        # connect signals with slots
        self.ui.a_addVideos.triggered.connect(self.showAddVideos)
        self.ui.a_searchBrowser.triggered.connect(self.searchBrowser)
        self.ui.a_clearCompleted.triggered.connect(self.clearCompleted)
        self.ui.a_preferences.triggered.connect(self.showPreferences)
        self.ui.a_about.triggered.connect(self.showAbout)
        self.ui.a_quit.triggered.connect(self.close)
        self.ui.a_clipboard.triggered.connect(self.addFromClipboard)
        self.ui.a_clipboard.hovered.connect(self.showStatusMessage)
        self.ui.a_play.triggered.connect(self.addFromClipboard)
        self.ui.a_play.hovered.connect(self.showStatusMessage)
        self.ui.a_download.triggered.connect(self.addFromClipboard)
        self.ui.a_download.hovered.connect(self.showStatusMessage)
        self.copyurl.triggered.connect(self.copyOriginalUrl)
        self.ui.tree_downloads.customContextMenuRequested.connect(self.showRightClickMenu)
        self.ui.tree_downloads.itemDoubleClicked.connect(self.onDownloadDoubleClick)
        self.start.triggered.connect(self.startDownloads)
        self.stop.triggered.connect(self.stopDownloads)
        self.remove.triggered.connect(self.removeTriggered)
        self.remove_delete.triggered.connect(self.removeAndDelete)
        self.opendir.triggered.connect(self.openDir)
        self.trayicon.activated.connect(self.openWindow)
        self.a_play_local.triggered.connect(self.play)
        self.clipboard.dataChanged.connect(self.clipboardDataChanged)
       
        self.ui.btn_replay.clicked.connect(self.onReplayClicked)
        self.btn_quality.clicked.connect(self.switchQuality)

        #search related signals
        self.ui.searchLine.returnPressed.connect(self.searchYoutube)
        self.ui.b_search.pressed.connect(self.searchYoutube)
        self.ui.resultsWidget.itemDoubleClicked.connect(self.onSearchDoubleClick)
        self.a_download.triggered.connect(self.onDownloadActionPressed)
        self.ui.resultsWidget.customContextMenuRequested.connect(self.showResultsRightClickMenu)
        self.ui.a_viewSearch.toggled.connect(lambda state: self.ui.dockWidget.setVisible(state))
        
        self.loadWindow() #loads window geometry, widgets' size, etc
        
        if len(args) > 0:
            if options.down:
                self.action = "download"
                self.getFilesUrl(args)
            elif options.more:
                self.action = "clipboard"
                self.getFilesUrl(args)
            else:
                self.action = "play"
                self.getFilesUrl(args)
class Gui(QtGui.QMainWindow):
    """WatchVideo's main class."""
    #gotVideo = Signal(tuple)  
    
    def __init__(self, app=None, options=None, args=None):
        """Initialize the GUI and many variables and load the configuration."""
        
        
        super(Gui, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.playlistWidget.hide()
        
        self.app = app
        
        # Load settings
        self.settings = Settings()
        
        self.download_urls = {}
        self.download_folder = c.HOME_FOLDER
        self.convert_thread = None
        self.active_download_items = []
        self.downloads_trash = []
        self.match_url = None
        self.action = ""
        self.namelabel = None
        self.menu_active = None
        self.show_confirm_dialog = True
        self.active_tree_widget = None
        self.ignoreMovement = 0
        self.quality_options = ["custom", "ask", "low", "high"]
        #the user can use different temporary quality
        self.global_quality = self.settings.global_quality 
        self.clipboard = QtGui.QApplication.clipboard()
        self.visited_urls = []
        self.searchIconSize = QSize(0, 0)
        
        #create actions for downloads, search and player's right click menu
        self.start = QAction(QIcon(c.PATH_MEDIA + "start.png"), self.tr("Start"), self)
        self.stop = QAction(QIcon(c.PATH_MEDIA + "stop.png"), self.tr("Stop"), self)
        self.remove = QAction(QIcon(c.ICON_REMOVE), self.tr("Remove"), self)
        self.remove_delete = QAction(QIcon(c.ICON_DELETE), self.tr("Remove and delete file"), self)
        self.opendir = QAction(QIcon(c.ICON_OPEN_FOLDER), self.tr("Open Folder"), self)
        self.copyurl = QAction(QIcon(c.ICON_COPY), self.tr("Copy original URL"), self)
        self.a_play_local = QAction(self.tr("Play local file"), self)
        self.a_download = QAction(QIcon(c.ICON_DOWNLOAD), self.tr("Download"), self)
        
        
        if HAS_PLAYER and c.HAS_FFMPEG:
          self.player = Player(self)
          #self.ui.horizontalLayout.addWidget(self.player.slider)
          self.ui.videoWidget.installEventFilter(self)
          self.ui.playlistWidget.installEventFilter(self)
          self.videoWidgetParent = self.ui.videoWidget.parentWidget()
          

          #player's right click menu
          self.ui.videoWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
          self.menu_player = QMenu(self)
          self.menu_player.addAction(self.copyurl)
          self.menu_player.addAction(self.a_download)
          self.ui.videoWidget.customContextMenuRequested.connect(self.showPlayerRightClickMenu)
          
          
          self.ui.nameLabel.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
          #repeat button
          self.disabled_replay_icon = gui_utils.getGreyedIcon(c.ICON_REPEAT)
          self.enabled_replay_icon = QIcon(c.ICON_REPEAT)
          self.ui.btn_replay.setFlat(True)
          self.onReplayClicked(next=False)#update button's icon
        else:
          self.ui.tab_widget.removeTab(0)
          self.player = None
        
        #cancel button
        self.b_cancelSearch = QPushButton("Cancel", self.ui.statusbar)
        self.b_cancelSearch.clicked.connect(self.cancelSearch)
        self.b_cancelSearch.hide()
        
        #quality button
        self.btn_quality = QPushButton(self.ui.statusbar)
        self.btn_quality.setFlat(True)
        self.ui.statusbar.addPermanentWidget(self.btn_quality)
        self.switchQuality(next=False)
        
        #create tray icon
        self.trayicon = QSystemTrayIcon(QIcon(c.ICON_WATCHVIDEO), self.app)
        self.trayicon.show()
        
        self.notification = Notification(self.trayicon, self.settings)
        

        self.dialogs = {
            'about': None,        # The instance of the "About..." window will be stored here
            'preferences': None,        # The instance of the "Preferences" window will be stored here
            'add_videos': None,
            }

        
        if c.FIREFOX_SESSION is None:
            self.ui.a_searchBrowser.setDisabled(True)
        
        
        self.ui.tree_downloads.setColumnCount(5)
        self.ui.tree_downloads.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.menu = QMenu(self)
        
        #Timers
        self.timer_check_downloads = QTimer(self)
        self.timer_check_downloads.timeout.connect(self.updateDownloads)
        self.convert_timer = QTimer(self)
        self.convert_timer.timeout.connect(self.isConversionDone)
        self.timer_match_urls = QTimer(self)
        self.timer_match_urls.timeout.connect(self.isCheckingDone)
        self.close_timer = QTimer(self)
        self.close_timer.timeout.connect(self.close_window)
        self.close_timer.setSingleShot(True)
        
        #stuff related to the search
        self.search = None
        self.ui.searchLine.addResultsWidget(self.ui.resultsWidget)
        self.ui.resultsWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.ui.searchLine.setFocus(QtCore.Qt.MouseFocusReason)
        self.ui.dockWidget.addAction(self.ui.a_viewSearch)
        self.abort_search_timer = QTimer(self)
        self.abort_search_timer.timeout.connect(self.searchYoutube)
        self.abort_search_timer.setSingleShot(True)
        
        #add actions to the search's right click menu
        self.search_menu = QMenu(self)
        self.search_menu.addAction(self.copyurl)
        self.search_menu.addAction(self.a_download)
        
        #add actions to the download's right click menu
        self.menu.addAction(self.start)
        self.menu.addAction(self.stop)
        self.menu.addSeparator()
        self.menu.addAction(self.remove)
        self.menu.addAction(self.remove_delete)
        self.menu.addSeparator()
        self.menu.addAction(self.opendir)
        self.menu.addAction(self.copyurl)
        self.menu.addAction(self.a_play_local)

        
        # connect signals with slots
        self.ui.a_addVideos.triggered.connect(self.showAddVideos)
        self.ui.a_searchBrowser.triggered.connect(self.searchBrowser)
        self.ui.a_clearCompleted.triggered.connect(self.clearCompleted)
        self.ui.a_preferences.triggered.connect(self.showPreferences)
        self.ui.a_about.triggered.connect(self.showAbout)
        self.ui.a_quit.triggered.connect(self.close)
        self.ui.a_clipboard.triggered.connect(self.addFromClipboard)
        self.ui.a_clipboard.hovered.connect(self.showStatusMessage)
        self.ui.a_play.triggered.connect(self.addFromClipboard)
        self.ui.a_play.hovered.connect(self.showStatusMessage)
        self.ui.a_download.triggered.connect(self.addFromClipboard)
        self.ui.a_download.hovered.connect(self.showStatusMessage)
        self.copyurl.triggered.connect(self.copyOriginalUrl)
        self.ui.tree_downloads.customContextMenuRequested.connect(self.showRightClickMenu)
        self.ui.tree_downloads.itemDoubleClicked.connect(self.onDownloadDoubleClick)
        self.start.triggered.connect(self.startDownloads)
        self.stop.triggered.connect(self.stopDownloads)
        self.remove.triggered.connect(self.removeTriggered)
        self.remove_delete.triggered.connect(self.removeAndDelete)
        self.opendir.triggered.connect(self.openDir)
        self.trayicon.activated.connect(self.openWindow)
        self.a_play_local.triggered.connect(self.play)
        self.clipboard.dataChanged.connect(self.clipboardDataChanged)
       
        self.ui.btn_replay.clicked.connect(self.onReplayClicked)
        self.btn_quality.clicked.connect(self.switchQuality)

        #search related signals
        self.ui.searchLine.returnPressed.connect(self.searchYoutube)
        self.ui.b_search.pressed.connect(self.searchYoutube)
        self.ui.resultsWidget.itemDoubleClicked.connect(self.onSearchDoubleClick)
        self.a_download.triggered.connect(self.onDownloadActionPressed)
        self.ui.resultsWidget.customContextMenuRequested.connect(self.showResultsRightClickMenu)
        self.ui.a_viewSearch.toggled.connect(lambda state: self.ui.dockWidget.setVisible(state))
        
        self.loadWindow() #loads window geometry, widgets' size, etc
        
        if len(args) > 0:
            if options.down:
                self.action = "download"
                self.getFilesUrl(args)
            elif options.more:
                self.action = "clipboard"
                self.getFilesUrl(args)
            else:
                self.action = "play"
                self.getFilesUrl(args)
                
        

    def clipboardDataChanged(self):
        if not self.settings.check_links_auto: return
        
        if "http" in self.clipboard.text():
            text = self.clipboard.text().split()
            text = [ url for url in text if url not in self.visited_urls and "http://" in url ]
            
            if text:
                self.action = "clipboard-auto"
                self.getFilesUrl(text)
            
      
    def showPlayerRightClickMenu(self):
        if self.player and self.player.download:
            self.menu_active = "player"
            point = QtGui.QCursor.pos() 
            self.menu_player.exec_(point)
    
    
    def onDownloadActionPressed(self):
        """Used by the player and search"""
        if self.menu_active == "player":
            download_item = self.player.getDownloadItem()
            name = os.path.split(download_item.dest_file)[1]
            download_item.copyAfterComplete(self.settings.download_folder, name)
            tree_item = TreeWidgetItem([name, "-", "", "0", "00:00:00"], 
                                        download_item)
                                        
            #insert QProgressBar
            self.ui.tree_downloads.addTopLevelItem(tree_item)
            self.ui.tree_downloads.setItemWidget(tree_item, 2, QProgressBar(self.ui.tree_downloads))
            
            self.active_download_items.append(tree_item)
            if not self.timer_check_downloads.isActive():
                self.timer_check_downloads.start(1000)

                
        else:
            urls = [ item.getOriginalUrl() for item in self.ui.resultsWidget.selectedItems()]
            self.action = "download"
            self.getFilesUrl(urls)
            
            
    def onSearchDoubleClick(self, item, pos):
        """On double click play the video - ToDo: Add option in preferences"""
        last_index = self.ui.resultsWidget.topLevelItemCount() - 1
        if not self.search.isRunning() and self.ui.resultsWidget.indexOfTopLevelItem(item) == last_index:
            self.ui.resultsWidget.takeTopLevelItem(last_index)
            self.searchYoutube(False)
            return
        
        self.action = "play"
        self.getFilesUrl([item.getOriginalUrl()])
        
    
    def searchYoutube(self, clear_previous_search=True):
        if self.ui.searchLine.isEmpty():
            return
    
        if self.search and self.search.isRunning():
            self.search.abort()
            self.abort_search_timer.start(1000)
            return
        
        if clear_previous_search:
            for i in xrange(self.ui.resultsWidget.topLevelItemCount()-1, -1, -1):
                self.ui.resultsWidget.takeTopLevelItem(i)
            
        start_pos = self.ui.resultsWidget.topLevelItemCount() + 1
        
        self.search = Search(self, start_pos)
        self.search.start()
    
    
    def addResult(self, item):
        image = item[0]
        if image:
            if image != QImage(c.ICON_ADD) and (image.width() > self.searchIconSize.width() and 
            image.height() > self.searchIconSize.height()):
                self.searchIconSize = QSize(image.width(), image.height())
                self.ui.resultsWidget.setIconSize(QSize(image.width(),image.height()))
                
                #image = gui_utils.setTextOnImage(image, "")
                
            item[1].setIcon(0, QIcon(QPixmap.fromImage(image)))
        self.ui.resultsWidget.addTopLevelItem(item[1])
    
    def onReplayClicked(self, checked=False, next=True):
        
        if next:
            i = self.player.repeat_modes.index(self.player.repeat)
            if i == len(self.player.repeat_modes) - 1:
                i = 0
            else:
                i += 1
                
            self.player.repeat = self.player.repeat_modes[i]
      
        if self.player.repeat == "none":
            self.ui.btn_replay.setIcon(self.disabled_replay_icon)
            self.ui.btn_replay.setToolTip(self.tr("Don't repeat"))
        elif self.player.repeat == "one":
            self.ui.btn_replay.setIcon(self.enabled_replay_icon)
            self.ui.btn_replay.setToolTip(self.tr("Repeat track"))
        else:
            self.ui.btn_replay.setIcon(QIcon(c.ICON_PLAYLIST_REPEAT))
            self.ui.btn_replay.setToolTip(self.tr("Repeat playlist"))
        

    def switchQuality(self, checked=False, next=True):
    
        if next: #when clicking in the button
            quality_options = self.quality_options
            if self.settings.global_video_quality: #remove the "custom" key
                quality_options = quality_options[1:]
            
            try:
                i = quality_options.index(self.global_quality)
                if i == len(quality_options) - 1:  i = 0
                else: i += 1
            except ValueError:
                i = 0
                
            option = quality_options[i]
        else:
            option = self.global_quality = self.settings.global_quality
        
        if option == "ask":
            icon = QIcon(c.ICON_ASK_QUALITY)
            msg = self.tr("A dialog to choose the format will appear for all videos with more than one format available.")
            img = "<img src='%s'><br></br>" % c.ICON_ASK_QUALITY
        elif option == "low":
            icon = QIcon(c.ICON_LOW_QUALITY)
            msg = self.tr("All videos are played/downloaded in the lowest quality available.")
            img = "<img src='%s'><br></br>" % c.ICON_LOW_QUALITY
        elif option == "high":
            icon = QIcon(c.ICON_HIGH_QUALITY)
            msg = self.tr("All videos are played/downloaded in the highest quality available.")
            img = "<img src='%s'><br></br>" % c.ICON_HIGH_QUALITY
        else:
            icon = QIcon(c.ICON_CUSTOM_QUALITY)
            msg = self.tr("The videos are played/downloaded according to what " + \
            "was defined in preferences. If it's the first time accessing a particular " + \
            "website through WatchVideo, the default action will be to ask for the quality.")
            img = "<img src='%s'><br></br>" % c.ICON_CUSTOM_QUALITY
        
        self.global_quality = img.split(":/media/")[1].split("-")[0]
        self.btn_quality.setToolTip(img+msg)
        self.btn_quality.setIcon(icon)
   
    def onDownloadDoubleClick(self, item, pos):
        #Open the folder containing the video or play it.
        download = item.getDownload()
        if not self.settings.play_downloaded:
            self.playDownload(download)
        else:
            self.openDir(os.path.split(download.dest_file)[0])
    
    def playDownload(self, download):
        if os.path.exists(download.dest_file):
            filename = os.path.split(download.dest_file)[1]
            Thread(target=main.play, args=(download.dest_file, filename,
            self.settings.media_player)).start()
                
                
    def startDownloads(self):
        if self.active_tree_widget is None: return
        for item in self.active_tree_widget.selectedItems():
            download = item.getDownload().resume()

    def stopDownloads(self):
        if self.active_tree_widget is None: return
        for item in self.active_tree_widget.selectedItems():
            download = item.getDownload()
            download.stop()
            item.setText(3, "Paused")
            item.setText(4, "Paused")

                    
    def removeTriggered(self):
        downloads_removed = []
        if self.active_tree_widget is None: return
        
        answer = None
 
        for item in self.active_tree_widget.selectedItems():
            download = item.getDownload()
            
            if answer is None:
                if not download.isActive():
                    answer = QtGui.QMessageBox.Yes
                else:
                    answer = gui_utils.confirm(self, "Abort Download(s)", self.tr("This will abort the download(s) too, are you sure?"))
            
            if answer == QtGui.QMessageBox.No: return
            
            if "playlist" in self.active_tree_widget.objectName():
                if download == self.player.download:
                    self.player.stop()
                
                if item in self.player.treeWidgetItems:
                    self.player.treeWidgetItems.remove(item)
                    
            
            if download.isActive():
                download.abort()
                self.downloads_trash.append(download)
            
            #remove the item
            self.removeDownloadItem(item)
            
            downloads_removed.append(download)
        
        if ( "downloads" in self.active_tree_widget.objectName()
        and self.active_tree_widget.topLevelItemCount() == 0 ):
            self.ui.a_clearCompleted.setDisabled(True)
                    
        return downloads_removed
                        
            
    
    def removeAndDelete(self):
        downloads_removed = self.removeTriggered()
        
        for download in downloads_removed:
            os.remove(download.dest_file)


    def showResultsRightClickMenu(self, point):
        if self.ui.resultsWidget.selectedItems():
            self.menu_active = "search"
            point = QtGui.QCursor.pos() 
            self.search_menu.exec_(point) 
     
    def showRightClickMenu(self, point):
        if self.ui.tree_downloads.selectedItems():
            self.active_tree_widget = self.ui.tree_downloads
            paused_found = False
            active_found = False
            completed_found = False
            self.menu_active = "download"
            
            for item in self.ui.tree_downloads.selectedItems():
                download = item.getDownload()
                
                if download.isStopped():
                    paused_found = True
                elif download.completed:
                    completed_found = True
                else:
                    active_found = True
                    
                    
            if completed_found:
                self.a_play_local.setEnabled(True)
            else:
                self.a_play_local.setEnabled(False)
            
            if active_found: #if an active download is found
                if not self.stop.isEnabled(): self.stop.setEnabled(True)
            else:
                if self.stop.isEnabled(): self.stop.setEnabled(False)
            
            if paused_found: #if a paused download is found
                if not self.start.isEnabled(): self.start.setEnabled(True)
            else:
                if self.start.isEnabled(): self.start.setEnabled(False)
                        
            point = QtGui.QCursor.pos() 
            self.menu.exec_(point)
        
        
    def addNewDownloads(self, videos):
        self.action = ""
        if not videos: return
        
        if videos[0].down: #download
            self.ui.tab_widget.setCurrentIndex(1)
            for video in videos:
                if len(video.name) * 7 > self.ui.tree_downloads.header().sectionSize(0):
                    self.ui.tree_downloads.header().resizeSection(0, len(video.name)*7)
                
                download_item = DownloadItem(video.url, video.dl_url, video.filepath, video.after_complete, self)
                
                item = TreeWidgetItem([video.name, "-", "", "0", "00:00:00"], download_item)
                #insert QProgressBar
                self.ui.tree_downloads.addTopLevelItem(item)
                self.ui.tree_downloads.setItemWidget(item, 2, QProgressBar(self.ui.tree_downloads))
                
                download_item.start()
                self.active_download_items.append(item)
                
                if not self.timer_check_downloads.isActive():
                    self.timer_check_downloads.start(750)
        else: #Play
            self.ui.tab_widget.setCurrentIndex(0)
            if self.settings.use_builtin_player:
                for video in videos:
                    item = DownloadItem(video.url, video.dl_url, video.filepath, video.after_complete, self)
                    self.player.loadfile(video.filepath, item)
            else:
                #names = [video.name for video in videos]
                #urls = [video.dl_url for video in videos]
                for video in videos:
                    Thread(target=main.play, args=(video.dl_url, video.name,
                        self.settings.media_player)).start()
                    time.sleep(2)
                
        
        

    def afterComplete(self, download_item):
        start_thread = False
        if download_item.after_complete == 1: #play option
            Thread(target=main.play, args=(download_item.dest_file, os.path.split(download_item.dest_file)[1],
            self.settings.media_player)).start()
        elif download_item.after_complete == 2: #convert to Ogg Vorbis
            self.convert_thread = Convert(main.convert, download_item.dest_file)
            start_thread = True
        elif download_item.after_complete == 3: #convert to Ogg Theora
            self.convert_thread = Convert(main.convert, download_item.dest_file, audio_only=False)
            start_thread = True
        elif download_item.after_complete == 4: #rip audio option
            self.convert_thread = Convert(main.rip, download_item.dest_file)
            start_thread = True
            
        if start_thread:
            self.convert_thread.start()
            self.convert_timer.start(750)
            
            
    def isConversionDone(self):
        if self.convert_thread.type == "rip":
            message_waiting = self.tr("Ripping audio of") + " " + self.convert_thread.filename
            title_done = self.tr("Audio Ripped")
            title_error = self.tr("Error ripping audio")
        else:
            message_waiting = self.tr("Converting video:") + " " + self.convert_thread.filename
            title_done = self.tr("Video Converted")
            title_error = self.tr("Error converting video")

        if self.convert_thread.isDone():
            self.convert_timer.stop()

            if self.convert_thread.successful:
                if self.settings.notify_done:
                    self.notification.show(title_done, self.convert_thread.filename)
                self.ui.statusbar.showMessage(title_done + ": " + self.convert_thread.filename)
            else:
                self.notification.show(title_error, self.convert_thread.filename)
                self.ui.statusbar.showMessage(title_error + ": " + self.convert_thread.filename)
                if self.settings.notify_error:
                    self.notification.show(title_error, self.convert_thread.filename)
            
            self.convert_thread = None
        else:
            self.ui.statusbar.showMessage(message_waiting)

    def searchBrowser(self):
        session = json.loads(open(c.FIREFOX_SESSION).read().strip("()"))
        urls = []

        #search windows and tabs open in firefox
        for window in session["windows"]:
            for tab in window["tabs"]:
                for entry in tab["entries"]:
                    try:
                        urls.append(entry["url"])
                    except IndexError:
                        pass
        
        self.getFilesUrl(urls, fast=True)
                        

    def getFilesUrl(self, urls, fast=False):
        if self.match_url: return
        urls = [url for url in urls if "http" in url and len(url) > len("http")] 

        if urls:
            print urls
            #add cancel button
            self.b_cancelSearch.show()
            self.ui.statusbar.insertPermanentWidget(0, self.b_cancelSearch)
            self.cleanStatusTip()
            
            
            if "clipboard" in self.action: 
                quality = "ask"
            else:
                quality = self.global_quality
            
            self.match_url = main.Match(urls, quality, fast=False) #start a check thread       
            Thread(target=self.match_url.match, args=()).start()
            
            self.timer_match_urls.start(750)
        else:
            self.ui.statusbar.showMessage(self.tr("No valid URLs found."))
    

    
    def isCheckingDone(self):
        """Called in intervals of 750ms to see if the url thread is ready"""
        if self.match_url.done:
            self.timer_match_urls.stop()
            mediums = self.match_url.mediums
            ready_mediums = self.match_url.ready_mediums
            #a new website might have been added to the settings file
            #through ConfigParser, so we need to sync the QSettings instance with
            #the settings' file
            if self.match_url.update_settings: self.settings.sync()
            self.match_url = None
            self.resetStatusBar()
            
            if not mediums and not ready_mediums:
                self.ui.statusbar.showMessage(self.tr("No supported services were found"))
                self.b_cancelSearch.setText(self.tr("Close"))
                return
            
            #append mediums' urls to the visited urls
            for medium in mediums.keys() + ready_mediums.keys():
                self.visited_urls.append(medium.url)
            
            if self.action == "clipboard-auto":
                for medium in mediums: 
                    self.notification.show("WatchVideo", medium.title)
                self.action = "clipboard"
                
            if "clipboard" in self.action:
                for medium in ready_mediums:
                    mediums[medium] = [ready_mediums[medium]]
                ready_mediums = None
            
            if mediums:
                if "clipboard" in self.action:
                    self.showAddVideos(mediums)
                else:
                    self.showAddVideos(mediums, format_mode=True)
                
            if ready_mediums: 
                self.processVideos(ready_mediums)
                
                
        elif self.match_url.url: #if the url is valid, show it
            self.ui.statusbar.showMessage(self.tr("Currently checking: ") + self.match_url.url)
    
    
    def clearCompleted(self):
        for i in xrange(self.ui.tree_downloads.topLevelItemCount()-1, -1, -1):
            item = self.ui.tree_downloads.topLevelItem(i)
            download = item.getDownload()
            
            if download.completed:
                self.ui.tree_downloads.takeTopLevelItem(i)
                
        self.ui.a_clearCompleted.setDisabled(True)
        
    def updateDownloads(self):
        if not self.active_download_items:
            if self.timer_check_downloads.isActive():
                self.timer_check_downloads.stop()
            return
        
        for download in self.downloads_trash:
            if download.aborted: self.downloads_trash.remove(download)
        
        for download_item in self.active_download_items:
            download = download_item.getDownload()
            if download.isStopped(): continue
            
            progressBar = self.ui.tree_downloads.itemWidget(download_item, 2)
            total_size = download.size
            unit = download.size_unit
            downloaded = download.downloaded
            speed = round(download.speed, 2)
            speed_unit = download.speed_unit
            time_left_str = download.time_left_str
            
            if download.completed:
                progressBar.setMaximum(download.size_kib)
                progressBar.setValue(download.size_kib)
                download_item.setText(3, "Completed") #Cleans the 'speed' column
                download_item.setText(4, "Completed") #Cleans the 'time left' column
                self.active_download_items.remove(download_item)
                
                if not self.ui.a_clearCompleted.isEnabled():
                    self.ui.a_clearCompleted.setEnabled(True)
                
                if self.settings.notify_done:
                    self.notification.show(self.tr("Download Finished"), 
                    os.path.split(download.dest_file)[1])
                
                self.afterComplete(download)
                
            else:
                download_item.setText(1, str(total_size) + " " + unit)
                progressBar.setMaximum(download.size_kib)
                progressBar.setValue(downloaded)
                
                download_item.setText(3, str(speed) + " " + speed_unit)
                download_item.setText(4, time_left_str)

    def openDir(self, dir=None):
        
        if not dir:
            directories = set()
            for item in self.active_tree_widget.selectedItems():
                download = item.getDownload()
                directories.add(os.path.split(download.dest_file)[0])
            
            filemanager = None
        else:
            directories = (dir,)
        
        for manager in c.FILEMANAGERS:
            if is_command(manager):
                filemanager = manager
                break

        if filemanager:
            for directory in directories:
                subprocess.Popen((filemanager, directory))
            
            self.ui.statusbar.showMessage(self.tr("Opening download directory %s with %s") % (" ".join(directories), filemanager), 5000)

    def processVideos(self, mediums=None):
        
        if mediums is None: return
        
        videos = []
        
        for medium in mediums:
            format = mediums[medium]
            videos.append(VideoInfo(medium.title, medium.url, format.url))
        
        if self.action == "download":
            for video in videos: 
                video.folder = self.settings.download_folder
                video.after_complete = self.settings.after_download
        elif self.action == "play":
            for video in videos: video.toPlay()
        
        self.addNewDownloads(videos)

    #dialogs
    def showAddVideos(self, urls=None, format_mode=False):
        if self.dialogs["add_videos"] is None:
            from watchvideo.add_videos import AddVideosDialog
            self.dialogs["add_videos"] = AddVideosDialog(self, self.settings)
        
        self.dialogs["add_videos"].load(urls, format_mode)
        if self.isVisible():
            self.dialogs["add_videos"].show()
            self.dialogs["add_videos"].activateWindow()
        
        

    def showPreferences(self):
        """Displays the Preferences dialog."""
        self.dialogs['preferences'] = Preferences(self, self.settings)
        self.dialogs['preferences'].show()
        self.dialogs['preferences'].activateWindow()
        
    def showAbout(self):
        """Displays the About dialog."""
        if self.dialogs['about'] is None:
            from watchvideo.about import AboutDialog
            self.dialogs['about'] = AboutDialog(self)
        
        self.dialogs['about'].show()
        self.dialogs['about'].activateWindow()
        
    def addFromClipboard(self):
        urls = self.getClipboardText().split()
        objname = self.sender().objectName()
        if "a_" in objname:
            objname = objname.split("a_")[1]
        self.action = objname
        self.getFilesUrl(urls)
        
    def getClipboardText(self):
        return self.clipboard.text()
        
    def copyOriginalUrl(self):
        """Copies the original url to the Clipboard"""
        if self.menu_active == "download":
            urls = [item.getOriginalUrl() for item in self.ui.tree_downloads.selectedItems()]
        elif self.menu_active == "search":
            urls = [item.getOriginalUrl() for item in self.ui.resultsWidget.selectedItems()]
        elif self.menu_active == "playlist":
            urls = [item.getOriginalUrl() for item in self.ui.playlistWidget.selectedItems()]
        else:
            urls = [self.player.getOriginalUrl()]
        self.clipboard.setText("\n".join(urls))
        
    def showStatusMessage(self):
        if not self.match_url:
            self.sender().setStatusTip(self.getClipboardText())
            self.sender().showStatusText()
            
    def cleanStatusTip(self):
        self.ui.a_clipboard.setStatusTip("")
        self.ui.a_download.setStatusTip("")
        self.ui.a_play.setStatusTip("")
    
    def cancelSearch(self):
        self.stopChecking()
        self.resetStatusBar()
        
    def stopChecking(self):
        if self.match_url:
            self.match_url.stop = True
            self.timer_match_urls.stop()
            self.match_url = None
            
    def resetStatusBar(self):
        self.ui.statusbar.showMessage("")
        self.ui.statusbar.removeWidget(self.b_cancelSearch)
        
    def play(self, video):
        if self.settings.use_builtin_player:
            item = DownloadItem(video.url, video.dl_url, video.filepath, video.after_complete, self)
            self.player.loadfile(video.filepath, item)
        else:
            Thread(target=main.play, args=(video.dl_url, video.name,
            self.settings.media_player)).start()
            
    def removeDownloadItem(self, item, rmFromGui=True):
        """item: is a TreeWidgetItem
           rmFromGui: if true, removes the item from the QTreeWidget """
            
        if item in self.active_download_items:
            self.active_download_items.remove(item)
            
        if rmFromGui:
            i = self.active_tree_widget.indexOfTopLevelItem(item)
            if i != -1:
                if "playlist" in self.active_tree_widget.objectName():
                    del self.player.counters[i]
                self.active_tree_widget.takeTopLevelItem(i)
        
    
    def openWindow(self, activation):
        if activation in (3, 2): #show/hide window
            if self.isVisible():
                self.hide()
                for dialog in self.dialogs:
                    if self.dialogs[dialog] and self.dialogs[dialog].isVisible():
                        self.dialogs[dialog].hide()

            else:
                self.show()
                for dialog in self.dialogs:
                    if self.dialogs[dialog] and self.dialogs[dialog].visible:
                        self.dialogs[dialog].show()
                
                if self.dialogs['add_videos'] and self.dialogs['add_videos'].mediums:
                    self.dialogs['add_videos'].show()
                
    def eventFilter(self, obj, event):
        if obj == self.ui.videoWidget:

            if self.ignoreMovement:
                self.ignoreMovement -= 1
                return False
                
            if  event.type() == QEvent.MouseMove:
                if self.ui.videoWidget.width() - 50 < event.x() < self.ui.videoWidget.width():
                    self.ui.playlistWidget.show()
                    self.ignoreMovement = 8
                    self.player.startTextMoveTimer()
                else:
                    self.ui.playlistWidget.hide()
                    self.player.stopTextMoveTimer()

                return True
            elif event.type() == QEvent.MouseButtonDblClick:
                self.player.setFullscreen()
                return True
            else:
                return False
        elif obj == self.ui.playlistWidget:
            
            if self.ignoreMovement:
                self.ignoreMovement -= 1
                return False
                
            if  event.type() == QEvent.MouseMove:
                if event.x() < 0 or event.x() > self.ui.playlistWidget.width() or\
                event.y() < 0 or event.y() > self.ui.playlistWidget.height():
                    self.ui.playlistWidget.hide()
                    self.player.stopTextMoveTimer()
                    self.ignoreMovement = 10
                return True
            else:
                return False
    
        return QtGui.QMainWindow.eventFilter(obj, event)
    
    def isEverythingAborted(self):
        abortCompleted = True 
        for download_item in self.active_download_items:
            if not download_item.getDownload().aborted:
                download_item.getDownload().abort()
                return False
                     
        if self.player and self.player.areDownloadsActive():
            return False
           
        #just a measure for extra security when closing the app
        for download in self.downloads_trash:
            if not download.aborted:
                return False
                
        if self.dialogs["add_videos"] and not self.dialogs["add_videos"].isFinished():
            return False
            
        return True
    
    def abortDownloads(self):
        for download_item in self.active_download_items:
            download = download_item.getDownload()
            if download.isActive(): download.abort()
                
        if self.player: 
            self.player.reset(downloads=True)
            
        if self.dialogs["add_videos"] and not self.dialogs["add_videos"].isFinished():
            self.dialogs["add_videos"].close()
    
    def saveWindow(self):
        self.settings.window_state = self.saveState()
        self.settings.window_geometry = self.saveGeometry()
        self.settings.show_search = self.ui.a_viewSearch.isChecked()

        
    def loadWindow(self):
        if self.settings.window_geometry:
            self.restoreGeometry(self.settings.window_geometry)
        if self.settings.window_state:
            self.restoreState(self.settings.window_state)

        self.ui.a_viewSearch.setChecked(self.settings.show_search)
        
    
    def close_window(self):
        """called by self.close_timer"""
        self.show_confirm_dialog = False
        self.close()
    
    def closeEvent(self, event):
        if self.active_download_items or (self.player and self.player.isActive()) or (
        self.dialogs["add_videos"] and not self.dialogs["add_videos"].isFinished()):
            if self.show_confirm_dialog:
                answer = gui_utils.confirm(self, title="Quit?",
                msg=self.tr("There are still some tasks active, do you really want to quit?" + 
                "\n(you won't be able to continue them after quitting)"))
            else:
                answer = QtGui.QMessageBox.Yes
            
            if answer == QtGui.QMessageBox.Yes:
                self.abortDownloads()
                if not self.isEverythingAborted():
                    #hide GUI so it gets out of the user's way while the app is closing
                    self.hide() 
                    self.close_timer.start(750)
                    event.ignore()
                    return
            else:
                event.ignore()
                return
           

        self.saveWindow()