Esempio n. 1
0
 def loadFile(self, filename):
     file = QFile()
     file.setFileName("./js/" + filename)
     file.open(QIODevice.ReadOnly)
     code = file.readAll()
     file.close()
     return "".join(str(line) for line in code)
Esempio n. 2
0
    def read_project_info(self) -> None:
        """Reads project configuration data from default storage location"""
        if QFile.exists(self.root_path + "/.manuwrite/project.toml"):
            try:
                file = QFile()
                file.setFileName(self.root_path + "/.manuwrite/project.toml")
                file.open(QFile.ReadOnly)
                data = OrderedDict(toml.loads(file.readAll().data().decode()))
            except OSError:
                raise ProjectError("An error occured while reading project file")
            finally:
                file.close()
            self.project_info = data

            for key in self.defaults.keys():
                if key not in self.project_info:
                    self.project_info[key] = self.defaults[key]

            # Update project structure
            filenames = []
            for filename in self.get_setting_value("Files to render"):
                filenames.append(self.get_setting_value("Absolute path") + "/" + filename)

            self.ThreadManager.perform_operation("parse_project", self.on_MarkdownProjectParserThread_finished,
                                                 filepaths=filenames)
            self.set_setting_value("Absolute path", self.root_path)

        else:
            raise ProjectError("Project file doesn't exits")
Esempio n. 3
0
    def readThemeIndex(self, themeName):

        dirList = []
        parents = []
        themeIndex = QFile()

        # Read theme index files
        for i in range(len(self.iconDirs)):
            themeIndex.setFileName(path.join(unicode(self.iconDirs[i]), 
                unicode(themeName), "index.theme"))
            if themeIndex.exists():
                indexReader = QSettings(themeIndex.fileName(), 
                        QSettings.IniFormat)
                for key in indexReader.allKeys():
                    if str(key).endswith("/Size"):
                        size = str(indexReader.value(key))
                        
                        dirList.append((size, 
                            unicode(key[:-5])))
                
                parents = indexReader.value('Icon Theme/Inherits')
                dump=parents
                parents = list()
                parents.append(dump)
                break
            
        return QIconTheme(dirList, parents)
Esempio n. 4
0
    def __init__(self, url):
        super().__init__()
        self.setAttribute(Qt.WA_DeleteOnClose, True)
        self.progress = 0

        f = QFile()
        f.setFileName(":/jquery.min.js")
        f.open(QIODevice.ReadOnly)
        self.jQuery = f.readAll().data().decode()
        self.jQuery += "\nvar qt = { 'jQuery': jQuery.noConflict(true) };"
        f.close()

        self.view = QWebEngineView(self)
        self.view.load(url)

        self.view.loadFinished.connect(self.adjustLocation)
        self.view.titleChanged.connect(self.adjustTitle)
        self.view.loadProgress.connect(self.setProgress)
        self.view.loadFinished.connect(self.finishLoading)

        self.locationEdit = QLineEdit(self)
        self.locationEdit.setSizePolicy(
            QSizePolicy.Expanding,
            self.locationEdit.sizePolicy().verticalPolicy())
        self.locationEdit.returnPressed.connect(self.changeLocation)

        toolBar = self.addToolBar(self.tr("Navigation"))
        toolBar.addAction(self.view.pageAction(QWebEnginePage.Back))
        toolBar.addAction(self.view.pageAction(QWebEnginePage.Forward))
        toolBar.addAction(self.view.pageAction(QWebEnginePage.Reload))
        toolBar.addAction(self.view.pageAction(QWebEnginePage.Stop))
        toolBar.addWidget(self.locationEdit)

        viewMenu = self.menuBar().addMenu(self.tr("&View"))
        viewSourceAction = QAction(self.tr("Page Source"), self)
        viewSourceAction.triggered.connect(self.viewSource)
        viewMenu.addAction(viewSourceAction)

        effectMenu = self.menuBar().addMenu(self.tr("&Effect"))
        effectMenu.addAction(self.tr("Highlight all links"),
                             self.highlightAllLinks)

        self.rotateAction = QAction(self)
        self.rotateAction.setIcon(self.style().standardIcon(
            QStyle.SP_FileDialogDetailedView))
        self.rotateAction.setCheckable(True)
        self.rotateAction.setText(self.tr("Turn images upside down"))
        self.rotateAction.toggled.connect(self.rotateImages)
        effectMenu.addAction(self.rotateAction)

        toolsMenu = self.menuBar().addMenu(self.tr("&Tools"))
        toolsMenu.addAction(self.tr("Remove GIF images"), self.removeGifImages)
        toolsMenu.addAction(self.tr("Remove all inline frames"),
                            self.removeInlineFrames)
        toolsMenu.addAction(self.tr("Remove all object elements"),
                            self.removeObjectElements)
        toolsMenu.addAction(self.tr("Remove all embedded elements"),
                            self.removeEmbeddedElements)

        self.setCentralWidget(self.view)
Esempio n. 5
0
    def readThemeIndex(self, themeName):

        dirList = []
        parents = []
        themeIndex = QFile()

        # Read theme index files
        for i in range(len(self.iconDirs)):
            themeIndex.setFileName(
                path.join(unicode(self.iconDirs[i]), unicode(themeName),
                          "index.theme"))
            if themeIndex.exists():
                indexReader = QSettings(themeIndex.fileName(),
                                        QSettings.IniFormat)
                for key in indexReader.allKeys():
                    if str(key).endswith("/Size"):
                        size = str(indexReader.value(key))

                        dirList.append((size, unicode(key[:-5])))

                parents = indexReader.value('Icon Theme/Inherits')
                dump = parents
                parents = list()
                parents.append(dump)

                break
        return QIconTheme(dirList, parents)
Esempio n. 6
0
    def transferFile(self, src_path):
        dest_path = self.model.filePath(self.rootIndex())

        src_file = QFile()
        src_file.setFileName(src_path)

        src_file_info = QFileInfo(src_path)

        dst_path = os.path.join(dest_path, src_file_info.fileName())

        src_file.copy(dst_path)
Esempio n. 7
0
 def save_project_data(self) -> None:
     """Saves project configuration data to permanent storage"""
     try:
         file = QFile()
         file.setFileName(self.root_path + "/.manuwrite/project.toml")
         file.open(QFile.WriteOnly)
         file.write(toml.dumps(self.project_info).encode())
     except OSError:
         raise ProjectError("Failed to write project configuration data")
     finally:
         file.close()
Esempio n. 8
0
    def create_file(self, path: str) -> None:
        """Creates a file at a given path"""

        try:
            file = QFile()
            file.setFileName(path)
            file.open(QFile.ReadWrite)
        except OSError:
            raise ProjectError
        finally:
            file.close()
Esempio n. 9
0
    def readFile(selfself):
        file = QFile()
        file.setFileName("./doc/test.txt")

        isok = file.open(QIODevice.ReadOnly)
        if isok:
            stream = QTextStream(file)
            #stream.setCodec("utf8")
            str = stream.readAll()
            print(str)

            file.close()
Esempio n. 10
0
class DocumentReader:
    def __init__(self, filename):
        self.file = QFile()
        self.file.setFileName(filename)
        self.is_error = False
        self.errorString = ""
        if not self.file.open(QFile.ReadOnly):
            error = self.file.errorString()
            qDebug("cannot open file \"{1}\"".format(error))
            self.is_error = True
            self.errorString = error

    def read(self, document):
        if not self.file.isOpen():
            return
        text = str(self.file.readAll().data(), encoding='utf-8')
        document.setPlainText(text)
Esempio n. 11
0
class QDeckAudioItemWidget(QAudioInput):

    audio_input = None
    outputFile = None

    def __init__(self):
        super().__init__()

    def initAudioInput(self, filepath):

        self.outputFile = QFile()
        self.outputFile.setFileName(filepath)
        self.outputFile.open(QIODevice.WriteOnly | QIODevice.Truncate)

        format = QAudioFormat()
        format.setSampleType(QAudioFormat.Float)
        format.setSampleRate(44100)
        format.setChannelCount(1)
        format.setSampleSize(32)
        format.setCodec("audio/pcm")
        format.setByteOrder(QAudioFormat.LittleEndian)

        print(format.codec())

        #self.audio_input = QAudioInput(QAudioDeviceInfo.defaultInputDevice(), format);

        self.audio_input = QAudioInput(format)

        print(self.audio_input.error())
        print(self.audio_input.state())

        #QTimer.singleShot(3000, self,

    def start(self):
        self.audio_input.start(self.outputFile)

    def stop(self):
        self.audio_input.stop()
        self.outputFile.close()

    def suspend(self):
        self.audio_input.suspend()

    def resume(self):
        self.audio_input.resume()
Esempio n. 12
0
class DocumentWriter:
    def __init__(self, filename):
        self.file = QFile()
        self.file.setFileName(filename)
        self.is_error = False
        self.errorString = ""
        if not self.file.open(QFile.WriteOnly):
            error = self.file.errorString()
            qDebug("cannot open file \"{1}\"".format(error))
            self.is_error = True
            self.errorString = error

    def write(self, document):
        if not self.file.isOpen():
            return
        writer = QTextDocumentWriter()
        writer.setFormat(QByteArray().append("plaintext"))
        writer.setDevice(self.file)
        writer.write(document)
    def readThemeIndex(self, themeName):

        dirList = []
        parents = []
        themeIndex = QFile()

        # Read theme index files
        for i in range(len(self.iconDirs)):
            themeIndex.setFileName(path.join(unicode(self.iconDirs[i]), 
                unicode(themeName), "index.theme"))
            if themeIndex.exists():
                indexReader = QSettings(themeIndex.fileName(), 
                        QSettings.IniFormat)
                for key in indexReader.allKeys():
                    if key.endswith("/Size"):
                        size = indexReader.value(key)
                        dirList.append((size[0], 
                            unicode(key.left(key.size() - 5))))
                parents = indexReader.value('Icon Theme/Inherits')
                parents = parents.toStringList()
                break
        return QIconTheme(dirList, parents)
