Example #1
0
    def _load_settings(self):
        """ Load the user specific settings. """

        settings = QSettings()

        self.resize(settings.value('size', QSize(860, 400)))
        self.move(settings.value('pos', QPoint(200, 200)))
Example #2
0
 def readSettings(self):
     """read the settings"""
     settings = QSettings('Pixel Stereo', 'lekture')
     pos = settings.value('pos', QPoint(200, 200))
     size = settings.value('size', QSize(1000, 650))
     self.move(pos)
     self.resize(size)
Example #3
0
 def dropEvent(self, event):
     if event.mimeData().hasFormat('text/uri-list'):
         paths = [url for url in event.mimeData().urls()]
         # If we drop many files, only the first one will be take into
         # acount
         fileName = paths[0]
         index = self.indexAt(event.pos())
         row, col = index.row(), index.column()
         settings = QSettings()
         if col == UploadListView.COL_VIDEO:
             if(VideoTools.isVideofile(fileName)):
                 settings.setValue("mainwindow/workingDirectory", fileName)
                 video = VideoFile(fileName)
                 self.model().layoutAboutToBeChanged.emit()
                 self.model().addVideos(row, [video])
                 subtitle = Subtitle.AutoDetectSubtitle(video.getFilePath())
                 if subtitle:
                     sub = SubtitleFile(False, subtitle)
                     self.model().addSubs(row, [sub])
                     thread.start_new_thread(
                         self.uploadModel.ObtainUploadInfo, ())
                 self.resizeRowsToContents()
                 self.model().layoutChanged.emit()
         else:  # if it's the column in SUBTITLES
             print(fileName)
             if(Subtitle.isSubtitle(fileName)):
                 settings.setValue("mainwindow/workingDirectory", fileName)
                 sub = SubtitleFile(False, fileName)
                 self.model().layoutAboutToBeChanged.emit()
                 self.model().addSubs(row, [sub])
                 self.resizeRowsToContents()
                 self.model().layoutChanged.emit()
                 thread.start_new_thread(
                     self.uploadModel.ObtainUploadInfo, ())
Example #4
0
    def _save_settings(self):
        """ Save the user specific settings. """

        settings = QSettings()

        settings.setValue('size', self.size())
        settings.setValue('pos', self.pos())
 def _clearSettings(self):
     """
     Just clears all peacock settings.
     """
     settings = QSettings()
     settings.clear()
     settings.sync()
Example #6
0
def rock_and_roll():
    qsettings = QSettings(paths.SETTINGS, QSettings.IniFormat)
    qapp = QApplication(sys.argv)
    # Load components after qapp
    #lint:disable
    import amaru.ui.main_container
    import amaru.ui.status_bar
    import amaru.ui.lateral.tree_project
    import amaru.ui.lateral.lateral
    #lint:enable

    # StyleSheet
    log.debug("Aply style sheet...")
    with open(style, mode='r') as f:
        qapp.setStyleSheet(f.read())

    # Show GUI
    log.debug("Showing GUI...")
    gui = Amaru()
    gui.setMinimumSize(700, 500)
    gui.show()

    # Load tabs from last session
    tabs = qsettings.value("opened-tabs")
    if tabs is None:
        tabs = []
    gui.load_files(tabs)

    sys.exit(qapp.exec_())
Example #7
0
	def setUp(self):
		self.tempFile = tempfile.NamedTemporaryFile(prefix='retext-', suffix='.ini')
		baseName = splitext(basename(self.tempFile.name))[0]
		QSettings.setPath(QSettings.IniFormat, QSettings.UserScope,
		                  dirname(self.tempFile.name))
		self.settings = QSettings(QSettings.IniFormat,
		                          QSettings.UserScope, baseName)
Example #8
0
def main():

    if len(sys.argv) > 1:
        font = TFont(os.path.abspath(sys.argv[1]))
    else:
        font = None

    representationFactories.registerAllFactories()
    app = Application(sys.argv)
    # TODO: http://stackoverflow.com/a/21330349/2037879
    app.setOrganizationName("TruFont")
    app.setOrganizationDomain("trufont.github.io")
    app.setApplicationName("TruFont")
    app.setWindowIcon(QIcon(":/resources/app.png"))
    settings = QSettings()
    glyphListPath = settings.value("settings/glyphListPath", "", type=str)
    if glyphListPath and os.path.exists(glyphListPath):
        from defconQt.util import glyphList
        try:
            glyphList = glyphList.parseGlyphList(glyphListPath)
        except Exception as e:
            print(e)
        else:
            app.GL2UV = glyphList
    window = MainWindow(font)
    window.show()
    sys.exit(app.exec_())
Example #9
0
 def updateReport(self, data):
     if data == self.data:
         return
     settings = QSettings('Floppy', 'Floppy')
     self.fileBase = settings.value('WorkDir', type=str)
     self.data = data
     self._update()
Example #10
0
def langs():
    """Returns a list of language codes wished for documentation.
    
    If the list is empty, english (untranslated) is assumed.
    If a language code also has a country suffix, a hyphen will be used
    as separator (as required per RFC2616, Accept-Language header).
    
    """
    s = QSettings()
    langs = []
    lang = s.value("documentation/language", "default", str)

    if lang == "default":
        lang = s.value("language", "", str)
    if lang and lang != "C":
        langs.append(lang)
    langs.extend(po.setup.preferred())
    
    # now fixup the list, remove dups and
    # language/country codes in Accept-Language headers must have '-' and not '_'
    result = []
    def add(item):
        if item not in result:
            result.append(item)
    for l in langs:
        # if there is a language/country code, insert also the generic language code
        if '_' in l:
            add(l.replace('_', '-'))
            add(l.split('_')[0])
        else:
            add(l)
    return result
Example #11
0
 def showEvent(self, event):
     #Show Event
     QWidget.showEvent(self, event)
     #Avoid recalculate the panel sizes if they are already loaded
     if self._splitterArea.count() == 2:
         return
     #Rearrange widgets on Window
     self._splitterArea.insertWidget(0, self._splitterMain)
     if not event.spontaneous():
         self.change_misc_visibility()
     if bin(settings.UI_LAYOUT)[-1] == '1':
         self.splitter_central_rotate()
     if bin(settings.UI_LAYOUT >> 1)[-1] == '1':
         self.splitter_misc_rotate()
     if bin(settings.UI_LAYOUT >> 2)[-1] == '1':
         self.splitter_central_orientation()
     qsettings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat)
     #Lists of sizes as list of QVariant- heightList = [QVariant, QVariant]
     heightList = list(qsettings.value("window/central/mainSize",
         [(self.height() / 3) * 2, self.height() / 3]))
     widthList = list(qsettings.value("window/central/areaSize",
         [(self.width() / 6) * 5, self.width() / 6]))
     self._splitterMainSizes = [int(heightList[0]), int(heightList[1])]
     self._splitterAreaSizes = [int(widthList[0]), int(widthList[1])]
     #Set the sizes to splitters
     #self._splitterMain.setSizes(self._splitterMainSizes)
     self._splitterMain.setSizes(self._splitterMainSizes)
     self._splitterArea.setSizes(self._splitterAreaSizes)
     self.misc.setVisible(
         qsettings.value("window/show_misc", False, type=bool))
Example #12
0
 def requireScripts(self, urlList):
     """
     Public method to get the sources of all required scripts.
     
     @param urlList list of URLs (list of string)
     @return sources of all required scripts (string)
     """
     requiresDir = QDir(self.requireScriptsDirectory())
     if not requiresDir.exists() or len(urlList) == 0:
         return ""
     
     script = ""
     
     settings = QSettings(
         os.path.join(self.requireScriptsDirectory(), "requires.ini"),
         QSettings.IniFormat)
     settings.beginGroup("Files")
     for url in urlList:
         if settings.contains(url):
             fileName = settings.value(url)
             try:
                 f = open(fileName, "r", encoding="utf-8")
                 source = f.read()
                 f.close()
             except (IOError, OSError):
                 source = ""
             script += source.strip() + "\n"
     
     return script
Example #13
0
    def loadSettings(self, firstTime):
        qsettings   = QSettings()
        websettings = self.ui.webview.settings()

        self.fSavedSettings = {
            # WebView
            MOD_KEY_WEBVIEW_INSPECTOR:      qsettings.value(MOD_KEY_WEBVIEW_INSPECTOR,      MOD_DEFAULT_WEBVIEW_INSPECTOR,      type=bool),
            MOD_KEY_WEBVIEW_SHOW_INSPECTOR: qsettings.value(MOD_KEY_WEBVIEW_SHOW_INSPECTOR, MOD_DEFAULT_WEBVIEW_SHOW_INSPECTOR, type=bool)
        }

        inspectorEnabled = self.fSavedSettings[MOD_KEY_WEBVIEW_INSPECTOR] and not USING_LIVE_ISO

        websettings.setAttribute(QWebSettings.DeveloperExtrasEnabled, inspectorEnabled)

        if firstTime:
            self.restoreGeometry(qsettings.value("Geometry", ""))

            if inspectorEnabled and self.fSavedSettings[MOD_KEY_WEBVIEW_SHOW_INSPECTOR]:
                QTimer.singleShot(1000, self.ui.webinspector.show)

        self.ui.act_file_inspect.setVisible(inspectorEnabled)

        if self.fIdleTimerId != 0:
            self.killTimer(self.fIdleTimerId)

        self.fIdleTimerId = self.startTimer(MOD_DEFAULT_MAIN_REFRESH_INTERVAL)
Example #14
0
    def loadSettings(self):
        settings = QSettings("falkTX", "Carla2")

        audioDevice     = settings.value("%s%s/Device"     % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), "",                              type=str)
        audioNumPeriods = settings.value("%s%s/NumPeriods" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), CARLA_DEFAULT_AUDIO_NUM_PERIODS, type=int)
        audioBufferSize = settings.value("%s%s/BufferSize" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), CARLA_DEFAULT_AUDIO_BUFFER_SIZE, type=int)
        audioSampleRate = settings.value("%s%s/SampleRate" % (CARLA_KEY_ENGINE_DRIVER_PREFIX, self.fDriverName), CARLA_DEFAULT_AUDIO_SAMPLE_RATE, type=int)

        if audioDevice and audioDevice in self.fDeviceNames:
            self.ui.cb_device.setCurrentIndex(self.fDeviceNames.index(audioDevice))
        else:
            self.ui.cb_device.setCurrentIndex(-1)

        # fill combo-boxes first
        self.slot_updateDeviceInfo()

        if audioNumPeriods in (2, 3):
            self.ui.sb_numperiods.setValue(audioNumPeriods)
        else:
            self.ui.sb_numperiods.setValue(CARLA_DEFAULT_AUDIO_NUM_PERIODS)

        if audioBufferSize and audioBufferSize in self.fBufferSizes:
            self.ui.cb_buffersize.setCurrentIndex(self.fBufferSizes.index(audioBufferSize))
        elif self.fBufferSizes == BUFFER_SIZE_LIST:
            self.ui.cb_buffersize.setCurrentIndex(BUFFER_SIZE_LIST.index(CARLA_DEFAULT_AUDIO_BUFFER_SIZE))
        else:
            self.ui.cb_buffersize.setCurrentIndex(len(self.fBufferSizes)/2)

        if audioSampleRate and audioSampleRate in self.fSampleRates:
            self.ui.cb_samplerate.setCurrentIndex(self.fSampleRates.index(audioSampleRate))
        elif self.fSampleRates == SAMPLE_RATE_LIST:
            self.ui.cb_samplerate.setCurrentIndex(SAMPLE_RATE_LIST.index(CARLA_DEFAULT_AUDIO_SAMPLE_RATE))
        else:
            self.ui.cb_samplerate.setCurrentIndex(len(self.fSampleRates)/2)
Example #15
0
 def loadSettings(self):
     settings = QSettings(QSettings.UserScope, 'Georgia Tech', 'RamanGui',
         self)
     if settings.contains('alpha'):
         self.alphaBox.setText(settings.value('alpha'))
     if settings.contains('l1Ratio'):
         self.l1RatioBox.setText(settings.value('l1Ratio'))
Example #16
0
def _init_misc():
    """Initialize misc. config-related files."""
    save_manager = objreg.get('save-manager')
    state_config = ini.ReadWriteConfigParser(standarddir.data(), 'state')
    for sect in ['general', 'geometry']:
        try:
            state_config.add_section(sect)
        except configparser.DuplicateSectionError:
            pass
    # See commit a98060e020a4ba83b663813a4b9404edb47f28ad.
    state_config['general'].pop('fooled', None)
    objreg.register('state-config', state_config)
    save_manager.add_saveable('state-config', state_config.save)

    # We need to import this here because lineparser needs config.
    from qutebrowser.misc import lineparser
    command_history = lineparser.LimitLineParser(
        standarddir.data(), 'cmd-history',
        limit=('completion', 'cmd-history-max-items'),
        parent=objreg.get('config'))
    objreg.register('command-history', command_history)
    save_manager.add_saveable('command-history', command_history.save,
                              command_history.changed)

    # Set the QSettings path to something like
    # ~/.config/qutebrowser/qsettings/qutebrowser/qutebrowser.conf so it
    # doesn't overwrite our config.
    #
    # This fixes one of the corruption issues here:
    # https://github.com/qutebrowser/qutebrowser/issues/515

    path = os.path.join(standarddir.config(), 'qsettings')
    for fmt in [QSettings.NativeFormat, QSettings.IniFormat]:
        QSettings.setPath(fmt, QSettings.UserScope, path)
Example #17
0
def removeConfigurationData():
    """
    Remove the eric configuration directory.
    """
    try:
        from PyQt5.QtCore import QSettings
    except ImportError:
        try:
            from PyQt4.QtCore import QSettings
        except ImportError:
            print("No PyQt variant installed. The configuration directory")
            print("cannot be determined. You have to remove it manually.\n")
            return
    
    settings = QSettings(QSettings.IniFormat, QSettings.UserScope,
                         settingsNameOrganization, settingsNameGlobal)
    settingsDir = os.path.dirname(settings.fileName())
    if os.path.exists(settingsDir):
        print("Found the eric configuration directory")
        print("  - {0}".format(settingsDir))
        answer = "c"
        while answer not in ["y", "Y", "n", "N", ""]:
            if sys.version_info[0] == 2:
                answer = raw_input(
                    "Shall this directory be removed (y/N)? ")
            else:
                answer = input(
                    "Shall this directory be removed (y/N)? ")
        if answer in ["y", "Y"]:
            shutil.rmtree(settings)
Example #18
0
 def _on_click_on_favorite(self, path, value):
     settings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat)
     recent_projects = settings.value("recentProjects")
     properties = recent_projects[path]
     properties["isFavorite"] = value
     recent_projects[path] = properties
     settings.setValue("recentProjects", recent_projects)
Example #19
0
    def load_items(self):
        settings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat)
        listByFavorites = []
        listNoneFavorites = []
        recent_projects_dict = dict(settings.value('recentProjects', {}))
        #Filter for favorites
        for recent_project_path, content in list(recent_projects_dict.items()):
            if bool(dict(content)["isFavorite"]):
                listByFavorites.append((recent_project_path,
                    content["lastopen"]))
            else:
                listNoneFavorites.append((recent_project_path,
                    content["lastopen"]))
        if len(listByFavorites) > 1:
            # sort by date favorites
            listByFavorites = sorted(listByFavorites,
                key=lambda date: listByFavorites[1])

        if len(listNoneFavorites) > 1:
            #sort by date last used
            listNoneFavorites = sorted(listNoneFavorites,
                key=lambda date: listNoneFavorites[1])

        for recent_project_path in listByFavorites:
            path = recent_project_path[0]
            name = recent_projects_dict[path]['name']
            self.root.add_project(name, path, True)

        for recent_project_path in listNoneFavorites:
            path = recent_project_path[0]
            name = recent_projects_dict[path]['name']
            self.root.add_project(name, path, False)
Example #20
0
def sGetCGVersion():
    s = QSettings( "EZUSoft", fncProgKennung() )
    try:
        if int(s.value( "cgversion"))==0: return "V11"
        if int(s.value( "cgversion"))==1: return "V20xx"
    except:
        return None
Example #21
0
 def _run_git_command(self, cmd, args = []):
     """
     run a git command and return its output
     as a string list.
     Raise an exception if it returns an error.
     - cmd is the git command (without 'git')
     - args is a string or a list of strings
     """
     from PyQt5.QtCore import QSettings
     s = QSettings()
     s.beginGroup("helper_applications")
     git_cmd = s.value("git", "git", str)
     git_cmd = git_cmd if git_cmd else "git"
     cmd = [git_cmd, cmd]
     cmd.extend(args)
     pr = subprocess.Popen(cmd, cwd = self.rootDir,
                           stdout = subprocess.PIPE,
                           stderr = subprocess.PIPE,
                           universal_newlines = True)
     (out, error) = pr.communicate()
     if error:
         raise GitError(error)
     result = out.split('\n')
     if result[-1] == '':
         result.pop()
     return result
Example #22
0
 def loadSettings(self):
     output_port = midihub.default_output()
     input_port = midihub.default_input()
     s = QSettings()
     s.beginGroup("midi")
     self._playerPort.setEditText(s.value("player/output_port", output_port, str))
     self._inputPort.setEditText(s.value("midi/input_port", input_port, str))
Example #23
0
def main():
    app = QApplication(sys.argv)
    QCoreApplication.setOrganizationName('Hardcoded Software')
    QCoreApplication.setApplicationName(__appname__)
    QCoreApplication.setApplicationVersion(__version__)
    setupQtLogging()
    settings = QSettings()
    lang = settings.value('Language')
    locale_folder = op.join(BASE_PATH, 'locale')
    install_gettext_trans_under_qt(locale_folder, lang)
    # Handle OS signals
    setUpSignals()
    # Let the Python interpreter runs every 500ms to handle signals.  This is
    # required because Python cannot handle signals while the Qt event loop is
    # running.
    from PyQt5.QtCore import QTimer
    timer = QTimer()
    timer.start(500)
    timer.timeout.connect(lambda: None)
    # Many strings are translated at import time, so this is why we only import after the translator
    # has been installed
    from qt.app import DupeGuru
    app.setWindowIcon(QIcon(QPixmap(":/{0}".format(DupeGuru.LOGO_NAME))))
    global dgapp
    dgapp = DupeGuru()
    install_excepthook('https://github.com/hsoft/dupeguru/issues')
    result = app.exec()
    # I was getting weird crashes when quitting under Windows, and manually deleting main app
    # references with gc.collect() in between seems to fix the problem.
    del dgapp
    gc.collect()
    del app
    gc.collect()
    return result
Example #24
0
def getThemeName(theme):
    settings = QSettings(theme, QSettings.IniFormat)

    if settings.contains("Name"):
        return settings.value("Name")
    else:
        return os.path.splitext(os.path.split(theme)[1])[0]
Example #25
0
 def getLastAccessedDirectory(self):
     sttgs = QSettings()
     lastDirectory = sttgs.value("lastAccessedDirectory", defaultValue=".", type=str)
     if lastDirectory != '.':
         print(qApp.translate("lastAccessedDirectoryInfo", "Last accessed directory \"{}\" loaded.").format(
             lastDirectory))
     return lastDirectory
Example #26
0
def playNotification(file):
    # getting user setting from persepolis_setting
    persepolis_setting = QSettings('persepolis_download_manager', 'persepolis')

    # enbling or disabling notification sound in persepolis_setting
    enable_notification = str(persepolis_setting.value('settings/sound'))

    # volume of notification in persepolis_setting(an integer between 0 to 100)
    volume_percent = int(persepolis_setting.value('settings/sound-volume'))

# Paplay volume value must be between 0 (silent) and 65536 (100% volume)
    volume = int((65536 * volume_percent)/100)

    if enable_notification == 'yes':
        if os_type == 'Linux' or os_type == 'FreeBSD' or os_type == 'OpenBSD':
            answer = os.system("paplay --volume='" + str(volume) + "' '" + file + "' &")
            if answer != 0:
                print("paplay not installed!Install it for playing sound notification")
                logger.sendToLog(
                    "paplay not installed!Install it for playing sound notification", "WARNING")


        elif os_type == 'Darwin':
            os.system("osascript -e 'set volume alert volume " +
                      str(volume) + "'")
            os.system("osascript -e 'beep 3' &")

        elif os_type == 'Windows':
            CREATE_NO_WINDOW = 0x08000000
            subprocess.Popen(['rundll32', 'user32.dll,MessageBeep'],
                             shell=False, creationflags=CREATE_NO_WINDOW)
Example #27
0
    def start(self):
        file = self.destination.text().strip()
        if not file:
            QMessageBox.warning(self,
                              self.tr("Create mobile collection"),
                              self.tr("Destination file not specified"))
            return

        density = self.densitySelector.currentText()
        settings = QSettings()
        settings.setValue('density', density)

        self.params['filter'] = self.filterSelector.itemData(self.filterSelector.currentIndex())
        self.params['density'] = density
        self.params['file'] = file
        if self.obverseRadio.isChecked():
            self.params['image'] = self.IMAGE_OBVERSE
        elif self.reverseRadio.isChecked():
            self.params['image'] = self.IMAGE_REVERSE
        elif self.noneRadio.isChecked():
            self.params['image'] = self.IMAGE_NONE
        else:
            self.params['image'] = self.IMAGE_BOTH

        self.accept()
Example #28
0
 def run_command(cls, cmd, args=[], dir=None):
     """
     run a git command and return its output
     as a string list.
     Raise an exception if it returns an error.
     - cmd is the git command (without 'git')
     - args is a string or a list of strings
     If no dir is passed the running dir of
     Frescobaldi is used as default
     """
     dir = os.path.normpath(os.path.join(sys.path[0], '..')) if dir is None else dir
     from PyQt5.QtCore import QSettings
     s = QSettings()
     s.beginGroup("helper_applications")
     git_cmd = s.value("git", "git", str)
     git_cmd = git_cmd if git_cmd else "git"
     cmd = [git_cmd, cmd]
     cmd.extend(args)
     pr = subprocess.Popen(cmd, cwd=dir,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE,
                           universal_newlines=True)
     (out, error) = pr.communicate()
     if error:
         raise GitError(error)
     result = out.split('\n')
     if result[-1] == '':
         result.pop()
     return result
Example #29
0
    def update_cmp_list(self, cd):

        keys = list( cd.keys() )
        keys.sort( key=split_alphanumeric )    

        self.setRowCount(len(cd))

        Settings = QSettings('kicad-tools', 'Schematic Component Manager')
        if Settings.contains('component-view'):
            CmpViewDict = Settings.value('component-view')
        else:
            CmpViewDict = {}
        
        for idx, k in enumerate( keys ):
            Ref  = QTableWidgetItem(k)
            res  = re.match('([a-zA-Z]+)\d+', k)
            Pattern = '$LibRef'
            if res:
                RefBase = res.groups()[0]
                if RefBase in CmpViewDict.keys():
                    Pattern = CmpViewDict[RefBase]
            
            cmp = cd[k][0]
            info_str = cmp.get_str_from_pattern(Pattern)
            Name = QTableWidgetItem(info_str)
            self.setItem(idx, 0, Ref)
            self.setItem(idx, 1, Name)
