예제 #1
0
    def __listenerBCancel(self):
        self.objGUI.bCancel.setEnabled(False)
        self.thread_cancel = Thread_Cancel_Autosub(self.thread_exec)

        #Only if worker thread is running
        if self.thread_exec and self.thread_exec.isRunning():
            #reset progress indicator
            self.__listenerProgress("Cancelling", 0)
            self.__setProgressBarIndefinite()
            self.__updateProgressFileYofN("")

            #connect the terminate signal to resetGUI
            self.thread_cancel.signalTerminated.connect(self.__resetGUI)
            #run the cancel autosub operation in new thread
            #to avoid progressbar freezing
            self.thread_cancel.start()
            self.thread_exec = None
예제 #2
0
class Ctr_Main():
    def __init__(self):
        import sys
        app = QtWidgets.QApplication(sys.argv)
        window = QtWidgets.QMainWindow()
        self.objGUI = Ui_window()
        self.objGUI.setupUi(window)
        self.__initGUI()
        window.setFixedSize(window.size())
        window.show()
        sys.exit(app.exec_())

    def __initGUI(self):

        #language selection list
        list_languages = [
            "en-US - English (United States)", "en-AU - English (Australia)",
            "en-CA - English (Canada)", "en-GB - English (United Kingdom)",
            "en-IN - English (India)", "en-GB - English (Ireland)",
            "en-NZ - English (New Zealand)", "en-PH - English (Philippines)",
            "en-SG - English (Singapore)", "af - Afrikaans", "ar - Arabic",
            "az - Azerbaijani", "be - Belarusian", "bg - Bulgarian",
            "bn - Bengali", "bs - Bosnian", "ca - Catalan", "ceb -Cebuano",
            "cs - Czech", "cy - Welsh", "da - Danish", "de - German",
            "el - Greek", "eo - Esperanto", "es-AR - Spanish (Argentina)",
            "es-CL - Spanish (Chile)", "es-ES - Spanish (Spain)",
            "es-US - Spanish (United States)", "es-MX - Spanish (Mexico)",
            "et - Estonian", "eu - Basque", "fa - Persian", "fi - Finnish",
            "fr - French", "ga - Irish", "gl - Galician", "gu -Gujarati",
            "ha - Hausa", "hi - Hindi", "hmn - Hmong", "hr - Croatian",
            "ht Haitian Creole", "hu - Hungarian", "hy - Armenian",
            "id - Indonesian", "ig - Igbo", "is - Icelandic", "it - Italian",
            "iw - Hebrew", "ja - Japanese", "jw - Javanese", "ka - Georgian",
            "kk - Kazakh", "km - Khmer", "kn - Kannada", "ko - Korean",
            "la - Latin", "lo - Lao", "lt - Lithuanian", "lv - Latvian",
            "mg - Malagasy", "mi - Maori", "mk - Macedonian", "ml - Malayalam",
            "mn - Mongolian", "mr - Marathi", "ms - Malay", "mt - Maltese",
            "my - Myanmar (Burmese)", "ne - Nepali", "nl - Dutch",
            "no - Norwegian", "ny - Chichewa", "pa - Punjabi", "pl - Polish",
            "pt-BR - Portuguese (Brazil)", "pt-PT - Portuguese (Portugal)",
            "ro - Romanian", "ru - Russian", "si - Sinhala", "sk - Slovak",
            "sl - Slovenian", "so - Somali", "sq - Albanian", "sr - Serbian",
            "st - Sesotho", "su - Sudanese", "sv - Swedish", "sw - Swahili",
            "ta - Tamil", "te - Telugu", "tg - Tajik", "th - Thai",
            "tl - Filipino", "tr - Turkish", "uk - Ukrainian", "ur - Urdu",
            "uz - Uzbek", "vi - Vietnamese", "yi - Yiddish", "yo - Yoruba",
            "yue-Hant-HK - Cantonese (Traditional, HK)",
            "zh - Chinese (Simplified, China)",
            "zh-HK - Chinese (Simplified, Hong Kong)",
            "zh-TW - Chinese (Traditional, Taiwan)", "zu - Zulu"
        ]

        self.objGUI.cbSelectLang.addItems(list_languages)
        self.__listenerProgress("", 0)

        #default output folder at user desktop
        userHome = Path.home()
        pathOutputFolder = userHome / 'Desktop' / 'pyTranscriber'
        self.objGUI.qleOutputFolder.setText(str(pathOutputFolder))

        self.objGUI.bRemoveFile.setEnabled(False)

        self.objGUI.bCancel.hide()

        #button listeners
        self.objGUI.bConvert.clicked.connect(self.__listenerBExec)
        self.objGUI.bCancel.clicked.connect(self.__listenerBCancel)
        self.objGUI.bRemoveFile.clicked.connect(self.__listenerBRemove)
        self.objGUI.bSelectOutputFolder.clicked.connect(
            self.__listenerBSelectOuputFolder)
        self.objGUI.bOpenOutputFolder.clicked.connect(
            self.__listenerBOpenOutputFolder)
        self.objGUI.bSelectMedia.clicked.connect(self.__listenerBSelectMedia)

        self.objGUI.actionLicense.triggered.connect(self.__listenerBLicense)
        self.objGUI.actionAbout_pyTranscriber.triggered.connect(
            self.__listenerBAboutpyTranscriber)

    def __resetGUI(self):

        self.__resetProgressBar()

        self.objGUI.qlwListFilesSelected.clear()
        self.objGUI.bConvert.setEnabled(False)
        self.objGUI.bRemoveFile.setEnabled(False)

        self.objGUI.bSelectMedia.setEnabled(True)
        self.objGUI.bSelectOutputFolder.setEnabled(True)
        self.objGUI.cbSelectLang.setEnabled(True)

        self.objGUI.bCancel.hide()

    def __lockButtonsDuringOperation(self):
        self.objGUI.bConvert.setEnabled(False)
        self.objGUI.bRemoveFile.setEnabled(False)
        self.objGUI.bSelectMedia.setEnabled(False)
        self.objGUI.bSelectOutputFolder.setEnabled(False)
        self.objGUI.cbSelectLang.setEnabled(False)
        QtCore.QCoreApplication.processEvents()

    def __listenerProgress(self, str, percent):
        self.objGUI.labelCurrentOperation.setText(str)
        self.objGUI.progressBar.setProperty("value", percent)
        QtCore.QCoreApplication.processEvents()

    def __setProgressBarIndefinite(self):
        self.objGUI.progressBar.setMinimum(0)
        self.objGUI.progressBar.setMaximum(0)
        self.objGUI.progressBar.setValue(0)

    def __resetProgressBar(self):
        self.objGUI.progressBar.setMinimum(0)
        self.objGUI.progressBar.setMaximum(100)
        self.objGUI.progressBar.setValue(0)
        self.__listenerProgress("", 0)

    def __updateProgressFileYofN(self, str):
        self.objGUI.labelProgressFileIndex.setText(str)
        QtCore.QCoreApplication.processEvents()

    def __listenerBSelectOuputFolder(self):
        fSelectDir = QFileDialog.getExistingDirectory(
            self.objGUI.centralwidget)
        if fSelectDir:
            self.objGUI.qleOutputFolder.setText(fSelectDir)

    def __listenerBSelectMedia(self):
        #options = QFileDialog.Options()
        options = QFileDialog.DontUseNativeDialog
        files, _ = QFileDialog.getOpenFileNames(
            self.objGUI.centralwidget, "Select media", "",
            "All Media Files (*.mp3 *.mp4 *.wav *.m4a *.wma)")

        if files:
            self.objGUI.qlwListFilesSelected.addItems(files)

            #enable the convert button only if list of files is not empty
            self.objGUI.bConvert.setEnabled(True)
            self.objGUI.bRemoveFile.setEnabled(True)

    def __listenerBExec(self):
        if not MyUtil.is_internet_connected():
            self.__showErrorMessage(
                "Error! You need to have internet connection to use pyTranscriber!"
            )
        else:
            #extracts the two letter lang_code from the string on language selection
            selectedLanguage = self.objGUI.cbSelectLang.currentText()
            indexSpace = selectedLanguage.index(" ")
            langCode = selectedLanguage[:indexSpace]

            listFiles = []
            for i in range(self.objGUI.qlwListFilesSelected.count()):
                listFiles.append(
                    str(self.objGUI.qlwListFilesSelected.item(i).text()))

            outputFolder = self.objGUI.qleOutputFolder.text()
            objParamAutosub = Param_Autosub(listFiles, outputFolder, langCode)

            #execute the main process in separate thread to avoid gui lock
            self.thread_exec = Thread_Exec_Autosub(objParamAutosub)

            #connect signals from work thread to gui controls
            self.thread_exec.signalLockGUI.connect(
                self.__lockButtonsDuringOperation)
            self.thread_exec.signalResetGUI.connect(self.__resetGUI)
            self.thread_exec.signalProgress.connect(self.__listenerProgress)
            self.thread_exec.signalProgressFileYofN.connect(
                self.__updateProgressFileYofN)
            self.thread_exec.signalErrorMsg.connect(self.__showErrorMessage)

            self.thread_exec.start()

            #Show the cancel button
            self.objGUI.bCancel.show()
            self.objGUI.bCancel.setEnabled(True)

    def __listenerBCancel(self):
        self.objGUI.bCancel.setEnabled(False)
        self.thread_cancel = Thread_Cancel_Autosub(self.thread_exec)

        #Only if worker thread is running
        if self.thread_exec and self.thread_exec.isRunning():
            #reset progress indicator
            self.__listenerProgress("Cancelling", 0)
            self.__setProgressBarIndefinite()
            self.__updateProgressFileYofN("")

            #connect the terminate signal to resetGUI
            self.thread_cancel.signalTerminated.connect(self.__resetGUI)
            #run the cancel autosub operation in new thread
            #to avoid progressbar freezing
            self.thread_cancel.start()
            self.thread_exec = None

    def __listenerBRemove(self):
        indexSelected = self.objGUI.qlwListFilesSelected.currentRow()
        if indexSelected >= 0:
            self.objGUI.qlwListFilesSelected.takeItem(indexSelected)

        #if no items left disables the remove and convert button
        if self.objGUI.qlwListFilesSelected.count() == 0:
            self.objGUI.bRemoveFile.setEnabled(False)
            self.objGUI.bConvert.setEnabled(False)

    def __listenerBOpenOutputFolder(self):
        pathOutputFolder = Path(self.objGUI.qleOutputFolder.text())

        #if folder exists and is valid directory
        if os.path.exists(pathOutputFolder) and os.path.isdir(
                pathOutputFolder):
            MyUtil.open_file(pathOutputFolder)
        else:
            self.__showErrorMessage("Error! Invalid output folder.")

    def __listenerBLicense(self):
        self.__showInfoMessage(
            "<html><body><a href=\"https://www.gnu.org/licenses/gpl-3.0.html\">GPL License</a><br><br>"
            +
            "Copyright (C) 2019 Raryel C. Souza <raryel.costa at gmail.com><br>"
            +
            "<br>This program is free software: you can redistribute it and/or modify<br>"
            +
            "it under the terms of the GNU General Public License as published by<br>"
            +
            "the Free Software Foundation, either version 3 of the License, or<br>"
            + " any later version<br>" + "<br>" +
            "This program is distributed in the hope that it will be useful,<br>"
            +
            "but WITHOUT ANY WARRANTY; without even the implied warranty of<br>"
            +
            "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>"
            + "GNU General Public License for more details.<br>" + "<br>" +
            "You should have received a copy of the GNU General Public License<br>"
            +
            "along with this program.  If not, see <a href=\"https://www.gnu.org/licenses\">www.gnu.org/licenses</a>."
            + "</body></html>", "License")

    def __listenerBAboutpyTranscriber(self):
        self.__showInfoMessage(
            "<html><body>" +
            "<a href=\"https://github.com/raryelcostasouza/pyTranscriber\">pyTranscriber</a> is an application that can be used "
            +
            "to generate <b>automatic transcription / automatic subtitles </b>"
            +
            "for audio/video files through a friendly graphical user interface. "
            + "<br><br>" +
            "The hard work of speech recognition is made by the <a href=\"https://cloud.google.com/speech/\">Google Speech Recognition API</a> "
            +
            "using <a href=\"https://github.com/agermanidis/autosub\">Autosub</a>"
            + "</body></html>", "About pyTranscriber")

    def __showInfoMessage(self, info_msg, title):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Information)

        msg.setWindowTitle(title)
        msg.setText(info_msg)
        msg.exec()

    def __showErrorMessage(self, errorMsg):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Critical)

        msg.setWindowTitle("Error!")
        msg.setText(errorMsg)
        msg.exec()