Esempio n. 14
0
    def create_project(directory_path: str) -> None:
        """Creates a new project at given path"""

        try:
            directory = QDir(directory_path)

            directory.mkdir(".manuwrite")
            directory.mkdir("images")
            directory.mkdir("notes")
            directory.mkdir("data")

            directory.mkpath(".manuwrite/render")
            file = QFile()
            file.setFileName(directory_path + "/.manuwrite/project.toml")
            file.open(QFile.ReadWrite)

            project_settings = copy.deepcopy(defaults.project_settings)
            project_settings["Absolute path"] = {"type": "str", "value": directory_path}

            file.write(toml.dumps(project_settings).encode())
            file.close()
        except OSError:
            raise ProjectError("Error creating project files")
Esempio n. 15
0
    def readThemeIndex(self, themeName):

        dirList = []
        parents = []
        themeIndex = QFile()

        # Read theme index files
        for i in range(len(self.iconDirs)):
            themeIndex.setFileName(
                path.join(unicode(self.iconDirs[i]), unicode(themeName),
                          "index.theme"))
            if themeIndex.exists():
                indexReader = QSettings(themeIndex.fileName(),
                                        QSettings.IniFormat)
                for key in indexReader.allKeys():
                    if key.endswith("/Size"):
                        size = indexReader.value(key)
                        dirList.append(
                            (size[0], unicode(key.left(key.size() - 5))))
                parents = indexReader.value('Icon Theme/Inherits')
                parents = parents.toStringList()
                break
        return QIconTheme(dirList, parents)
Esempio n. 16
0
class NSwapFile(QObject):
    """
    In case Ninja-IDE crash, this can be used to recover the lost data.

    When the user begins to edit an existing file on the disk, this object
    creates a swap file and activates a timer that will execute a function,
    that will update that swap file as soon as the timeout ends (by default,
    is 15 seconds).
    The swap file is deleted when the original file is saved or closed.
    When system or Ninja crash, the swap file exists on disk and Ninja will
    used to recover the lost data.
    """

    canBeRecovered = pyqtSignal()

    def __init__(self, neditable):
        QObject.__init__(self)
        self._neditable = neditable
        self.__swap_file = QFile()
        self.__stream = QTextStream()

        # Activate timer when user typing
        self.__timer = QTimer()
        self.__timer.setSingleShot(True)

        self.__timer.timeout.connect(self._finish_typing)
        self._neditable.fileLoaded.connect(self._file_loaded)
        self._neditable.fileSaved.connect(self._file_saved)

        self.init(tracking=True)

    def init(self, tracking):
        if tracking:
            self._neditable.editor.textChanged.connect(self._start_typing)
            self._neditable.fileClosing.connect(self._file_closed)
        else:
            self._neditable.editor.textChanged.disconnect(self._start_typing)
            self._neditable.fileClosing.disconnect(self._file_closed)

    def _file_closed(self):
        """Editor was closed normally, now remove swap file"""

        self.__remove()

    def _file_saved(self):
        """If file is saved, remove swap file"""

        # Remove old swap file and set the name for the new swap file
        self.__remove()
        self.__update_filename()

    def __remove(self):
        """Remove swap file"""

        if self.__swap_file.fileName() and self.__swap_file.exists():
            self.__stream.setDevice(None)
            self.__swap_file.close()
            self.__swap_file.remove()

    def _file_loaded(self):
        """This slot is executed when a file is loaded on the editor and
        look for swap file, if exists then can be recover"""

        self.__update_filename()
        if self.__swap_file.exists():
            # In recovery process can't edit
            self._neditable.editor.setReadOnly(True)
            # Ok, can be recover
            self.canBeRecovered.emit()

    def __update_filename(self):
        # First clear filename
        self.__swap_file.setFileName("")
        # Get new path
        filename = self.filename()
        self.__swap_file.setFileName(filename)

    def _start_typing(self):
        # Skip if editor is not modified
        if not self._neditable.editor.is_modified:
            return
        # No swap file, no work
        if not self.__swap_file.fileName():
            return
        # Create the file
        if not self.__swap_file.exists():
            self.__swap_file.open(QIODevice.WriteOnly)
            permissions = QFileDevice.ReadOwner | QFileDevice.WriteOwner
            self.__swap_file.setPermissions(permissions)
            self.__stream.setDevice(self.__swap_file)

        if self.__timer.isActive():
            self.__timer.stop()
        # Write swap file to the disk every 10 seconds by default
        self.__timer.start(settings.SWAP_FILE_INTERVAL * 1000)

    def _finish_typing(self):
        if not self.__swap_file.isOpen():
            return
        logger.debug("Now write the swap file...")
        text = self._neditable.editor.text
        self.__swap_file.write(text.encode())
        self.__swap_file.flush()

    def filename(self):
        """Returns the filename for swap file"""

        path, name = os.path.split(
            os.path.join(SWAP_PATH, self._neditable.nfile.file_name))
        filename = os.path.join(path, "%s.ninja-swap" % name)
        return filename

    def recover(self):
        self._neditable.editor.setReadOnly(False)
        # Disconnect signals
        self.init(tracking=False)

        self.__stream.setDevice(self.__swap_file)
        if not self.__swap_file.open(QIODevice.ReadOnly):
            logger.warning("Can't open swap file")
            return
        # Ok
        data = []
        append = data.append
        while not self.__stream.atEnd():
            line = self.__stream.readLine()
            append(line)

        # Set data in the editor
        self._neditable.editor.text = "\n".join(data)
        self._neditable.document.setModified(True)

        # Close swap file
        self.__stream.setDevice(None)
        self.__swap_file.close()
        # Reconnect signals
        self.init(tracking=True)

    def discard(self):
        self._neditable.editor.setReadOnly(False)
        # Remove swap file
        self.__remove()
Esempio n. 17
0
class QHexWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.currentFile = str()
        self.isUntitled = False

        self.hexEdit = QHexEdit(self)

        self.file = QFile()
        self.fileMenu = QMenu()
        self.editMenu = QMenu()
        self.helpMenu = QMenu()
        self.labelSize = QLabel()
        self.fileToolBar = QToolBar()
        self.editToolBar = QToolBar()
        self.undoAction = QAction()
        self.redoAction = QAction()
        self.openAction = QAction()
        self.saveAction = QAction()
        self.exitAction = QAction()
        self.findAction = QAction()
        self.aboutAction = QAction()
        self.closeAction = QAction()
        self.saveAsAction = QAction()
        self.saveReadable = QAction()
        self.aboutQtAction = QAction()
        self.optionsAction = QAction()
        self.findNextAction = QAction()
        self.saveReadableSelection = QAction()
        self.optionsDialog = OptionsDialog(self)

        self.setAcceptDrops(True)
        self.init()
        self.setFixedSize(QSize(1200, 600))
        self.show()

    def closeEvent(self, event: QCloseEvent) -> None:
        self.writeSettings()

    def dragEnterEvent(self, event: QDragEnterEvent) -> None:
        if event.mimeData().hasUrls():
            event.accept()

    def dropEvent(self, event: QDropEvent) -> None:
        if event.mimeData().hasUrls():
            urls = event.mimeData().urls()
            filepath = urls[0].toLocalFile()
            self.loadFile(filepath)
            event.accept()

    def about(self):
        QMessageBox.about(self, 'Hex', 'Hexadecimal View')

    def dataChanged(self):
        self.setWindowModified(self.hexEdit.isModified())

    def open(self):
        options = QFileDialog().Options()
        options |= QFileDialog.DontUseNativeDialog
        filename, _ = QFileDialog.getOpenFileName(self,
                                                  "Select File",
                                                  options=options)
        if filename:
            self.loadFile(filename)

    def optionsAccepted(self):
        self.writeSettings()
        self.readSettings()

    def findNext(self):
        pass

    def save(self):
        if self.isUntitled:
            self.saveAs()
        else:
            self.saveFile(self.currentFile)

    def saveAs(self):
        filename = QFileDialog.getSaveFileName(self, 'Save As...',
                                               self.currentFile)
        if len(filename) == 0:
            return False

        return self.saveFile(filename)

    def saveSelectionToReadableFile(self):
        pass

    def saveToReadableFile(self):
        pass

    def setAddress(self):
        pass

    def setOverwriteMode(self):
        pass

    def setSize(self, size):
        self.labelSize.setText(str(size))

    def showOptionsDialog(self):
        pass

    def showSearchDialog(self):
        pass

    # noinspection PyUnresolvedReferences
    def init(self):
        self.optionsDialog.accepted.connect(self.optionsAccepted)
        self.hexEdit.dataChanged.connect(self.dataChanged)
        self.hexEdit.overwriteModeChanged.connect(self.setOverwriteMode)

        self.setUnifiedTitleAndToolBarOnMac(True)
        self.setCentralWidget(self.hexEdit)
        self.createActions()
        self.createMenus()
        self.createStatusBar()
        self.createToolBars()
        self.readSettings()

    # noinspection PyUnresolvedReferences
    def createActions(self):
        self.openAction = QAction(QIcon('Icons/MenuOpen.svg'), '&Open', self)
        self.openAction.setStatusTip('Open a existing file')
        self.openAction.setShortcut(QKeySequence.Open)
        self.openAction.triggered.connect(self.open)

        self.saveAction = QAction(QIcon('Icons/MenuSaveAll'), '&Save', self)
        self.saveAsAction = QAction('Save &As...', self)
        self.saveReadable = QAction('Save &Readable', self)
        self.exitAction = QAction('E&xit', self)
        self.undoAction = QAction(QIcon('Icons/Undo.svg'), '&Undo', self)
        self.redoAction = QAction(QIcon('Icons/Redo.svg'), '&Redo', self)
        self.saveReadableSelection = QAction('Save Selection Readable', self)
        self.aboutAction = QAction('&About', self)
        self.aboutQtAction = QAction('About &Qt', self)
        self.findAction = QAction(QIcon('Icons/Find.svg'), '&Find/Replace',
                                  self)
        self.findNextAction = QAction('Find &Next', self)
        self.optionsAction = QAction('&Options', self)

    def createMenus(self):
        self.fileMenu = self.menuBar().addMenu('&File')
        self.fileMenu.addAction(self.openAction)
        self.fileMenu.addAction(self.saveAction)
        self.fileMenu.addAction(self.saveAsAction)
        self.fileMenu.addAction(self.saveReadable)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.exitAction)

        self.editMenu = self.menuBar().addMenu('&Edit')
        self.editMenu.addAction(self.undoAction)
        self.editMenu.addAction(self.redoAction)
        self.editMenu.addAction(self.saveReadableSelection)
        self.editMenu.addSeparator()
        self.editMenu.addAction(self.findAction)
        self.editMenu.addAction(self.findNextAction)
        self.editMenu.addSeparator()
        self.editMenu.addAction(self.optionsAction)

        self.helpMenu = self.menuBar().addMenu('&Help')
        self.helpMenu.addAction(self.aboutAction)
        self.helpMenu.addAction(self.aboutQtAction)

    def createStatusBar(self):
        self.statusBar().addPermanentWidget(QLabel('Address:'))
        labelAddress = QLabel()
        labelAddress.setMinimumWidth(70)
        self.statusBar().addPermanentWidget(labelAddress)

        self.statusBar().addPermanentWidget(QLabel('Size:'))
        self.labelSize.setMinimumWidth(70)
        self.statusBar().addPermanentWidget(self.labelSize)
        self.hexEdit.currentSizeChanged.connect(self.setSize)

        self.statusBar().addPermanentWidget(QLabel('Mode:'))
        labelOverwriteMode = QLabel()
        labelOverwriteMode.setMinimumWidth(70)
        self.statusBar().addPermanentWidget(labelOverwriteMode)

        self.statusBar().showMessage('Ready', 2000)

    def createToolBars(self):
        self.fileToolBar = self.addToolBar('File')
        self.fileToolBar.setIconSize(QSize(16, 16))
        self.fileToolBar.addAction(self.openAction)
        self.fileToolBar.addAction(self.saveAction)

        self.editToolBar = self.addToolBar('Edit')
        self.editToolBar.setIconSize(QSize(16, 16))
        self.editToolBar.addAction(self.undoAction)
        self.editToolBar.addAction(self.redoAction)
        self.editToolBar.addAction(self.findAction)

    def loadFile(self, filename: str):
        self.file.setFileName(filename)
        if not self.hexEdit.setDataDevice(self.file):
            QMessageBox.warning(
                self, "Hex",
                f"Cannot read the file {filename}: {self.file.errorString()}.")
        self.setCurrentFile(filename)
        self.statusBar().showMessage('File Loaded', 2000)

    def readSettings(self):
        pass

    def saveFile(self, filename: str):
        pass

    def setCurrentFile(self, filename: str):
        currentFile = QFileInfo(filename).canonicalFilePath()
        isUntitled = len(currentFile) == 0
        self.setWindowModified(False)
        if isUntitled:
            self.setWindowFilePath("QHexEdit")
        else:
            self.setWindowFilePath(currentFile + " - QHexEdit")

    @staticmethod
    def strippedName(fullFilename: str) -> str:
        return QFileInfo(fullFilename).fileName()

    def writeSettings(self):
        settings = QSettings()
        settings.setValue("pos", self.pos())
        settings.setValue("size", self.size())