Example #30
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)
Example #31
0
class MyMainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)
        self.setupUi(self)
        # 设置ini文件
        self.settings = QSettings("./QtPad.ini", QSettings.IniFormat)
        self.lineEdit_dirSaveImage.setText(self.settings.value('dirSaveImage'))
        self.lineEdit_dirSaveAnnotation.setText(
            self.settings.value('dirSaveAnnotation'))
        self.lineEdit_RGBdirSaveImage.setText(
            self.settings.value('RGBdirSaveImage'))

        self.listWidget_image_list.clear()
        self.listWidget_image_list.addItems(
            self.getFileList(self.settings.value('dirSaveImage')))
        self.cap_depth = None
        self.jump_frame = 1
        self.last_choice = None
        self.dir_depth_video = None
        self.initUI()
        self.action_last_page.triggered.connect(self.last_page)
        self.action_next_page.triggered.connect(self.next_page)
        self.pushButton_delete_files.clicked.connect(self.delete_files)
        self.pushButton_dirSaveAnnotation.clicked.connect(
            self.change_dir_annotation)
        self.pushButton_dirSaveImage.clicked.connect(self.change_dir_image)
        self.pushButton_RGBdirSaveImage.clicked.connect(
            self.change_dir_RGBimage)
        self.pushButton_Head.clicked.connect(self.change_body_part)
        self.pushButton_LShouder.clicked.connect(self.change_body_part)
        self.pushButton_LAncon.clicked.connect(self.change_body_part)
        self.pushButton_LHand.clicked.connect(self.change_body_part)
        self.pushButton_RShouder.clicked.connect(self.change_body_part)
        self.pushButton_RAncon.clicked.connect(self.change_body_part)
        self.pushButton_RHand.clicked.connect(self.change_body_part)
        self.action_openImageFolder.triggered.connect(self.openImageFolder)
        self.action_openDepthVideo.triggered.connect(self.openDepthVideo)
        self.listWidget_image_list.itemClicked.connect(self.listChange)
        self.listWidget_image_list.setCurrentRow(0)
        self.listWidget_image_list.itemClicked.emit(
            self.listWidget_image_list.item(0))
        self.update()

    def initUI(self):

        self.frame1 = MyShowWidget()
        self.frame1.setMinimumSize(QtCore.QSize(500, 500))
        self.frame1.setObjectName("frame1")
        self.horizontalLayout.addWidget(self.frame1)
        self.frame1.myclicked.connect(self.update_frame2_annotation)
        self.frame2 = MyShowWidget()
        self.frame2.setMinimumSize(QtCore.QSize(500, 500))
        self.frame2.setObjectName("frame2")
        self.horizontalLayout.addWidget(self.frame2)
        self.frame2.myclicked.connect(self.update_frame1_annotation)

    def last_page(self):
        if (self.listWidget_image_list.currentRow() > 0):
            self.listWidget_image_list.itemClicked.emit(
                self.listWidget_image_list.item(
                    self.listWidget_image_list.currentRow() - 1))
            self.listWidget_image_list.setCurrentRow(
                self.listWidget_image_list.currentRow() - 1)

    def next_page(self):
        self.listWidget_image_list.itemClicked.emit(
            self.listWidget_image_list.item(
                self.listWidget_image_list.currentRow() + 1))
        self.listWidget_image_list.setCurrentRow(
            self.listWidget_image_list.currentRow() + 1)

    def delete_files(self):
        file = self.listWidget_image_list.currentItem().text()
        self.listWidget_image_list.takeItem(
            self.listWidget_image_list.currentRow())
        self.listWidget_image_list.removeItemWidget(
            self.listWidget_image_list.currentItem())
        self.listWidget_image_list.itemClicked.emit(
            self.listWidget_image_list.currentItem())

        os.remove(self.lineEdit_RGBdirSaveImage.text() + '/' +
                  file.split('/')[-1])
        os.remove(file)

    def update_frame1_annotation(self, ann, x, y):
        self.frame1.dict_body[ann] = x, y
        self.frame1.update()

    def update_frame2_annotation(self, ann, x, y):
        self.frame2.dict_body[ann] = x, y
        self.frame2.update()

    def change_dir_annotation(self):
        dir = QFileDialog.getExistingDirectory(
            self, "选择标注保存路径", '/home/learn/PycharmProjects/test/')
        self.lineEdit_dirSaveAnnotation.setText(dir)

    def change_dir_image(self):
        dir = QFileDialog.getExistingDirectory(
            self, "选择图片保存路径", '/home/learn/PycharmProjects/test/')
        self.lineEdit_dirSaveImage.setText(dir)

    def change_dir_RGBimage(self):
        dir = QFileDialog.getExistingDirectory(
            self, "选择RGB图片保存路径", '/home/learn/PycharmProjects/test/')
        self.lineEdit_RGBdirSaveImage.setText(dir)

    def change_body_part(self):
        sender = self.sender()
        if not self.last_choice:
            self.last_choice = sender
            self.frame1.str_body = sender.objectName()[11:]
            self.frame2.str_body = sender.objectName()[11:]

        elif self.last_choice == sender:
            self.last_choice = None
            self.frame1.str_body = None
            self.frame2.str_body = None
        else:
            self.last_choice.setChecked(False)
            self.last_choice = sender
            self.frame1.str_body = sender.objectName()[11:]
            self.frame2.str_body = sender.objectName()[11:]

        self.frame1.update()
        self.frame2.update()

    def openImageFolder(self):
        dir = QFileDialog.getExistingDirectory(self, "打开", '/')

    def openDepthVideo(self):
        self.dir_depth_video, ok = QFileDialog.getOpenFileName(
            self, "打开", '/home/learn/PycharmProjects/test/',
            "All Files (*);;Video Files(*.avi)")
        if not self.cap_depth:
            self.cap_depth = cv2.VideoCapture(self.dir_depth_video)

    def closeEvent(self, event):
        self.settings.setValue("dirSaveImage",
                               self.lineEdit_dirSaveImage.text())
        self.settings.setValue("dirSaveAnnotation",
                               self.lineEdit_dirSaveAnnotation.text())
        self.settings.setValue("RGBdirSaveImage",
                               self.lineEdit_RGBdirSaveImage.text())
        del self.settings

    def getFileList(self, fileDir):
        _list = os.listdir(fileDir)  # 列出文件夹下所有的目录与文件
        dirlist = []
        for i in range(0, len(_list)):
            path = os.path.join(fileDir, _list[i])
            if os.path.isfile(path):
                dirlist.append(path)
        dirlist.sort()
        return dirlist

    def listChange(self, imageChoice):
        self.frame2.showImageFromDir(
            imageChoice.text(),
            self.lineEdit_RGBdirSaveImage.text() + '/' +
            imageChoice.text().split('/')[-1],
            self.lineEdit_dirSaveAnnotation.text() + '/' +
            imageChoice.text().split('/')[-1][:-4] + '.xml', 'depth')

        self.frame1.showImageFromDir(
            imageChoice.text(),
            self.lineEdit_RGBdirSaveImage.text() + '/' +
            imageChoice.text().split('/')[-1],
            self.lineEdit_dirSaveAnnotation.text() + '/' +
            imageChoice.text().split('/')[-1][:-4] + '.xml', 'color')
Example #32
0
 def writeSettings(self):
     s = QSettings()
     s.beginGroup('copy_image')
     s.setValue("dpi", self.dpiCombo.currentText())
     s.setValue("papercolor", self.colorButton.color())
     s.setValue("autocrop", self.crop.isChecked())
     s.setValue("antialias", self.antialias.isChecked())
     s.setValue("scaleup", self.scaleup.isChecked())
Example #33
0
 def remember_checked_handler(self):
     """ 记住密码状态改变 """
     client_config_path = os.path.join(BASE_DIR, "dawn/client.ini")
     app_configs = QSettings(client_config_path, QSettings.IniFormat)
     state = self.login_widget.remember_psd.checkState()
     if state == Qt.Checked:
         phone = self.login_widget.phone_edit.text().strip()
         password = self.login_widget.password_edit.text().strip()
         encrypt_phone = base64.b64encode(
             phone.encode('utf-8')).decode('utf-8')
         encrypt_password = base64.b64encode(
             password.encode('utf-8')).decode('utf-8')
         app_configs.setValue("USER/USER", encrypt_phone)
         app_configs.setValue("USER/USERP", encrypt_password)
     else:
         app_configs.remove("USER/USER")
         app_configs.remove("USER/USERP")
         app_configs.remove("USER/AUTOLOGIN")
Example #34
0
 def save_account_settings(self):
     settings = QSettings()
     settings.setValue(SETTINGS_ACCOUNT, self.accountLineEdit.text())
     settings.sync()
Example #35
0
 def closeApp(self):
     settings = QSettings()
     settings.setValue(SETTINGS_SIZE, self.size())
     settings.setValue(SETTINGS_POS, self.pos())
     settings.sync()
     sys.exit()
Example #36
0
    def __init__(self):
        super(QMainWindow, self).__init__()
        # Set up the user interface from Designer.
        self.setupUi(self)
        
        self.setAccessibleName("Hive Desktop")
        self.redrawLock = Lock()
        self.updateLock = Lock()
        
        self.optionsDialog = dialogs.Options(self)
        self.aboutDialog = dialogs.About(self,
            copyright='holger80',
            programName='Hive Desktop',
            version=VERSION,
            website='https://github.com/holgern/hivedesktop',
            websiteLabel='Github',
            comments='"Welcome to Hive desktop!\n This is the first release for testing qt5.\n Please vote for holger80 as witness, if you like this :).',
            licenseName='GPL-3.0',
            # licenseUrl=helpers.joinpath_to_cwd('LICENSE').as_uri(),
            authors=('holger80',),
            # dependencies=[l.strip() for l in requirements.readlines()],
        )		
        self.mdrenderer = MDRenderer(str(helpers.joinpath_to_cwd('themes')))

        # tmpfile = helpers.mktemp(prefix='hivedesktop', suffix='.html')
        
        self.post = {"body": "##test", "authorperm": "@test/test"}
        self.thread = threads.MDThread(self)
        
        
        # self.webview.url = tmpfile.as_uri()
        
        
        self.feedListWidget.currentRowChanged.connect(self.change_displayed_post, Qt.QueuedConnection)
        
        self.timer = QTimer()
        self.timer.timeout.connect(self.refresh_account_thread)
        
        self.timer2 = QTimer()
        self.timer2.timeout.connect(self.update_account_hist_thread)

        self.timer3 = QTimer()
        self.timer3.timeout.connect(self.update_account_feed_thread)
        
        self.cache_path = QStandardPaths.writableLocation(QStandardPaths.CacheLocation)
        self.db_type = "shelve"
        self.db_type = "sqlite"
        self.feed = []
        self.post = None
        # Get settings
        settings = QSettings()
        # Get checkbox state with speciying type of checkbox:
        # type=bool is a replacement of toBool() in PyQt5
        check_state = settings.value(SETTINGS_TRAY, True, type=bool)
        hist_info_check_state = settings.value(SETTINGS_HIST_INFO, True, type=bool)
        account_state = settings.value(SETTINGS_ACCOUNT, "", type=str)
        self.resize(settings.value(SETTINGS_SIZE, QSize(1053, 800)))
        self.move(settings.value(SETTINGS_POS, QPoint(50, 50)))
        
        #self.accountHistTableWidget.setColumnCount(5)
        #self.accountHistTableWidget.setHorizontalHeaderLabels(["type", "1", "2", "3", "timestamp"])
        
        self.update_account_refreshtime = 5000
        
        # Set state
        self.accountHistNotificationCheckBox.setChecked(hist_info_check_state)
        self.autoRefreshCheckBox.setChecked(check_state)
        if check_state:
            self.timer.start(self.update_account_refreshtime)
            self.timer2.start(15000)
            self.timer3.start(60000)
        self.accountLineEdit.setText(account_state)
        # connect the slot to the signal by clicking the checkbox to save the state settings
        self.autoRefreshCheckBox.clicked.connect(self.save_check_box_settings)   
        self.accountHistNotificationCheckBox.clicked.connect(self.save_check_box_settings)  
        self.accountLineEdit.editingFinished.connect(self.save_account_settings)
        self.actionAbout.triggered.connect(self.about)
        self.actionOptions.triggered.connect(self.options)
        self.threadpool = QThreadPool()
        
        self.minimizeAction = QAction("Mi&nimize", self, triggered=self.hide)
        self.maximizeAction = QAction("Ma&ximize", self,
                triggered=self.showMaximized)
        self.restoreAction = QAction("&Restore", self,
                triggered=self.showNormal)        
        
        menu = QMenu()
        menu.addAction(self.minimizeAction)
        menu.addAction(self.maximizeAction)
        menu.addAction(self.restoreAction)
        menu.addSeparator()        
        # aboutAction = menu.addAction("about")
        # aboutAction.triggered.connect(self.about)
        exitAction = menu.addAction("Exit")
        exitAction.triggered.connect(self.closeApp)
        
        self.tray = QSystemTrayIcon(QIcon(':/icons/icon.ico'))
        
        self.tray.setContextMenu(menu)
        self.tray.activated.connect(self.trayAction)
        
        self.tray.setToolTip("Hive Desktop!")
        self.tray.setObjectName("Hive Desktop")
        self.setWindowTitle("Hive Desktop")
        self.tray.show()
        
        splash_pix = QPixmap(':/icons/splash.png')
        splash = QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint)
        splash.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
        splash.setEnabled(False)
        
        #splash.show()
        #splash.showMessage("<h1><font color='green'>starting...</font></h1>", Qt.AlignTop | Qt.AlignCenter, Qt.black)        
        
        account = account_state
        nodelist = NodeList()
        nodelist.update_nodes()
        self.stm = Steem(node=nodelist.get_nodes(hive=True))
        set_shared_blockchain_instance(self.stm)
        if account != "":
            try:
                self.hist_account = Account(account, steem_instance=self.stm)
            except:
                self.hist_account = None
        else:
            self.hist_account = None
            
        self.refreshPushButton.clicked.connect(self.refresh_account)
        self.refreshPushButton.clicked.connect(self.update_account_hist_thread)
        self.accountLineEdit.editingFinished.connect(self.update_account_info)        
        if self.hasFocus is not None:
            self.init_new_account()
            self.init_new_blocks()
        splash.deleteLater()
Example #37
0

def chunks(l, n):
    for i in range(0, len(l), n):
        yield l[i:i + n]


QCoreApplication.setOrganizationName("QGIS")
QCoreApplication.setOrganizationDomain("qgis.org")
QCoreApplication.setApplicationName("QGIS3")

if len(sys.argv) == 1:
    print("Usage: ./scripts/mkuidefaults.py \"location_to_ini\"")
    sys.exit(1)

s = QSettings(sys.argv[1], QSettings.IniFormat)

ba = bytes(s.value("/UI/geometry"))
print

with open("src/app/ui_defaults.h", "w") as f:

    f.write("#ifndef UI_DEFAULTS_H\n#define UI_DEFAULTS_H\n" +
            "\nstatic const unsigned char defaultUIgeometry[] =\n{\n")

    for chunk in chunks(ba, 16):
        f.write('  {},\n'.format(
            ', '.join(map(hex, struct.unpack('B' * len(chunk), chunk)))))

    f.write("};\n\nstatic const unsigned char defaultUIstate[] =\n{\n")
Example #38
0
def update():

    # APPLICATION ------------------------------------------------------------------------------------------

    appSettings = QSettings(COMPANY, APPLICATION)

    # Saving preferences
    appSettings.setValue('auto_connect_output', auto_connect_output)
    appSettings.setValue('auto_connect_input', auto_connect_input)

    # save mixer settings
    appSettings.setValue('save_mixerstrip_gain', save_mixerstrip_gain)
    appSettings.setValue('save_mixerstrip_send1', save_mixerstrip_send1)
    appSettings.setValue('save_mixerstrip_send2', save_mixerstrip_send2)
    appSettings.setValue('save_mixerstrip_volume', save_mixerstrip_volume)
    appSettings.setValue('save_mixerstrip_mute', save_mixerstrip_mute)
    appSettings.setValue('save_mixerstrip_to_master',
                         save_mixerstrip_to_master)

    # customreset
    appSettings.setValue('customreset_mixerstrip_gain',
                         customreset_mixerstrip_gain)
    appSettings.setValue('customreset_mixerstrip_send1',
                         customreset_mixerstrip_send1)
    appSettings.setValue('customreset_mixerstrip_send2',
                         customreset_mixerstrip_send2)
    appSettings.setValue('customreset_mixerstrip_volume',
                         customreset_mixerstrip_volume)
    appSettings.setValue('customreset_mixerstrip_mute',
                         customreset_mixerstrip_mute)

    # Performance
    appSettings.setValue('disable_shift_after_processing',
                         disable_shift_after_processing)
    appSettings.setValue('show_clip_details_on_trigger',
                         show_clip_details_on_trigger)
    appSettings.setValue('use_big_fonts_playlist', use_big_fonts_playlist)
    appSettings.setValue('use_big_fonts_scenes', use_big_fonts_scenes)
    appSettings.setValue('allow_record_empty_clip', allow_record_empty_clip)
    appSettings.setValue('auto_assign_new_clip_column',
                         auto_assign_new_clip_column)
    appSettings.setValue('play_clip_after_record', play_clip_after_record)
    appSettings.setValue('show_scenes_on_start', show_scenes_on_start)
    appSettings.setValue('show_playlist_on_start', show_playlist_on_start)
    appSettings.setValue('show_song_annotation_on_load',
                         show_song_annotation_on_load)
    appSettings.setValue('slower_processing', slower_processing)
    appSettings.setValue('system_monitoring', system_monitoring)
    appSettings.setValue('rec_color', rec_color)
    appSettings.setValue('grid_rows', str(grid_rows))
    appSettings.setValue('grid_columns', str(grid_columns))
    appSettings.setValue('bigFontSize', str(bigFontSize))
    appSettings.setValue('new_song_master_volume', str(new_song_master_volume))
    appSettings.setValue('new_song_bpm', str(new_song_bpm))
    appSettings.setValue('new_song_beats', str(new_song_beats))
    appSettings.setValue('prevent_song_save', prevent_song_save)

    # and windows position and geometry
    appSettings.setValue("gui_geometry", gui_geometry)
    appSettings.setValue("scenes_geometry", scenes_geometry)
    appSettings.setValue("playlist_geometry", playlist_geometry)
    appSettings.setValue("song_annotation_geometry", song_annotation_geometry)
    appSettings.setValue("mixer_geometry", mixer_geometry)

    # session
    appSettings.setValue('paths_used', paths_used)
    appSettings.value('playlist', playlist)

    appSettings.sync()

    # DEVICE ---------------------------------------------------------------------------------------------

    devSettings = QSettings(COMPANY, DEVICES)

    devSettings.setValue('devices', devices)

    devSettings.sync()

    # PORTS ---------------------------------------------------------------------------------------------

    portSettings = QSettings(COMPANY, PORTS)

    portSettings.setValue('output_ports', output_ports)

    portSettings.setValue('master_port_final_volume',
                          str(master_port_final_volume))
    portSettings.setValue('master_port_mute', master_port_mute)

    portSettings.sync()