예제 #3
0
class Ctr_Main():
    def __init__(self):
        import sys
        app = QtWidgets.QApplication(sys.argv)
        window = QtWidgets.QMainWindow()
        self.objGUI = Ui_window()
        self.objGUI.setupUi(window)
        self.__initGUI()
        window.setFixedSize(window.size())
        window.show()
        sys.exit(app.exec_())

    def __initGUI(self):

        #language selection list
        list_languages = [
            "en-US - English (United States)", "en-AU - English (Australia)",
            "en-CA - English (Canada)", "en-GB - English (United Kingdom)",
            "en-HK - English (Hong Kong)", "en-IN - English (India)",
            "en-GB - English (Ireland)", "en-NZ - English (New Zealand)",
            "en-PH - English (Philippines)", "en-SG - English (Singapore)",
            "af - Afrikaans", "ar - Arabic", 'ar-DZ - Arabic (Algeria)',
            'ar-EG - Arabic (Egypt)', 'ar-IQ - Arabic (Iraq)',
            'ar-IS - Arabic (Israel)', 'ar-JO - Arabic (Jordan)',
            'ar-KW - Arabic (Kuwait)', 'ar-LB - Arabic (Lebanon)',
            'ar-MA - Arabic (Morocco)', 'ar-OM - Arabic (Oman)',
            'ar-QA - Arabic (Qatar)', 'ar-SA - Arabic (Saudi Arabia)',
            'ar-PS - Arabic (State of Palestine)', 'ar-TN - Arabic (Tunisia)',
            'ar-AE - Arabic (United Arab Emirates)', 'ar-YE - Arabic (Yemen)',
            "az - Azerbaijani", "be - Belarusian", "bg - Bulgarian",
            "bn - Bengali", "bs - Bosnian", "ca - Catalan", "ceb -Cebuano",
            "cs - Czech", "cy - Welsh", "da - Danish", "de - German",
            'de-AT - German (Austria)', 'de-CH - German (Switzerland)',
            "el - Greek", "eo - Esperanto", 'es-ES - Spanish (Spain)',
            'es-AR - Spanish (Argentina)', 'es-BO - Spanish (Bolivia)',
            'es-CL - Spanish (Chile)', 'es-CO - Spanish (Colombia)',
            'es-CR - Spanish (Costa Rica)',
            'es-DO - Spanish (Dominican Republic)',
            'es-EC - Spanish (Ecuador)', 'es-GT - Spanish (Guatemala)',
            'es-HN - Spanish (Honduras)', 'es-MX - Spanish (Mexico)',
            'es-NI - Spanish (Nicaragua)', 'es-PA - Spanish (Panama)',
            'es-PE - Spanish (Peru)', 'es-PR - Spanish (Puerto Rico)',
            'es-PY - Spanish (Paraguay)', 'es-SV - Spanish (El Salvador)',
            'es-UY - Spanish (Uruguay)', 'es-US - Spanish (United States)',
            'es-VE - Spanish (Venezuela)', "et - Estonian", "eu - Basque",
            "fa - Persian", 'fil-PH - Filipino (Philippines)', "fi - Finnish",
            "fr - French", 'fr-BE - French (Belgium)',
            'fr-CA - French (Canada)', 'fr-CH - French (Switzerland)',
            "ga - Irish", "gl - Galician", "gu -Gujarati", "ha - Hausa",
            "hi - Hindi", "hmn - Hmong", "hr - Croatian",
            "ht - Haitian Creole", "hu - Hungarian", "hy - Armenian",
            "id - Indonesian", "ig - Igbo", "is - Icelandic", "it - Italian",
            'it-CH - Italian (Switzerland)', "iw - Hebrew", "ja - Japanese",
            "jw - Javanese", "ka - Georgian", "kk - Kazakh", "km - Khmer",
            "kn - Kannada", "ko - Korean", "la - Latin", "lo - Lao",
            "lt - Lithuanian", "lv - Latvian", "mg - Malagasy", "mi - Maori",
            "mk - Macedonian", "ml - Malayalam", "mn - Mongolian",
            "mr - Marathi", "ms - Malay", "mt - Maltese",
            "my - Myanmar (Burmese)", "ne - Nepali", "nl - Dutch",
            "no - Norwegian", "ny - Chichewa", "pa - Punjabi", "pl - Polish",
            "pt-BR - Portuguese (Brazil)", "pt-PT - Portuguese (Portugal)",
            "ro - Romanian", "ru - Russian", "si - Sinhala", "sk - Slovak",
            "sl - Slovenian", "so - Somali", "sq - Albanian", "sr - Serbian",
            "st - Sesotho", "su - Sudanese", "sv - Swedish", "sw - Swahili",
            "ta - Tamil", 'ta-IN - Tamil (India)', 'ta-MY - Tamil (Malaysia)',
            'ta-SG - Tamil (Singapore)', 'ta-LK - Tamil (Sri Lanka)',
            "te - Telugu", "tg - Tajik", "th - Thai", "tl - Filipino",
            "tr - Turkish", "uk - Ukrainian", "ur - Urdu", "uz - Uzbek",
            "vi - Vietnamese", "yi - Yiddish", "yo - Yoruba",
            "yue-Hant-HK - Cantonese (Traditional, HK)",
            "zh - Chinese (Simplified, China)",
            "zh-HK - Chinese (Simplified, Hong Kong)",
            "zh-TW - Chinese (Traditional, Taiwan)", "zu - Zulu"
        ]

        self.objGUI.cbSelectLang.addItems(list_languages)
        self.__listenerProgress("", 0)

        #default output folder at user desktop
        userHome = Path.home()
        pathOutputFolder = userHome / 'Desktop' / 'pyTranscriber'
        self.objGUI.qleOutputFolder.setText(str(pathOutputFolder))

        self.objGUI.bRemoveFile.setEnabled(False)

        self.objGUI.bCancel.hide()

        #button listeners
        self.objGUI.bConvert.clicked.connect(self.__listenerBExec)
        self.objGUI.bCancel.clicked.connect(self.__listenerBCancel)
        self.objGUI.bRemoveFile.clicked.connect(self.__listenerBRemove)
        self.objGUI.bSelectOutputFolder.clicked.connect(
            self.__listenerBSelectOuputFolder)
        self.objGUI.bOpenOutputFolder.clicked.connect(
            self.__listenerBOpenOutputFolder)
        self.objGUI.bSelectMedia.clicked.connect(self.__listenerBSelectMedia)

        self.objGUI.actionLicense.triggered.connect(self.__listenerBLicense)
        self.objGUI.actionDonation.triggered.connect(self.__listenerBDonation)
        self.objGUI.actionAbout_pyTranscriber.triggered.connect(
            self.__listenerBAboutpyTranscriber)

    def __resetGUIAfterSuccess(self):
        self.__resetGUIAfterCancel()

        self.objGUI.qlwListFilesSelected.clear()
        self.objGUI.bConvert.setEnabled(False)
        self.objGUI.bRemoveFile.setEnabled(False)

    def __resetGUIAfterCancel(self):

        self.__resetProgressBar()

        self.objGUI.bSelectMedia.setEnabled(True)
        self.objGUI.bSelectOutputFolder.setEnabled(True)
        self.objGUI.cbSelectLang.setEnabled(True)
        self.objGUI.chbxOpenOutputFilesAuto.setEnabled(True)

        self.objGUI.bCancel.hide()
        self.objGUI.bConvert.setEnabled(True)
        self.objGUI.bRemoveFile.setEnabled(True)

    def __lockButtonsDuringOperation(self):
        self.objGUI.bConvert.setEnabled(False)
        self.objGUI.bRemoveFile.setEnabled(False)
        self.objGUI.bSelectMedia.setEnabled(False)
        self.objGUI.bSelectOutputFolder.setEnabled(False)
        self.objGUI.cbSelectLang.setEnabled(False)
        self.objGUI.chbxOpenOutputFilesAuto.setEnabled(False)
        QtCore.QCoreApplication.processEvents()

    def __listenerProgress(self, str, percent):
        self.objGUI.labelCurrentOperation.setText(str)
        self.objGUI.progressBar.setProperty("value", percent)
        QtCore.QCoreApplication.processEvents()

    def __setProgressBarIndefinite(self):
        self.objGUI.progressBar.setMinimum(0)
        self.objGUI.progressBar.setMaximum(0)
        self.objGUI.progressBar.setValue(0)

    def __resetProgressBar(self):
        self.objGUI.progressBar.setMinimum(0)
        self.objGUI.progressBar.setMaximum(100)
        self.objGUI.progressBar.setValue(0)
        self.__listenerProgress("", 0)

    def __updateProgressFileYofN(self, str):
        self.objGUI.labelProgressFileIndex.setText(str)
        QtCore.QCoreApplication.processEvents()

    def __listenerBSelectOuputFolder(self):
        fSelectDir = QFileDialog.getExistingDirectory(
            self.objGUI.centralwidget)
        if fSelectDir:
            self.objGUI.qleOutputFolder.setText(fSelectDir)

    def __listenerBSelectMedia(self):
        #options = QFileDialog.Options()
        options = QFileDialog.DontUseNativeDialog
        files, _ = QFileDialog.getOpenFileNames(
            self.objGUI.centralwidget, "Select media", "",
            "All Media Files (*.mp3 *.mp4 *.wav *.m4a *.wma)")

        if files:
            self.objGUI.qlwListFilesSelected.addItems(files)

            #enable the convert button only if list of files is not empty
            self.objGUI.bConvert.setEnabled(True)
            self.objGUI.bRemoveFile.setEnabled(True)

    def __listenerBExec(self):
        if not MyUtil.is_internet_connected():
            self.__showErrorMessage(
                "Error! Cannot reach Google Speech Servers. \n\n1) Please make sure you are connected to the internet. \n2) If you are in China or other place that blocks access to Google servers: please install and enable a desktop-wide VPN app like Windscribe before trying to use pyTranscriber!"
            )
        else:
            #extracts the two letter lang_code from the string on language selection
            selectedLanguage = self.objGUI.cbSelectLang.currentText()
            indexSpace = selectedLanguage.index(" ")
            langCode = selectedLanguage[:indexSpace]

            listFiles = []
            for i in range(self.objGUI.qlwListFilesSelected.count()):
                listFiles.append(
                    str(self.objGUI.qlwListFilesSelected.item(i).text()))

            outputFolder = self.objGUI.qleOutputFolder.text()

            if self.objGUI.chbxOpenOutputFilesAuto.checkState() == Qt.Checked:
                boolOpenOutputFilesAuto = True
            else:
                boolOpenOutputFilesAuto = False

            objParamAutosub = Param_Autosub(listFiles, outputFolder, langCode,
                                            boolOpenOutputFilesAuto)

            #execute the main process in separate thread to avoid gui lock
            self.thread_exec = Thread_Exec_Autosub(objParamAutosub)

            #connect signals from work thread to gui controls
            self.thread_exec.signalLockGUI.connect(
                self.__lockButtonsDuringOperation)
            self.thread_exec.signalResetGUIAfterSuccess.connect(
                self.__resetGUIAfterSuccess)
            self.thread_exec.signalResetGUIAfterCancel.connect(
                self.__resetGUIAfterCancel)
            self.thread_exec.signalProgress.connect(self.__listenerProgress)
            self.thread_exec.signalProgressFileYofN.connect(
                self.__updateProgressFileYofN)
            self.thread_exec.signalErrorMsg.connect(self.__showErrorMessage)
            self.thread_exec.start()

            #Show the cancel button
            self.objGUI.bCancel.show()
            self.objGUI.bCancel.setEnabled(True)

    def __listenerBCancel(self):
        self.objGUI.bCancel.setEnabled(False)
        self.thread_cancel = Thread_Cancel_Autosub(self.thread_exec)

        #Only if worker thread is running
        if self.thread_exec and self.thread_exec.isRunning():
            #reset progress indicator
            self.__listenerProgress("Cancelling", 0)
            self.__setProgressBarIndefinite()
            self.__updateProgressFileYofN("")

            #connect the terminate signal to resetGUI
            self.thread_cancel.signalTerminated.connect(
                self.__resetGUIAfterCancel)
            #run the cancel autosub operation in new thread
            #to avoid progressbar freezing
            self.thread_cancel.start()
            self.thread_exec = None

    def __listenerBRemove(self):
        indexSelected = self.objGUI.qlwListFilesSelected.currentRow()
        if indexSelected >= 0:
            self.objGUI.qlwListFilesSelected.takeItem(indexSelected)

        #if no items left disables the remove and convert button
        if self.objGUI.qlwListFilesSelected.count() == 0:
            self.objGUI.bRemoveFile.setEnabled(False)
            self.objGUI.bConvert.setEnabled(False)

    def __listenerBOpenOutputFolder(self):
        pathOutputFolder = Path(self.objGUI.qleOutputFolder.text())

        #if folder exists and is valid directory
        if os.path.exists(pathOutputFolder) and os.path.isdir(
                pathOutputFolder):
            MyUtil.open_file(pathOutputFolder)
        else:
            self.__showErrorMessage("Error! Invalid output folder.")

    def __listenerBLicense(self):
        self.__showInfoMessage(
            "<html><body><a href=\"https://www.gnu.org/licenses/gpl-3.0.html\">GPL License</a><br><br>"
            +
            "Copyright (C) 2019 Raryel C. Souza <raryel.costa at gmail.com><br>"
            +
            "<br>This program is free software: you can redistribute it and/or modify<br>"
            +
            "it under the terms of the GNU General Public License as published by<br>"
            +
            "the Free Software Foundation, either version 3 of the License, or<br>"
            + " any later version<br>" + "<br>" +
            "This program is distributed in the hope that it will be useful,<br>"
            +
            "but WITHOUT ANY WARRANTY; without even the implied warranty of<br>"
            +
            "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>"
            + "GNU General Public License for more details.<br>" + "<br>" +
            "You should have received a copy of the GNU General Public License<br>"
            +
            "along with this program.  If not, see <a href=\"https://www.gnu.org/licenses\">www.gnu.org/licenses</a>."
            + "</body></html>", "License")

    def __listenerBDonation(self):
        self.__showInfoMessage(
            "<html><body>" +
            "pyTranscriber is developed as a hobby, so donations of any value are welcomed and essential for further improvements and fixes."
            +
            "<br><br>If you feel that this software has been useful and would like to contribute for it to continue improve and have more features and fixes you can <a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=YHB854YHPJCU8&item_name=Donation+pyTranscriber&currency_code=BRL\">DONATE VIA PAYPAL</a> or <a href=\"https://blockchain.com/btc/payment_request?address=153LcqV59paxEEJX7riLrEHQbE54vhcko9&amount=0.00026351&message=Donation to support pyTranscriber development\"> DONATE US$5 VIA BITCOIN</a>."
            + "<br><br>Thanks in advance!" + "</body></html>", "DONATIONS")

    def __listenerBAboutpyTranscriber(self):
        self.__showInfoMessage(
            "<html><body>" +
            "<a href=\"https://github.com/raryelcostasouza/pyTranscriber\">pyTranscriber</a> is an application that can be used "
            +
            "to generate <b>automatic transcription / automatic subtitles </b>"
            +
            "for audio/video files through a friendly graphical user interface. "
            + "<br><br>" +
            "The hard work of speech recognition is made by the <a href=\"https://cloud.google.com/speech/\">Google Speech Recognition API</a> "
            +
            "using <a href=\"https://github.com/agermanidis/autosub\">Autosub</a>"
            +
            "<br><br>pyTranscriber is developed as a hobby, so donations of any value are welcomed and essential for further improvements and fixes."
            +
            "<br><br>If you feel that this software has been useful and would like to contribute for it to continue improve and have more features and fixes you can <a href=\"https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=YHB854YHPJCU8&item_name=Donation+pyTranscriber&currency_code=BRL\">DONATE VIA PAYPAL</a> or <a href=\"https://blockchain.com/btc/payment_request?address=153LcqV59paxEEJX7riLrEHQbE54vhcko9&amount=0.00026351&message=Donation to support pyTranscriber development\"> DONATE US$5 VIA BITCOIN</a>."
            + "<br><br>Thanks in advance!" + "</body></html>",
            "About pyTranscriber")

    def __showInfoMessage(self, info_msg, title):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Information)

        msg.setWindowTitle(title)
        msg.setText(info_msg)
        msg.exec()

    def __showErrorMessage(self, errorMsg):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Critical)

        msg.setWindowTitle("Error!")
        msg.setText(errorMsg)
        msg.exec()