Esempio n. 18
0
class Recorder(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(Recorder, self).__init__()
        self.setupUi(self)
        self.output = QFile()
        self.audio = QAudioInput()
        self.NEED_ASR = False
        self.Open = True

        self.th1 = threading.Thread(target=self.ASR)
        self.th1.start()

        self.Pause_Button.clicked.connect(self.toggle_pause)
        self.Record_Button.clicked.connect(self.toggle_record)

    def closeEvent(self, event):
        self.Open = False

    def toggle_record(self):
        if self.Record_Button.text() == "开始录音":
            self.statusbar.showMessage("开始录音")
            self.setup()
            self.audio.start(self.output)
            self.Record_Button.setText("停止")
            self.Pause_Button.setText("暂停")
            self.Pause_Button.setEnabled(True)
        else:
            self.audio.stop()
            self.output.close()
            self.Pause_Button.setText("暂停")
            self.Record_Button.setText("开始录音")
            self.statusbar.showMessage("正在使用百度智能云识别,请稍等")
            self.NEED_ASR = True

    def toggle_pause(self):
        if self.Pause_Button.text() == "暂停":
            self.Pause_Button.setText("继续")
            self.audio.suspend()

        else:
            self.Pause_Button.setText("暂停")
            self.audio.resume()

    def ASR(self):
        while self.Open:
            print(1)
            if self.NEED_ASR:
                try:
                    text = ASR().Baidu_ASR("record.pcm")
                    print(text)
                    if text['err_msg'] == 'success.':
                        self.Text_plainTextEdit.setPlainText(text['result'][0])
                        self.statusbar.showMessage("识别成功")

                    else:
                        self.statusbar.showMessage("识别失败,请再说一遍")
                except:
                    self.statusbar.showMessage("网络故障,请检查网络设置以及百度智能云账号")

                self.NEED_ASR = False
            else:
                pass

    def setup(self):
        self.output.setFileName("record.pcm")
        self.output.open(QIODevice.WriteOnly | QIODevice.Truncate)
        settings = QAudioFormat()
        settings.setCodec("audio/pcm")
        settings.setSampleRate(16000)
        settings.setSampleSize(16)
        settings.setChannelCount(1)
        settings.setByteOrder(QAudioFormat.LittleEndian)
        settings.setSampleType(QAudioFormat.SignedInt)
        self.audio = QAudioInput(settings)
Esempio n. 19
0
class DownloadItem(QWidget, Ui_DownloadItem):
    """
    Class implementing a widget controlling a download.
    
    @signal statusChanged() emitted upon a status change of a download
    @signal downloadFinished() emitted when a download finished
    @signal progress(int, int) emitted to signal the download progress
    """
    statusChanged = pyqtSignal()
    downloadFinished = pyqtSignal()
    progress = pyqtSignal(int, int)
    
    Downloading = 0
    DownloadSuccessful = 1
    DownloadCancelled = 2
    
    def __init__(self, reply=None, requestFilename=False, webPage=None,
                 download=False, parent=None, mainWindow=None):
        """
        Constructor
        
        @keyparam reply reference to the network reply object (QNetworkReply)
        @keyparam requestFilename flag indicating to ask the user for a
            filename (boolean)
        @keyparam webPage reference to the web page object the download
            originated from (QWebPage)
        @keyparam download flag indicating a download operation (boolean)
        @keyparam parent reference to the parent widget (QWidget)
        @keyparam mainWindow reference to the main window (HelpWindow)
        """
        super(DownloadItem, self).__init__(parent)
        self.setupUi(self)
        
        p = self.infoLabel.palette()
        p.setColor(QPalette.Text, Qt.darkGray)
        self.infoLabel.setPalette(p)
        
        self.progressBar.setMaximum(0)
        
        self.__isFtpDownload = reply is not None and \
            reply.url().scheme() == "ftp"
        
        self.tryAgainButton.setIcon(UI.PixmapCache.getIcon("restart.png"))
        self.tryAgainButton.setEnabled(False)
        self.tryAgainButton.setVisible(False)
        self.stopButton.setIcon(UI.PixmapCache.getIcon("stopLoading.png"))
        self.pauseButton.setIcon(UI.PixmapCache.getIcon("pause.png"))
        self.openButton.setIcon(UI.PixmapCache.getIcon("open.png"))
        self.openButton.setEnabled(False)
        self.openButton.setVisible(False)
        if self.__isFtpDownload:
            self.stopButton.setEnabled(False)
            self.stopButton.setVisible(False)
            self.pauseButton.setEnabled(False)
            self.pauseButton.setVisible(False)
        
        self.__state = DownloadItem.Downloading
        
        icon = self.style().standardIcon(QStyle.SP_FileIcon)
        self.fileIcon.setPixmap(icon.pixmap(48, 48))
        
        self.__mainWindow = mainWindow
        self.__reply = reply
        self.__requestFilename = requestFilename
        self.__page = webPage
        self.__pageUrl = webPage and webPage.mainFrame().url() or QUrl()
        self.__toDownload = download
        self.__bytesReceived = 0
        self.__bytesTotal = -1
        self.__downloadTime = QTime()
        self.__output = QFile()
        self.__fileName = ""
        self.__originalFileName = ""
        self.__startedSaving = False
        self.__finishedDownloading = False
        self.__gettingFileName = False
        self.__canceledFileSelect = False
        self.__autoOpen = False
        
        self.__sha1Hash = QCryptographicHash(QCryptographicHash.Sha1)
        self.__md5Hash = QCryptographicHash(QCryptographicHash.Md5)
        
        if not requestFilename:
            self.__requestFilename = \
                Preferences.getUI("RequestDownloadFilename")
        
        self.__initialize()
    
    def __initialize(self, tryAgain=False):
        """
        Private method to (re)initialize the widget.
        
        @param tryAgain flag indicating a retry (boolean)
        """
        if self.__reply is None:
            return
        
        self.__startedSaving = False
        self.__finishedDownloading = False
        self.__bytesReceived = 0
        self.__bytesTotal = -1
        
        self.__sha1Hash.reset()
        self.__md5Hash.reset()
        
        # start timer for the download estimation
        self.__downloadTime.start()
        
        # attach to the reply object
        self.__url = self.__reply.url()
        self.__reply.setParent(self)
        self.__reply.setReadBufferSize(16 * 1024 * 1024)
        self.__reply.readyRead.connect(self.__readyRead)
        self.__reply.error.connect(self.__networkError)
        self.__reply.downloadProgress.connect(self.__downloadProgress)
        self.__reply.metaDataChanged.connect(self.__metaDataChanged)
        self.__reply.finished.connect(self.__finished)
        
        # reset info
        self.infoLabel.clear()
        self.progressBar.setValue(0)
        self.__getFileName()
        
        if self.__reply.error() != QNetworkReply.NoError:
            self.__networkError()
            self.__finished()
    
    def __getFileName(self):
        """
        Private method to get the file name to save to from the user.
        """
        if self.__gettingFileName:
            return
        
        import Helpviewer.HelpWindow
        downloadDirectory = Helpviewer.HelpWindow.HelpWindow\
            .downloadManager().downloadDirectory()
        
        if self.__fileName:
            fileName = self.__fileName
            originalFileName = self.__originalFileName
            self.__toDownload = True
            ask = False
        else:
            defaultFileName, originalFileName = \
                self.__saveFileName(downloadDirectory)
            fileName = defaultFileName
            self.__originalFileName = originalFileName
            ask = True
        self.__autoOpen = False
        if not self.__toDownload:
            from .DownloadAskActionDialog import DownloadAskActionDialog
            url = self.__reply.url()
            dlg = DownloadAskActionDialog(
                QFileInfo(originalFileName).fileName(),
                self.__reply.header(QNetworkRequest.ContentTypeHeader),
                "{0}://{1}".format(url.scheme(), url.authority()),
                self)
            if dlg.exec_() == QDialog.Rejected or dlg.getAction() == "cancel":
                self.progressBar.setVisible(False)
                self.__reply.close()
                self.on_stopButton_clicked()
                self.filenameLabel.setText(
                    self.tr("Download canceled: {0}").format(
                        QFileInfo(defaultFileName).fileName()))
                self.__canceledFileSelect = True
                return
            
            if dlg.getAction() == "scan":
                self.__mainWindow.requestVirusTotalScan(url)
                
                self.progressBar.setVisible(False)
                self.__reply.close()
                self.on_stopButton_clicked()
                self.filenameLabel.setText(
                    self.tr("VirusTotal scan scheduled: {0}").format(
                        QFileInfo(defaultFileName).fileName()))
                self.__canceledFileSelect = True
                return
            
            self.__autoOpen = dlg.getAction() == "open"
            if PYQT_VERSION_STR >= "5.0.0":
                from PyQt5.QtCore import QStandardPaths
                tempLocation = QStandardPaths.standardLocations(
                    QStandardPaths.TempLocation)[0]
            else:
                from PyQt5.QtGui import QDesktopServices
                tempLocation = QDesktopServices.storageLocation(
                    QDesktopServices.TempLocation)
            fileName = tempLocation + '/' + \
                QFileInfo(fileName).completeBaseName()
        
        if ask and not self.__autoOpen and self.__requestFilename:
            self.__gettingFileName = True
            fileName = E5FileDialog.getSaveFileName(
                None,
                self.tr("Save File"),
                defaultFileName,
                "")
            self.__gettingFileName = False
            if not fileName:
                self.progressBar.setVisible(False)
                self.__reply.close()
                self.on_stopButton_clicked()
                self.filenameLabel.setText(
                    self.tr("Download canceled: {0}")
                        .format(QFileInfo(defaultFileName).fileName()))
                self.__canceledFileSelect = True
                return
        
        fileInfo = QFileInfo(fileName)
        Helpviewer.HelpWindow.HelpWindow.downloadManager()\
            .setDownloadDirectory(fileInfo.absoluteDir().absolutePath())
        self.filenameLabel.setText(fileInfo.fileName())
        
        self.__output.setFileName(fileName + ".part")
        self.__fileName = fileName
        
        # check file path for saving
        saveDirPath = QFileInfo(self.__fileName).dir()
        if not saveDirPath.exists():
            if not saveDirPath.mkpath(saveDirPath.absolutePath()):
                self.progressBar.setVisible(False)
                self.on_stopButton_clicked()
                self.infoLabel.setText(self.tr(
                    "Download directory ({0}) couldn't be created.")
                    .format(saveDirPath.absolutePath()))
                return
        
        self.filenameLabel.setText(QFileInfo(self.__fileName).fileName())
        if self.__requestFilename:
            self.__readyRead()
    
    def __saveFileName(self, directory):
        """
        Private method to calculate a name for the file to download.
        
        @param directory name of the directory to store the file into (string)
        @return proposed filename and original filename (string, string)
        """
        path = parseContentDisposition(self.__reply)
        info = QFileInfo(path)
        baseName = info.completeBaseName()
        endName = info.suffix()
        
        origName = baseName
        if endName:
            origName += '.' + endName
        
        name = directory + baseName
        if endName:
            name += '.' + endName
            if not self.__requestFilename:
                # do not overwrite, if the user is not being asked
                i = 1
                while QFile.exists(name):
                    # file exists already, don't overwrite
                    name = directory + baseName + ('-{0:d}'.format(i))
                    if endName:
                        name += '.' + endName
                    i += 1
        return name, origName
    
    def __open(self):
        """
        Private slot to open the downloaded file.
        """
        info = QFileInfo(self.__output)
        url = QUrl.fromLocalFile(info.absoluteFilePath())
        QDesktopServices.openUrl(url)
    
    @pyqtSlot()
    def on_tryAgainButton_clicked(self):
        """
        Private slot to retry the download.
        """
        self.retry()
    
    def retry(self):
        """
        Public slot to retry the download.
        """
        if not self.tryAgainButton.isEnabled():
            return
        
        self.tryAgainButton.setEnabled(False)
        self.tryAgainButton.setVisible(False)
        self.openButton.setEnabled(False)
        self.openButton.setVisible(False)
        if not self.__isFtpDownload:
            self.stopButton.setEnabled(True)
            self.stopButton.setVisible(True)
            self.pauseButton.setEnabled(True)
            self.pauseButton.setVisible(True)
        self.progressBar.setVisible(True)
        
        if self.__page:
            nam = self.__page.networkAccessManager()
        else:
            import Helpviewer.HelpWindow
            nam = Helpviewer.HelpWindow.HelpWindow.networkAccessManager()
        reply = nam.get(QNetworkRequest(self.__url))
        if self.__output.exists():
            self.__output.remove()
        self.__output = QFile()
        self.__reply = reply
        self.__initialize(tryAgain=True)
        self.__state = DownloadItem.Downloading
        self.statusChanged.emit()
    
    @pyqtSlot(bool)
    def on_pauseButton_clicked(self, checked):
        """
        Private slot to pause the download.
        
        @param checked flag indicating the state of the button (boolean)
        """
        if checked:
            self.__reply.readyRead.disconnect(self.__readyRead)
            self.__reply.setReadBufferSize(16 * 1024)
        else:
            self.__reply.readyRead.connect(self.__readyRead)
            self.__reply.setReadBufferSize(16 * 1024 * 1024)
            self.__readyRead()
    
    @pyqtSlot()
    def on_stopButton_clicked(self):
        """
        Private slot to stop the download.
        """
        self.cancelDownload()
    
    def cancelDownload(self):
        """
        Public slot to stop the download.
        """
        self.setUpdatesEnabled(False)
        if not self.__isFtpDownload:
            self.stopButton.setEnabled(False)
            self.stopButton.setVisible(False)
            self.pauseButton.setEnabled(False)
            self.pauseButton.setVisible(False)
        self.tryAgainButton.setEnabled(True)
        self.tryAgainButton.setVisible(True)
        self.openButton.setEnabled(False)
        self.openButton.setVisible(False)
        self.setUpdatesEnabled(True)
        self.__state = DownloadItem.DownloadCancelled
        self.__reply.abort()
        self.downloadFinished.emit()
    
    @pyqtSlot()
    def on_openButton_clicked(self):
        """
        Private slot to open the downloaded file.
        """
        self.openFile()
    
    def openFile(self):
        """
        Public slot to open the downloaded file.
        """
        info = QFileInfo(self.__fileName)
        url = QUrl.fromLocalFile(info.absoluteFilePath())
        QDesktopServices.openUrl(url)
    
    def openFolder(self):
        """
        Public slot to open the folder containing the downloaded file.
        """
        info = QFileInfo(self.__fileName)
        url = QUrl.fromLocalFile(info.absolutePath())
        QDesktopServices.openUrl(url)
    
    def __readyRead(self):
        """
        Private slot to read the available data.
        """
        if self.__requestFilename and not self.__output.fileName():
            return
        
        if not self.__output.isOpen():
            # in case someone else has already put a file there
            if not self.__requestFilename:
                self.__getFileName()
            if not self.__output.open(QIODevice.WriteOnly):
                self.infoLabel.setText(
                    self.tr("Error opening save file: {0}")
                    .format(self.__output.errorString()))
                self.on_stopButton_clicked()
                self.statusChanged.emit()
                return
            self.statusChanged.emit()
        
        buffer = self.__reply.readAll()
        self.__sha1Hash.addData(buffer)
        self.__md5Hash.addData(buffer)
        bytesWritten = self.__output.write(buffer)
        if bytesWritten == -1:
            self.infoLabel.setText(
                self.tr("Error saving: {0}")
                    .format(self.__output.errorString()))
            self.on_stopButton_clicked()
        else:
            self.__startedSaving = True
            if self.__finishedDownloading:
                self.__finished()
    
    def __networkError(self):
        """
        Private slot to handle a network error.
        """
        self.infoLabel.setText(
            self.tr("Network Error: {0}")
                .format(self.__reply.errorString()))
        self.tryAgainButton.setEnabled(True)
        self.tryAgainButton.setVisible(True)
        self.downloadFinished.emit()
    
    def __metaDataChanged(self):
        """
        Private slot to handle a change of the meta data.
        """
        locationHeader = self.__reply.header(QNetworkRequest.LocationHeader)
        if locationHeader and locationHeader.isValid():
            self.__url = QUrl(locationHeader)
            import Helpviewer.HelpWindow
            self.__reply = Helpviewer.HelpWindow.HelpWindow\
                .networkAccessManager().get(QNetworkRequest(self.__url))
            self.__initialize()
    
    def __downloadProgress(self, bytesReceived, bytesTotal):
        """
        Private method to show the download progress.
        
        @param bytesReceived number of bytes received (integer)
        @param bytesTotal number of total bytes (integer)
        """
        self.__bytesReceived = bytesReceived
        self.__bytesTotal = bytesTotal
        currentValue = 0
        totalValue = 0
        if bytesTotal > 0:
            currentValue = bytesReceived * 100 / bytesTotal
            totalValue = 100
        self.progressBar.setValue(currentValue)
        self.progressBar.setMaximum(totalValue)
        
        self.progress.emit(currentValue, totalValue)
        self.__updateInfoLabel()
    
    def bytesTotal(self):
        """
        Public method to get the total number of bytes of the download.
        
        @return total number of bytes (integer)
        """
        if self.__bytesTotal == -1:
            self.__bytesTotal = self.__reply.header(
                QNetworkRequest.ContentLengthHeader)
            if self.__bytesTotal is None:
                self.__bytesTotal = -1
        return self.__bytesTotal
    
    def bytesReceived(self):
        """
        Public method to get the number of bytes received.
        
        @return number of bytes received (integer)
        """
        return self.__bytesReceived
    
    def remainingTime(self):
        """
        Public method to get an estimation for the remaining time.
        
        @return estimation for the remaining time (float)
        """
        if not self.downloading():
            return -1.0
        
        if self.bytesTotal() == -1:
            return -1.0
        
        cSpeed = self.currentSpeed()
        if cSpeed != 0:
            timeRemaining = (self.bytesTotal() - self.bytesReceived()) / cSpeed
        else:
            timeRemaining = 1
        
        # ETA should never be 0
        if timeRemaining == 0:
            timeRemaining = 1
        
        return timeRemaining
    
    def currentSpeed(self):
        """
        Public method to get an estimation for the download speed.
        
        @return estimation for the download speed (float)
        """
        if not self.downloading():
            return -1.0
        
        return self.__bytesReceived * 1000.0 / self.__downloadTime.elapsed()
    
    def __updateInfoLabel(self):
        """
        Private method to update the info label.
        """
        if self.__reply.error() != QNetworkReply.NoError:
            return
        
        bytesTotal = self.bytesTotal()
        running = not self.downloadedSuccessfully()
        
        speed = self.currentSpeed()
        timeRemaining = self.remainingTime()
        
        info = ""
        if running:
            remaining = ""
            
            if bytesTotal > 0:
                remaining = timeString(timeRemaining)
            
            info = self.tr("{0} of {1} ({2}/sec)\n{3}")\
                .format(
                    dataString(self.__bytesReceived),
                    bytesTotal == -1 and self.tr("?")
                    or dataString(bytesTotal),
                    dataString(int(speed)),
                    remaining)
        else:
            if self.__bytesReceived == bytesTotal or bytesTotal == -1:
                info = self.tr("{0} downloaded\nSHA1: {1}\nMD5: {2}")\
                    .format(dataString(self.__output.size()),
                            str(self.__sha1Hash.result().toHex(),
                                encoding="ascii"),
                            str(self.__md5Hash.result().toHex(),
                                encoding="ascii")
                            )
            else:
                info = self.tr("{0} of {1} - Stopped")\
                    .format(dataString(self.__bytesReceived),
                            dataString(bytesTotal))
        self.infoLabel.setText(info)
    
    def downloading(self):
        """
        Public method to determine, if a download is in progress.
        
        @return flag indicating a download is in progress (boolean)
        """
        return self.__state == DownloadItem.Downloading
    
    def downloadedSuccessfully(self):
        """
        Public method to check for a successful download.
        
        @return flag indicating a successful download (boolean)
        """
        return self.__state == DownloadItem.DownloadSuccessful
    
    def downloadCanceled(self):
        """
        Public method to check, if the download was cancelled.
        
        @return flag indicating a canceled download (boolean)
        """
        return self.__state == DownloadItem.DownloadCancelled
    
    def __finished(self):
        """
        Private slot to handle the download finished.
        """
        self.__finishedDownloading = True
        if not self.__startedSaving:
            return
        
        noError = self.__reply.error() == QNetworkReply.NoError
        
        self.progressBar.setVisible(False)
        if not self.__isFtpDownload:
            self.stopButton.setEnabled(False)
            self.stopButton.setVisible(False)
            self.pauseButton.setEnabled(False)
            self.pauseButton.setVisible(False)
        self.openButton.setEnabled(noError)
        self.openButton.setVisible(noError)
        self.__output.close()
        if QFile.exists(self.__fileName):
            QFile.remove(self.__fileName)
        self.__output.rename(self.__fileName)
        self.__updateInfoLabel()
        self.__state = DownloadItem.DownloadSuccessful
        self.statusChanged.emit()
        self.downloadFinished.emit()
        
        if self.__autoOpen:
            self.__open()
    
    def canceledFileSelect(self):
        """
        Public method to check, if the user canceled the file selection.
        
        @return flag indicating cancellation (boolean)
        """
        return self.__canceledFileSelect
    
    def setIcon(self, icon):
        """
        Public method to set the download icon.
        
        @param icon reference to the icon to be set (QIcon)
        """
        self.fileIcon.setPixmap(icon.pixmap(48, 48))
    
    def fileName(self):
        """
        Public method to get the name of the output file.
        
        @return name of the output file (string)
        """
        return self.__fileName
    
    def absoluteFilePath(self):
        """
        Public method to get the absolute path of the output file.
        
        @return absolute path of the output file (string)
        """
        return QFileInfo(self.__fileName).absoluteFilePath()
    
    def getData(self):
        """
        Public method to get the relevant download data.
        
        @return tuple of URL, save location, flag and the
            URL of the related web page (QUrl, string, boolean,QUrl)
        """
        return (self.__url, QFileInfo(self.__fileName).filePath(),
                self.downloadedSuccessfully(), self.__pageUrl)
    
    def setData(self, data):
        """
        Public method to set the relevant download data.
        
        @param data tuple of URL, save location, flag and the
            URL of the related web page (QUrl, string, boolean, QUrl)
        """
        self.__url = data[0]
        self.__fileName = data[1]
        self.__pageUrl = data[3]
        self.__isFtpDownload = self.__url.scheme() == "ftp"
        
        self.filenameLabel.setText(QFileInfo(self.__fileName).fileName())
        self.infoLabel.setText(self.__fileName)
        
        self.stopButton.setEnabled(False)
        self.stopButton.setVisible(False)
        self.pauseButton.setEnabled(False)
        self.pauseButton.setVisible(False)
        self.openButton.setEnabled(data[2])
        self.openButton.setVisible(data[2])
        self.tryAgainButton.setEnabled(not data[2])
        self.tryAgainButton.setVisible(not data[2])
        if data[2]:
            self.__state = DownloadItem.DownloadSuccessful
        else:
            self.__state = DownloadItem.DownloadCancelled
        self.progressBar.setVisible(False)
    
    def getInfoData(self):
        """
        Public method to get the text of the info label.
        
        @return text of the info label (string)
        """
        return self.infoLabel.text()
    
    def getPageUrl(self):
        """
        Public method to get the URL of the download page.
        
        @return URL of the download page (QUrl)
        """
        return self.__pageUrl
Esempio n. 20
0
class QmyMainWindow(QMainWindow): 

   def __init__(self, parent=None):
      super().__init__(parent)    #调用父类构造函数,创建窗体
      self.ui=Ui_MainWindow()     #创建UI对象
      self.ui.setupUi(self)       #构造UI界面

      self.ui.progBar_Max.setMaximum(256)
      self.ui.progBar_Min.setMaximum(256)
      self.ui.progBar_Diff.setMaximum(256)

      self.ui.sliderVolumn.setMaximum(100)
      self.ui.sliderVolumn.setValue(100)

      self.ui.comboDevices.clear()
      self.__deviceList=QAudioDeviceInfo.availableDevices(QAudio.AudioInput) #音频输入设备列表
      for i in range(len(self.__deviceList)):
         device=self.__deviceList[i]    #QAudioDeviceInfo类
         self.ui.comboDevices.addItem(device.deviceName())

##      self.__deviceInfo =None   #当前设备信息,QAudioDeviceInfo
      self.audioDevice=None       #音频输入设备,QAudioInput
      self.BUFFER_SIZE=4000

      self.ioDevice=None      #第1种读取方法,内建的IODevice

##      self.externalReader=None        #第2种读取方法,外建的IODevice

      self.recordFile=QFile()      #第3种读取方法,使用QFile直接写入文件

      if len(self.__deviceList)>0:
         self.ui.comboDevices.setCurrentIndex(0) #触发comboDevices的信号currentIndexChanged()
##         self.__deviceInfo =deviceList[0]
      else:
         self.ui.actStart.setEnabled(False)
         self.ui.actDeviceTest.setEnabled(False)
         self.ui.groupBoxDevice.setTitle("支持的音频输入设置(无设备)")
      

##  ==============自定义功能函数========================
   def __getSampleTypeStr(self,sampleType):
      result="Unknown"
      if sampleType==QAudioFormat.SignedInt:
         result = "SignedInt"
      elif sampleType==QAudioFormat.UnSignedInt:
         result = "UnSignedInt"
      elif sampleType==QAudioFormat.Float:
         result = "Float"
      elif sampleType==QAudioFormat.Unknown:
         result = "Unknown"
         
      return result

   def __getByteOrderStr(self,endian):
      if (endian==QAudioFormat.LittleEndian):
         return "LittleEndian"
      else:
         return "BigEndian"
      

##  ==============event处理函数==========================
        
        
##  ==========由connectSlotsByName()自动连接的槽函数============
      
   @pyqtSlot(int)   ##选择音频输入设备
   def on_comboDevices_currentIndexChanged(self,index):        
      deviceInfo =self.__deviceList[index]   #当前音频设备,QAudioDeviceInfo类型
      self.ui.comboCodec.clear()             
      codecs = deviceInfo.supportedCodecs()  #支持的音频编码,字符串列表
      for strLine in codecs:
         self.ui.comboCodec.addItem(strLine)

      self.ui.comboSampleRate.clear()  #支持的采样率
      sampleRates = deviceInfo.supportedSampleRates()  #QList<int>
      for i in  sampleRates:
         self.ui.comboSampleRate.addItem("%d"% i)

      self.ui.comboChannels.clear()    #支持的通道数
      Channels = deviceInfo.supportedChannelCounts() #QList<int> 
      for i in Channels:
         self.ui.comboChannels.addItem("%d"%i )

      self.ui.comboSampleTypes.clear() #支持的采样点类型
      sampleTypes = deviceInfo.supportedSampleTypes() #QList<QAudioFormat::SampleType>
      for i in  sampleTypes:
         sampTypeStr=self.__getSampleTypeStr(i)
         self.ui.comboSampleTypes.addItem(sampTypeStr,i)
         
      self.ui.comboSampleSizes.clear() #采样点大小
      sampleSizes = deviceInfo.supportedSampleSizes() #QList<int>
      for i in  sampleSizes:
         self.ui.comboSampleSizes.addItem("%d"%i)

      self.ui.comboByteOrder.clear() #字节序
      endians = deviceInfo.supportedByteOrders()  #QList<QAudioFormat::Endian> 
      for i in endians:
         self.ui.comboByteOrder.addItem(self.__getByteOrderStr(i))

   @pyqtSlot()   ##使用内建IODevice
   def on_radioSaveMode_Inner_clicked(self):
      self.ui.groupBox_disp.setVisible(True)
      
   @pyqtSlot()   ##使用QFile对象(test.raw)
   def on_radioSaveMode_QFile_clicked(self):
      self.ui.groupBox_disp.setVisible(False)

   @pyqtSlot(int)   ##调节录音音量
   def on_sliderVolumn_valueChanged(self,value):
      self.ui.LabVol.setText("录音音量(%d%%)"%value)


   @pyqtSlot()   ##测试音频输入设备是否支持选择的设置
   def on_actDeviceTest_triggered(self):
      settings=QAudioFormat()
      settings.setCodec(self.ui.comboCodec.currentText())
      settings.setSampleRate(int(self.ui.comboSampleRate.currentText()))
      settings.setChannelCount(int(self.ui.comboChannels.currentText()))

      k=self.ui.comboSampleTypes.currentData()
      settings.setSampleType(k)  #QAudioFormat.SampleType

      settings.setSampleSize(int(self.ui.comboSampleSizes.currentText()))

      if (self.ui.comboByteOrder.currentText()=="LittleEndian"):
         settings.setByteOrder(QAudioFormat.LittleEndian)
      else:
         settings.setByteOrder(QAudioFormat.BigEndian)

      index=self.ui.comboDevices.currentIndex()
      deviceInfo =self.__deviceList[index]  #当前音频设备

      if deviceInfo.isFormatSupported(settings):
         QMessageBox.information(self,"消息","测试成功,设备支持此设置")
      else:
         QMessageBox.critical(self,"错误","测试失败,设备不支持此设置")

   @pyqtSlot()   ##开始音频输入
   def on_actStart_triggered(self):
      audioFormat=QAudioFormat() #使用固定格式
      audioFormat.setSampleRate(8000)
      audioFormat.setChannelCount(1)
      audioFormat.setSampleSize(8)
      audioFormat.setCodec("audio/pcm")
      audioFormat.setByteOrder(QAudioFormat.LittleEndian)
      audioFormat.setSampleType(QAudioFormat.UnSignedInt)

      index=self.ui.comboDevices.currentIndex()
      deviceInfo =self.__deviceList[index]  #当前音频设备

      if (False== deviceInfo.isFormatSupported(audioFormat)):
         QMessageBox.critical(self,"错误","测试失败,输入设备不支持此设置")
         return

      self.audioDevice = QAudioInput(deviceInfo,audioFormat) #音频输入设备
      self.audioDevice.setBufferSize(self.BUFFER_SIZE)   #设置的缓冲区大小,字节数,并不一定等于实际数据块大小
      self.audioDevice.stateChanged.connect(self.do_stateChanged)  #状态变化


   ##1. 使用 start()->QIODevice 启动,返回的内置的IODevice, pull mode,利用readyRead()信号读出数据
      if self.ui.radioSaveMode_Inner.isChecked():
         self.ioDevice=self.audioDevice.start()  #返回内建的IODevice
         self.ioDevice.readyRead.connect(self.do_IO_readyRead)

   ## 2. 自定义流设备QWAudioBlockReader,push mode, start(QIODevice),不行
   ##      if self.ui.radioSaveMode_External.isChecked():
   ##         self.externalReader = QmyAudioReader()
   ##         self.externalReader.open(QIODevice.WriteOnly)
   ##         self.externalReader.updateBlockInfo.connect(self.do_updateBlockInfo)
   ##         self.audioDevice.start(self.externalReader)  #使用外建的IODevice
         
      
   ##3. 写入文件,用 start(QIODevice)启动
      if self.ui.radioSaveMode_QFile.isChecked():
         self.recordFile.setFileName("test.raw") 
         self.recordFile.open(QIODevice.WriteOnly)
         self.audioDevice.start(self.recordFile)  


   @pyqtSlot()   ##停止音频输入
   def on_actStop_triggered(self):
      self.audioDevice.stop()
      self.audioDevice.deleteLater()
      
   ##1. 使用 QIODevice  =start()返回的内置的IODevice, pull mode,利用readyRead()信号读出数据
      #无需处理,停止后self.ioDevice自动变为无效

   ##2. 外部IODevice接收音频输入数据的流设备
   ##      if self.ui.radioSaveMode_External.isChecked():
   ##         self.externalReader.close()
   ##         self.externalReader.updateBlockSize.disconnect(self.do_updateBlockInfo)
   ##         del self.externalReader  #删除外建设备
      
   ##3. 写入文件,start(QIODevice) 启动
      if self.ui.radioSaveMode_QFile.isChecked():
         self.recordFile.close() #关闭文件
      

        
##  =============自定义槽函数===============================        
##1. 使用QIODevice* start()返回的内置的IODevice, pull mode,利用readyRead()信号读出数据
   def do_IO_readyRead(self):    ##内建IODevice,读取缓冲区数据
      self.ui.LabBufferSize.setText("bufferSize()=%d"
                                    %self.audioDevice.bufferSize())

      byteCount = self.audioDevice.bytesReady() #可以读取的字节数
      self.ui.LabBytesReady.setText("bytesReady()=%d"%byteCount)

      if byteCount>self.BUFFER_SIZE:
         byteCount=self.BUFFER_SIZE
      
      buffer=self.ioDevice.read(byteCount)  #返回的是bytes类型,便于处理
   ##      buffer=self.ioDevice.readAll()  #不能用readAll()读取,返回的是QByteArray,需要再转换为bytes
      
   ##      print(type(buffer))
   ##      print(buffer)
      
      maxSize=len(buffer)
   ##      print(maxSize)

      self.ui.LabBlockSize.setText("IODevice数据字节数=%d"%maxSize)

      maxV=0
      minV=255
      for k in range(maxSize):
         V=buffer[k]  #取一个字节,整数
         if V>maxV:
            maxV=V   #求最大值
         if V<minV:
            minV=V   #求最小值

      self.ui.progBar_Max.setValue(maxV)
      self.ui.progBar_Min.setValue(minV)
      self.ui.progBar_Diff.setValue(maxV-minV)


   def do_stateChanged(self,state):    ##设备状态变化
      isStoped=(state== QAudio.StoppedState) #停止状态
      self.ui.groupBox_saveMode.setEnabled(isStoped)
      self.ui.sliderVolumn.setEnabled(isStoped)
      self.ui.actStart.setEnabled(isStoped)
      self.ui.actStop.setEnabled(not isStoped)
      self.ui.actDeviceTest.setEnabled(isStoped)
      self.ui.sliderVolumn.setEnabled(isStoped)

      if  state== QAudio.ActiveState:
         self.ui.statusBar.showMessage("state: ActiveState")
      elif state== QAudio.SuspendedState:
         self.ui.statusBar.showMessage("state: SuspendedState")
      elif state== QAudio.StoppedState:
         self.ui.statusBar.showMessage("state: StoppedState")
      elif state== QAudio.IdleState:
         self.ui.statusBar.showMessage("state: IdleState")
      elif state== QAudio.InterruptedState:
         self.ui.statusBar.showMessage("state: InterruptedState")
class LogFilePositionSource(QGeoPositionInfoSource):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.lastPosition = QGeoPositionInfo()

        self.logFile = QFile(self)
        self.timer = QTimer(self)

        self.timer.timeout.connect(self.readNextPosition)

        self.logFile.setFileName(":/simplelog.txt")
        if not self.logFile.open(QIODevice.ReadOnly):
            print("Error: cannot open source file", self.logFile.fileName())

    def lastKnownPosition(self, fromSatellitePositioningMethodsOnly=False):
        return self.lastPosition

    def supportedPositioningMethods(self):
        return QGeoPositionInfoSource.AllPositioningMethods

    def minimumUpdateInterval(self):
        return 500

    def error(self):
        return QGeoPositionInfoSource.NoError

    def startUpdates(self):
        interval = self.updateInterval()
        if interval < self.minimumUpdateInterval():
            interval = self.minimumUpdateInterval()
        self.timer.start(interval)

    def stopUpdates(self):
        self.timer.stop()

    def requestUpdate(self, timeout=5000):
        # For simplicity, ignore timeout - assume that if data is not available
        # now, no data will be added to the file later
        if self.logFile.canReadLine():
            self.readNextPosition()
        else:
            self.updateTimeout.emit()

    def readNextPosition(self):
        line = self.logFile.readLine().trimmed()
        if not line.isEmpty():
            data = line.split(" ")
            latitude = 0
            longitude = 0
            hasLatitude = False
            hasLongitude = False
            timestamp = QDateTime.fromString(data[0].data().decode(),
                                             Qt.ISODate)
            latitude, hasLatitude = data[1].toDouble()
            longitude, hasLongitude = data[2].toDouble()
            if hasLatitude and hasLongitude and timestamp.isValid():
                coordinate = QGeoCoordinate(latitude, longitude)
                info = QGeoPositionInfo(coordinate, timestamp)
                if info.isValid():
                    self.lastPosition = info
                    self.positionUpdated.emit(info)
Esempio n. 22
0
class DownloadItem(QWidget, Ui_DownloadItem):
    """
    Class implementing a widget controlling a download.
    
    @signal statusChanged() emitted upon a status change of a download
    @signal downloadFinished() emitted when a download finished
    @signal progress(int, int) emitted to signal the download progress
    """
    statusChanged = pyqtSignal()
    downloadFinished = pyqtSignal()
    progress = pyqtSignal(int, int)

    Downloading = 0
    DownloadSuccessful = 1
    DownloadCancelled = 2

    def __init__(self,
                 reply=None,
                 requestFilename=False,
                 webPage=None,
                 download=False,
                 parent=None,
                 mainWindow=None):
        """
        Constructor
        
        @keyparam reply reference to the network reply object (QNetworkReply)
        @keyparam requestFilename flag indicating to ask the user for a
            filename (boolean)
        @keyparam webPage reference to the web page object the download
            originated from (QWebPage)
        @keyparam download flag indicating a download operation (boolean)
        @keyparam parent reference to the parent widget (QWidget)
        @keyparam mainWindow reference to the main window (HelpWindow)
        """
        super(DownloadItem, self).__init__(parent)
        self.setupUi(self)

        p = self.infoLabel.palette()
        p.setColor(QPalette.Text, Qt.darkGray)
        self.infoLabel.setPalette(p)

        self.progressBar.setMaximum(0)

        self.__isFtpDownload = reply is not None and \
            reply.url().scheme() == "ftp"

        self.tryAgainButton.setIcon(UI.PixmapCache.getIcon("restart.png"))
        self.tryAgainButton.setEnabled(False)
        self.tryAgainButton.setVisible(False)
        self.stopButton.setIcon(UI.PixmapCache.getIcon("stopLoading.png"))
        self.pauseButton.setIcon(UI.PixmapCache.getIcon("pause.png"))
        self.openButton.setIcon(UI.PixmapCache.getIcon("open.png"))
        self.openButton.setEnabled(False)
        self.openButton.setVisible(False)
        if self.__isFtpDownload:
            self.stopButton.setEnabled(False)
            self.stopButton.setVisible(False)
            self.pauseButton.setEnabled(False)
            self.pauseButton.setVisible(False)

        self.__state = DownloadItem.Downloading

        icon = self.style().standardIcon(QStyle.SP_FileIcon)
        self.fileIcon.setPixmap(icon.pixmap(48, 48))

        self.__mainWindow = mainWindow
        self.__reply = reply
        self.__requestFilename = requestFilename
        self.__page = webPage
        self.__pageUrl = webPage and webPage.mainFrame().url() or QUrl()
        self.__toDownload = download
        self.__bytesReceived = 0
        self.__bytesTotal = -1
        self.__downloadTime = QTime()
        self.__output = QFile()
        self.__fileName = ""
        self.__originalFileName = ""
        self.__startedSaving = False
        self.__finishedDownloading = False
        self.__gettingFileName = False
        self.__canceledFileSelect = False
        self.__autoOpen = False

        self.__sha1Hash = QCryptographicHash(QCryptographicHash.Sha1)
        self.__md5Hash = QCryptographicHash(QCryptographicHash.Md5)

        if not requestFilename:
            self.__requestFilename = \
                Preferences.getUI("RequestDownloadFilename")

        self.__initialize()

    def __initialize(self, tryAgain=False):
        """
        Private method to (re)initialize the widget.
        
        @param tryAgain flag indicating a retry (boolean)
        """
        if self.__reply is None:
            return

        self.__startedSaving = False
        self.__finishedDownloading = False
        self.__bytesReceived = 0
        self.__bytesTotal = -1

        self.__sha1Hash.reset()
        self.__md5Hash.reset()

        # start timer for the download estimation
        self.__downloadTime.start()

        # attach to the reply object
        self.__url = self.__reply.url()
        self.__reply.setParent(self)
        self.__reply.setReadBufferSize(16 * 1024 * 1024)
        self.__reply.readyRead.connect(self.__readyRead)
        self.__reply.error.connect(self.__networkError)
        self.__reply.downloadProgress.connect(self.__downloadProgress)
        self.__reply.metaDataChanged.connect(self.__metaDataChanged)
        self.__reply.finished.connect(self.__finished)

        # reset info
        self.infoLabel.clear()
        self.progressBar.setValue(0)
        self.__getFileName()

        if self.__reply.error() != QNetworkReply.NoError:
            self.__networkError()
            self.__finished()

    def __getFileName(self):
        """
        Private method to get the file name to save to from the user.
        """
        if self.__gettingFileName:
            return

        import Helpviewer.HelpWindow
        downloadDirectory = Helpviewer.HelpWindow.HelpWindow\
            .downloadManager().downloadDirectory()

        if self.__fileName:
            fileName = self.__fileName
            originalFileName = self.__originalFileName
            self.__toDownload = True
            ask = False
        else:
            defaultFileName, originalFileName = \
                self.__saveFileName(downloadDirectory)
            fileName = defaultFileName
            self.__originalFileName = originalFileName
            ask = True
        self.__autoOpen = False
        if not self.__toDownload:
            from .DownloadAskActionDialog import DownloadAskActionDialog
            url = self.__reply.url()
            dlg = DownloadAskActionDialog(
                QFileInfo(originalFileName).fileName(),
                self.__reply.header(QNetworkRequest.ContentTypeHeader),
                "{0}://{1}".format(url.scheme(), url.authority()), self)
            if dlg.exec_() == QDialog.Rejected or dlg.getAction() == "cancel":
                self.progressBar.setVisible(False)
                self.__reply.close()
                self.on_stopButton_clicked()
                self.filenameLabel.setText(
                    self.tr("Download canceled: {0}").format(
                        QFileInfo(defaultFileName).fileName()))
                self.__canceledFileSelect = True
                return

##            if dlg.getAction() == "scan":
##                self.__mainWindow.requestVirusTotalScan(url)
##
##                self.progressBar.setVisible(False)
##                self.__reply.close()
##                self.on_stopButton_clicked()
##                self.filenameLabel.setText(
##                    self.tr("VirusTotal scan scheduled: {0}").format(
##                        QFileInfo(defaultFileName).fileName()))
##                self.__canceledFileSelect = True
##                return
##
            self.__autoOpen = dlg.getAction() == "open"
            if PYQT_VERSION_STR >= "5.0.0":
                from PyQt5.QtCore import QStandardPaths
                tempLocation = QStandardPaths.storageLocation(
                    QStandardPaths.TempLocation)
            else:
                from PyQt5.QtGui import QDesktopServices
                tempLocation = QDesktopServices.storageLocation(
                    QDesktopServices.TempLocation)
            fileName = tempLocation + '/' + \
                QFileInfo(fileName).completeBaseName()

        if ask and not self.__autoOpen and self.__requestFilename:
            self.__gettingFileName = True
            fileName = E5FileDialog.getSaveFileName(None, self.tr("Save File"),
                                                    defaultFileName, "")
            self.__gettingFileName = False
            if not fileName:
                self.progressBar.setVisible(False)
                self.__reply.close()
                self.on_stopButton_clicked()
                self.filenameLabel.setText(
                    self.tr("Download canceled: {0}").format(
                        QFileInfo(defaultFileName).fileName()))
                self.__canceledFileSelect = True
                return

        fileInfo = QFileInfo(fileName)
        Helpviewer.HelpWindow.HelpWindow.downloadManager()\
            .setDownloadDirectory(fileInfo.absoluteDir().absolutePath())
        self.filenameLabel.setText(fileInfo.fileName())

        self.__output.setFileName(fileName + ".part")
        self.__fileName = fileName

        # check file path for saving
        saveDirPath = QFileInfo(self.__fileName).dir()
        if not saveDirPath.exists():
            if not saveDirPath.mkpath(saveDirPath.absolutePath()):
                self.progressBar.setVisible(False)
                self.on_stopButton_clicked()
                self.infoLabel.setText(
                    self.tr("Download directory ({0}) couldn't be created.").
                    format(saveDirPath.absolutePath()))
                return

        self.filenameLabel.setText(QFileInfo(self.__fileName).fileName())
        if self.__requestFilename:
            self.__readyRead()

    def __saveFileName(self, directory):
        """
        Private method to calculate a name for the file to download.
        
        @param directory name of the directory to store the file into (string)
        @return proposed filename and original filename (string, string)
        """
        path = ""
        if self.__reply.hasRawHeader("Content-Disposition"):
            header = bytes(self.__reply.rawHeader("Content-Disposition"))\
                .decode()
            if header:
                pos = header.find("filename=")
                if pos != -1:
                    path = header[pos + 9:]
                    if path.startswith('"') and path.endswith('"'):
                        path = path[1:-1]
        if not path:
            path = self.__url.path()

        info = QFileInfo(path)
        baseName = info.completeBaseName()
        endName = info.suffix()

        if not baseName:
            baseName = "unnamed_download"

        origName = baseName
        if endName:
            origName += '.' + endName

        name = directory + baseName
        if endName:
            name += '.' + endName
            if not self.__requestFilename:
                # do not overwrite, if the user is not being asked
                i = 1
                while QFile.exists(name):
                    # file exists already, don't overwrite
                    name = directory + baseName + ('-{0:d}'.format(i))
                    if endName:
                        name += '.' + endName
                    i += 1
        return name, origName

    def __open(self):
        """
        Private slot to open the downloaded file.
        """
        info = QFileInfo(self.__output)
        url = QUrl.fromLocalFile(info.absoluteFilePath())
        QDesktopServices.openUrl(url)

    @pyqtSlot()
    def on_tryAgainButton_clicked(self):
        """
        Private slot to retry the download.
        """
        self.retry()

    def retry(self):
        """
        Public slot to retry the download.
        """
        if not self.tryAgainButton.isEnabled():
            return

        self.tryAgainButton.setEnabled(False)
        self.tryAgainButton.setVisible(False)
        self.openButton.setEnabled(False)
        self.openButton.setVisible(False)
        if not self.__isFtpDownload:
            self.stopButton.setEnabled(True)
            self.stopButton.setVisible(True)
            self.pauseButton.setEnabled(True)
            self.pauseButton.setVisible(True)
        self.progressBar.setVisible(True)

        if self.__page:
            nam = self.__page.networkAccessManager()
        else:
            import Helpviewer.HelpWindow
            nam = Helpviewer.HelpWindow.HelpWindow.networkAccessManager()
        reply = nam.get(QNetworkRequest(self.__url))
        if self.__output.exists():
            self.__output.remove()
        self.__output = QFile()
        self.__reply = reply
        self.__initialize(tryAgain=True)
        self.__state = DownloadItem.Downloading
        self.statusChanged.emit()

    @pyqtSlot(bool)
    def on_pauseButton_clicked(self, checked):
        """
        Private slot to pause the download.
        
        @param checked flag indicating the state of the button (boolean)
        """
        if checked:
            self.__reply.readyRead.disconnect(self.__readyRead)
            self.__reply.setReadBufferSize(16 * 1024)
        else:
            self.__reply.readyRead.connect(self.__readyRead)
            self.__reply.setReadBufferSize(16 * 1024 * 1024)
            self.__readyRead()

    @pyqtSlot()
    def on_stopButton_clicked(self):
        """
        Private slot to stop the download.
        """
        self.cancelDownload()

    def cancelDownload(self):
        """
        Public slot to stop the download.
        """
        self.setUpdatesEnabled(False)
        if not self.__isFtpDownload:
            self.stopButton.setEnabled(False)
            self.stopButton.setVisible(False)
            self.pauseButton.setEnabled(False)
            self.pauseButton.setVisible(False)
        self.tryAgainButton.setEnabled(True)
        self.tryAgainButton.setVisible(True)
        self.openButton.setEnabled(False)
        self.openButton.setVisible(False)
        self.setUpdatesEnabled(True)
        self.__state = DownloadItem.DownloadCancelled
        self.__reply.abort()
        self.downloadFinished.emit()

    @pyqtSlot()
    def on_openButton_clicked(self):
        """
        Private slot to open the downloaded file.
        """
        self.openFile()

    def openFile(self):
        """
        Public slot to open the downloaded file.
        """
        info = QFileInfo(self.__fileName)
        url = QUrl.fromLocalFile(info.absoluteFilePath())
        QDesktopServices.openUrl(url)

    def openFolder(self):
        """
        Public slot to open the folder containing the downloaded file.
        """
        info = QFileInfo(self.__fileName)
        url = QUrl.fromLocalFile(info.absolutePath())
        QDesktopServices.openUrl(url)

    def __readyRead(self):
        """
        Private slot to read the available data.
        """
        if self.__requestFilename and not self.__output.fileName():
            return

        if not self.__output.isOpen():
            # in case someone else has already put a file there
            if not self.__requestFilename:
                self.__getFileName()
            if not self.__output.open(QIODevice.WriteOnly):
                self.infoLabel.setText(
                    self.tr("Error opening save file: {0}").format(
                        self.__output.errorString()))
                self.on_stopButton_clicked()
                self.statusChanged.emit()
                return
            self.statusChanged.emit()

        buffer = self.__reply.readAll()
        self.__sha1Hash.addData(buffer)
        self.__md5Hash.addData(buffer)
        bytesWritten = self.__output.write(buffer)
        if bytesWritten == -1:
            self.infoLabel.setText(
                self.tr("Error saving: {0}").format(
                    self.__output.errorString()))
            self.on_stopButton_clicked()
        else:
            self.__startedSaving = True
            if self.__finishedDownloading:
                self.__finished()

    def __networkError(self):
        """
        Private slot to handle a network error.
        """
        self.infoLabel.setText(
            self.tr("Network Error: {0}").format(self.__reply.errorString()))
        self.tryAgainButton.setEnabled(True)
        self.tryAgainButton.setVisible(True)
        self.downloadFinished.emit()

    def __metaDataChanged(self):
        """
        Private slot to handle a change of the meta data.
        """
        locationHeader = self.__reply.header(QNetworkRequest.LocationHeader)
        if locationHeader and locationHeader.isValid():
            self.__url = QUrl(locationHeader)
            import Helpviewer.HelpWindow
            self.__reply = Helpviewer.HelpWindow.HelpWindow\
                .networkAccessManager().get(QNetworkRequest(self.__url))
            self.__initialize()

    def __downloadProgress(self, bytesReceived, bytesTotal):
        """
        Private method to show the download progress.
        
        @param bytesReceived number of bytes received (integer)
        @param bytesTotal number of total bytes (integer)
        """
        self.__bytesReceived = bytesReceived
        self.__bytesTotal = bytesTotal
        currentValue = 0
        totalValue = 0
        if bytesTotal > 0:
            currentValue = bytesReceived * 100 / bytesTotal
            totalValue = 100
        self.progressBar.setValue(currentValue)
        self.progressBar.setMaximum(totalValue)

        self.progress.emit(currentValue, totalValue)
        self.__updateInfoLabel()

    def bytesTotal(self):
        """
        Public method to get the total number of bytes of the download.
        
        @return total number of bytes (integer)
        """
        if self.__bytesTotal == -1:
            self.__bytesTotal = self.__reply.header(
                QNetworkRequest.ContentLengthHeader)
            if self.__bytesTotal is None:
                self.__bytesTotal = -1
        return self.__bytesTotal

    def bytesReceived(self):
        """
        Public method to get the number of bytes received.
        
        @return number of bytes received (integer)
        """
        return self.__bytesReceived

    def remainingTime(self):
        """
        Public method to get an estimation for the remaining time.
        
        @return estimation for the remaining time (float)
        """
        if not self.downloading():
            return -1.0

        if self.bytesTotal() == -1:
            return -1.0

        timeRemaining = (self.bytesTotal() -
                         self.bytesReceived()) / self.currentSpeed()

        # ETA should never be 0
        if timeRemaining == 0:
            timeRemaining = 1

        return timeRemaining

    def currentSpeed(self):
        """
        Public method to get an estimation for the download speed.
        
        @return estimation for the download speed (float)
        """
        if not self.downloading():
            return -1.0

        return self.__bytesReceived * 1000.0 / self.__downloadTime.elapsed()

    def __updateInfoLabel(self):
        """
        Private method to update the info label.
        """
        if self.__reply.error() != QNetworkReply.NoError:
            return

        bytesTotal = self.bytesTotal()
        running = not self.downloadedSuccessfully()

        speed = self.currentSpeed()
        timeRemaining = self.remainingTime()

        info = ""
        if running:
            remaining = ""

            if bytesTotal > 0:
                remaining = timeString(timeRemaining)

            info = self.tr("{0} of {1} ({2}/sec)\n{3}")\
                .format(
                    dataString(self.__bytesReceived),
                    bytesTotal == -1 and self.tr("?")
                    or dataString(bytesTotal),
                    dataString(int(speed)),
                    remaining)
        else:
            if self.__bytesReceived == bytesTotal or bytesTotal == -1:
                info = self.tr("{0} downloaded\nSHA1: {1}\nMD5: {2}")\
                    .format(dataString(self.__output.size()),
                            str(self.__sha1Hash.result().toHex(),
                                encoding="ascii"),
                            str(self.__md5Hash.result().toHex(),
                                encoding="ascii")
                            )
            else:
                info = self.tr("{0} of {1} - Stopped")\
                    .format(dataString(self.__bytesReceived),
                            dataString(bytesTotal))
        self.infoLabel.setText(info)

    def downloading(self):
        """
        Public method to determine, if a download is in progress.
        
        @return flag indicating a download is in progress (boolean)
        """
        return self.__state == DownloadItem.Downloading

    def downloadedSuccessfully(self):
        """
        Public method to check for a successful download.
        
        @return flag indicating a successful download (boolean)
        """
        return self.__state == DownloadItem.DownloadSuccessful

    def downloadCanceled(self):
        """
        Public method to check, if the download was cancelled.
        
        @return flag indicating a canceled download (boolean)
        """
        return self.__state == DownloadItem.DownloadCancelled

    def __finished(self):
        """
        Private slot to handle the download finished.
        """
        self.__finishedDownloading = True
        if not self.__startedSaving:
            return

        noError = self.__reply.error() == QNetworkReply.NoError

        self.progressBar.setVisible(False)
        if not self.__isFtpDownload:
            self.stopButton.setEnabled(False)
            self.stopButton.setVisible(False)
            self.pauseButton.setEnabled(False)
            self.pauseButton.setVisible(False)
        self.openButton.setEnabled(noError)
        self.openButton.setVisible(noError)
        self.__output.close()
        if QFile.exists(self.__fileName):
            QFile.remove(self.__fileName)
        self.__output.rename(self.__fileName)
        self.__updateInfoLabel()
        self.__state = DownloadItem.DownloadSuccessful
        self.statusChanged.emit()
        self.downloadFinished.emit()

        if self.__autoOpen:
            self.__open()

    def canceledFileSelect(self):
        """
        Public method to check, if the user canceled the file selection.
        
        @return flag indicating cancellation (boolean)
        """
        return self.__canceledFileSelect

    def setIcon(self, icon):
        """
        Public method to set the download icon.
        
        @param icon reference to the icon to be set (QIcon)
        """
        self.fileIcon.setPixmap(icon.pixmap(48, 48))

    def fileName(self):
        """
        Public method to get the name of the output file.
        
        @return name of the output file (string)
        """
        return self.__fileName

    def absoluteFilePath(self):
        """
        Public method to get the absolute path of the output file.
        
        @return absolute path of the output file (string)
        """
        return QFileInfo(self.__fileName).absoluteFilePath()

    def getData(self):
        """
        Public method to get the relevant download data.
        
        @return tuple of URL, save location, flag and the
            URL of the related web page (QUrl, string, boolean,QUrl)
        """
        return (self.__url, QFileInfo(self.__fileName).filePath(),
                self.downloadedSuccessfully(), self.__pageUrl)

    def setData(self, data):
        """
        Public method to set the relevant download data.
        
        @param data tuple of URL, save location, flag and the
            URL of the related web page (QUrl, string, boolean, QUrl)
        """
        self.__url = data[0]
        self.__fileName = data[1]
        self.__pageUrl = data[3]
        self.__isFtpDownload = self.__url.scheme() == "ftp"

        self.filenameLabel.setText(QFileInfo(self.__fileName).fileName())
        self.infoLabel.setText(self.__fileName)

        self.stopButton.setEnabled(False)
        self.stopButton.setVisible(False)
        self.pauseButton.setEnabled(False)
        self.pauseButton.setVisible(False)
        self.openButton.setEnabled(data[2])
        self.openButton.setVisible(data[2])
        self.tryAgainButton.setEnabled(not data[2])
        self.tryAgainButton.setVisible(not data[2])
        if data[2]:
            self.__state = DownloadItem.DownloadSuccessful
        else:
            self.__state = DownloadItem.DownloadCancelled
        self.progressBar.setVisible(False)

    def getInfoData(self):
        """
        Public method to get the text of the info label.
        
        @return text of the info label (string)
        """
        return self.infoLabel.text()

    def getPageUrl(self):
        """
        Public method to get the URL of the download page.
        
        @return URL of the download page (QUrl)
        """
        return self.__pageUrl