Example #39
0
class TriblerWindow(QMainWindow):
    resize_event = pyqtSignal()
    escape_pressed = pyqtSignal()
    received_search_completions = pyqtSignal(object)

    def on_exception(self, *exc_info):
        if self.exception_handler_called:
            # We only show one feedback dialog, even when there are two consecutive exceptions.
            return

        self.exception_handler_called = True

        self.delete_tray_icon()

        # Stop the download loop
        self.downloads_page.stop_loading_downloads()

        # Add info about whether we are stopping Tribler or not
        os.environ['TRIBLER_SHUTTING_DOWN'] = str(
            self.core_manager.shutting_down)

        if not self.core_manager.shutting_down:
            self.core_manager.stop(stop_app_on_shutdown=False)

        self.setHidden(True)

        if self.debug_window:
            self.debug_window.setHidden(True)

        exception_text = "".join(traceback.format_exception(*exc_info))
        logging.error(exception_text)

        dialog = FeedbackDialog(
            self, exception_text,
            self.core_manager.events_manager.tribler_version, self.start_time)
        dialog.show()

    def __init__(self, core_args=None, core_env=None, api_port=None):
        QMainWindow.__init__(self)

        QCoreApplication.setOrganizationDomain("nl")
        QCoreApplication.setOrganizationName("TUDelft")
        QCoreApplication.setApplicationName("Tribler")
        QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)

        self.gui_settings = QSettings()
        api_port = api_port or int(
            get_gui_setting(self.gui_settings, "api_port", DEFAULT_API_PORT))
        dispatcher.update_worker_settings(port=api_port)

        self.navigation_stack = []
        self.tribler_started = False
        self.tribler_settings = None
        self.debug_window = None
        self.core_manager = CoreManager(api_port)
        self.pending_requests = {}
        self.pending_uri_requests = []
        self.download_uri = None
        self.dialog = None
        self.new_version_dialog = None
        self.start_download_dialog_active = False
        self.request_mgr = None
        self.search_request_mgr = None
        self.search_suggestion_mgr = None
        self.selected_torrent_files = []
        self.vlc_available = True
        self.has_search_results = False
        self.last_search_query = None
        self.last_search_time = None
        self.start_time = time.time()
        self.exception_handler_called = False
        self.token_refresh_timer = None

        sys.excepthook = self.on_exception

        uic.loadUi(get_ui_file_path('mainwindow.ui'), self)
        TriblerRequestManager.window = self
        self.tribler_status_bar.hide()

        # Load dynamic widgets
        uic.loadUi(get_ui_file_path('torrent_channel_list_container.ui'),
                   self.channel_page_container)
        self.channel_torrents_list = self.channel_page_container.items_list
        self.channel_torrents_detail_widget = self.channel_page_container.details_tab_widget
        self.channel_torrents_detail_widget.initialize_details_widget()
        self.channel_torrents_list.itemSelectionChanged.connect(
            self.channel_page.clicked_item)

        uic.loadUi(get_ui_file_path('torrent_channel_list_container.ui'),
                   self.search_page_container)
        self.search_results_list = self.search_page_container.items_list
        self.search_torrents_detail_widget = self.search_page_container.details_tab_widget
        self.search_torrents_detail_widget.initialize_details_widget()
        self.search_results_list.itemClicked.connect(
            self.on_channel_item_click)
        self.search_results_list.itemSelectionChanged.connect(
            self.search_results_page.clicked_item)
        self.token_balance_widget.mouseReleaseEvent = self.on_token_balance_click

        def on_state_update(new_state):
            self.loading_text_label.setText(new_state)

        self.core_manager.core_state_update.connect(on_state_update)

        self.magnet_handler = MagnetHandler(self.window)
        QDesktopServices.setUrlHandler("magnet", self.magnet_handler,
                                       "on_open_magnet_link")

        self.debug_pane_shortcut = QShortcut(QKeySequence("Ctrl+d"), self)
        self.debug_pane_shortcut.activated.connect(
            self.clicked_menu_button_debug)

        # Remove the focus rect on OS X
        for widget in self.findChildren(QLineEdit) + self.findChildren(
                QListWidget) + self.findChildren(QTreeWidget):
            widget.setAttribute(Qt.WA_MacShowFocusRect, 0)

        self.menu_buttons = [
            self.left_menu_button_home, self.left_menu_button_search,
            self.left_menu_button_my_channel,
            self.left_menu_button_subscriptions,
            self.left_menu_button_video_player,
            self.left_menu_button_downloads, self.left_menu_button_discovered
        ]

        self.video_player_page.initialize_player()
        self.search_results_page.initialize_search_results_page()
        self.settings_page.initialize_settings_page()
        self.subscribed_channels_page.initialize()
        self.edit_channel_page.initialize_edit_channel_page()
        self.downloads_page.initialize_downloads_page()
        self.home_page.initialize_home_page()
        self.loading_page.initialize_loading_page()
        self.discovering_page.initialize_discovering_page()
        self.discovered_page.initialize_discovered_page()
        self.trust_page.initialize_trust_page()

        self.stackedWidget.setCurrentIndex(PAGE_LOADING)

        # Create the system tray icon
        if QSystemTrayIcon.isSystemTrayAvailable():
            self.tray_icon = QSystemTrayIcon()
            use_monochrome_icon = get_gui_setting(self.gui_settings,
                                                  "use_monochrome_icon",
                                                  False,
                                                  is_bool=True)
            self.update_tray_icon(use_monochrome_icon)

            # Create the tray icon menu
            menu = self.create_add_torrent_menu()
            show_downloads_action = QAction('Show downloads', self)
            show_downloads_action.triggered.connect(
                self.clicked_menu_button_downloads)
            token_balance_action = QAction('Show token balance', self)
            token_balance_action.triggered.connect(
                lambda: self.on_token_balance_click(None))
            quit_action = QAction('Quit Tribler', self)
            quit_action.triggered.connect(self.close_tribler)
            menu.addSeparator()
            menu.addAction(show_downloads_action)
            menu.addAction(token_balance_action)
            menu.addSeparator()
            menu.addAction(quit_action)
            self.tray_icon.setContextMenu(menu)
        else:
            self.tray_icon = None

        self.hide_left_menu_playlist()
        self.left_menu_button_debug.setHidden(True)
        self.top_menu_button.setHidden(True)
        self.left_menu.setHidden(True)
        self.token_balance_widget.setHidden(True)
        self.settings_button.setHidden(True)
        self.add_torrent_button.setHidden(True)
        self.top_search_bar.setHidden(True)

        # Set various icons
        self.top_menu_button.setIcon(QIcon(get_image_path('menu.png')))

        self.search_completion_model = QStringListModel()
        completer = QCompleter()
        completer.setModel(self.search_completion_model)
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.item_delegate = QStyledItemDelegate()
        completer.popup().setItemDelegate(self.item_delegate)
        completer.popup().setStyleSheet("""
        QListView {
            background-color: #404040;
        }

        QListView::item {
            color: #D0D0D0;
            padding-top: 5px;
            padding-bottom: 5px;
        }

        QListView::item:hover {
            background-color: #707070;
        }
        """)
        self.top_search_bar.setCompleter(completer)

        # Toggle debug if developer mode is enabled
        self.window().left_menu_button_debug.setHidden(not get_gui_setting(
            self.gui_settings, "debug", False, is_bool=True))

        # Start Tribler
        self.core_manager.start(core_args=core_args, core_env=core_env)

        self.core_manager.events_manager.received_search_result_channel.connect(
            self.search_results_page.received_search_result_channel)
        self.core_manager.events_manager.received_search_result_torrent.connect(
            self.search_results_page.received_search_result_torrent)
        self.core_manager.events_manager.torrent_finished.connect(
            self.on_torrent_finished)
        self.core_manager.events_manager.new_version_available.connect(
            self.on_new_version_available)
        self.core_manager.events_manager.tribler_started.connect(
            self.on_tribler_started)
        self.core_manager.events_manager.events_started.connect(
            self.on_events_started)
        self.core_manager.events_manager.low_storage_signal.connect(
            self.on_low_storage)
        self.core_manager.events_manager.credit_mining_signal.connect(
            self.on_credit_mining_error)

        # Install signal handler for ctrl+c events
        def sigint_handler(*_):
            self.close_tribler()

        signal.signal(signal.SIGINT, sigint_handler)

        self.installEventFilter(self.video_player_page)

        # Resize the window according to the settings
        center = QApplication.desktop().availableGeometry(self).center()
        pos = self.gui_settings.value(
            "pos",
            QPoint(center.x() - self.width() * 0.5,
                   center.y() - self.height() * 0.5))
        size = self.gui_settings.value("size", self.size())

        self.move(pos)
        self.resize(size)

        self.show()

    def update_tray_icon(self, use_monochrome_icon):
        if not QSystemTrayIcon.isSystemTrayAvailable():
            return

        if use_monochrome_icon:
            self.tray_icon.setIcon(
                QIcon(QPixmap(get_image_path('monochrome_tribler.png'))))
        else:
            self.tray_icon.setIcon(
                QIcon(QPixmap(get_image_path('tribler.png'))))
        self.tray_icon.show()

    def delete_tray_icon(self):
        if self.tray_icon:
            try:
                self.tray_icon.deleteLater()
            except RuntimeError:
                # The tray icon might have already been removed when unloading Qt.
                # This is due to the C code actually being asynchronous.
                logging.debug(
                    "Tray icon already removed, no further deletion necessary."
                )
            self.tray_icon = None

    def on_low_storage(self):
        """
        Dealing with low storage space available. First stop the downloads and the core manager and ask user to user to
        make free space.
        :return:
        """
        self.downloads_page.stop_loading_downloads()
        self.core_manager.stop(False)
        close_dialog = ConfirmationDialog(
            self.window(), "<b>CRITICAL ERROR</b>",
            "You are running low on disk space (<100MB). Please make sure to have "
            "sufficient free space available and restart Tribler again.",
            [("Close Tribler", BUTTON_TYPE_NORMAL)])
        close_dialog.button_clicked.connect(lambda _: self.close_tribler())
        close_dialog.show()

    def on_torrent_finished(self, torrent_info):
        self.tray_show_message(
            "Download finished",
            "Download of %s has finished." % torrent_info["name"])

    def show_loading_screen(self):
        self.top_menu_button.setHidden(True)
        self.left_menu.setHidden(True)
        self.token_balance_widget.setHidden(True)
        self.settings_button.setHidden(True)
        self.add_torrent_button.setHidden(True)
        self.top_search_bar.setHidden(True)
        self.stackedWidget.setCurrentIndex(PAGE_LOADING)

    def tray_set_tooltip(self, message):
        """
        Set a tooltip message for the tray icon, if possible.

        :param message: the message to display on hover
        """
        if self.tray_icon:
            try:
                self.tray_icon.setToolTip(message)
            except RuntimeError as e:
                logging.error("Failed to set tray tooltip: %s", str(e))

    def tray_show_message(self, title, message):
        """
        Show a message at the tray icon, if possible.

        :param title: the title of the message
        :param message: the message to display
        """
        if self.tray_icon:
            try:
                self.tray_icon.showMessage(title, message)
            except RuntimeError as e:
                logging.error("Failed to set tray message: %s", str(e))

    def on_tribler_started(self):
        self.tribler_started = True

        self.top_menu_button.setHidden(False)
        self.left_menu.setHidden(False)
        self.token_balance_widget.setHidden(False)
        self.settings_button.setHidden(False)
        self.add_torrent_button.setHidden(False)
        self.top_search_bar.setHidden(False)

        # fetch the settings, needed for the video player port
        self.request_mgr = TriblerRequestManager()
        self.fetch_settings()

        self.downloads_page.start_loading_downloads()
        self.home_page.load_popular_torrents()
        if not self.gui_settings.value(
                "first_discover",
                False) and not self.core_manager.use_existing_core:
            self.window().gui_settings.setValue("first_discover", True)
            self.discovering_page.is_discovering = True
            self.stackedWidget.setCurrentIndex(PAGE_DISCOVERING)
        else:
            self.clicked_menu_button_home()

        self.setAcceptDrops(True)

    def on_events_started(self, json_dict):
        self.setWindowTitle("Tribler %s" % json_dict["version"])

    def show_status_bar(self, message):
        self.tribler_status_bar_label.setText(message)
        self.tribler_status_bar.show()

    def hide_status_bar(self):
        self.tribler_status_bar.hide()

    def process_uri_request(self):
        """
        Process a URI request if we have one in the queue.
        """
        if len(self.pending_uri_requests) == 0:
            return

        uri = self.pending_uri_requests.pop()
        if uri.startswith('file') or uri.startswith('magnet'):
            self.start_download_from_uri(uri)

    def perform_start_download_request(self,
                                       uri,
                                       anon_download,
                                       safe_seeding,
                                       destination,
                                       selected_files,
                                       total_files=0,
                                       callback=None):
        # Check if destination directory is writable
        is_writable, error = is_dir_writable(destination)
        if not is_writable:
            gui_error_message = "Insufficient write permissions to <i>%s</i> directory. Please add proper " \
                                "write permissions on the directory and add the torrent again. %s" \
                                % (destination, error)
            ConfirmationDialog.show_message(self.window(),
                                            "Download error <i>%s</i>" % uri,
                                            gui_error_message, "OK")
            return

        selected_files_uri = ""
        if len(selected_files) != total_files:  # Not all files included
            selected_files_uri = u'&' + u''.join(
                u"selected_files[]=%s&" % quote_plus_unicode(filename)
                for filename in selected_files)[:-1]

        anon_hops = int(self.tribler_settings['download_defaults']
                        ['number_hops']) if anon_download else 0
        safe_seeding = 1 if safe_seeding else 0
        post_data = "uri=%s&anon_hops=%d&safe_seeding=%d&destination=%s%s" % (
            quote_plus_unicode(uri), anon_hops, safe_seeding, destination,
            selected_files_uri)
        post_data = post_data.encode(
            'utf-8')  # We need to send bytes in the request, not unicode

        request_mgr = TriblerRequestManager()
        request_mgr.perform_request(
            "downloads",
            callback if callback else self.on_download_added,
            method='PUT',
            data=post_data)

        # Save the download location to the GUI settings
        current_settings = get_gui_setting(self.gui_settings,
                                           "recent_download_locations", "")
        recent_locations = current_settings.split(
            ",") if len(current_settings) > 0 else []
        if isinstance(destination, unicode):
            destination = destination.encode('utf-8')
        encoded_destination = destination.encode('hex')
        if encoded_destination in recent_locations:
            recent_locations.remove(encoded_destination)
        recent_locations.insert(0, encoded_destination)

        if len(recent_locations) > 5:
            recent_locations = recent_locations[:5]

        self.gui_settings.setValue("recent_download_locations",
                                   ','.join(recent_locations))

    def on_new_version_available(self, version):
        if version == str(self.gui_settings.value('last_reported_version')):
            return

        self.new_version_dialog = ConfirmationDialog(
            self, "New version available",
            "Version %s of Tribler is available.Do you want to visit the "
            "website to download the newest version?" % version,
            [('IGNORE', BUTTON_TYPE_NORMAL), ('LATER', BUTTON_TYPE_NORMAL),
             ('OK', BUTTON_TYPE_NORMAL)])
        self.new_version_dialog.button_clicked.connect(
            lambda action: self.on_new_version_dialog_done(version, action))
        self.new_version_dialog.show()

    def on_new_version_dialog_done(self, version, action):
        if action == 0:  # ignore
            self.gui_settings.setValue("last_reported_version", version)
        elif action == 2:  # ok
            import webbrowser
            webbrowser.open("https://tribler.org")
        if self.new_version_dialog:
            self.new_version_dialog.close_dialog()
            self.new_version_dialog = None

    def on_search_text_change(self, text):
        self.search_suggestion_mgr = TriblerRequestManager()
        self.search_suggestion_mgr.perform_request(
            "search/completions?q=%s" % text,
            self.on_received_search_completions)

    def on_received_search_completions(self, completions):
        if completions is None:
            return
        self.received_search_completions.emit(completions)
        self.search_completion_model.setStringList(completions["completions"])

    def fetch_settings(self):
        self.request_mgr = TriblerRequestManager()
        self.request_mgr.perform_request("settings",
                                         self.received_settings,
                                         capture_errors=False)

    def received_settings(self, settings):
        if not settings:
            return
        # If we cannot receive the settings, stop Tribler with an option to send the crash report.
        if 'error' in settings:
            raise RuntimeError(
                TriblerRequestManager.get_message_from_error(settings))

        self.tribler_settings = settings['settings']

        # Set the video server port
        self.video_player_page.video_player_port = settings["ports"][
            "video_server~port"]

        # Disable various components based on the settings
        if not self.tribler_settings['search_community']['enabled']:
            self.window().top_search_bar.setHidden(True)
        if not self.tribler_settings['video_server']['enabled']:
            self.left_menu_button_video_player.setHidden(True)
        self.downloads_creditmining_button.setHidden(
            not self.tribler_settings["credit_mining"]["enabled"])
        self.downloads_all_button.click()

        # process pending file requests (i.e. someone clicked a torrent file when Tribler was closed)
        # We do this after receiving the settings so we have the default download location.
        self.process_uri_request()

        # Set token balance refresh timer and load the token balance
        self.token_refresh_timer = QTimer()
        self.token_refresh_timer.timeout.connect(self.load_token_balance)
        self.token_refresh_timer.start(60000)

        self.load_token_balance()

    def on_top_search_button_click(self):
        current_ts = time.time()
        current_search_query = self.top_search_bar.text()

        if self.last_search_query and self.last_search_time \
                and self.last_search_query == self.top_search_bar.text() \
                and current_ts - self.last_search_time < 1:
            logging.info(
                "Same search query already sent within 500ms so dropping this one"
            )
            return

        self.left_menu_button_search.setChecked(True)
        self.has_search_results = True
        self.clicked_menu_button_search()
        self.search_results_page.perform_search(current_search_query)
        self.search_request_mgr = TriblerRequestManager()
        self.search_request_mgr.perform_request(
            "search?q=%s" % current_search_query, None)
        self.last_search_query = current_search_query
        self.last_search_time = current_ts

    def on_settings_button_click(self):
        self.deselect_all_menu_buttons()
        self.stackedWidget.setCurrentIndex(PAGE_SETTINGS)
        self.settings_page.load_settings()
        self.navigation_stack = []
        self.hide_left_menu_playlist()

    def on_token_balance_click(self, _):
        self.raise_window()
        self.deselect_all_menu_buttons()
        self.stackedWidget.setCurrentIndex(PAGE_TRUST)
        self.load_token_balance()
        self.trust_page.load_blocks()
        self.navigation_stack = []
        self.hide_left_menu_playlist()

    def load_token_balance(self):
        self.request_mgr = TriblerRequestManager()
        self.request_mgr.perform_request("trustchain/statistics",
                                         self.received_trustchain_statistics,
                                         capture_errors=False)

    def received_trustchain_statistics(self, statistics):
        if not statistics or "statistics" not in statistics:
            return

        self.trust_page.received_trustchain_statistics(statistics)

        statistics = statistics["statistics"]
        if 'latest_block' in statistics:
            balance = (statistics["latest_block"]["transaction"]["total_up"] -
                       statistics["latest_block"]["transaction"]["total_down"])
            self.set_token_balance(balance)
        else:
            self.token_balance_label.setText("0 MB")

        # If trust page is currently visible, then load the graph as well
        if self.stackedWidget.currentIndex() == PAGE_TRUST:
            self.trust_page.load_blocks()

    def set_token_balance(self, balance):
        if abs(balance) > 1024**4:  # Balance is over a TB
            balance /= 1024.0**4
            self.token_balance_label.setText("%.1f TB" % balance)
        elif abs(balance) > 1024**3:  # Balance is over a GB
            balance /= 1024.0**3
            self.token_balance_label.setText("%.1f GB" % balance)
        else:
            balance /= 1024.0**2
            self.token_balance_label.setText("%d MB" % balance)

    def raise_window(self):
        self.setWindowState(self.windowState() & ~Qt.WindowMinimized
                            | Qt.WindowActive)
        self.raise_()
        self.activateWindow()

    def create_add_torrent_menu(self):
        """
        Create a menu to add new torrents. Shows when users click on the tray icon or the big plus button.
        """
        menu = TriblerActionMenu(self)

        browse_files_action = QAction('Import torrent from file', self)
        browse_directory_action = QAction('Import torrent(s) from directory',
                                          self)
        add_url_action = QAction('Import torrent from magnet/URL', self)

        browse_files_action.triggered.connect(self.on_add_torrent_browse_file)
        browse_directory_action.triggered.connect(
            self.on_add_torrent_browse_dir)
        add_url_action.triggered.connect(self.on_add_torrent_from_url)

        menu.addAction(browse_files_action)
        menu.addAction(browse_directory_action)
        menu.addAction(add_url_action)

        return menu

    def on_add_torrent_button_click(self, pos):
        self.create_add_torrent_menu().exec_(
            self.mapToGlobal(self.add_torrent_button.pos()))

    def on_add_torrent_browse_file(self):
        filenames = QFileDialog.getOpenFileNames(
            self, "Please select the .torrent file", QDir.homePath(),
            "Torrent files (*.torrent)")
        if len(filenames[0]) > 0:
            [
                self.pending_uri_requests.append(u"file:%s" % filename)
                for filename in filenames[0]
            ]
            self.process_uri_request()

    def start_download_from_uri(self, uri):
        self.download_uri = uri

        if get_gui_setting(self.gui_settings,
                           "ask_download_settings",
                           True,
                           is_bool=True):
            # If tribler settings is not available, fetch the settings and inform the user to try again.
            if not self.tribler_settings:
                self.fetch_settings()
                ConfirmationDialog.show_error(
                    self, "Download Error",
                    "Tribler settings is not available yet. "
                    "Fetching it now. Please try again later.")
                return
            # Clear any previous dialog if exists
            if self.dialog:
                self.dialog.close_dialog()
                self.dialog = None

            self.dialog = StartDownloadDialog(self, self.download_uri)
            self.dialog.button_clicked.connect(self.on_start_download_action)
            self.dialog.show()
            self.start_download_dialog_active = True
        else:
            # In the unlikely scenario that tribler settings are not available yet, try to fetch settings again and
            # add the download uri back to self.pending_uri_requests to process again.
            if not self.tribler_settings:
                self.fetch_settings()
                if self.download_uri not in self.pending_uri_requests:
                    self.pending_uri_requests.append(self.download_uri)
                return

            self.window().perform_start_download_request(
                self.download_uri,
                self.window().tribler_settings['download_defaults']
                ['anonymity_enabled'],
                self.window().tribler_settings['download_defaults']
                ['safeseeding_enabled'],
                self.tribler_settings['download_defaults']['saveas'], [], 0)
            self.process_uri_request()

    def on_start_download_action(self, action):
        if action == 1:
            if self.dialog and self.dialog.dialog_widget:
                self.window().perform_start_download_request(
                    self.download_uri,
                    self.dialog.dialog_widget.anon_download_checkbox.isChecked(
                    ),
                    self.dialog.dialog_widget.safe_seed_checkbox.isChecked(),
                    self.dialog.dialog_widget.destination_input.currentText(),
                    self.dialog.get_selected_files(),
                    self.dialog.dialog_widget.files_list_view.
                    topLevelItemCount())
            else:
                ConfirmationDialog.show_error(
                    self, "Tribler UI Error",
                    "Something went wrong. Please try again.")
                logging.exception(
                    "Error while trying to download. Either dialog or dialog.dialog_widget is None"
                )

        self.dialog.request_mgr.cancel_request(
        )  # To abort the torrent info request
        self.dialog.close_dialog()
        self.dialog = None
        self.start_download_dialog_active = False

        if action == 0:  # We do this after removing the dialog since process_uri_request is blocking
            self.process_uri_request()

    def on_add_torrent_browse_dir(self):
        chosen_dir = QFileDialog.getExistingDirectory(
            self, "Please select the directory containing the .torrent files",
            QDir.homePath(), QFileDialog.ShowDirsOnly)

        if len(chosen_dir) != 0:
            self.selected_torrent_files = [
                torrent_file
                for torrent_file in glob.glob(chosen_dir + "/*.torrent")
            ]
            self.dialog = ConfirmationDialog(
                self, "Add torrents from directory",
                "Are you sure you want to add %d torrents to Tribler?" %
                len(self.selected_torrent_files),
                [('ADD', BUTTON_TYPE_NORMAL), ('CANCEL', BUTTON_TYPE_CONFIRM)])
            self.dialog.button_clicked.connect(
                self.on_confirm_add_directory_dialog)
            self.dialog.show()

    def on_confirm_add_directory_dialog(self, action):
        if action == 0:
            for torrent_file in self.selected_torrent_files:
                escaped_uri = u"file:%s" % pathname2url(torrent_file)
                self.perform_start_download_request(
                    escaped_uri,
                    self.window().tribler_settings['download_defaults']
                    ['anonymity_enabled'],
                    self.window().tribler_settings['download_defaults']
                    ['safeseeding_enabled'],
                    self.tribler_settings['download_defaults']['saveas'], [],
                    0)

        if self.dialog:
            self.dialog.close_dialog()
            self.dialog = None

    def on_add_torrent_from_url(self):
        # Make sure that the window is visible (this action might be triggered from the tray icon)
        self.raise_window()

        if self.video_player_page.isVisible():
            # If we're adding a torrent from the video player page, go to the home page.
            # This is necessary since VLC takes the screen and the popup becomes invisible.
            self.clicked_menu_button_home()

        self.dialog = ConfirmationDialog(
            self,
            "Add torrent from URL/magnet link",
            "Please enter the URL/magnet link in the field below:",
            [('ADD', BUTTON_TYPE_NORMAL), ('CANCEL', BUTTON_TYPE_CONFIRM)],
            show_input=True)
        self.dialog.dialog_widget.dialog_input.setPlaceholderText(
            'URL/magnet link')
        self.dialog.dialog_widget.dialog_input.setFocus()
        self.dialog.button_clicked.connect(
            self.on_torrent_from_url_dialog_done)
        self.dialog.show()

    def on_torrent_from_url_dialog_done(self, action):
        if self.dialog and self.dialog.dialog_widget:
            uri = self.dialog.dialog_widget.dialog_input.text()

            # Remove first dialog
            self.dialog.close_dialog()
            self.dialog = None

            if action == 0:
                self.start_download_from_uri(uri)

    def on_download_added(self, result):
        if not result:
            return
        if len(self.pending_uri_requests
               ) == 0:  # Otherwise, we first process the remaining requests.
            self.window().left_menu_button_downloads.click()
        else:
            self.process_uri_request()

    def on_top_menu_button_click(self):
        if self.left_menu.isHidden():
            self.left_menu.show()
        else:
            self.left_menu.hide()

    def deselect_all_menu_buttons(self, except_select=None):
        for button in self.menu_buttons:
            if button == except_select:
                button.setEnabled(False)
                continue
            button.setEnabled(True)

            if button == self.left_menu_button_search and not self.has_search_results:
                button.setEnabled(False)

            button.setChecked(False)

    def clicked_menu_button_home(self):
        self.deselect_all_menu_buttons(self.left_menu_button_home)
        self.stackedWidget.setCurrentIndex(PAGE_HOME)
        self.navigation_stack = []
        self.hide_left_menu_playlist()

    def clicked_menu_button_search(self):
        self.deselect_all_menu_buttons(self.left_menu_button_search)
        self.stackedWidget.setCurrentIndex(PAGE_SEARCH_RESULTS)
        self.navigation_stack = []
        self.hide_left_menu_playlist()

    def clicked_menu_button_discovered(self):
        self.deselect_all_menu_buttons(self.left_menu_button_discovered)
        self.stackedWidget.setCurrentIndex(PAGE_DISCOVERED)
        self.discovered_page.load_discovered_channels()
        self.navigation_stack = []
        self.hide_left_menu_playlist()

    def clicked_menu_button_my_channel(self):
        self.deselect_all_menu_buttons(self.left_menu_button_my_channel)
        self.stackedWidget.setCurrentIndex(PAGE_EDIT_CHANNEL)
        self.edit_channel_page.load_my_channel_overview()
        self.navigation_stack = []
        self.hide_left_menu_playlist()

    def clicked_menu_button_video_player(self):
        self.deselect_all_menu_buttons(self.left_menu_button_video_player)
        self.stackedWidget.setCurrentIndex(PAGE_VIDEO_PLAYER)
        self.navigation_stack = []
        self.show_left_menu_playlist()

    def clicked_menu_button_downloads(self):
        self.raise_window()
        self.left_menu_button_downloads.setChecked(True)
        self.deselect_all_menu_buttons(self.left_menu_button_downloads)
        self.stackedWidget.setCurrentIndex(PAGE_DOWNLOADS)
        self.navigation_stack = []
        self.hide_left_menu_playlist()

    def clicked_menu_button_debug(self):
        if not self.debug_window:
            self.debug_window = DebugWindow(
                self.tribler_settings,
                self.core_manager.events_manager.tribler_version)
        self.debug_window.show()

    def clicked_menu_button_subscriptions(self):
        self.deselect_all_menu_buttons(self.left_menu_button_subscriptions)
        self.subscribed_channels_page.load_subscribed_channels()
        self.stackedWidget.setCurrentIndex(PAGE_SUBSCRIBED_CHANNELS)
        self.navigation_stack = []
        self.hide_left_menu_playlist()

    def hide_left_menu_playlist(self):
        self.left_menu_seperator.setHidden(True)
        self.left_menu_playlist_label.setHidden(True)
        self.left_menu_playlist.setHidden(True)

    def show_left_menu_playlist(self):
        self.left_menu_seperator.setHidden(False)
        self.left_menu_playlist_label.setHidden(False)
        self.left_menu_playlist.setHidden(False)

    def on_channel_item_click(self, channel_list_item):
        list_widget = channel_list_item.listWidget()
        from TriblerGUI.widgets.channel_list_item import ChannelListItem
        if isinstance(list_widget.itemWidget(channel_list_item),
                      ChannelListItem):
            channel_info = channel_list_item.data(Qt.UserRole)
            self.channel_page.initialize_with_channel(channel_info)
            self.navigation_stack.append(self.stackedWidget.currentIndex())
            self.stackedWidget.setCurrentIndex(PAGE_CHANNEL_DETAILS)

    def on_playlist_item_click(self, playlist_list_item):
        list_widget = playlist_list_item.listWidget()
        from TriblerGUI.widgets.playlist_list_item import PlaylistListItem
        if isinstance(list_widget.itemWidget(playlist_list_item),
                      PlaylistListItem):
            playlist_info = playlist_list_item.data(Qt.UserRole)
            self.playlist_page.initialize_with_playlist(playlist_info)
            self.navigation_stack.append(self.stackedWidget.currentIndex())
            self.stackedWidget.setCurrentIndex(PAGE_PLAYLIST_DETAILS)

    def on_page_back_clicked(self):
        try:
            prev_page = self.navigation_stack.pop()
            self.stackedWidget.setCurrentIndex(prev_page)
            if prev_page == PAGE_SEARCH_RESULTS:
                self.stackedWidget.widget(
                    prev_page).load_search_results_in_list()
            if prev_page == PAGE_SUBSCRIBED_CHANNELS:
                self.stackedWidget.widget(prev_page).load_subscribed_channels()
            if prev_page == PAGE_DISCOVERED:
                self.stackedWidget.widget(prev_page).load_discovered_channels()
        except IndexError:
            logging.exception("Unknown page found in stack")

    def on_credit_mining_error(self, error):
        ConfirmationDialog.show_error(self, "Credit Mining Error",
                                      error[u'message'])

    def on_edit_channel_clicked(self):
        self.stackedWidget.setCurrentIndex(PAGE_EDIT_CHANNEL)
        self.navigation_stack = []
        self.channel_page.on_edit_channel_clicked()

    def resizeEvent(self, _):
        # Resize home page cells
        cell_width = self.home_page_table_view.width(
        ) / 3 - 3  # We have some padding to the right
        cell_height = cell_width / 2 + 60

        for i in range(0, 3):
            self.home_page_table_view.setColumnWidth(i, cell_width)
            self.home_page_table_view.setRowHeight(i, cell_height)
        self.resize_event.emit()

    def exit_full_screen(self):
        self.top_bar.show()
        self.left_menu.show()
        self.video_player_page.is_full_screen = False
        self.showNormal()

    def close_tribler(self):
        if not self.core_manager.shutting_down:

            def show_force_shutdown():
                self.loading_text_label.setText(
                    "Tribler is taking longer than expected to shut down. You can force "
                    "Tribler to shutdown by pressing the button below. This might lead "
                    "to data loss.")
                self.window().force_shutdown_btn.show()

            self.delete_tray_icon()
            self.show_loading_screen()
            self.hide_status_bar()
            self.loading_text_label.setText("Shutting down...")

            self.shutdown_timer = QTimer()
            self.shutdown_timer.timeout.connect(show_force_shutdown)
            self.shutdown_timer.start(SHUTDOWN_WAITING_PERIOD)

            self.gui_settings.setValue("pos", self.pos())
            self.gui_settings.setValue("size", self.size())

            if self.core_manager.use_existing_core:
                # Don't close the core that we are using
                QApplication.quit()

            self.core_manager.stop()
            self.core_manager.shutting_down = True
            self.downloads_page.stop_loading_downloads()
            request_queue.clear()

            # Stop the token balance timer
            if self.token_refresh_timer:
                self.token_refresh_timer.stop()

    def closeEvent(self, close_event):
        self.close_tribler()
        close_event.ignore()

    def keyReleaseEvent(self, event):
        if event.key() == Qt.Key_Escape:
            self.escape_pressed.emit()
            if self.isFullScreen():
                self.exit_full_screen()

    def dragEnterEvent(self, e):
        file_urls = [_qurl_to_path(url) for url in e.mimeData().urls()
                     ] if e.mimeData().hasUrls() else []

        if any(os.path.isfile(filename) for filename in file_urls):
            e.accept()
        else:
            e.ignore()

    def dropEvent(self, e):
        file_urls = ([(_qurl_to_path(url), url.toString())
                      for url in e.mimeData().urls()]
                     if e.mimeData().hasUrls() else [])

        for filename, fileurl in file_urls:
            if os.path.isfile(filename):
                self.start_download_from_uri(fileurl)

        e.accept()

    def clicked_force_shutdown(self):
        process_checker = ProcessChecker()
        if process_checker.already_running:
            core_pid = process_checker.get_pid_from_lock_file()
            os.kill(int(core_pid), 9)
        # Stop the Qt application
        QApplication.quit()
Example #40
0
def init():

    global COMPANY
    COMPANY = "MeltinPop"

    # SECTIONS -------------------------------

    global APPLICATION
    APPLICATION = "SpinTool"

    global DEVICES
    DEVICES = "Devices"

    global PORTS
    PORTS = "Ports"

    # Enums ----------------------------------

    global COLOR_RED
    COLOR_RED = "RED"

    global COLOR_AMBER
    COLOR_AMBER = "AMBER"

    # APPLICATION ------------------------------------------------------------------------------------------

    appSettings = QSettings(COMPANY, APPLICATION)

    # Load preferences

    global use_big_fonts_playlist
    use_big_fonts_playlist = appSettings.value('use_big_fonts_playlist',
                                               'false') == 'true'

    global use_big_fonts_scenes
    use_big_fonts_scenes = appSettings.value('use_big_fonts_scenes',
                                             'false') == 'true'

    global auto_connect_output
    auto_connect_output = appSettings.value('auto_connect_output',
                                            'true') == 'true'

    global auto_connect_input
    auto_connect_input = appSettings.value('auto_connect_input',
                                           'true') == 'true'

    # save mixer settings
    global save_mixerstrip_gain
    save_mixerstrip_gain = appSettings.value('save_mixerstrip_gain',
                                             'false') == 'true'

    global save_mixerstrip_send1
    save_mixerstrip_send1 = appSettings.value('save_mixerstrip_send1',
                                              'false') == 'true'

    global save_mixerstrip_send2
    save_mixerstrip_send2 = appSettings.value('save_mixerstrip_send2',
                                              'false') == 'true'

    global save_mixerstrip_volume
    save_mixerstrip_volume = appSettings.value('save_mixerstrip_volume',
                                               'false') == 'true'

    global save_mixerstrip_mute
    save_mixerstrip_mute = appSettings.value('save_mixerstrip_mute',
                                             'false') == 'true'

    global save_mixerstrip_to_master
    save_mixerstrip_to_master = appSettings.value('save_mixerstrip_to_master',
                                                  'false') == 'true'

    # reset all
    global customreset_mixerstrip_gain
    customreset_mixerstrip_gain = appSettings.value(
        'customreset_mixerstrip_gain', 'false') == 'true'

    global customreset_mixerstrip_send1
    customreset_mixerstrip_send1 = appSettings.value(
        'customreset_mixerstrip_send1', 'false') == 'true'

    global customreset_mixerstrip_send2
    customreset_mixerstrip_send2 = appSettings.value(
        'customreset_mixerstrip_send2', 'false') == 'true'

    global customreset_mixerstrip_volume
    customreset_mixerstrip_volume = appSettings.value(
        'customreset_mixerstrip_volume', 'false') == 'true'

    global customreset_mixerstrip_mute
    customreset_mixerstrip_mute = appSettings.value(
        'customreset_mixerstrip_mute', 'false') == 'true'

    # Performance
    global disable_shift_after_processing
    disable_shift_after_processing = appSettings.value(
        'disable_shift_after_processing', 'true') == 'true'

    global show_clip_details_on_trigger
    show_clip_details_on_trigger = appSettings.value(
        'show_clip_details_on_trigger', 'false') == 'true'

    global play_clip_after_record
    play_clip_after_record = appSettings.value('play_clip_after_record',
                                               'false') == 'true'

    global show_scenes_on_start
    show_scenes_on_start = appSettings.value('show_scenes_on_start',
                                             'false') == 'true'

    global allow_record_empty_clip
    allow_record_empty_clip = appSettings.value('allow_record_empty_clip',
                                                'false') == 'true'

    global auto_assign_new_clip_column
    auto_assign_new_clip_column = appSettings.value(
        'auto_assign_new_clip_column', 'false') == 'true'

    global show_playlist_on_start
    show_playlist_on_start = appSettings.value('show_playlist_on_start',
                                               'false') == 'true'

    global show_song_annotation_on_load
    show_song_annotation_on_load = appSettings.value(
        'show_song_annotation_on_load', 'false') == 'true'

    global slower_processing
    slower_processing = appSettings.value('slower_processing',
                                          'false') == 'true'

    global system_monitoring
    system_monitoring = appSettings.value('system_monitoring',
                                          'false') == 'true'

    global rec_color
    rec_color = appSettings.value('rec_color', COLOR_AMBER)

    global grid_rows
    grid_rows = int(appSettings.value('grid_rows', 8))

    global grid_columns
    grid_columns = int(appSettings.value('grid_columns', 8))

    global new_song_master_volume
    new_song_master_volume = int(
        appSettings.value('new_song_master_volume', 50))

    global new_song_bpm
    new_song_bpm = int(appSettings.value('new_song_bpm', 120))

    global new_song_beats
    new_song_beats = int(appSettings.value('new_song_beats', 4))

    global bigFontSize
    bigFontSize = int(appSettings.value('bigFontSize', 14))

    global prevent_song_save
    prevent_song_save = appSettings.value('prevent_song_save',
                                          'false') == 'true'

    # and windows positions

    global playlist_geometry
    playlist_geometry = appSettings.value('playlist_geometry', None)

    global scenes_geometry
    scenes_geometry = appSettings.value('scenes_geometry', None)

    global gui_geometry
    gui_geometry = appSettings.value('gui_geometry', None)

    global song_annotation_geometry
    song_annotation_geometry = appSettings.value('song_annotation_geometry',
                                                 None)

    global mixer_geometry
    mixer_geometry = appSettings.value('mixer_geometry', None)

    # session

    global paths_used
    paths_used = appSettings.value('paths_used', {})

    global playlist
    playlist = appSettings.value('playlist', []) or []

    # DEVICE ---------------------------------------------------------------------------------------------

    devSettings = QSettings(COMPANY, DEVICES)

    global devices
    devices = devSettings.value('devices', None)

    global hasDevices
    hasDevices = devSettings.contains('devices')

    # PORTS AND MIXER VALUES ------------------------------------------------------------------------------

    portSettings = QSettings(COMPANY, PORTS)

    # A dict maintaining the output ports. Every item of the list is a dict
    # which defines elements like: name:{"vol", "mute", "gain"}
    # e.g. output_ports = {"vol":1, "mute":False, "gain":0.5, "send1":0, "send2":0}
    # the default dict can be found in common.py
    global output_ports
    output_ports = portSettings.value('output_ports', None)

    # master port final volume
    global master_port_final_volume
    master_port_final_volume = float(
        portSettings.value('master_port_final_volume', 1))

    # master port mute
    global master_port_mute
    master_port_mute = portSettings.value('master_port_mute',
                                          'false') == 'true'
class UpdateRegistryWorker(QObject):
    '''Background worker for updating Image Registry'''

    finished = pyqtSignal(object)
    error = pyqtSignal(Exception, str)

    def __init__(self):
        QObject.__init__(self)
        self.killed = False
        self.settings = QSettings(QSettings().value("APIS/config_ini"), QSettings.IniFormat)

        # self.registryFile = pluginDir + "\\" + "apis_image_registry.json" #self.settings.value("APIS/image_registry_file", None)

        self.imageDirName = self.settings.value("APIS/image_dir")
        self.orthoDirName = self.settings.value("APIS/ortho_image_dir")
        self.imageDir = QDir(self.imageDirName)
        self.orthoDir = QDir(self.orthoDirName)

        self.imageFormats = self.settings.value("APIS/image_formats", ['jpg'])
        self.hiResFormats = self.settings.value("APIS/hires_formats", ['jpg', 'tif', 'sid', 'nef', 'raf', 'cr2', 'dng'])
        self.orthoFormats = self.settings.value("APIS/ortho_formats", ['jpg', 'tif', 'sid'])

        self.imageFormatsStr = "|".join(self.imageFormats)
        self.hiResFormatsStr = "|".join(self.hiResFormats)
        self.orthoFormatsStr = "|".join(self.orthoFormats)

    def run(self):
        try:
            self.updateImageRegistries()
            self.updateOrthoRegistries()

            if self.killed is False:
                ret = True
                ret = {
                    "imageRegistryNE": self.imageRegistryNE,
                    "hiResRegistryNE": self.hiResRegistryNE,
                    "i2cRegistryNE": self.i2cRegistryNE,
                    "orthoRegistryNE": self.orthoRegistryNE,
                    "mosaicRegistryNE": self.mosaicRegistryNE,
                    "imageRegistry": self.imageRegistry,
                    "hiResRegistry": self.hiResRegistry,
                    "i2cRegistry": self.i2cRegistry,
                    "orthoRegistry": self.orthoRegistry,
                    "mosaicRegistry": self.mosaicRegistry
                }
            else:
                ret = False
        except Exception as e:
            # forward the exception upstream
            self.error.emit(e, traceback.format_exc())
        self.finished.emit(ret)

    def kill(self):
        self.killed = True

    def updateImageRegistries(self):
        self.imageRegistry = []
        self.hiResRegistry = []
        self.i2cRegistry = []

        imageEntryList = self.imageDir.entryList(['??????????'], QDir.Dirs)
        for i in imageEntryList:
            if self.killed is True:
                # kill request received, exit loop early
                break
            iDir = QDir(self.imageDir.path() + '\\' + i)
            # FIXME implement solution for not just jpg but values from ini
            iEntryList = iDir.entryList([i + '_???.jpg'], QDir.Files)
            self.imageRegistry = self.imageRegistry + iEntryList

            hiResDirsEntryList = iDir.entryList(["highres*", "mrsid", "raw"], QDir.Dirs)
            hiResFilters = [i + '_???.' + ext for ext in self.hiResFormats]
            for hr in hiResDirsEntryList:
                if self.killed is True:
                    # kill request received, exit loop early
                    break
                hrDir = QDir(iDir.path() + '\\' + hr)
                hrEntryList = hrDir.entryList(hiResFilters, QDir.Files)
                self.hiResRegistry = self.hiResRegistry + hrEntryList

            i2cDirEntryList = iDir.entryList(["ins2cam"], QDir.Dirs)
            i2cFilters = [i + '_???.' + ext for ext in ['jpg', 'tif', 'tiff']]
            for i2c in i2cDirEntryList:
                if self.killed is True:
                    # kill request received, exit loop early
                    break
                i2cDir = QDir(iDir.path() + '\\' + i2c)
                i2cEntryList = i2cDir.entryList(i2cFilters, QDir.Files)
                self.i2cRegistry = self.i2cRegistry + i2cEntryList

        if self.killed is False:
            self.imageRegistryNE = [img[:14].replace('_', '.') for img in self.imageRegistry]
            self.hiResRegistryNE = [img[:14].replace('_', '.') for img in self.hiResRegistry]
            self.i2cRegistryNE = [img[:14].replace('_', '.') for img in self.i2cRegistry]

    def updateOrthoRegistries(self):
        self.orthoRegistryNE = []
        self.orthoRegistry = []
        self.mosaicRegistryNE = []
        self.mosaicRegistry = []
        orthoEntryList = self.orthoDir.entryList(['??????????'], QDir.Dirs)
        for o in orthoEntryList:
            if self.killed is True:
                # kill request received, exit loop early
                break
            orthoFilters = [o + '_???_op*.' + ext for ext in self.orthoFormats]
            mosaicFilters = [o + '_???_???_op*.' + ext for ext in self.orthoFormats]
            oDir = QDir(self.orthoDir.path() + '\\' + o)
            oEntryList = oDir.entryList(orthoFilters, QDir.Files)
            mEntryList = oDir.entryList(mosaicFilters, QDir.Files)
            #chekc oEntryList if _INT_op
            oEntryList = [img for img in oEntryList if img[11:14].isdigit()]
            #check mEntryList if _INT_INT_op
            mEntryList = [img for img in mEntryList if img[11:14].isdigit() and img[15:18].isdigit()]
            self.orthoRegistry = self.orthoRegistry + oEntryList
            self.mosaicRegistry = self.mosaicRegistry + mEntryList
        if self.killed is False:
            self.orthoRegistryNE = [img[:14].replace('_', '.') for img in self.orthoRegistry]
            self.mosaicRegistryNE = [f"{img[:10]}.{img[11:14]}-{img[15:18]}" for img in self.mosaicRegistry]
Example #42
0
    def __init__(self, core_args=None, core_env=None, api_port=None):
        QMainWindow.__init__(self)

        QCoreApplication.setOrganizationDomain("nl")
        QCoreApplication.setOrganizationName("TUDelft")
        QCoreApplication.setApplicationName("Tribler")
        QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)

        self.gui_settings = QSettings()
        api_port = api_port or int(
            get_gui_setting(self.gui_settings, "api_port", DEFAULT_API_PORT))
        dispatcher.update_worker_settings(port=api_port)

        self.navigation_stack = []
        self.tribler_started = False
        self.tribler_settings = None
        self.debug_window = None
        self.core_manager = CoreManager(api_port)
        self.pending_requests = {}
        self.pending_uri_requests = []
        self.download_uri = None
        self.dialog = None
        self.new_version_dialog = None
        self.start_download_dialog_active = False
        self.request_mgr = None
        self.search_request_mgr = None
        self.search_suggestion_mgr = None
        self.selected_torrent_files = []
        self.vlc_available = True
        self.has_search_results = False
        self.last_search_query = None
        self.last_search_time = None
        self.start_time = time.time()
        self.exception_handler_called = False
        self.token_refresh_timer = None

        sys.excepthook = self.on_exception

        uic.loadUi(get_ui_file_path('mainwindow.ui'), self)
        TriblerRequestManager.window = self
        self.tribler_status_bar.hide()

        # Load dynamic widgets
        uic.loadUi(get_ui_file_path('torrent_channel_list_container.ui'),
                   self.channel_page_container)
        self.channel_torrents_list = self.channel_page_container.items_list
        self.channel_torrents_detail_widget = self.channel_page_container.details_tab_widget
        self.channel_torrents_detail_widget.initialize_details_widget()
        self.channel_torrents_list.itemSelectionChanged.connect(
            self.channel_page.clicked_item)

        uic.loadUi(get_ui_file_path('torrent_channel_list_container.ui'),
                   self.search_page_container)
        self.search_results_list = self.search_page_container.items_list
        self.search_torrents_detail_widget = self.search_page_container.details_tab_widget
        self.search_torrents_detail_widget.initialize_details_widget()
        self.search_results_list.itemClicked.connect(
            self.on_channel_item_click)
        self.search_results_list.itemSelectionChanged.connect(
            self.search_results_page.clicked_item)
        self.token_balance_widget.mouseReleaseEvent = self.on_token_balance_click

        def on_state_update(new_state):
            self.loading_text_label.setText(new_state)

        self.core_manager.core_state_update.connect(on_state_update)

        self.magnet_handler = MagnetHandler(self.window)
        QDesktopServices.setUrlHandler("magnet", self.magnet_handler,
                                       "on_open_magnet_link")

        self.debug_pane_shortcut = QShortcut(QKeySequence("Ctrl+d"), self)
        self.debug_pane_shortcut.activated.connect(
            self.clicked_menu_button_debug)

        # Remove the focus rect on OS X
        for widget in self.findChildren(QLineEdit) + self.findChildren(
                QListWidget) + self.findChildren(QTreeWidget):
            widget.setAttribute(Qt.WA_MacShowFocusRect, 0)

        self.menu_buttons = [
            self.left_menu_button_home, self.left_menu_button_search,
            self.left_menu_button_my_channel,
            self.left_menu_button_subscriptions,
            self.left_menu_button_video_player,
            self.left_menu_button_downloads, self.left_menu_button_discovered
        ]

        self.video_player_page.initialize_player()
        self.search_results_page.initialize_search_results_page()
        self.settings_page.initialize_settings_page()
        self.subscribed_channels_page.initialize()
        self.edit_channel_page.initialize_edit_channel_page()
        self.downloads_page.initialize_downloads_page()
        self.home_page.initialize_home_page()
        self.loading_page.initialize_loading_page()
        self.discovering_page.initialize_discovering_page()
        self.discovered_page.initialize_discovered_page()
        self.trust_page.initialize_trust_page()

        self.stackedWidget.setCurrentIndex(PAGE_LOADING)

        # Create the system tray icon
        if QSystemTrayIcon.isSystemTrayAvailable():
            self.tray_icon = QSystemTrayIcon()
            use_monochrome_icon = get_gui_setting(self.gui_settings,
                                                  "use_monochrome_icon",
                                                  False,
                                                  is_bool=True)
            self.update_tray_icon(use_monochrome_icon)

            # Create the tray icon menu
            menu = self.create_add_torrent_menu()
            show_downloads_action = QAction('Show downloads', self)
            show_downloads_action.triggered.connect(
                self.clicked_menu_button_downloads)
            token_balance_action = QAction('Show token balance', self)
            token_balance_action.triggered.connect(
                lambda: self.on_token_balance_click(None))
            quit_action = QAction('Quit Tribler', self)
            quit_action.triggered.connect(self.close_tribler)
            menu.addSeparator()
            menu.addAction(show_downloads_action)
            menu.addAction(token_balance_action)
            menu.addSeparator()
            menu.addAction(quit_action)
            self.tray_icon.setContextMenu(menu)
        else:
            self.tray_icon = None

        self.hide_left_menu_playlist()
        self.left_menu_button_debug.setHidden(True)
        self.top_menu_button.setHidden(True)
        self.left_menu.setHidden(True)
        self.token_balance_widget.setHidden(True)
        self.settings_button.setHidden(True)
        self.add_torrent_button.setHidden(True)
        self.top_search_bar.setHidden(True)

        # Set various icons
        self.top_menu_button.setIcon(QIcon(get_image_path('menu.png')))

        self.search_completion_model = QStringListModel()
        completer = QCompleter()
        completer.setModel(self.search_completion_model)
        completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.item_delegate = QStyledItemDelegate()
        completer.popup().setItemDelegate(self.item_delegate)
        completer.popup().setStyleSheet("""
        QListView {
            background-color: #404040;
        }

        QListView::item {
            color: #D0D0D0;
            padding-top: 5px;
            padding-bottom: 5px;
        }

        QListView::item:hover {
            background-color: #707070;
        }
        """)
        self.top_search_bar.setCompleter(completer)

        # Toggle debug if developer mode is enabled
        self.window().left_menu_button_debug.setHidden(not get_gui_setting(
            self.gui_settings, "debug", False, is_bool=True))

        # Start Tribler
        self.core_manager.start(core_args=core_args, core_env=core_env)

        self.core_manager.events_manager.received_search_result_channel.connect(
            self.search_results_page.received_search_result_channel)
        self.core_manager.events_manager.received_search_result_torrent.connect(
            self.search_results_page.received_search_result_torrent)
        self.core_manager.events_manager.torrent_finished.connect(
            self.on_torrent_finished)
        self.core_manager.events_manager.new_version_available.connect(
            self.on_new_version_available)
        self.core_manager.events_manager.tribler_started.connect(
            self.on_tribler_started)
        self.core_manager.events_manager.events_started.connect(
            self.on_events_started)
        self.core_manager.events_manager.low_storage_signal.connect(
            self.on_low_storage)
        self.core_manager.events_manager.credit_mining_signal.connect(
            self.on_credit_mining_error)

        # Install signal handler for ctrl+c events
        def sigint_handler(*_):
            self.close_tribler()

        signal.signal(signal.SIGINT, sigint_handler)

        self.installEventFilter(self.video_player_page)

        # Resize the window according to the settings
        center = QApplication.desktop().availableGeometry(self).center()
        pos = self.gui_settings.value(
            "pos",
            QPoint(center.x() - self.width() * 0.5,
                   center.y() - self.height() * 0.5))
        size = self.gui_settings.value("size", self.size())

        self.move(pos)
        self.resize(size)

        self.show()
Example #43
0
class MainWindow(QMainWindow):

    APP_NAME = 'Tagit'
    APP_VERSION = '0.5'
    KEY_GROUP = 'groups'
    KEY_TAG = 'tags'
    KEY_ITEM = 'items'
    KEY_SETTING = 'settings'

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

        # whole views
        self.setupViews()

        # menu and toolbox
        self.createMainMenu()

        # init data: last saved database
        self.setting = QSettings('dothinking', 'tagit')
        filename = self.setting.value('database')
        self.initData(filename)

        # status bar
        self.createStatusBar()

        # window
        self.setTitle()
        self.resize(1000, 800)
        # self.showMaximized()

    # ----------------------------------------------
    # --------------- properties ---------------
    # ----------------------------------------------
    def groupsView(self):
        return self.groupsTreeView

    def tagsView(self):
        return self.tagsTableView

    def itemsView(self):
        return self.itemsTableView

    def propertyView(self):
        return self.dockProperty

    def tabViews(self):
        return self.tabWidget

    def database(self):
        return self._database

    # ----------------------------------------------
    # --------------- data operation ---------------
    # ----------------------------------------------
    def initData(self, database=None):
        '''load data from specified database, init default if failed.
           two failing situations:
           - database is not specified -> init by default and return true
           - specified but is invalid  -> init by default but return false
        '''
        ok = True
        if database and os.path.exists(database):
            # load database
            try:
                with open(database, 'rb') as f:
                    data = pickle.load(f)
            except Exception as e:
                ok = False
            else:
                if self.APP_NAME in data:  # valid database
                    self._database = database
                    self._initData(data)
                    return ok
                else:
                    ok = False

        # init by default if load data from database failed
        self._database = None
        self._initData()

        return ok

    def _initData(self, data={}):
        '''load data from database'''
        # set window title
        self.setTitle()
        self.groupsTreeView.setFocus()

        # get data
        if self.KEY_GROUP in data:
            groups = data.get(self.KEY_GROUP)[GroupModel.CHILDREN]
        else:
            groups = []
        tags = data.get(self.KEY_TAG, [])
        items = data.get(self.KEY_ITEM, [])

        # settings
        settings = data.get(self.KEY_SETTING, {})
        selected_group = settings.get('selected_group', GroupModel.ALLGROUPS)
        selected_tag = settings.get('selected_tag', TagModel.NOTAG)
        selected_style = settings.get('selected_style', None)
        dock_area = settings.get('dock_area', Qt.BottomDockWidgetArea)

        # init groups tree view
        self.groupsTreeView.setup(groups, selected_group)
        self.groupsTreeView.model().updateItems(items)
        self.groupsTreeView.setColumnHidden(GroupModel.KEY, True)

        # init tags table view
        self.tagsTableView.setup(tags, selected_tag)
        self.tagsTableView.model().updateItems(items)
        self.tagsTableView.setColumnHidden(TagModel.KEY,
                                           True)  # hide first column -> key

        # init items table view
        self.itemsTableView.setup(items)
        self.itemsTableView.setColumnHidden(ItemModel.GROUP, True)
        self.itemsTableView.setColumnHidden(ItemModel.TAGS, True)
        self.itemsTableView.setColumnHidden(ItemModel.PATH, True)
        self.itemsTableView.setColumnHidden(ItemModel.NOTES, True)

        # add dock widget
        self.addDockWidget(dock_area, self.dockProperty)

        # set style sheet
        self.main_menu.setStyleSheet(selected_style)

    def closeEvent(self, event):
        '''default method called when trying to close the app'''
        if self.main_menu.maybeSave():
            event.accept()
        else:
            event.ignore()

    def saveRequired(self):
        '''saving is required if anything is changed'''
        return (self.groupsTreeView.model().saveRequired()
                or self.tagsTableView.model().saveRequired()
                or self.itemsTableView.model().sourceModel().saveRequired())

    def serialize(self, filename):
        '''save project data to database'''
        # current group
        for index in self.groupsTreeView.selectedIndexes():
            selected_group = index.siblingAtColumn(GroupModel.KEY).data()
            break
        else:
            selected_group = self.groupsTreeView.model().ALLGROUPS

        # current tag
        for index in self.tagsTableView.selectedIndexes():
            selected_tag = index.siblingAtColumn(TagModel.KEY).data()
            break
        else:
            selected_tag = TagModel.NOTAG

        # collect all data
        data = {
            self.APP_NAME: self.APP_VERSION,
            self.KEY_GROUP: self.groupsTreeView.model().serialize(),
            self.KEY_TAG: self.tagsTableView.model().serialize(),
            self.KEY_ITEM:
            self.itemsTableView.model().sourceModel().serialize(),
            self.KEY_SETTING: {
                'selected_group': selected_group,
                'selected_tag': selected_tag,
                'selected_style': self.main_menu.getCurrentSheetStyle(),
                'dock_area': self.dockWidgetArea(self.dockProperty)
            },
        }

        # dump pickle file
        try:
            with open(filename, 'wb') as f:
                pickle.dump(data, f)
        except Exception as e:
            QMessageBox.critical(
                None, "Error",
                "Could not save current project to\n {0}.".format(filename))
        else:
            self._database = filename
            self.setting.setValue('database', filename)
            self.setTitle()
            self.statusBar().showMessage('File saved.')
            return True

        return False

    # ----------------------------------------------
    # --------------- user interface ---------------
    # ----------------------------------------------
    def setupViews(self):
        '''create main views'''

        # left widgets
        self.tabWidget = QTabWidget()
        self.groupsTreeView = GroupTreeView(['Group',
                                             'Key'])  # groups tree view
        self.tagsTableView = TagTableView(['KEY', 'TAG',
                                           'COLOR'])  # tags table view
        self.tabWidget.addTab(self.groupsTreeView, "Groups")
        self.tabWidget.addTab(self.tagsTableView, "Tags")

        # central widgets: reference item table widget
        headers = [
            'Item Title', 'Group', 'Tags', 'Path', 'Create Date', 'Notes'
        ]
        self.itemsTableView = ItemTableView(headers, self.tabWidget)

        # arranged views
        splitter = QSplitter()
        splitter.addWidget(self.tabWidget)
        splitter.addWidget(self.itemsTableView)
        splitter.setStretchFactor(0, 0)
        splitter.setStretchFactor(1, 1)
        self.setCentralWidget(splitter)

        # dock widgets
        # it has not been added to main window util called by addDockWidget() explicitly
        propWidget = PropertyWidget(self.itemsTableView)
        self.dockProperty = QDockWidget(self.tr("Properties"), self)
        self.dockProperty.setWidget(propWidget)

    def createMainMenu(self):
        '''main menu'''
        self.main_menu = MainMenu(self)
        # create menu items
        self.main_menu.createMenus()
        # set menu enable status
        self.main_menu.refreshMenus()
        # toolbar
        self.main_menu.createToolBars()

    def setTitle(self):
        '''set window title'''
        title = self._database if self._database else 'untitled.dat'
        self.setWindowTitle("Tagit - {0}".format(title))

    def createStatusBar(self):
        if self._database:
            msg = 'loading database successfully - {0}'.format(self._database)
        else:
            msg = 'New database'
        self.statusBar().showMessage(msg)
Example #44
0
    def run(self):
        settings = QSettings()
        pref_target_path = settings.value(Settings.SETTINGS_SAVE_PATH,
                                          Settings.DEFAULT_TARGET_PATH,
                                          type=str)
        pref_max_pool_cnt = settings.value(Settings.SETTINGS_MAX_POOL_CNT,
                                           Settings.DEFAULT_MAX_POOL,
                                           type=int)
        gallery_save_path = pref_target_path + '/' + self.gallery.path
        if not os.path.exists(gallery_save_path):
            os.makedirs(gallery_save_path)

        # Cloudflare Authorization
        self.state.emit('Authorize..')
        Logger.LOGGER.info("Wait for Cloudflare Authorization..")
        self.driver.get(URL_HITOMI)
        while "Just a moment..." in self.driver.page_source:
            pass
        user_agent = self.driver.execute_script("return navigator.userAgent;")

        try:
            cookie_value = '__cfduid=' + self.driver.get_cookie('__cfduid')['value'] + \
                           '; cf_clearance=' + self.driver.get_cookie('cf_clearance')['value']
            headers = {'User-Agent': user_agent}
            cookies = {'session_id': cookie_value}
        except TypeError:
            Logger.LOGGER.warning("Not apply cookies to requests")
            headers = None
            cookies = None

        # Make Download Session
        session = FuturesSession(max_workers=pref_max_pool_cnt)
        if headers is not None:
            session.headers = headers
        if cookies is not None:
            session.cookies = cookies
        responses = {}

        # Fetch image data from gallery page
        download_list = []
        self.state.emit('Fetch..')
        Logger.LOGGER.info("Connect to Gallery page..")
        self.driver.get(self.gallery.url.replace('galleries', 'reader'))
        source = self.driver.page_source
        soup = BeautifulSoup(source, 'html.parser')
        ref_url = soup.find('img')['src']
        ref_key = ref_url[:ref_url.index('.')]
        img_urls = soup.find_all('div', class_='img-url')
        self.total_cnt = len(img_urls)
        for img_url in img_urls:
            download_url = 'https:' + img_url.get_text().replace(
                '//g', ref_key)
            download_name = download_url.split('/')[-1]
            responses[download_name] = session.get(download_url)
            download_list.append(download_url)
        for filename in responses:
            self.response_to_file(response=responses[filename].result(),
                                  name=filename,
                                  path=gallery_save_path)
        session.close()

        # Compress Zip Files
        self.state.emit('Compressing..')
        if self.gallery.original != "":
            zip_path = pref_target_path + '/' + self.gallery.type + '/' + self.gallery.original + '/' + self.gallery.path + '.zip'
        else:
            zip_path = pref_target_path + '/' + self.gallery.type + '/' + self.gallery.path + '.zip'

        try:
            if not os.path.exists(zip_path[:zip_path.rfind('/')]):
                os.makedirs(zip_path[:zip_path.rfind('/')])
            FileUtil.make_zip(gallery_save_path, zip_path)
            shutil.rmtree(gallery_save_path)
        except:
            print(traceback.format_exc())
            Logger.LOGGER.error("Compressing Process Error... pass")
        # Save to Firebase
        # TODO Enable next line on Build
        FirebaseClient.fbclient.insert_data(self.gallery)
Example #45
0
    def __init__(self, parent=None):
        super(Proxy, self).__init__(parent)
        self.settings = QSettings()

        self.layout = QVBoxLayout()

        self.buttonLayout = QHBoxLayout()
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok |
                                          QDialogButtonBox.Cancel)
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonLayout.addWidget(self.buttonBox)

        self.proxy_url_label = QLabel(QCoreApplication.translate(
                                'Entry label for the proxy url',
                                'Proxy URL:', 'Proxy settings dialogue'))
        self.proxy_url_line = QLineEdit()
        url = self.settings.value('Proxy_url') or ''
        self.proxy_url_line = QLineEdit(url)
        self.proxy_url_line.setMinimumWidth(300)

        self.proxy_port_label = QLabel(QCoreApplication.translate(
                            'Entry label for the proxy port', 'Port:',
                            'Proxy settings dialogue'))
        port = self.settings.value('Proxy_port') or ''
        self.proxy_port_line = QLineEdit(port)

        self.proxy_auth_label = QLabel(QCoreApplication.translate(
                                    'Checkbox', 'Use proxy authentification',
                                    'Proxy settings dialogue'))
        self.proxy_auth_checkbox = QCheckBox()
        self.proxy_auth_bool = eval(self.settings.value(
                                    'Use_proxy_authentification') or 'False')
        self.proxy_auth_checkbox.setChecked(self.proxy_auth_bool)
        self.proxy_auth_checkbox.stateChanged.connect(self.proxy_auth)

        self.proxy_user_label = QLabel(QCoreApplication.translate(
            'Proxy username authentification',
            'User ID:', 'Proxy configuration dialogue'))
        self.proxy_user_label.setEnabled(self.proxy_auth_bool)
        self.proxy_pass_label = QLabel(QCoreApplication.translate(
            'Proxy password authentification',
            'Password:'******'Proxy configuration dialogue'))
        self.proxy_pass_label.setEnabled(self.proxy_auth_bool)

        user = self.settings.value('Proxy_user') or ''
        self.proxy_user_line = QLineEdit(user)
        self.proxy_user_line.setEnabled(self.proxy_auth_bool)
        password = self.settings.value('Proxy_password') or ''
        self.proxy_pass_line = QLineEdit(password)
        self.proxy_pass_line.setEnabled(self.proxy_auth_bool)
        self.proxy_pass_line.setEchoMode(QLineEdit.Password)

        self.status_layout = QHBoxLayout()
        self.status_label = QLabel()
        self.status_layout.addWidget(self.status_label)

        self.panel = QGridLayout()
        self.panel.addWidget(self.proxy_url_label, 0, 0)
        self.panel.addWidget(self.proxy_url_line, 0, 1)
        self.panel.addWidget(self.proxy_port_label, 0, 2)
        self.panel.addWidget(self.proxy_port_line, 0, 3)
        self.panel.addWidget(self.proxy_auth_label, 1, 0)
        self.panel.addWidget(self.proxy_auth_checkbox, 1, 1)
        self.panel.addWidget(self.proxy_user_label, 2, 0)
        self.panel.addWidget(self.proxy_user_line, 2, 1)
        self.panel.addWidget(self.proxy_pass_label, 3, 0)
        self.panel.addWidget(self.proxy_pass_line, 3, 1)

        self.layout.addLayout(self.panel)
        self.layout.addLayout(self.status_layout)
        self.layout.addLayout(self.buttonLayout)

        self.setLayout(self.layout)
class ApisImageRegistry(QObject):

    loaded = pyqtSignal(object)

    def __init__(self, pluginDir, iface):

        QObject.__init__(self)

        self.iface = iface
        self.registryFile = pluginDir + "\\" + "apis_image_registry.json"  # self.settings.value("APIS/image_registry_file", None)

        # NE ... NoExtension
        self.__imageRegistryNE = None
        self.__hiResRegistryNE = None
        self.__i2cRegistryNE = None
        self.__orthoRegistryNE = None
        self.__mosaicRegistryNE = None
        self.__imageRegistry = None
        self.__hiResRegistry = None
        self.__i2cRegistry = None
        self.__orthoRegistry = None
        self.__mosaicRegistry = None

        self.isLoaded = False
        self.isSetup = False

        self.worker = None

    def setupSettings(self):
        self.settings = QSettings(QSettings().value("APIS/config_ini"), QSettings.IniFormat)

        self.imageDirName = self.settings.value("APIS/image_dir")
        self.orthoDirName = self.settings.value("APIS/ortho_image_dir")
        self.imageDir = QDir(self.imageDirName)
        self.orthoDir = QDir(self.orthoDirName)

        self.imageFormats = self.settings.value("APIS/image_formats", [u'jpg'])
        self.hiResFormats = self.settings.value("APIS/hires_formats", [u'jpg', u'tif', u'sid', u'nef', u'raf', u'cr2', u'dng'])
        self.orthoFormats = self.settings.value("APIS/ortho_formats", [u'jpg', u'tif', u'sid'])

        self.imageFormatsStr = u"|".join(self.imageFormats)
        self.hiResFormatsStr = u"|".join(self.hiResFormats)
        self.orthoFormatsStr = u"|".join(self.orthoFormats)

        self.isSetup = True

    def registryIsSetup(self):
        return self.isSetup

    def setupRegistry(self):
        if self.registryFile and os.path.isfile(self.registryFile):
            if self.isOutdated():
                # If isOutdated > PopUp > Info: Local Image Registry is outdated > Please Update Image Registry
                # ask if update ImageRegistry
                msgBox = QMessageBox()
                msgBox.setWindowTitle(u'Image Registry')
                msgBox.setText(u'Die APIS Image Registry ist älter als ein Monat. Bitte führen Sie ein Update durch!')
                msgBox.addButton(QPushButton(u'Update'), QMessageBox.YesRole)
                msgBox.addButton(QPushButton(u'Abbrechen'), QMessageBox.NoRole)
                ret = msgBox.exec_()

                if ret == 0:
                    self.updateRegistries()
                else:
                    self.loadRegistryFromFile()
            else:
                self.loadRegistryFromFile()
        else:
            # ask if generate ImageRegistry
            msgBox = QMessageBox()
            msgBox.setWindowTitle(u'Image Registry')
            msgBox.setText(u'Für die Verwendung von APIS muss eine Image Registry erstellt werden!')
            msgBox.addButton(QPushButton(u'Jetzt erstellen'), QMessageBox.YesRole)
            msgBox.addButton(QPushButton(u'Abbrechen'), QMessageBox.NoRole)
            ret = msgBox.exec_()
            if ret == 0:
                self.updateRegistries()
            else:
                self.isLoaded = False

    def registryIsLoaded(self):
        return self.isLoaded

    def loadRegistryFromFile(self):
        #load self.__imageRegistry, self.__hiResRegistry, self.__orthoRegistry from JSON File
        if os.path.isfile(self.registryFile):
            with open(self.registryFile, 'rU') as registry:
                registryDict = json.load(registry)
                self.__imageRegistryNE = registryDict["imageRegistryNE"]
                self.__hiResRegistryNE = registryDict["hiResRegistryNE"]
                self.__i2cRegistryNE = registryDict["i2cRegistryNE"]
                self.__orthoRegistryNE = registryDict["orthoRegistryNE"]
                self.__mosaicRegistryNE = registryDict["mosaicRegistryNE"]

                self.__imageRegistry = registryDict["imageRegistry"]
                self.__hiResRegistry = registryDict["hiResRegistry"]
                self.__i2cRegistry = registryDict["i2cRegistry"]
                self.__orthoRegistry = registryDict["orthoRegistry"]
                self.__mosaicRegistry = registryDict["mosaicRegistry"]
            self.isLoaded = True
            self.loaded.emit(True)
        else:
            self.isLoaded = False

    def writeRegistryToFile(self):
        # write self.__imageRegistry, self.__hiResRegistry, self.__orthoRegistry to JSON File
        # does registry file exist
        if os.path.isfile(self.registryFile):
            os.remove(self.registryFile)

        with open(self.registryFile, 'w') as f:
            registryDict = {
                "imageRegistryNE": self.__imageRegistryNE,
                "hiResRegistryNE": self.__hiResRegistryNE,
                "i2cRegistryNE": self.__i2cRegistryNE,
                "orthoRegistryNE": self.__orthoRegistryNE,
                "mosaicRegistryNE": self.__mosaicRegistryNE,
                "imageRegistry": self.__imageRegistry,
                "hiResRegistry": self.__hiResRegistry,
                "i2cRegistry": self.__i2cRegistry,
                "orthoRegistry": self.__orthoRegistry,
                "mosaicRegistry": self.__mosaicRegistry
            }
            json.dump(registryDict, f)

    def isOutdated(self):
        if os.path.isfile(self.registryFile):
            today = datetime.datetime.today()
            creationDate = datetime.datetime.fromtimestamp(os.path.getctime(self.registryFile))
            modificationDate = datetime.datetime.fromtimestamp(os.path.getmtime(self.registryFile))
            if modificationDate > creationDate:
                fileAge = today - modificationDate
            else:
                fileAge = today - creationDate
            #QMessageBox.warning(None, "Zeit", "{0}".format(fileAge.days))
            if fileAge.days > 30:
                return True
            else:
                return False
            # Registry is Outdated > if local File is older than one month!

    def updateRegistries(self):
        self.startWorker()

    def hasImage(self, imageNumber):
        return True if imageNumber in self.__imageRegistryNE else False

    def hasHiRes(self, imageNumber):
        return True if imageNumber in self.__hiResRegistryNE else False

    def hasIns2Cam(self, imageNumber):
        return True if imageNumber in self.__i2cRegistryNE else False

    def hasOrtho(self, imageNumber):
        return True if imageNumber in self.__orthoRegistryNE else False

    def hasMosaic(self, imageNumber):
        filmNumber = imageNumber[:10]
        image = int(imageNumber[11:14])
        r = re.compile(r"^{0}*".format(filmNumber), re.IGNORECASE)
        mosaicCandidates = list(filter(r.match, self.__mosaicRegistryNE))
        mosaicsValid = []
        for mC in mosaicCandidates:
            fromTo = range(int(mC[11:14]), int(mC[15:18]) + 1)
            if image in fromTo:
                mosaicsValid.append(mC)
        return mosaicsValid
        # QMessageBox.information(None, "MosaicInfo", "{0}: {1}".format(imageNumber, ", ".join(mosaicsValid)))

    def hasOrthoOrMosaic(self, imageNumber):
        return self.hasOrtho(imageNumber) or bool(self.hasMosaic(imageNumber))

    def hasImageRE(self, imageNumber):
        r = re.compile(r"^{0}\.({1})$".format(imageNumber, self.imageFormatsStr), re.IGNORECASE)
        r = list(filter(r.match, self.__imageRegistry))
        return len(r)

    def hasHiResRE(self, imageNumber):
        r = re.compile(r"^{0}\.({1})$".format(imageNumber, self.hiResFormatsStr), re.IGNORECASE)
        r = list(filter(r.match, self.__hiResRegistry))
        return len(r)

    def hasIns2CamRE(self, imageNumber):
        pass

    def hasOrthoRE(self, imageNumber):
        r = re.compile(r"^{0}_op.+\.({1})$".format(imageNumber, self.orthoFormatsStr), re.IGNORECASE)
        r = list(filter(r.match, self.__orthoRegistry))
        return len(r)

    def hasMosaicRE(self, imageNumber):
        pass

    #filmNumber = OLD Film Number
    def getImageRegistryForFilm(self, filmNumber):
        imagesForFilm = []
        for imageNumber in self.__imageRegistryNE:
            if filmNumber in imageNumber:
                imagesForFilm.append(imageNumber)
        return imagesForFilm

    def startWorker(self):
        # create a new worker instance

        if self.worker is None:

            worker = UpdateRegistryWorker()

            # configure the QgsMessageBar
            messageBar = self.iface.messageBar().createMessage(u"Update Image Registry", u"Dieser Vorgang kann einige Minute dauern, bitte haben Sie Geduld!")
            progressBar = QProgressBar()
            progressBar.setMinimum(0)
            progressBar.setMaximum(0)
            progressBar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
            cancelButton = QPushButton()
            cancelButton.setText('Cancel')
            cancelButton.clicked.connect(self.killWorker)
            messageBar.layout().addWidget(progressBar)
            self.progressBar = progressBar
            messageBar.layout().addWidget(cancelButton)
            self.iface.messageBar().pushWidget(messageBar, Qgis.Info)
            #self.iface.messageBar().widgetRemoved
            # messageBar

            self.messageBar = messageBar

            # start the worker in a new thread
            thread = QThread()
            worker.moveToThread(thread)
            worker.finished.connect(self.workerFinished)
            worker.error.connect(self.workerError)
            #worker.progress.connect(progressBar.setValue)
            thread.started.connect(worker.run)
            thread.start()
            self.thread = thread
            self.worker = worker

    def killWorker(self):
        self.worker.kill()
        #self.progressBar.setMaximum(100)
        #self.progressBar.setValue(100)

    def workerFinished(self, ret):
        # clean up the worker and thread
        self.worker.deleteLater()
        self.thread.quit()
        self.thread.wait()
        self.thread.deleteLater()
        # remove widget from message bar
        self.iface.messageBar().popWidget(self.messageBar)
        if ret is not None:
            #report the result
            if not self.worker.killed:
                self.__imageRegistryNE = ret["imageRegistryNE"]
                self.__hiResRegistryNE = ret["hiResRegistryNE"]
                self.__i2cRegistryNE = ret["i2cRegistryNE"]
                self.__orthoRegistryNE = ret["orthoRegistryNE"]
                self.__mosaicRegistryNE = ret["mosaicRegistryNE"]

                self.__imageRegistry = ret["imageRegistry"]
                self.__hiResRegistry = ret["hiResRegistry"]
                self.__i2cRegistry = ret["i2cRegistry"]
                self.__orthoRegistry = ret["orthoRegistry"]
                self.__mosaicRegistry = ret["mosaicRegistry"]
                self.writeRegistryToFile()

                self.iface.messageBar().pushMessage(u"Update Image Registry", u"Das Update wurde erfolgreich abgeschloßen!", level=Qgis.Success, duration=5)
                self.isLoaded = True
                self.loaded.emit(True)
            else:
                self.iface.messageBar().pushMessage(u"Update Image Registry", u"Das Update wurde abgebrochen!", level=Qgis.Warning, duration=5)
                if os.path.isfile(self.registryFile):
                    os.remove(self.registryFile)
                self.isLoaded = False
                self.loaded.emit(False)
            #self.iface.messageBar().pushMessage('Result')
        else:
            # notify the user that something went wrong
            self.iface.messageBar().pushMessage('Something went wrong! See the message log for more information.', level=Qgis.Critical, duration=3)
            self.isLoaded = False
        self.worker = None

    def workerError(self, e, exception_string):
        QgsMessageLog.logMessage('APIS UpdateRegistryWorker thread raised an exception:\n'.format(exception_string), tag='APIS', level=Qgis.Critical)
Example #47
0
class qwProgressBox(QtWidgets.QWidget):
    ''' Widget personalise construisant la boite de progression lors du streaming d'un fichier GCode
  '''
    def __init__(self, parent=None):
        super().__init__()

        self.__settings = QSettings(QSettings.NativeFormat,
                                    QSettings.UserScope, ORG_NAME, APP_NAME)

        self.pBox = QtWidgets.QFrame(parent)
        self.pBox.setStyleSheet(
            ".QFrame{background-color: rgba(192, 192, 192, 192); border: 2px solid #000060;}"
        )

        self.pBoxBtnHeader = btnHeader(self.pBox)
        self.pBoxBtnHeader.setStyleSheet(
            ".btnHeader{background-color: rgba(48, 48, 80, 192); border-radius: 0px}"
        )

        self.pBoxLblStart = QtWidgets.QLabel(self.pBoxBtnHeader)
        debut = datetime.now()
        self.pBoxLblStart.setText(
            self.tr("GCode started at: {}").format(
                debut.strftime("%A %x %H:%M:%S")))
        self.pBoxLblStart.setStyleSheet("color: white;")
        self.pBoxLblStart.adjustSize()
        self.pBoxBtnHeader.setGeometry(2, 2,
                                       self.pBoxLblStart.width() + 36,
                                       self.pBoxBtnHeader.height())
        self.pBoxLblStart.setGeometry(
            20, (self.pBoxBtnHeader.height() - self.pBoxLblStart.height()) / 2,
            self.pBoxLblStart.width(), self.pBoxLblStart.height())

        self.pBoxProgress = QtWidgets.QProgressBar(self.pBox)
        self.pBoxProgress.setAlignment(Qt.AlignHCenter)
        self.pBoxProgress.setGeometry(
            20,
            self.pBoxBtnHeader.geometry().y() + self.pBoxBtnHeader.height() +
            9, self.pBoxLblStart.width(), 20)
        self.pBoxProgress.setRange(0, 100)
        self.pBoxProgress.setValue(37)

        self.pBoxLblComment = QtWidgets.QLabel(self.pBox)
        self.pBoxLblComment.setText("()")
        self.pBoxLblComment.setGeometry(
            20,
            self.pBoxProgress.geometry().y() + self.pBoxProgress.height() + 3,
            self.pBoxLblStart.width(), 20)

        self.pBoxLblElapse = QtWidgets.QLabel(self.pBox)
        total_seconds = int((datetime.now() - debut).total_seconds())
        hours, remainder = divmod(total_seconds, 60 * 60)
        minutes, seconds = divmod(remainder, 60)
        self.pBoxLblElapse.setText(self.tr("Elapsed time:"))
        self.pBoxLblElapse.setGeometry(
            20,
            self.pBoxLblComment.geometry().y() + self.pBoxLblComment.height() +
            3, self.pBoxLblStart.width(), 20)

        pBoxLargeur = self.pBoxLblStart.width() + 40
        pBoxHauteur = self.pBoxLblElapse.geometry().y(
        ) + self.pBoxLblElapse.height() + 6
        defaultX = int((parent.width() - pBoxLargeur) / 2)
        defaultY = int((parent.height() - pBoxHauteur) / 5 * 3)
        pBoxX = self.__settings.value("ProgressBox/posX", defaultX, type=int)
        pBoxY = self.__settings.value("ProgressBox/posY", defaultY, type=int)

        self.pBox.setGeometry(pBoxX, pBoxY, pBoxLargeur, pBoxHauteur)
        self.pBox.setVisible(False)

    def start(self):
        debut = datetime.now()
        self.pBoxLblStart.setText(
            self.tr("GCode started at: {}").format(
                debut.strftime("%A %x %H:%M:%S")))
        self.pBox.setVisible(True)
        # Démarre la mise à jour régulière du temps elapsed
        self.__elapseThread = elapseThread(self.pBoxLblElapse)
        self.__elapseThread.start()

    def stop(self):
        # Masque la boite
        self.pBox.setVisible(False)
        # Arrete la mise à jour régulière du temps elapsed
        self.__elapseThread.stop()

    def setRange(self, mini: int, maxi: int):
        self.pBoxProgress.setRange(mini, maxi)

    def setValue(self, val: int):
        self.pBoxProgress.setValue(val)
        self.pBoxProgress.setToolTip(
            self.tr("Line {} of {}").format(val, self.pBoxProgress.maximum()))

    def setComment(self, comment: str):
        self.pBoxLblComment.setText(comment)

    def isVisible(self):
        return self.pBox.isVisible()
Example #48
0
class Proxy(QDialog):
    id_signal = pyqtSignal([tuple])
    city_signal = pyqtSignal([tuple])
    country_signal = pyqtSignal([tuple])

    def __init__(self, parent=None):
        super(Proxy, self).__init__(parent)
        self.settings = QSettings()

        self.layout = QVBoxLayout()

        self.buttonLayout = QHBoxLayout()
        self.buttonBox = QDialogButtonBox()
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Ok |
                                          QDialogButtonBox.Cancel)
        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonLayout.addWidget(self.buttonBox)

        self.proxy_url_label = QLabel(QCoreApplication.translate(
                                'Entry label for the proxy url',
                                'Proxy URL:', 'Proxy settings dialogue'))
        self.proxy_url_line = QLineEdit()
        url = self.settings.value('Proxy_url') or ''
        self.proxy_url_line = QLineEdit(url)
        self.proxy_url_line.setMinimumWidth(300)

        self.proxy_port_label = QLabel(QCoreApplication.translate(
                            'Entry label for the proxy port', 'Port:',
                            'Proxy settings dialogue'))
        port = self.settings.value('Proxy_port') or ''
        self.proxy_port_line = QLineEdit(port)

        self.proxy_auth_label = QLabel(QCoreApplication.translate(
                                    'Checkbox', 'Use proxy authentification',
                                    'Proxy settings dialogue'))
        self.proxy_auth_checkbox = QCheckBox()
        self.proxy_auth_bool = eval(self.settings.value(
                                    'Use_proxy_authentification') or 'False')
        self.proxy_auth_checkbox.setChecked(self.proxy_auth_bool)
        self.proxy_auth_checkbox.stateChanged.connect(self.proxy_auth)

        self.proxy_user_label = QLabel(QCoreApplication.translate(
            'Proxy username authentification',
            'User ID:', 'Proxy configuration dialogue'))
        self.proxy_user_label.setEnabled(self.proxy_auth_bool)
        self.proxy_pass_label = QLabel(QCoreApplication.translate(
            'Proxy password authentification',
            'Password:'******'Proxy configuration dialogue'))
        self.proxy_pass_label.setEnabled(self.proxy_auth_bool)

        user = self.settings.value('Proxy_user') or ''
        self.proxy_user_line = QLineEdit(user)
        self.proxy_user_line.setEnabled(self.proxy_auth_bool)
        password = self.settings.value('Proxy_password') or ''
        self.proxy_pass_line = QLineEdit(password)
        self.proxy_pass_line.setEnabled(self.proxy_auth_bool)
        self.proxy_pass_line.setEchoMode(QLineEdit.Password)

        self.status_layout = QHBoxLayout()
        self.status_label = QLabel()
        self.status_layout.addWidget(self.status_label)

        self.panel = QGridLayout()
        self.panel.addWidget(self.proxy_url_label, 0, 0)
        self.panel.addWidget(self.proxy_url_line, 0, 1)
        self.panel.addWidget(self.proxy_port_label, 0, 2)
        self.panel.addWidget(self.proxy_port_line, 0, 3)
        self.panel.addWidget(self.proxy_auth_label, 1, 0)
        self.panel.addWidget(self.proxy_auth_checkbox, 1, 1)
        self.panel.addWidget(self.proxy_user_label, 2, 0)
        self.panel.addWidget(self.proxy_user_line, 2, 1)
        self.panel.addWidget(self.proxy_pass_label, 3, 0)
        self.panel.addWidget(self.proxy_pass_line, 3, 1)

        self.layout.addLayout(self.panel)
        self.layout.addLayout(self.status_layout)
        self.layout.addLayout(self.buttonLayout)

        self.setLayout(self.layout)

    def proxy_auth(self, state):
        if state == 2:
            self.proxy_auth_bool = True
            self.proxy_user_label.setEnabled(True)
            self.proxy_pass_label.setEnabled(True)
            self.proxy_user_line.setEnabled(True)
            self.proxy_pass_line.setEnabled(True)
        else:
            self.proxy_auth_bool = False
            self.proxy_user_label.setEnabled(False)
            self.proxy_pass_label.setEnabled(False)
            self.proxy_user_line.setEnabled(False)
            self.proxy_pass_line.setEnabled(False)

    def accept(self):
        port = self.proxy_port_line.text()
        if port.isdigit() or port == '':
            self.settings.setValue('Proxy_url', self.proxy_url_line.text())
            self.settings.setValue('Proxy_port', port)
            self.settings.setValue('Use_proxy_authentification',
                                   str(self.proxy_auth_bool))
            if self.proxy_auth_bool:
                self.settings.setValue('Proxy_user',
                                       self.proxy_user_line.text())
                self.settings.setValue('Proxy_password',
                                       self.proxy_pass_line.text())
        else:
            self.status_label.setText('Port number must contain only digits')
            return
        QDialog.accept(self)
Example #49
0
 def save(self):
     """Stores the settings."""
     s = QSettings()
     s.beginGroup("musicview/magnifier")
     s.setValue("size", self.size)
     s.setValue("scale", self.scale)
Example #50
0
    def __init__(self, parent=None):
        super().__init__()

        self.__settings = QSettings(QSettings.NativeFormat,
                                    QSettings.UserScope, ORG_NAME, APP_NAME)

        self.pBox = QtWidgets.QFrame(parent)
        self.pBox.setStyleSheet(
            ".QFrame{background-color: rgba(192, 192, 192, 192); border: 2px solid #000060;}"
        )

        self.pBoxBtnHeader = btnHeader(self.pBox)
        self.pBoxBtnHeader.setStyleSheet(
            ".btnHeader{background-color: rgba(48, 48, 80, 192); border-radius: 0px}"
        )

        self.pBoxLblStart = QtWidgets.QLabel(self.pBoxBtnHeader)
        debut = datetime.now()
        self.pBoxLblStart.setText(
            self.tr("GCode started at: {}").format(
                debut.strftime("%A %x %H:%M:%S")))
        self.pBoxLblStart.setStyleSheet("color: white;")
        self.pBoxLblStart.adjustSize()
        self.pBoxBtnHeader.setGeometry(2, 2,
                                       self.pBoxLblStart.width() + 36,
                                       self.pBoxBtnHeader.height())
        self.pBoxLblStart.setGeometry(
            20, (self.pBoxBtnHeader.height() - self.pBoxLblStart.height()) / 2,
            self.pBoxLblStart.width(), self.pBoxLblStart.height())

        self.pBoxProgress = QtWidgets.QProgressBar(self.pBox)
        self.pBoxProgress.setAlignment(Qt.AlignHCenter)
        self.pBoxProgress.setGeometry(
            20,
            self.pBoxBtnHeader.geometry().y() + self.pBoxBtnHeader.height() +
            9, self.pBoxLblStart.width(), 20)
        self.pBoxProgress.setRange(0, 100)
        self.pBoxProgress.setValue(37)

        self.pBoxLblComment = QtWidgets.QLabel(self.pBox)
        self.pBoxLblComment.setText("()")
        self.pBoxLblComment.setGeometry(
            20,
            self.pBoxProgress.geometry().y() + self.pBoxProgress.height() + 3,
            self.pBoxLblStart.width(), 20)

        self.pBoxLblElapse = QtWidgets.QLabel(self.pBox)
        total_seconds = int((datetime.now() - debut).total_seconds())
        hours, remainder = divmod(total_seconds, 60 * 60)
        minutes, seconds = divmod(remainder, 60)
        self.pBoxLblElapse.setText(self.tr("Elapsed time:"))
        self.pBoxLblElapse.setGeometry(
            20,
            self.pBoxLblComment.geometry().y() + self.pBoxLblComment.height() +
            3, self.pBoxLblStart.width(), 20)

        pBoxLargeur = self.pBoxLblStart.width() + 40
        pBoxHauteur = self.pBoxLblElapse.geometry().y(
        ) + self.pBoxLblElapse.height() + 6
        defaultX = int((parent.width() - pBoxLargeur) / 2)
        defaultY = int((parent.height() - pBoxHauteur) / 5 * 3)
        pBoxX = self.__settings.value("ProgressBox/posX", defaultX, type=int)
        pBoxY = self.__settings.value("ProgressBox/posY", defaultY, type=int)

        self.pBox.setGeometry(pBoxX, pBoxY, pBoxLargeur, pBoxHauteur)
        self.pBox.setVisible(False)
Example #51
0
class MainWindow(QMainWindow):
    """The main window, containing the search bar and results table."""
    def __init__(self, db, keybinds):
        super(MainWindow, self).__init__()
        self.settings = QSettings("xapers-qt", "xapers-qt")
        self.shortcuts = []
        self.db = db
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.results = self.ui.resultsWidget
        self.searchBar = self.ui.searchBar
        self.results.setDb(self.db)
        self.results.setSettings(self.settings)
        self.setupKeybinds(keybinds)
        self.restore_size()
        self.show()

    def restore_size(self):
        """Resize to size stored in settings.
        """
        try:
            width = int(self.settings.value("main/width", 800))
        except ValueError:
            width = 800
        try:
            height = int(self.settings.value("main/height", 300))
        except ValueError:
            height = 300
        self.resize(width, height)

    def startSearch(self):
        """Launches a search."""
        self.results.doSearch(self.searchBar.text())

    def setupKeybinds(self, binds):
        """Setup the keyboard shortcuts.
        """
        for shortcut in self.shortcuts:
            pass  # TODO Delete shortcut?
        for keys, action in binds:
            if action == "Search":
                func = self.focusSearchBar
            elif action == "Next":
                func = self.results.selectNext
            elif action == "Prev":
                func = self.results.selectPrev
            elif action == "OpenPDF":
                func = self.results.openPDF
            elif action == "OpenDoc":
                func = self.results.openDoc
            elif action == "Exit":
                func = self.close
            else:
                action = None
            if action:
                shortcut = QShortcut(QKeySequence(keys), self)
                shortcut.activated.connect(func)
                self.shortcuts.append(shortcut)

    def focusSearchBar(self):
        """Set focus to the search bar."""
        self.searchBar.searchLine.setFocus(Qt.ShortcutFocusReason)

    def saveSettings(self):
        """Save any settings we may have changed."""
        self.settings.setValue("main/width", self.width())
        self.settings.setValue("main/height", self.height())
        self.results.saveSettings()

    def closeEvent(self, event):
        """Things to do when closing the window.
        """
        self.saveSettings()

    def resizeEvent(self, resizeEvent):
        """Things to do when resizing the window.
        """
        self.results.refresh()
Example #52
0
 def saveApplicationSettings(self):
     settings = QSettings()
     settings.setValue("MainWindow/Size",        self.size())
     settings.setValue("MainWindow/Position",    self.pos())
     settings.setValue("MainWindow/State",       self.saveState())
     settings.setValue("MainWindow/ViewsLocked", self.ui.actionLocked.isChecked())
     if self.labeltool.getCurrentFilename() is not None:
         filename = self.labeltool.getCurrentFilename()
     else:
         filename = None
     settings.setValue("LastFile", filename)
Example #53
0
# SEPARATION COLORS
ONES_AREA_COLOR = QColor.fromRgb(0, 128, 128)
ZEROS_AREA_COLOR = QColor.fromRgb(90, 9, 148)
SEPARATION_OPACITY = 0.2
SEPARATION_PADDING = .05  # Prozent

# PROTOCOL TABLE COLORS
SELECTED_ROW_COLOR = QColor.fromRgb(0, 0, 255)
DIFFERENCE_CELL_COLOR = QColor.fromRgb(255, 0, 0)

PROPERTY_FOUND_COLOR = QColor.fromRgb(0, 124, 0, 100)
PROPERTY_NOT_FOUND_COLOR = QColor.fromRgb(124, 0, 0, 100)

SEPARATION_ROW_HEIGHT = 30

SETTINGS = QSettings(QSettings.IniFormat, QSettings.UserScope, 'urh', 'urh')
PROJECT_FILE = "URHProject.xml"
DECODINGS_FILE = "decodings.txt"
FIELD_TYPE_SETTINGS = os.path.realpath(os.path.join(SETTINGS.fileName(), "..", "fieldtypes.xml"))


# DECODING NAMES
DECODING_INVERT = "Invert"
DECODING_DIFFERENTIAL = "Differential Encoding"
DECODING_REDUNDANCY = "Remove Redundancy"
DECODING_DATAWHITENING = "Remove Data Whitening (CC1101)"
DECODING_CARRIER = "Remove Carrier"
DECODING_BITORDER = "Change Bitorder"
DECODING_EDGE = "Edge Trigger"
DECODING_SUBSTITUTION = "Substitution"
DECODING_EXTERNAL = "External Program"
Example #54
0
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.chunk_directory = Directory(
            "CHUNK",
            QIcon(Assets.get_asset_path("document_a4_locked.png")),
            None)
        self.mod_directory = Directory(
            "MOD",
            QIcon(Assets.get_asset_path("document_a4.png")),
            None)
        self.workspace = Workspace([self.mod_directory, self.chunk_directory],
                                   parent=self)
        self.workspace.fileOpened.connect(self.handle_workspace_file_opened)
        self.workspace.fileClosed.connect(self.handle_workspace_file_closed)
        self.workspace.fileActivated.connect(self.handle_workspace_file_activated)
        self.workspace.fileLoadError.connect(self.handle_workspace_file_load_error)
        self.init_actions()
        self.init_menu_bar()
        self.init_toolbar()
        self.setStatusBar(QStatusBar())
        self.setWindowTitle("MHW-Editor-Suite")
        self.init_file_tree(
            self.chunk_directory, "Chunk directory",
            self.open_chunk_directory_action,
            filtered=True)
        self.init_file_tree(
            self.mod_directory,
            "Mod directory",
            self.open_mod_directory_action)
        self.setCentralWidget(self.init_editor_tabs())
        self.load_settings()

    def closeEvent(self, event):
        self.write_settings()

    def load_settings(self):
        self.settings = QSettings(QSettings.IniFormat, QSettings.UserScope,
                                  "fre-sch.github.com",
                                  "MHW-Editor-Suite")
        self.settings.beginGroup("MainWindow")
        size = self.settings.value("size", QSize(1000, 800))
        position = self.settings.value("position", QPoint(300, 300))
        self.settings.endGroup()
        self.settings.beginGroup("Application")
        chunk_directory = self.settings.value("chunk_directory", None)
        mod_directory = self.settings.value("mod_directory", None)
        lang = self.settings.value("lang", None)
        self.settings.endGroup()
        self.resize(size)
        self.move(position)
        if chunk_directory:
            self.chunk_directory.set_path(chunk_directory)
        if mod_directory:
            self.mod_directory.set_path(mod_directory)
        if lang:
            self.handle_set_lang_action(lang)

    def write_settings(self):
        self.settings.beginGroup("MainWindow")
        self.settings.setValue("size", self.size())
        self.settings.setValue("position", self.pos())
        self.settings.endGroup()
        self.settings.beginGroup("Application")
        self.settings.setValue("chunk_directory", self.chunk_directory.path)
        self.settings.setValue("mod_directory", self.mod_directory.path)
        self.settings.setValue("lang", FilePluginRegistry.lang)
        self.settings.endGroup()

    def get_icon(self, name):
        return self.style().standardIcon(name)

    def init_actions(self):
        self.open_chunk_directory_action = create_action(
            self.get_icon(QStyle.SP_DirOpenIcon),
            "Open chunk_directory ...",
            self.handle_open_chunk_directory,
            None)
        self.open_mod_directory_action = create_action(
            self.get_icon(QStyle.SP_DirOpenIcon),
            "Open mod directory ...",
            self.handle_open_mod_directory,
            QKeySequence.Open)
        self.save_file_action = create_action(
            self.get_icon(QStyle.SP_DriveHDIcon),
            "Save file",
            self.handle_save_file_action,
            QKeySequence.Save)
        self.save_file_action.setDisabled(True)
        self.export_csv_action = create_action(
            self.get_icon(QStyle.SP_FileIcon),
            "Export file to CSV...",
            self.handle_export_file_action)
        self.export_csv_action.setDisabled(True)
        self.about_action = create_action(
            None, "About", self.handle_about_action)
        self.lang_actions = {
            lang: create_action(
                None, name, partial(self.handle_set_lang_action, lang),
                checkable=True)
            for lang, name in LANG
        }

    def init_menu_bar(self):
        menubar = self.menuBar()
        file_menu = menubar.addMenu("File")
        file_menu.insertAction(None, self.open_chunk_directory_action)
        file_menu.insertAction(None, self.open_mod_directory_action)
        file_menu.insertAction(None, self.export_csv_action)
        file_menu.insertAction(None, self.save_file_action)
        lang_menu = menubar.addMenu("Language")
        for action in self.lang_actions.values():
            lang_menu.insertAction(None, action)
        help_menu = menubar.addMenu("Help")
        help_menu.insertAction(None, self.about_action)

    def init_toolbar(self):
        toolbar = self.addToolBar("Main")
        toolbar.setIconSize(QSize(16, 16))
        toolbar.setFloatable(False)
        toolbar.setMovable(False)
        toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        toolbar.insertAction(None, self.open_mod_directory_action)
        toolbar.insertAction(None, self.save_file_action)

    def init_file_tree(self, directory, title, action, filtered=False):
        widget = DirectoryDockWidget(directory, filtered=filtered, parent=self)
        widget.path_label.addAction(action, QLineEdit.LeadingPosition)
        widget.tree_view.activated.connect(
            partial(self.handle_directory_tree_view_activated, directory))
        dock = QDockWidget(title, self)
        dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        dock.setFeatures(QDockWidget.DockWidgetMovable)
        dock.setWidget(widget)
        self.addDockWidget(Qt.LeftDockWidgetArea, dock)

    def handle_directory_tree_view_activated(self, directory, qindex: QModelIndex):
        if qindex.model().isDir(qindex):
            return
        file_path = qindex.model().filePath(qindex)
        self.workspace.open_file(directory, file_path)

    def init_editor_tabs(self):
        self.editor_tabs = QTabWidget()
        self.editor_tabs.setDocumentMode(True)
        self.editor_tabs.setTabsClosable(True)
        self.editor_tabs.tabCloseRequested.connect(
            self.handle_editor_tab_close_requested)
        return self.editor_tabs

    def handle_workspace_file_opened(self, path, rel_path):
        ws_file = self.workspace.files[path]
        editor_view = EditorView.factory(self.editor_tabs, ws_file)
        editor_view.setObjectName(path)
        self.editor_tabs.addTab(editor_view,
                                ws_file.directory.file_icon,
                                f"{ws_file.directory.name}: {rel_path}")
        self.editor_tabs.setCurrentWidget(editor_view)
        self.save_file_action.setDisabled(False)
        self.export_csv_action.setDisabled(False)

    def handle_workspace_file_activated(self, path, rel_path):
        widget = self.editor_tabs.findChild(QWidget, path)
        self.editor_tabs.setCurrentWidget(widget)

    def handle_workspace_file_closed(self, path, rel_path):
        widget = self.editor_tabs.findChild(QWidget, path)
        widget.deleteLater()
        self.save_file_action.setDisabled(not self.workspace.files)
        self.export_csv_action.setDisabled(not self.workspace.files)

    def handle_workspace_file_load_error(self, path, rel_path, error):
        QMessageBox.warning(self, f"Error loading file `{rel_path}`",
                            f"Error while loading\n{path}:\n\n{error}",
                            QMessageBox.Ok, QMessageBox.Ok)

    def handle_editor_tab_close_requested(self, tab_index):
        editor_view = self.editor_tabs.widget(tab_index)
        self.workspace.close_file(editor_view.workspace_file)

    def handle_open_chunk_directory(self):
        path = QFileDialog.getExistingDirectory(parent=self,
                                                caption="Open chunk directory")
        if path:
            self.chunk_directory.set_path(os.path.normpath(path))

    def handle_open_mod_directory(self):
        path = QFileDialog.getExistingDirectory(parent=self,
                                                caption="Open mod directory")
        if path:
            self.mod_directory.set_path(os.path.normpath(path))

    def handle_save_file_action(self):
        editor = self.editor_tabs.currentWidget()
        main_ws_file = editor.workspace_file
        for ws_file in main_ws_file.get_files_modified():
            if ws_file.directory is self.chunk_directory:
                if self.mod_directory.is_valid:
                    self.transfer_file_to_mod_workspace(
                        ws_file, ws_file is main_ws_file)
                else:
                    self.save_base_content_file(ws_file)
            else:
                with show_error_dialog(self, "Error writing file"):
                    self.save_workspace_file(ws_file)

    def handle_export_file_action(self):
        editor = self.editor_tabs.currentWidget()
        ws_file = editor.workspace_file
        file_name, file_type = QFileDialog.getSaveFileName(self, "Export file as CSV")
        if file_name:
            if not file_name.endswith(".csv"):
                file_name += ".csv"
            with show_error_dialog(self, "Error exporting file"):
                self.write_csv(ws_file, file_name)
                self.statusBar().showMessage(
                    f"Export '{file_name}' finished.", STATUSBAR_MESSAGE_TIMEOUT)

    def handle_set_lang_action(self, lang):
        FilePluginRegistry.lang = lang
        for act in self.lang_actions.values():
            act.setChecked(False)
        self.lang_actions[lang].setChecked(True)

    def write_csv(self, ws_file, file_name):
        with open(file_name, "w") as fp:
            csv_writer = csv.writer(
                fp, delimiter=",", doublequote=False, escapechar='\\',
                lineterminator="\n")
            cls = type(ws_file.data)
            fields = cls.EntryFactory.fields()
            csv_writer.writerow(fields)
            for entry in ws_file.data.entries:
                csv_writer.writerow(entry.values())

    def save_base_content_file(self, ws_file):
        result = QMessageBox.question(
            self, "Save base content file?",
            "Do you really want to update this chunk file?",
            QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Cancel)
        if result == QMessageBox.Ok:
            with show_error_dialog(self, "Error writing file"):
                self.save_workspace_file(ws_file)

    def transfer_file_to_mod_workspace(self, ws_file, reopen=False):
        mod_abs_path, exists = self.mod_directory.get_child_path(ws_file.rel_path)
        if not exists:
            return self.transfer_file(ws_file, self.mod_directory, reopen)

        result = QMessageBox.question(
            self,
            "File exists, overwrite?",
            f"File '{ws_file.rel_path}' already found in mod directory, overwrite?",
            QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)
        if result == QMessageBox.Ok:
            self.transfer_file(ws_file, self.mod_directory, reopen)

    def transfer_file(self, ws_file, target_directory, reopen=False):
        if target_directory is ws_file.directory:
            return
        self.workspace.close_file(ws_file)
        ws_file.set_directory(target_directory)
        self.save_workspace_file(ws_file)
        if reopen:
            self.workspace.open_file(target_directory, ws_file.abs_path)

    def save_workspace_file(self, ws_file):
        ws_file.save()
        self.statusBar().showMessage(
            f"File '{ws_file.abs_path}' saved.", STATUSBAR_MESSAGE_TIMEOUT)

    def handle_about_action(self):
        dialog = QDialog(self)
        dialog.setWindowTitle("About MHW Editor Suite")
        layout = QVBoxLayout()
        dialog.setLayout(layout)
        about_text = QLabel(ABOUT_TEXT)
        about_text.setTextFormat(Qt.RichText)
        about_text.setTextInteractionFlags(Qt.TextBrowserInteraction)
        about_text.setOpenExternalLinks(True)
        layout.addWidget(about_text)
        dialog.exec()
Example #55
0
 def __init__(self):
     super().__init__()
     self.setupUi(self)
     self.setWindowTitle('Settings')
     self.settings = QSettings('settings.ini', QSettings.IniFormat)
     self.load_settings()
Example #56
0
def run_gui(api_port, api_key, root_state_dir, parsed_args):
    logger.info('Running GUI' +
                ' in gui_test_mode' if parsed_args.gui_test_mode else '')

    # Workaround for macOS Big Sur, see https://github.com/Tribler/tribler/issues/5728
    if sys.platform == "darwin":
        logger.info('Enabling a workaround for macOS Big Sur')
        os.environ["QT_MAC_WANTS_LAYER"] = "1"
    # Workaround for Ubuntu 21.04+, see https://github.com/Tribler/tribler/issues/6701
    elif sys.platform == "linux":
        logger.info(
            'Enabling a workaround for Ubuntu 21.04+ wayland environment')
        os.environ["GDK_BACKEND"] = "x11"

    # Set up logging
    load_logger_config('tribler-gui', root_state_dir)

    # Enable tracer using commandline args: --trace-debug or --trace-exceptions
    trace_logger = check_and_enable_code_tracing('gui', root_state_dir)
    try:
        enable_fault_handler(root_state_dir)
        # Exit if we cant read/write files, etc.
        check_environment()
        check_free_space()

        app_name = os.environ.get('TRIBLER_APP_NAME', 'triblerapp')
        app = TriblerApplication(app_name, sys.argv)

        # Note (@ichorid): translator MUST BE created and assigned to a separate variable
        # before calling installTranslator on app. Otherwise, it won't work for some reason
        settings = QSettings('nl.tudelft.tribler')
        translator = get_translator(settings.value('translation', None))
        app.installTranslator(translator)

        if app.is_running():
            # if an application is already running, then send the command line
            # argument to it and close the current instance
            logger.info(
                'GUI Application is already running. Passing a torrent file path to it.'
            )
            for arg in sys.argv[1:]:
                if os.path.exists(arg) and arg.endswith(".torrent"):
                    app.send_message(path_to_uri(arg))
                elif arg.startswith('magnet'):
                    app.send_message(arg)
            logger.info('Close the current application.')
            sys.exit(1)

        logger.info('Start Tribler Window')
        window = TriblerWindow(settings,
                               root_state_dir,
                               api_port=api_port,
                               api_key=api_key)
        window.setWindowTitle("Tribler")
        app.set_activation_window(window)
        app.parse_sys_args(sys.argv)
        sys.exit(app.exec_())

    except ImportError as ie:
        logger.exception(ie)
        error_and_exit("Import Error", f"Import error: {ie}")

    except TriblerException as te:
        logger.exception(te)
        error_and_exit("Tribler Exception", f"{te}")

    except SystemExit:
        logger.info("Shutting down Tribler")
        if trace_logger:
            trace_logger.close()

        # Flush all the logs to make sure it is written to file before it exits
        for handler in logging.getLogger().handlers:
            handler.flush()

        gui_sentry_reporter.global_strategy = SentryStrategy.SEND_SUPPRESSED
        raise
Example #57
0
class NewNodeBaseDialog(QDialog):
    def __init__(self, parent, title, server):
        QDialog.__init__(self, parent)
        self.setWindowTitle(title)
        self.settings = QSettings()
        self.server = server

        self.vlayout = QVBoxLayout(self)
        self.layout = QHBoxLayout()
        self.vlayout.addLayout(self.layout)

        self.layout.addWidget(QLabel("ns:", self))

        self.nsComboBox = QComboBox(self)
        uries = server.get_namespace_array()
        for uri in uries:
            self.nsComboBox.addItem(uri)
        nsidx = int(self.settings.value("last_namespace", len(uries) - 1))
        if nsidx > len(uries) - 1:
            nsidx = len(uries) - 1
        self.nsComboBox.setCurrentIndex(nsidx)
        self.layout.addWidget(self.nsComboBox)

        self.layout.addWidget(QLabel("Name:", self))
        self.nameLabel = QLineEdit(self)
        self.nameLabel.setText("NoName")
        self.layout.addWidget(self.nameLabel)

        self.nodeidCheckBox = QCheckBox("Auto NodeId", self)
        self.nodeidCheckBox.setChecked(True)
        self.nodeidCheckBox.stateChanged.connect(self._show_nodeid)
        self.layout.addWidget(self.nodeidCheckBox)
        self.nodeidLineEdit = QLineEdit(self)
        self.nodeidLineEdit.setText("ns={};i=20000".format(nsidx))
        self.layout.addWidget(self.nodeidLineEdit)
        self.nodeidLineEdit.hide()

        self.buttons = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
        self.vlayout.addWidget(self.buttons)

        self.buttons.accepted.connect(self.accept)
        self.buttons.accepted.connect(self._store_state)
        self.buttons.rejected.connect(self.reject)

    def _store_state(self):
        self.settings.setValue("last_namespace",
                               self.nsComboBox.currentIndex())

    def _show_nodeid(self, val):
        if val:
            self.nodeidLineEdit.hide()
        else:
            self.nodeidLineEdit.show()
        self.adjustSize()

    def get_ns_and_name(self):
        args = []
        ns = self.nsComboBox.currentIndex()
        name = self.nameLabel.text()
        if self.nodeidCheckBox.isChecked():
            args.append(ns)
            args.append(name)
        else:
            nodeid = ua.NodeId.from_string(self.nodeidLineEdit.text())
            args.append(nodeid)
            args.append(ua.QualifiedName(name, ns))
        return args

    def get_args(self):
        args = self.get_ns_and_name()
        print("NewNodeBaseDialog returns:", args)
        return args

    @classmethod
    def getArgs(cls, parent, title, server, *args, **kwargs):
        dialog = cls(parent, title, server, *args, **kwargs)
        result = dialog.exec_()
        if result == QDialog.Accepted:
            return dialog.get_args(), True
        else:
            return [], False
Example #58
0
# create tables
plugins_db.createTables()

# delete old links
plugins_db.deleteOldLinks()

# close connections
plugins_db.closeConnections()


# import persepolis_setting
# persepolis is using QSettings for saving windows size and windows
# position and program settings.

persepolis_setting = QSettings('persepolis_download_manager', 'persepolis')

persepolis_setting.beginGroup('settings')

# download files is downloading in temporary folder(download_path_temp) and then they will be moved to user download folder(download_path) after completion.
# persepolis temporary download folder
if os_type != 'Windows':
    download_path_temp = str(home_address) + '/.persepolis'
else:
    download_path_temp = os.path.join(
        str(home_address), 'AppData', 'Local', 'persepolis')

# user download folder path    
download_path = os.path.join(str(home_address), 'Downloads', 'Persepolis')

# Persepolis default setting
Example #59
0
class RTG:
    def __init__(self, settings=None, db=None, overnight=0):
        '''
        :params overnight:Percentage of trades to include overnight transaction.
        '''
        self.overnight = overnight
        if settings:
            self.settings = settings
        else:
            self.settings = QSettings("zero_substance", "structjour")
        if db is not None:
            self.db = db
        else:
            self.db = self.settings.value('tradeDb')
        self.testfiles = []

    def makeRandomDASImport(self, numTrades, start, outfile=None, strict=False, overwrite=True):
        start = pd.Timestamp(start)
        df = self.getRandomTradeDF(numTrades=numTrades, start=start, strict=strict)

        if outfile:
            outfile, ext = os.path.splitext(outfile)
            outfile = f'''{outfile}_{start.strftime('%Y%m%d')}{ext}'''
            d = os.path.dirname(outfile)
            if not overwrite and os.path.exists(outfile):
                return outfile, df
            if os.path.exists(d):
                df.to_csv(outfile, index=False)
            else:
                logging.error(f'Failed to save file. Directory {d} does not exist')

        return outfile, df

    def makeOvernight(self, df):

        if len(df) > 2 and random.randint(0, 99) < self.overnight:
            r = random.random()
            delrow = df.index[0] if r < .5 else df.index[-1]
            df.drop(delrow, inplace=True)
        return df

    def saveSomeTestFiles(self, dates, outdir, outfile='DASrandomTrades.csv', strict=False, overwrite=False):
        '''
        Create DAS export like random trades.csv files for testing purposes
        :params dates: Create one file for each date. Date will be appended to the name
        :parmas outdir: The directory to place the files
        :params outfile: The name for the file. Date will be appended to each file
        :params outfile: The base name for the files. Final name will be {outfile}_yyyymmdd{ext}
        :params strict: If False, files will include Balance and Date fields
        :params overwrite: If False files already exist will be overwritten. Otherwise writing the file is quietly skipped.
        '''
        savedfiles = []
        for date in dates:
            date = pd.Timestamp(date)
            filename = os.path.join(outdir, outfile)
            filename, df = self.makeRandomDASImport(random.randint(3, 5), date, outfile=filename, strict=strict, overwrite=overwrite)
            savedfiles.append(filename)
        return savedfiles

    def getRandomTradeDF(self, numTrades=None, start='2018-06-06 09:30:00', strict=False):
        '''
        Creates a day of trades in the same form with the required columns from a DAS export
        plus a Balance and Date column. Use strict=True to remove them
        :numTrades: The number of trades in the statemnt
        :start: The earliest possible trade start time.
        '''

        if numTrades is None:
            numTrades = random.randint(1, 10)
        start = pd.Timestamp(start)
        df = pd.DataFrame()
        exclude = []
        for i in range(numTrades):
            tdf, start = self.randomTradeGenerator2(earliest=start,
                                            pdbool=True, exclude=exclude)
            if strict is True:
                tdf = tdf.drop(['Balance', 'Date'], axis=1)
            df = df.append(tdf)
            exclude.append(tdf.Symb.unique()[0])

        df.reset_index(drop=True, inplace=True)
        return df

    def randomTradeGenerator2(self, earliest=pd.Timestamp('2019-01-01 09:30:00'),
                            pdbool=True, exclude=None):
        '''
        Create a passable DAS import
        :params earliest: Transaction progress in time with earliest as the easliest possible trade
                        except for before HOLDs.
        :params pdbool: Setting to True will cause the return to be a DataFrame instead of an array.
                        Deprecated. Changed to allways return a dataframe
        :params exclude: A list of symbols to exclude as candidates for this trade
        :return pd.DataFrame:  DataFrame or list of transactions making up a single trade.
        '''
        earliest = pd.Timestamp(earliest)
        latest = earliest
        start = earliest
        nowtime = start
        numTrades = self.getNumTrades(maxt=10)
        trade = list()
        prevBal = 0
        price = 0
        long = True
        # duration = ''
        sumtotal = 0
        account = self.getAccount()
        # account = 'U000000'
        ticker = self.getTicker(exclude=exclude)
        daDate = pd.Timestamp(start.year, start.month, start.day)
        cloid = -1
        average = 0
        oc = ''

        for i in range(numTrades):
            firsttrade = True if i == 0 else False
            nexttime = self.getRandomFuture(nowtime)
            latest = nexttime
            pl = 0
            side = self.getSide(firsttrade=firsttrade)
            if firsttrade:
                # Note: not using these yet. If we start, may need to add a test identifier and convert to string
                cloid = random.randint(-999999999999, -100000000000)

                if side == 'S' or side.find('-') >= 0:
                    long = False
                price = self.getPrice()
                average = price
                oc = 'O'
            else:
                price = self.getPrice(price, long)

            time = nowtime.strftime("%H:%M:%S")
            daDate = pd.Timestamp(daDate.year, daDate.month, daDate.day, nowtime.hour, nowtime.minute, nowtime.second)
            cloid += 1

            if i == numTrades - 1:
                side = 'S' if prevBal >= 0 else 'B'
                # pl = self.getPL()
                pl = (average - price) * -prevBal
                trade.append([time, ticker, side, price, -prevBal, 0, account, pl, daDate, cloid, average, 'C'])
                sumtotal = sumtotal + pl
                prevBal = 0
                break
            else:
                qty = random.randint(1, 500)
                qty = -qty if (side == 'S' or side == 'HOLD-B') else qty

                # Check for flippers
                if long and (prevBal + qty) < 0:
                    long = False
                elif not long and (prevBal + qty) > 0:
                    long = True
                if (long is True and side == 'B') or (long is not True and side != 'B'):
                    # An opener -- adjust the average
                    # Average = ((PrevAvg * PrevBal) + (Qty * Price))/ Balance
                    average = ((average * prevBal) + (qty * price)) / (prevBal + qty)
                    oc = 'O'

                else:
                    # a closer-- figure the pl
                    #  pl = (average - price) * qty
                    pl = (average - price) * qty
                    oc = 'C'

                trade.append([time, ticker, side, price, qty, prevBal + qty, account, pl, daDate, cloid, average, oc])
                sumtotal = sumtotal + pl
                prevBal = prevBal + qty
                if prevBal == 0:
                    # We are coincidentally at 0 balance. Trade is over. Must be a hotkey mistake ;-)
                    break

            nowtime = nexttime
        # duration = nowtime - start

        tradedf = pd.DataFrame(data=trade, columns=['Time', 'Symb', 'Side', 'Price', 'Qty',
                                                    'Balance', 'Account', 'P / L', 'Date', 'Cloid', 'Average', 'OC'])
        tradedf['Commission'] = float('nan')
        tradedf = self.makeOvernight(tradedf)
        return tradedf, latest

    def getPrice(self, price=None, long=True):
        if price is None:
            price = random.randint(3, 300) + random.randint(0, 99) / 100
            return price

        change = (random.random() / 70)
        upordown = random.random()
        if long and upordown > .62:
            change *= -1
        elif not long and upordown > .38:
            change *= -1

        return price + (price * change)

    def getNumTrades(self, maxt=8):
        '''
        Return a number between 2 and 8 by default
        '''
        t = random.randint(2, maxt)
        return t

    def getAccount(self):
        '''
        Get a randoms account real or sim
        '''
        real = 'U000000'
        sim = 'TRIB0000'
        percentReal = .75
        r = random.random()
        acct = real if r < percentReal else sim
        return acct

    def getTicker(self, exclude=None):
        '''
        Get a random ticker symbol
        :exclude: A list of tickers to exclude from consideration.
        '''
        tickers = ['SQ', 'AAPL', 'TSLA', 'ROKU', 'NVDA', 'NUGT', 'MSFT', 'CAG', 'ACRS', 'FRED', 'PCG',
                'AMD', 'GE', 'NIO', 'AMRN', 'FIVE', 'BABA', 'BPTH', 'Z', ]
        tick = tickers[random.randint(0, len(tickers) - 1)]
        if exclude and tick in exclude:
            if not set(tickers).difference(set(exclude)):
                # We could make up some random letters here if this ever ....-- or include more
                raise ValueError("You have excluded every stock in the method")
            return self.getTicker(exclude=exclude)
        return tick

    def getRandomFuture(self, earliest=pd.Timestamp('2019-01-01 09:30:00')):
        '''
        Get a time that is in the future a random amount of seconds from earliset
        '''
        rsec = random.randint(45, 1500)
        nextt = earliest + pd.Timedelta(seconds=rsec)
        return nextt

    def getSide(self, firsttrade=False):
        '''
        Get a random distribution of 'B', 'S', 'HOLD+', 'HOLD-'. Set the probabilities here.
        HOLDs provide the weirdest exceptions. They should be relatively likely for tests.
        '''
        s = random.random()
        side = 'B'if s < .55 else 'S'
        return side

    def getPL(self):
        '''
        Get a random dollar amount
        '''
        amnt = random.random()
        upordown = random.random()
        upordown = 1 if upordown > .4 else -1
        multiplier = random.randint(2, 200)
        return amnt * upordown * multiplier
Example #60
0
class ProjectHTMLDlg(QDialog, Ui_ProjectHTMLDlg):
    """
    Class documentation goes here.
    """
    def __init__(self, parent=None, schemaModel = None, model = None):
        """
        Constructor
        
        @param parent reference to the parent widget
        @type QWidget
        """
        super(ProjectHTMLDlg, self).__init__(parent)
        self.setupUi(self)
        self.settings = QSettings()
        self.schemaModel = schemaModel
        self.model = model
        self.projectData = model.modelData
        self.helper = Helper()
        

        
        # initialize the header area
        dir = self.projectData["GenToDir"]
        self.lblOutputDir.setText(dir)
        self.lblOutputDir.setToolTip(dir)    
        
        # initialize the report generation fields
        self.txtTitle.setText(self.projectData["HeaderTitle"])  
        self.txtHomeTitle.setText(self.projectData["HomePageTitle"])  
        self.txtAuthor.setText(self.projectData["Author"])  
        self.txtFooter.setText(self.projectData["FooterTitle"])  
        self.txtImageFile.setText(self.projectData["IconFile"])  
        if len(self.projectData.get("IconFile", "")) > 0:
            self.loadImage()    

    def outputPath(self):
        return self.lblOutputDir.text()

    def fileFormat(self):
        '''only one file format for now
        '''
        return QByteArray(b'HTML')


    def fileExtension(self):
        '''Only one file extension for now
        '''
        return "HTML"

            
    def loadImage(self, ):
        '''load the image file into the frame
        '''
        try:
            fileName = self.txtImageFile.text()
            pixmap = QPixmap(fileName)
            self.frmImage.setPixmap(pixmap.scaled(self.frmImage.width(), self.frmImage.height(), aspectRatioMode = Qt.KeepAspectRatio))
        except Exception as e: 
            self.helper.displayErrMsg("Load Image", "Error loading {} image file. Error: {}".format(fileName, str(e)))
            return
            
    def getImage(self, ):
        '''return a QImage if valid image file is present
        '''
        try:
            fileName = self.txtImageFile.text()
            if len(fileName) > 0:
                if os.path.isfile(fileName) == True:
                    pixmap = QPixmap(fileName)
                    anImage = pixmap.toImage()
                    return fileName, anImage
                else:
                    self.helper.displayErrMsg("Load Image", "Image File: {} not a valid file.".format(fileName))
                    return fileName, None
            else:
                return fileName, None
        except Exception as e: 
            self.helper.displayErrMsg("Load Image", "Error loading {} image file. Error: {}".format(fileName, str(e)))
            return fileName, None
        
        # should never happen
        return None, None

    def saveSetupData(self):
        # save the report generation fields
        self.projectData["GenToDir"]= self.lblOutputDir.text()  
        self.projectData["HeaderTitle"]= self.txtTitle.text()  
        self.projectData["HomePageTitle"] = self.txtHomeTitle.text()  
        self.projectData["Author"] = self.txtAuthor.text()  
        self.projectData["FooterTitle"] = self.txtFooter.text()  
        self.projectData["IconFile"] = self.txtImageFile.text()          
        
    @pyqtSlot()
    def on_btnSelectDir_clicked(self):
        """
        User selects Path button to select an output path
        """
        curDir = self.lblOutputDir.text()
        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.Directory)
        dlg.setDirectory(curDir)
        file = str(dlg.getExistingDirectory(self, "Select Directory"))
        if file:
            self.lblOutputDir.setText(str(file))
            self.lblOutputDir.setToolTip(str(file))
    
    @pyqtSlot()
    def on_btnLoadImage_clicked(self):
        """
        User clicks on image file button.  They select an image file from disk.
        """
        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.ExistingFile)
        dlg.setAcceptMode(QFileDialog.AcceptOpen)
        dlg.setNameFilters(["Image Files (*.bmp *.gif *.jpg *.jpeg *.png)","all files (*.*)"])
        dlg.setDirectory(self.settings.value("Default/ProjPath"))
        if dlg.exec_():
            fileNames = dlg.selectedFiles()
            if fileNames:
                fileName = fileNames[0]
                self.txtImageFile.setText(fileName)  
                if len(self.txtImageFile.text()) > 0:
                    self.loadImage()
    
    @pyqtSlot()
    def on_btnGenerate_clicked(self):
        """
        User clicks button to generate html using Mako
        """
        try:
            # setup folder structure, cancel html generation if error
            if self.createFolders():
                QApplication.setOverrideCursor(Qt.WaitCursor)
                # generate home page
                self.genIndexPage2()
                # generate object pages
                for objectType in self.projectData["TopLevel"]:
                    if objectType in ["Label","Property","Relationship","Node Template",  "Relationship Template", "Template Diagram", "Instance Diagram" ]:
                        objectList = self.model.instanceList(objectType)
                        objectPath = self.outputPath() + "/PAGES/{}".format(''.join(objectType.upper().split()) )
                        if len(objectList) > 0:
                            if os.path.exists(objectPath) == False:
                                os.mkdir(objectPath)
                            for objectName in objectList:
                                self.genObjectPage2(objectType=objectType, objectName=objectName)        
                # completed message
                QApplication.restoreOverrideCursor() 
                self.helper.displayErrMsg("Generate HTML", 'HTML generation complete! Click "View In Browser" button.')
                
        except Exception as e: 
            self.helper.displayErrMsg("Generate HTML", "Error clearing html folders. Error: {}".format(str(e)))
        finally:
            QApplication.restoreOverrideCursor() 
        
    @pyqtSlot()
    def on_btnViewBrowser_clicked(self):
        """
        user clicks on the view in browser button
        """
        genPath = self.outputPath()
        indexFileName = genPath + "/index.html"   
        if os.path.isfile(indexFileName) == True:
            webbrowser.open(indexFileName)
        else:
            self.helper.displayErrMsg("Open Browser", "Error - index.html file {} not found.")
    
    
    @pyqtSlot()
    def on_btnClose_clicked(self):
        """
        User clicks the Close button
        """
        # save the report generation fields
        self.saveSetupData()

        QDialog.accept(self)

############################################################
## diagram render methods
############################################################
    def renderDiagram(self, diagramType=None, diagramName=None, fileName=None):
        # the parent of the scene needs to maintain these dictionaries 
        self.itemDict = {}   # dictionary of graphic items rendered on the scene
        self.relIRPair = {}
        self.relTRPair = {} 
        # create the scene
        self.scene = DiagramScene(self)
        # render the diagram
        self.scene.renderDiagram(diagramType=diagramType, diagramName=diagramName)
        # save the image
        self.scene.saveImage(fileName=fileName)


    # these functions need to be in the parent of the scene.  This needs to be refactored so the scene handles this
    def addRelationship(self, relItem):
        '''Track how many relationship instances exist
           between any pair of node instances.
        '''
        key=relItem.startNZID + relItem.endNZID
        x = self.relIRPair.setdefault(key, 0)
        self.relIRPair[key] = x + 1
        
    def numRels(self, startNZID, endNZID):  
        return self.relIRPair.setdefault(startNZID + endNZID, 0)
    
    def anyRels(self, startNZID, endNZID):
        ''' return True if there are any instance relationships between these two nodes'''
        for key, value in self.itemDict.items():
            if value.diagramType == "Instance Relationship":
                if value.startNZID in [startNZID, endNZID] and value.endNZID in [startNZID, endNZID]:
                    return True
        return False
        
    def addTRelationship(self, relItem):
        '''Track how many relationship templates exist
           between any pair of node templates.
        '''
        key=relItem.startNZID + relItem.endNZID
        # add the from/to key to the dictionary if it's not there, then return the current total which is initialized to zero (see next step)
        x = self.relTRPair.setdefault(key, 0)
        # increment the count and save it as the new total
        self.relTRPair[key] = x + 1
        return self.relTRPair[key]
        
############################################################
    def createFolders(self, ):
        # create directories
        indexFileName = self.outputPath() + "/index.html"
        pagePath = self.outputPath() + "/PAGES"
        imagePath = self.outputPath() + "/IMAGES"
        try:
            # first delete existing content if the user says ok
            if (os.path.isfile(indexFileName) == True or os.path.exists(pagePath) == True or os.path.exists(imagePath) == True):
                if self.helper.delObjectPrompt("Generated HTML files in {}".format(self.outputPath())):
                    # delete existing content and re-add the needed folders
                    if os.path.isfile(indexFileName) == True:
                        os.remove(indexFileName)
                    if os.path.exists(pagePath) == True:
                        shutil.rmtree(pagePath)
                    if os.path.exists(imagePath) == True:
                        shutil.rmtree(imagePath)
                else:
                    return False
            # now create the two needed folders if they don't exist
            if os.path.exists(pagePath) == False:
                os.mkdir(pagePath)
            if os.path.exists(imagePath) == False:
                os.mkdir(imagePath)
                    
        except Exception as e: 
            self.helper.displayErrMsg("Generate HTML", "Error checking {} for existing html folders, html generation cancelled. Error: {}".format(self.outputPath(), str(e)))
            return False
        
        # create the icon image file in the /images directory
        try:
            self.logoImage = None
            self.logoFile = None
            fileName, anImage = self.getImage()
            if not anImage is None:
                self.logoImage = anImage
                self.logoFile = imagePath + "/" + os.path.basename(fileName)
                anImage.save (self.logoFile)
        except Exception as e: 
            self.helper.displayErrMsg("Generate HTML", "Error saving {} to {}. Error: {}".format(fileName, self.logoFile, str(e)))
            return False
        
        return True
            
    def genIndexPage2(self, ):
        try:
            genPath = self.outputPath()
            indexFileName = genPath + "/index.html"   
            # make sur current generation settings are in the project model so template can see them
            self.saveSetupData()
            # get the template for the index page
            mytemplate = self.indexPageTemplate()
            # validate the file to write to
            file = QFile(indexFileName)
            if not file.open(QFile.WriteOnly | QFile.Text):
                self.helper.displayErrMsg("Generate HTML", "Cannot write file %s:\n%s." % (self.indexFileName, file.errorString()))
                return 
            # generate the html page
            outstr = QTextStream(file)
            outstr << mytemplate.render(model=self.model, outputPath= self.outputPath())
        except Exception as e: 
            self.helper.displayErrMsg("Generate HTML", "Error saving {}. Error: {}".format(indexFileName, str(e)))
            
        
    def genObjectPage2(self, objectType=None, objectName=None ):
        try:
            # get the object dictionary
            index, objectDict = self.model.getDictByName(objectType, objectName)
            objectPath = self.outputPath() + "/PAGES/{}".format(''.join(objectType.upper().split()) )
            objName = objectDict.get("name", "NoName")
    #        goodObjName = self.helper.slugify(objName)
            goodObjName = "".join(x for x in objName if x.isalpha() or x.isnumeric() )  + "_file"
            objFileName = objectPath + "/{}.html".format(goodObjName)
            # get the template for the page
            mytemplate = self.objectPageTemplate(objectDict = objectDict)
            # validate the file to write to
            file = QFile(objFileName)
            if not file.open(QFile.WriteOnly | QFile.Text):
                self.helper.displayErrMsg("Generate HTML", "Cannot write file %s:\n%s." % (self.indexFileName, file.errorString()))
                return 
            # generate the html page
            outstr = QTextStream(file)
            outstr << mytemplate.render(objectDict=objectDict, model=self.model, outputPath= self.outputPath(), genObjectType=objectType, genObjectName=objectName)
        except Exception as e: 
            self.helper.displayErrMsg("Generate HTML", "Error saving {}. Error: {}".format(objFileName, str(e)))            
        
        try:
            # for diagrams, also generate the PNG file and save it
            if objectType in ("Template Diagram", "Instance Diagram"):
                goodImgName = "".join(x for x in objName if x.isalpha() or x.isnumeric() )  + "_image"
                imgFileName = objectPath + "/{}.png".format(goodImgName)
                self.renderDiagram(diagramType=objectType, diagramName=objectName)
                # save the image
                self.scene.saveImage(fileName=imgFileName)
        except Exception as e: 
            self.helper.displayErrMsg("Generate HTML", "Error saving {}. Error: {}".format(imgFileName, str(e)))            
            
    def indexPageTemplate(self):
        aTemplate = Template(self.htmlHead() + self.htmlHeader() + self.htmlAside() + self.htmlIndexArticle() + self.htmlFooter() + self.htmlEnd())
        return aTemplate
        
    def objectPageTemplate(self, objectDict = None):
        aTemplate = Template(self.htmlHead() + self.htmlHeader() + self.htmlAside() + self.htmlObjectArticle(objectDict = objectDict) + self.htmlFooter() + self.htmlEnd())
        return aTemplate    

    def htmlHead(self, ):
        html = '''
<!DOCTYPE html>
<html>
    <head>
        <title>NodeEra Generated Web Page</title>
        <meta charset="UTF-8">
        <style type="text/css">''' + self.htmlCSS() + '''      </style>
    </head>
    <body>
        <div class="wrapper">'''
        return html
        
    def htmlHeader(self, ):
        html = '''
            <header class="header">
                <table>
                    <tbody>
                        <tr>
                            <h1><p>
                                <img src="${model.modelData["IconFile"]}" />
                                <span>${model.modelData["HeaderTitle"]}</span>
                            </p></h1>
                        </tr>
                    </tbody>
                </table>
            </header>'''
        return html
        
    def htmlAside(self, ):
        '''
        this is the object list of links on the left hand side of the screen
        '''
        html = '''
            <aside class="aside">
            <%
                homeURL = outputPath + "/index.html"
            %>     
            <a href="${homeURL}">
                <span>Home</span>
            </a>
            <h2><p>Model Objects</p></h2>
            % for objectType in ["Label","Property","Relationship","Node Template",  "Relationship Template", "Template Diagram", "Instance Diagram" ]:
            <%
                objectPath = outputPath + "/PAGES/{}".format(''.join(objectType.upper().split()) )
            %>            
                <h3><p>${objectType}</p></h3>
                <ul>
                % for objectName in model.instanceList(objectType):
                        <li>
                        <%
                            goodObjName = "".join(x for x in objectName if x.isalpha() or x.isnumeric() )  + "_file"
                            objFile = "/{}.html".format(goodObjName)
                        %>
                            <a href="${objectPath}${objFile}">
                                <span>${objectName}</span>
                            </a>
                        </li>
                % endfor
                </ul>
            % endfor
            </aside>
            '''
        return html        

    def htmlIndexArticle(self, ):
        html = '''
            <article class="content">
                <table>
                    <tbody>
                        <tr>
                            <h2><p>${model.modelData["HomePageTitle"]}</p></h2>
                            <p>Project File: ${model.modelFileName}</p>
                            <p>Author: ${model.modelData["Author"]}</p>
                            <p>Description: ${model.modelData["Description"]}</p>
                        </tr>
                    </tbody>
                </table>
            </article>'''
        return html    
        
    def htmlObjectArticle(self, objectDict = None):
        html = '''
            <article class="content">
                ## generic header for all object types
                <h1>${genObjectType}: ${genObjectName}</h1>
                <p>Description: ${objectDict.get("desc","No Description")}</p>
                ## generate object specific stuff

                % if genObjectType == "Instance Diagram":
                <%
                    diagramImgFile = "".join(x for x in objectDict.get("name", "") if x.isalpha() or x.isnumeric() )  + "_image"
                    diagramImgURL = "{}/PAGES/INSTANCEDIAGRAM/{}.png".format(outputPath, diagramImgFile)
                %>    
                    <p>Diagram Image:</p>
                    <p>
                        <img src="${diagramImgURL}" />
                    </p>
                % endif
                
                % if genObjectType == "Template Diagram":
                <%
                    diagramImgFile = "".join(x for x in objectDict.get("name", "") if x.isalpha() or x.isnumeric() )  + "_image"
                    diagramImgURL = "{}/PAGES/TEMPLATEDIAGRAM/{}.png".format(outputPath, diagramImgFile)
                %>    
                    <p>Diagram Image:</p>
                    <p>
                        <img src="${diagramImgURL}" />
                    </p>
                % endif
                
                % if genObjectType == "Node Template":
                    ## label grid
                    <p>Labels:</p>
                    ''' + self.htmlTable(listName="labels", dict=objectDict) + '''
                    <p></p>
                    ## property grid
                    <p>Properties:</p>
                    ''' + self.htmlTable(listName="properties", dict=objectDict) + '''
                    <p></p>
                    ## constraint grid
                    <p>Constraints:</p>
                    ''' + self.htmlTable(listName="constraints", dict=objectDict) + '''
                    <p></p>
                    ## index grid
                    <p>Indexes:</p>
                    ''' + self.htmlTable(listName="indexes", dict=objectDict) + '''
                    <p></p>
                % endif
                
                % if genObjectType == "Relationship Template":
                <%
                    relNameFile = "".join(x for x in objectDict.get("relname", "") if x.isalpha() or x.isnumeric() )  + "_file"
                    relNameURL = "{}/PAGES/RELATIONSHIP/{}.html".format(outputPath, relNameFile)
                    toNodeFile = "".join(x for x in objectDict.get("toTemplate", "") if x.isalpha() or x.isnumeric() )  + "_file"
                    toNodeURL = "{}/PAGES/NODETEMPLATE/{}.html".format(outputPath, toNodeFile)
                    fromNodeFile = "".join(x for x in objectDict.get("fromTemplate", "") if x.isalpha() or x.isnumeric() )  + "_file"
                    fromNodeURL = "{}/PAGES/NODETEMPLATE/{}.html".format(outputPath, fromNodeFile)
                %>
                <p>Relationship Type:                
                    <a href="${relNameURL}">
                        <span>${objectDict.get("relname", "")}</span>
                    </a>
                </p> 
                <p>From node template: 
                    <a href="${fromNodeURL}">
                        <span>${objectDict.get("fromTemplate", "")}</span>
                    </a> has ${objectDict.get("fromCardinality", "")} node template: ${objectDict.get("toTemplate", "")}
                </p> 
                <p>To  node template: 
                    <a href="${toNodeURL}">
                        <span>${objectDict.get("toTemplate", "")}</span>
                    </a> has ${objectDict.get("toCardinality", "")} node template: ${objectDict.get("fromTemplate", "")}                    
                </p> 
                
                <p>Properties:</p>
                ''' + self.htmlTable(listName="properties", dict=objectDict) + '''
                <p></p>
                <p>Constraints:</p>
                ''' + self.htmlTable(listName="constraints", dict=objectDict) + '''
                <p></p>
                % endif
                
                % if genObjectType == "Property":
                    <p>Data Type: ${objectDict.get("dataType", "")} </p>                  
                % endif
                
                ## generate the where used section                
                <p>Where Used:</p>
                <% 
                    hitList = model.scanForObjectUse(genObjectType, genObjectName)
                %>
                % if not hitList is None:
                    % if len(hitList) > 0:
                    <ul>
                        % for hit in hitList:
                            % if hit[0] in ["Label","Property","Node Template",  "Relationship Template", "Template Diagram", "Instance Diagram"]:
                                <%
                                    goodObjName = "".join(x for x in hit[1] if x.isalpha() or x.isnumeric() )  + "_file"
                                    objURL = "../{}/{}.html".format(''.join(hit[0].upper().split()), goodObjName)
                                    ##text = "{} - {} ({})".format(hit[0], hit[1], hit[2])
                                %>
                                <li>
                                    <p>${hit[0]} - 
                                        <a href="${objURL}">
                                            <span>${hit[1]}</span>
                                        </a>
                                        (${hit[2]})
                                    </p>
                                </li>
                            % endif
                        % endfor
                    </ul>
                    % endif
                % endif
                
                
            </article>'''
        return html       

    def htmlTable(self, listName=None, dict=None ):
        '''generate a table from the list in the dictionary
        '''
#        print(objectType, objectName, listName, dict)

        html = '''
                    <%
                        aList = objectDict.get("{}", [])  ## labels
                    %>
                    % if not aList is None:
                        % if (len(aList) > 0 ):
                            <%    
                                rows = len(aList)+1
                                columns = len(aList[0])
                                colMetaDataList = model.getHeaderList(objectType=genObjectType, listName="{}")  ## labels
                            %>
                            <table id=object-section>
                            % if not colMetaDataList is None:
                                <%
                                    colHeaderList = colMetaDataList[0]
                                    colLinkList  = colMetaDataList[1]
                                %>
                                <thead>
                                <tr>
                                % for header in colHeaderList:
                                    <th>${{header}}</td>
                                % endfor
                                </tr>
                                </thead>
                            % endif
                            <tbody>
                            % for indexObject, listObject in enumerate(aList):
                                <tr>
                                % for indexItem, listItem in enumerate(listObject):
                                    % if isinstance(listItem, int):
                                        % if listItem == 0:
                                            <% displayText = "False" %>
                                        % else:
                                            <% displayText = "True" %>
                                        % endif
                                    % else:
                                        <% displayText = str(listItem) %>
                                    % endif
                                    ##<td>${{displayText}}</td>
                                    % if len(colLinkList[indexItem]) > 0:   
                                        <% linkItemList = displayText.split(",") %>
                                        <td>
                                        % for linkItem in linkItemList:
                                            <%
                                                goodObjName = "".join(x for x in linkItem if x.isalpha() or x.isnumeric() )  + "_file"
                                                objURL = "../{{}}/{{}}.html".format(''.join(colLinkList[indexItem].upper().split()), goodObjName)
                                            %>                
                                                <a href="${{objURL}}">
                                                    <span>${{linkItem}} </span>
                                                </a>
                                        % endfor
                                        </td>
                                    % else:
                                        <td>${{displayText}}</td>
                                    % endif
                                % endfor
                                </tr>
                            % endfor
                            </tbody>
                        % endif
                            </table>
                    % endif
        '''.format(listName, listName)
        
        return html

    def htmlFooter(self, ):

        html = '''
            <footer class="footer">
                <table>
                    <tbody>
                        <tr>
                            <p>${model.modelData["FooterTitle"]}</p>
                        </tr>
                    </tbody>
                </table>
            </footer>'''
        return html

        
    def htmlEnd(self, ):
        html = '''
        </div>
    </body>
</html>'''
        return html      

    def htmlCSS(self, ):
        html = '''
*, *:before, *:after {
  box-sizing: border-box;
}

body {
  margin: 40px;
  font-family: 'Open Sans', 'sans-serif';
  background-color: #fff;
  color: #444;
}

h1, p {
  margin: 0 0 1em 0;
}

.wrapper {
  max-width: 1100px;
  margin: 0 20px;
  display: grid;
  grid-gap: 10px;
}

@media screen and (min-width: 500px) {

  /* no grid support? */
  .sidebar {
    float: left;
    width: 19.1489%;
  }

  .content {
    float: right;
    width: 79.7872%;
  }

  .wrapper {
    margin: 0 auto;
    grid-template-columns: 1fr 3fr;
  }
  
  .header, .footer {
    grid-column: 1 / -1;
    /* needed for the floated layout */
    clear: both;
  }

}

.wrapper > * {
  background-color: AliceBlue;
  color: Black;
  border-radius: 5px;
  padding: 10px;
  font-size: 100%;
  /* needed for the floated layout*/
  margin-bottom: 10px;
}

/* We need to set the widths used on floated items back to auto, and remove the bottom margin as when we have grid we have gaps. */
@supports (display: grid) {
  .wrapper > * {
    width: auto;
    margin: 0;
  }
}

#object-section {font-family:lucida sans unicode,lucida grande,Sans-Serif;font-size:12px;width:480px;text-align:left;border-collapse:collapse;margin:20px}

#object-section th{font-size:13px;font-weight:400;background:#b9c9fe;border-top:4px solid #aabcfe;border-bottom:1px solid #fff;color:#039;padding:8px}

#object-section td{background:#e8edff;border-bottom:1px solid #fff;color:#669;border-top:1px solid transparent;padding:8px}

#object-section tr:hover td{background:#d0dafd;color:#339}'''
        
        return html