Пример #1
0
    def next_wallpaper(self):
        self.temp = QTemporaryDir()

        if not self.temp.isValid():
            print("tmp dir not valid...")
            return

        self.start()
Пример #2
0
    def initMisc(self):
        self.multihashDb = IPFSObjectMetadataDatabase(self._mHashDbLocation,
                                                      loop=self.loop)

        self.resourceOpener = IPFSResourceOpener(parent=self)

        self.downloadsManager = downloads.DownloadsManager(self)
        self.marksLocal = IPFSMarks(self.localMarksFileLocation, backup=True)

        self.marksLocal.addCategory('general')
        self.marksLocal.addCategory('uncategorized')
        self.marksNetwork = IPFSMarks(self.networkMarksFileLocation,
                                      autosave=False)

        self.tempDir = QTemporaryDir()
        self.tempDirWeb = self.tempDirCreate(self.tempDir.path(),
                                             'webdownloads')
Пример #3
0
 def __init__(self):
     self.environmentOk = False
     super().__init__()
     self.overwrite = Overwrite.UNSET
     # Save current work dir and change into a temporary one
     self.savedWD = os.getcwd()
     pycirkuit.__tmpDir__ = QTemporaryDir()
     os.chdir(pycirkuit.__tmpDir__.path())
Пример #4
0
    def Successful_Tmp(self):  # CheckTmpDir, StateTmpDir
        failed = lambda: not self.tdir or not self.tdir.isValid()
        if failed():  # not successfully
            self.tdir = QTemporaryDir()
            if failed():
                QMessageBox.critical(
                    self, "Unexpected Failurer",
                    "The application has detected a problem trying to\nCreate or Access a Temporary File!."
                )
                return None
            else:
                self.tdir.setAutoRemove(True)

        d = QDir(self.tdir.path())
        if not d.exists("ninja-ide"):
            if not d.mkdir("ninja-ide"):
                self.tdir = None
        d.cd("ninja-ide")
        return d
Пример #5
0
    def run(self):
        threats_found = []

        for file_url in self.files:
            name = file_url.toString()
            self.log_line("Checking {}".format(name))

            tdir = QTemporaryDir()
            if tdir.isValid():
                path = tdir.path()
            else:
                self.log_line("Could not create temporary directory")
                continue
            local_file = file_url.toLocalFile()
            scan_result = scan(str(local_file), path, self.log_line)
            if True in (res[1] for res in scan_result):
                threat = ThreatModel(
                    local_file, local_file, "yoba",
                    "Be careful, that's some advanced magics")
                threats_found += [threat]

            self.advance()
        self.log_line("Found {} threats".format(len(threats_found)))
        self.setResult(threats_found)
Пример #6
0
    def Successful_Tmp(self):# CheckTmpDir, StateTmpDir
        failed = lambda: not self.tdir or not self.tdir.isValid()
        if failed():# not successfully
            self.tdir = QTemporaryDir()
            if failed():
                QMessageBox.critical(self, "Unexpected Failurer", "The application has detected a problem trying to\nCreate or Access a Temporary File!.")
                return None
            else:
                self.tdir.setAutoRemove(True)

        d = QDir(self.tdir.path())
        if not d.exists("ninja-ide"):
            if not d.mkdir("ninja-ide"):
                self.tdir = None
        d.cd("ninja-ide")
        return d
Пример #7
0
    def build(self, opt, nr_resources, clean, sysroot, build_dir, include_dir,
              interpreter, python_library, source_dir, standard_library_dir):
        """ Build the project in a given directory.  Raise a UserException if
        there is an error.
        """

        project = self._project

        py_major, py_minor, py_patch = project.python_target_version
        py_version = (py_major << 16) + (py_minor << 8) + py_patch

        # Set $SYSROOT.  An explicit sysroot will override any existing value.
        if sysroot:
            os.environ['SYSROOT'] = os.path.abspath(sysroot)
        elif 'SYSROOT' not in os.environ:
            # Provide a default.
            os.environ['SYSROOT'] = os.path.abspath('sysroot-' +
                                                    self._target.name)

        # Create a temporary directory which will be removed automatically when
        # this function's objects are garbage collected.
        temp_dir = QTemporaryDir()
        if not temp_dir.isValid():
            raise UserException(
                "There was an error creating a temporary directory")

        # Get the names of the required Python modules, extension modules and
        # libraries.
        metadata = get_python_metadata(project.python_target_version)
        required_modules, required_libraries = project.get_stdlib_requirements(
            include_hidden=True)

        required_py = {}
        required_ext = {}
        for name in required_modules.keys():
            module = metadata[name]

            if module.target and not self._is_targeted(module.target):
                continue

            if module.source is None:
                required_py[name] = module
            elif not module.core:
                required_ext[name] = module

        # Initialise and check we have the information we need.
        if len(required_ext) != 0:
            if source_dir is None:
                if project.python_source_dir == '':
                    raise UserException(
                        "The name of the Python source directory has not "
                        "been specified")

                source_dir = project.path_from_user(project.python_source_dir)

        if project.get_executable_basename() == '':
            raise UserException("The name of the application has not been "
                                "specified and cannot be inferred")

        if project.application_script == '':
            if project.application_entry_point == '':
                raise UserException("Either the application script name or "
                                    "the entry point must be specified")
            elif len(project.application_entry_point.split(':')) != 2:
                raise UserException("An entry point must be a module name and "
                                    "a callable separated by a colon.")
        elif project.application_entry_point != '':
            raise UserException("Either the application script name or the "
                                "entry point must be specified but not both")

        # Get other directories from the project that may be overridden.
        if include_dir is None:
            include_dir = project.path_from_user(
                project.python_target_include_dir)

        if interpreter is None:
            if project.python_host_interpreter != '':
                # Note that we assume a relative filename is on PATH rather
                # than being relative to the project file.
                interpreter = project.expandvars(
                    project.python_host_interpreter)
            elif self._host.platform.name == 'win':
                interpreter = get_py_install_path(
                    project.python_target_version, self._target) + 'python'
            else:
                interpreter = 'python{0}.{1}'.format(py_major, py_minor)

        if python_library is None:
            python_library = project.path_from_user(
                project.python_target_library)

        if standard_library_dir is None:
            standard_library_dir = project.path_from_user(
                project.python_target_stdlib_dir)

        # Set the name of the build directory.
        if not build_dir:
            build_dir = 'build-' + self._target.name

        self._build_dir = os.path.abspath(build_dir)

        # Remove any build directory if required.
        if clean:
            native_build_dir = QDir.toNativeSeparators(self._build_dir)
            self._message_handler.progress_message(
                "Cleaning {0}".format(native_build_dir))
            shutil.rmtree(native_build_dir, ignore_errors=True)

        # Now start the build.
        self._create_directory(self._build_dir)

        # Create the job file and writer.
        job_filename = QDir.toNativeSeparators(temp_dir.path() + '/jobs.csv')
        job_file = open(job_filename, 'w', newline='')
        job_writer = csv.writer(job_file)

        # Freeze the bootstrap.  Note that from Python v3.5 the modified part
        # is in _bootstrap_external.py and _bootstrap.py is unchanged from the
        # original source.  We continue to use a local copy of _bootstrap.py
        # as it still needs to be frozen and we don't want to depend on an
        # external source.
        self._freeze_bootstrap('bootstrap', py_version, self._build_dir,
                               temp_dir, job_writer)

        if py_version >= 0x030500:
            self._freeze_bootstrap('bootstrap_external', py_version,
                                   self._build_dir, temp_dir, job_writer)

        # Freeze any main application script.
        if project.application_script != '':
            self._freeze(job_writer,
                         self._build_dir + '/frozen_main.h',
                         project.path_from_user(project.application_script),
                         'pyqtdeploy_main',
                         as_c=True)

        # Create the pyqtdeploy module version file.
        version_f = self._create_file(self._build_dir +
                                      '/pyqtdeploy_version.h')
        version_f.write('#define PYQTDEPLOY_HEXVERSION %s\n' %
                        hex(PYQTDEPLOY_HEXVERSION))
        version_f.close()

        # Generate the application resource.
        resource_names = self._generate_resource(
            self._build_dir + '/resources', required_py, standard_library_dir,
            job_writer, nr_resources)

        # Write the .pro file.
        self._write_qmake(py_version, required_ext, required_libraries,
                          include_dir, python_library, standard_library_dir,
                          source_dir, job_writer, opt, resource_names)

        # Run the freeze jobs.
        job_file.close()

        # The odd naming of Python source files is to prevent them from being
        # frozen if we deploy ourself.
        freeze = self._copy_lib_file(self._get_lib_file_name('freeze.python'),
                                     temp_dir.path(),
                                     dst_file_name='freeze.py')

        self._run_freeze(freeze, interpreter, job_filename, opt)
Пример #8
0
    def build(self, opt, nr_resources, build_dir=None, clean=False):
        """ Build the project in a given directory.  Raise a UserException if
        there is an error.
        """

        project = self._project

        # Create a temporary directory which will be removed automatically when
        # this function's objects are garbage collected.
        temp_dir = QTemporaryDir()
        if not temp_dir.isValid():
            raise UserException(
                    "There was an error creating a temporary directory")

        # Get the names of the required Python modules, extension modules and
        # libraries.
        metadata = get_python_metadata(project.python_target_version)
        required_modules, required_libraries = project.get_stdlib_requirements(
                include_hidden=True)

        required_py = {}
        required_ext = {}
        for name in required_modules.keys():
            module = metadata[name]

            if module.source is None:
                required_py[name] = module
            elif not module.core:
                required_ext[name] = module

        # Initialise and check we have the information we need.
        if len(required_py) != 0 or len(required_ext) != 0:
            if project.python_source_dir == '':
                raise UserException(
                        "The name of the Python source directory has not been "
                        "specified")

        if project.get_executable_basename() == '':
            raise UserException("The name of the application has not been "
                    "specified and cannot be inferred")

        if project.application_script == '':
            if project.application_entry_point == '':
                raise UserException("Either the application script name or "
                        "the entry point must be specified")
            elif len(project.application_entry_point.split(':')) != 2:
                raise UserException("An entry point must be a module name and "
                        "a callable separated by a colon.")
        elif project.application_entry_point != '':
            raise UserException("Either the application script name or the "
                    "entry point must be specified but not both")

        # Get the name of the build directory.
        if build_dir is None:
            build_dir = project.build_dir
            if build_dir == '':
                build_dir = '.'

            build_dir = project.path_from_user(build_dir)

        # Remove any build directory if required.
        if clean:
            native_build_dir = QDir.toNativeSeparators(build_dir)
            self._message_handler.progress_message(
                    "Cleaning {0}".format(native_build_dir))
            shutil.rmtree(native_build_dir, ignore_errors=True)

        # Now start the build.
        self._create_directory(build_dir)

        # Create the job file and writer.
        job_filename = QDir.toNativeSeparators(temp_dir.path() + '/jobs.csv')
        job_file = open(job_filename, 'w', newline='')
        job_writer = csv.writer(job_file)

        # Freeze the bootstrap.
        py_major, py_minor, py_patch = project.python_target_version
        py_version = (py_major << 16) + (py_minor << 8) + py_patch

        bootstrap_src = get_embedded_file_for_version(py_version, __file__,
                'lib', 'bootstrap')
        bootstrap = self._copy_lib_file(bootstrap_src, temp_dir.path(),
                dst_file_name='bootstrap.py')
        self._freeze(job_writer, build_dir + '/frozen_bootstrap.h', bootstrap,
                'pyqtdeploy_bootstrap', as_c=True)

        # Freeze any main application script.
        if project.application_script != '':
            self._freeze(job_writer, build_dir + '/frozen_main.h',
                    project.path_from_user(project.application_script),
                    'pyqtdeploy_main', as_c=True)

        # Create the pyqtdeploy module version file.
        version_f = self._create_file(build_dir + '/pyqtdeploy_version.h')
        version_f.write(
                '#define PYQTDEPLOY_HEXVERSION %s\n' % hex(
                        PYQTDEPLOY_HEXVERSION))
        version_f.close()

        # Generate the application resource.
        resource_names = self._generate_resource(build_dir + '/resources',
                required_py, job_writer, nr_resources)

        # Write the .pro file.
        self._write_qmake(build_dir, required_ext, required_libraries,
                job_writer, opt, resource_names)

        # Run the freeze jobs.
        job_file.close()

        # The odd naming of Python source files is to prevent them from being
        # frozen if we deploy ourself.
        freeze = self._copy_lib_file(self._get_lib_file_name('freeze.python'),
                temp_dir.path(), dst_file_name='freeze.py')

        self._run_freeze(freeze, job_filename, opt)

        # Remove the contents of the temporary directory.
        QFile.remove(freeze)
        QFile.remove(bootstrap)
        QFile.remove(job_filename)
Пример #9
0
    def build(self, opt, nr_resources, build_dir=None, clean=False, include_dir=None, interpreter=None, python_library=None, source_dir=None, standard_library_dir=None):
        """ Build the project in a given directory.  Raise a UserException if
        there is an error.
        """

        project = self._project

        py_major, py_minor, py_patch = project.python_target_version

        # Create a temporary directory which will be removed automatically when
        # this function's objects are garbage collected.
        temp_dir = QTemporaryDir()
        if not temp_dir.isValid():
            raise UserException(
                    "There was an error creating a temporary directory")

        # Get the names of the required Python modules, extension modules and
        # libraries.
        metadata = get_python_metadata(project.python_target_version)
        required_modules, required_libraries = project.get_stdlib_requirements(
                include_hidden=True)

        required_py = {}
        required_ext = {}
        for name in required_modules.keys():
            module = metadata[name]

            if module.source is None:
                required_py[name] = module
            elif not module.core:
                required_ext[name] = module

        # Initialise and check we have the information we need.
        if len(required_ext) != 0:
            if source_dir is None:
                if project.python_source_dir == '':
                    raise UserException(
                            "The name of the Python source directory has not "
                            "been specified")

                source_dir = project.path_from_user(project.python_source_dir)

        if project.get_executable_basename() == '':
            raise UserException("The name of the application has not been "
                    "specified and cannot be inferred")

        if project.application_script == '':
            if project.application_entry_point == '':
                raise UserException("Either the application script name or "
                        "the entry point must be specified")
            elif len(project.application_entry_point.split(':')) != 2:
                raise UserException("An entry point must be a module name and "
                        "a callable separated by a colon.")
        elif project.application_entry_point != '':
            raise UserException("Either the application script name or the "
                    "entry point must be specified but not both")

        # Get other directories from the project that may be overridden.
        if include_dir is None:
            include_dir = project.path_from_user(
                    project.python_target_include_dir)

        if interpreter is None:
            if project.python_host_interpreter != '':
                # Note that we assume a relative filename is on PATH rather
                # than being relative to the project file.
                interpreter = project.expandvars(
                        project.python_host_interpreter)
            elif sys.platform == 'win32':
                interpreter = get_windows_install_path(py_major, py_minor) + 'python'
            else:
                interpreter = 'python{0}.{1}'.format(py_major, py_minor)

        if python_library is None:
            python_library = project.path_from_user(
                    project.python_target_library)

        if standard_library_dir is None:
            standard_library_dir = project.path_from_user(
                    project.python_target_stdlib_dir)

        # Get the name of the build directory.
        if build_dir is None:
            build_dir = project.build_dir
            if build_dir == '':
                build_dir = '.'

            build_dir = project.path_from_user(build_dir)

        # Remove any build directory if required.
        if clean:
            native_build_dir = QDir.toNativeSeparators(build_dir)
            self._message_handler.progress_message(
                    "Cleaning {0}".format(native_build_dir))
            shutil.rmtree(native_build_dir, ignore_errors=True)

        # Now start the build.
        self._create_directory(build_dir)

        # Create the job file and writer.
        job_filename = QDir.toNativeSeparators(temp_dir.path() + '/jobs.csv')
        job_file = open(job_filename, 'w', newline='')
        job_writer = csv.writer(job_file)

        # Freeze the bootstrap.  Note that from Python v3.5 the modified part
        # is in _bootstrap_external.py and _bootstrap.py is unchanged from the
        # original source.  However we continue to use a local copy of
        # _bootstrap.py for now in case the structure changes again.
        py_version = (py_major << 16) + (py_minor << 8) + py_patch

        self._freeze_bootstrap('bootstrap', py_version, build_dir, temp_dir,
                job_writer)

        if py_version >= 0x030500:
            self._freeze_bootstrap('bootstrap_external', py_version, build_dir,
                    temp_dir, job_writer)

        # Freeze any main application script.
        if project.application_script != '':
            self._freeze(job_writer, build_dir + '/frozen_main.h',
                    project.path_from_user(project.application_script),
                    'pyqtdeploy_main', as_c=True)

        # Create the pyqtdeploy module version file.
        version_f = self._create_file(build_dir + '/pyqtdeploy_version.h')
        version_f.write(
                '#define PYQTDEPLOY_HEXVERSION %s\n' % hex(
                        PYQTDEPLOY_HEXVERSION))
        version_f.close()

        # Generate the application resource.
        resource_names = self._generate_resource(build_dir + '/resources',
                required_py, standard_library_dir, job_writer, nr_resources)

        # Write the .pro file.
        self._write_qmake(py_version, build_dir, required_ext,
                required_libraries, include_dir, python_library,
                standard_library_dir, job_writer, opt, resource_names)

        # Run the freeze jobs.
        job_file.close()

        # The odd naming of Python source files is to prevent them from being
        # frozen if we deploy ourself.
        freeze = self._copy_lib_file(self._get_lib_file_name('freeze.python'),
                temp_dir.path(), dst_file_name='freeze.py')

        self._run_freeze(freeze, interpreter, job_filename, opt)
Пример #10
0
class GalacteekApplication(QApplication):
    """
    Galacteek application class

    :param bool debug: enable debugging
    :param str profile: application profile
    """

    manualAvailable = pyqtSignal(str, dict)
    messageDisplayRequest = pyqtSignal(str, str)
    appImageImported = pyqtSignal(str)

    dbConfigured = AsyncSignal(bool)

    def __init__(self,
                 debug=False,
                 profile='main',
                 sslverify=True,
                 enableOrbital=False,
                 progName=None,
                 cmdArgs={}):
        QApplication.__init__(self, sys.argv)

        QCoreApplication.setApplicationName(GALACTEEK_NAME)

        self.dbConfigured.connectTo(self.onDbConfigured)

        self.setQuitOnLastWindowClosed(False)

        self._cmdArgs = cmdArgs
        self._debugEnabled = debug
        self._appProfile = profile
        self._loop = None
        self._executor = None
        self._ipfsClient = None
        self._ipfsOpMain = None
        self._ipfsd = None
        self._sslverify = sslverify
        self._progName = progName
        self._progCid = None
        self._system = platform.system()
        self._urlSchemes = {}
        self._shuttingDown = False

        self._icons = {}
        self._ipfsIconsCache = {}
        self._ipfsIconsCacheMax = 32

        self.enableOrbital = enableOrbital
        self.orbitConnector = None

        self.translator = None
        self.mainWindow = None
        self.feedFollowerTask = None

        self.webProfiles = {}
        self.ipfsCtx = IPFSContext(self)
        self.peersTracker = peers.PeersTracker(self.ipfsCtx)

        self.desktopWidget = QDesktopWidget()
        self.desktopGeometry = self.desktopWidget.screenGeometry()

        self.setWindowIcon(getIcon('galacteek.png'))

        self.setupAsyncLoop()
        self.setupPaths()

    @property
    def cmdArgs(self):
        return self._cmdArgs

    @property
    def shuttingDown(self):
        return self._shuttingDown

    @property
    def offline(self):
        return self.cmdArgs.offline

    @property
    def system(self):
        return self._system

    @property
    def debugEnabled(self):
        return self._debugEnabled

    @property
    def ipfsIconsCacheMax(self):
        return self._ipfsIconsCacheMax

    @property
    def ipfsIconsCache(self):
        return self._ipfsIconsCache

    @property
    def progName(self):
        return self._progName

    @property
    def progCid(self):
        return self._progCid

    @property
    def sslverify(self):
        return self._sslverify

    @property
    def appProfile(self):
        return self._appProfile

    @property
    def ipfsd(self):
        return self._ipfsd

    @property
    def loop(self):
        return self._loop

    @property
    def executor(self):
        return self._executor

    @loop.setter
    def loop(self, newLoop):
        self._loop = newLoop

    @property
    def allTasks(self):
        return asyncio.Task.all_tasks(loop=self.loop)

    @property
    def pendingTasks(self):
        return [task for task in self.allTasks if not task.done()]

    @property
    def ipfsClient(self):
        return self._ipfsClient

    @ipfsClient.setter
    def ipfsClient(self, client):
        self.debug('IPFS client changed: {}'.format(client))
        self._ipfsClient = client

    @property
    def ipfsOpMain(self):
        return self._ipfsOpMain

    @ipfsOpMain.setter
    def ipfsOpMain(self, op):
        """ The main IPFS operator, used by @ipfsOp """
        self.debug('Main IPFS operator upgrade: ID {}'.format(op.uid))
        self._ipfsOpMain = op

    @property
    def gatewayAuthority(self):
        params = self.getIpfsConnectionParams()
        return '{0}:{1}'.format(params.host, params.gatewayPort)

    @property
    def gatewayUrl(self):
        params = self.getIpfsConnectionParams()
        return params.gatewayUrl

    @property
    def dataLocation(self):
        return self._dataLocation

    @property
    def ipfsBinLocation(self):
        return self._ipfsBinLocation

    @property
    def ipfsDataLocation(self):
        return self._ipfsDataLocation

    @property
    def nsCacheLocation(self):
        return self._nsCacheLocation

    @property
    def orbitDataLocation(self):
        return self._orbitDataLocation

    def applyStyle(self, theme='default'):
        qssPath = ":/share/static/qss/{theme}/galacteek.qss".format(
            theme=theme)
        qssFile = QFile(qssPath)

        try:
            qssFile.open(QFile.ReadOnly)
            styleSheetBa = qssFile.readAll()
            styleSheetStr = styleSheetBa.data().decode('utf-8')
            self.setStyleSheet(styleSheetStr)
        except BaseException:
            # that would probably occur if the QSS is not
            # in the resources file..  set some default stylesheet here?
            pass

        self.gStyle = GalacteekStyle()
        self.setStyle(self.gStyle)

    def debug(self, msg):
        if self.debugEnabled:
            log.debug(msg)

    def initSystemTray(self):
        self.systemTray = QSystemTrayIcon(self)
        self.systemTray.setIcon(getIcon('galacteek-incandescent.png'))
        self.systemTray.show()
        self.systemTray.activated.connect(self.onSystemTrayIconClicked)

        systemTrayMenu = QMenu(self.mainWindow)

        actionShow = systemTrayMenu.addAction('Show')
        actionShow.setIcon(getIcon('galacteek-incandescent.png'))
        actionShow.triggered.connect(self.onShowWindow)

        systemTrayMenu.addSeparator()

        actionQuit = systemTrayMenu.addAction('Quit')
        actionQuit.setIcon(getIcon('quit.png'))
        actionQuit.triggered.connect(self.onExit)

        self.systemTray.setContextMenu(systemTrayMenu)

    def initMisc(self):
        self.multihashDb = IPFSObjectMetadataDatabase(self._mHashDbLocation,
                                                      loop=self.loop)

        self.resourceOpener = IPFSResourceOpener(parent=self)

        self.downloadsManager = downloads.DownloadsManager(self)
        self.marksLocal = IPFSMarks(self.localMarksFileLocation, backup=True)

        self.marksLocal.addCategory('general')
        self.marksLocal.addCategory('uncategorized')
        self.marksNetwork = IPFSMarks(self.networkMarksFileLocation,
                                      autosave=False)

        self.tempDir = QTemporaryDir()
        self.tempDirWeb = self.tempDirCreate(self.tempDir.path(),
                                             'webdownloads')

    def tempDirCreate(self, basedir, name=None):
        tmpdir = QDir(basedir)

        if not tmpdir.exists():
            return

        uid = name if name else str(uuid.uuid4())

        path = tmpdir.absoluteFilePath(uid)
        if tmpdir.mkpath(path):
            return path

    async def setupHashmarks(self):
        pkg = 'galacteek.hashmarks.default'

        res = await database.hashmarkSourceSearch(
            name='core', url=pkg, type=models.HashmarkSource.TYPE_PYMODULE)

        if not res:
            await database.hashmarkSourceAdd(
                type=models.HashmarkSource.TYPE_PYMODULE, url=pkg, name='core')
            await self.hmSynchronizer.sync()

        await database.hashmarkSourceAdd(
            type=models.HashmarkSource.TYPE_GITREPOS,
            url='https://github.com/galacteek/hashmarks-dwebland')

        await self.scheduler.spawn(self.hmSynchronizer.syncTask())

    def setupTranslator(self):
        if self.translator:
            QApplication.removeTranslator(self.translator)

        self.translator = QTranslator()
        QApplication.installTranslator(self.translator)
        lang = self.settingsMgr.getSetting(CFG_SECTION_UI, CFG_KEY_LANG)
        self.translator.load(
            ':/share/translations/galacteek_{0}.qm'.format(lang))

    def createMainWindow(self, show=True):
        self.mainWindow = mainui.MainWindow(self)
        if show is True:
            self.mainWindow.show()

    def onSystemTrayIconClicked(self, reason):
        if reason == QSystemTrayIcon.Unknown:
            pass
        elif reason == QSystemTrayIcon.Context:
            pass
        elif reason == QSystemTrayIcon.DoubleClick:
            self.mainWindow.showMaximized()
        else:
            pass

    def systemTrayMessage(self,
                          title,
                          message,
                          timeout=2000,
                          messageIcon=QSystemTrayIcon.Information):
        self.systemTray.showMessage(title, message, messageIcon, timeout)

    @ipfsOp
    async def setupRepository(self, op):
        pubsubEnabled = True  # mandatory now ..
        hExchEnabled = self.settingsMgr.isTrue(CFG_SECTION_IPFS,
                                               CFG_KEY_HASHMARKSEXCH)

        self.ipfsCtx.resources['ipfs-logo-ice'] = await self.importQtResource(
            '/share/icons/ipfs-logo-128-ice.png')
        self.ipfsCtx.resources['ipfs-cube-64'] = await self.importQtResource(
            '/share/icons/ipfs-cube-64.png')
        self.ipfsCtx.resources['atom-feed'] = await self.importQtResource(
            '/share/icons/atom-feed.png')
        self.ipfsCtx.resources['markdown-reference'] = \
            await self.importQtResource(
                '/share/static/docs/markdown-reference.html')

        await self.ipfsCtx.setup(pubsubEnable=pubsubEnabled,
                                 pubsubHashmarksExch=hExchEnabled,
                                 offline=self.offline)
        await self.ipfsCtx.profilesInit()
        await self.qSchemeHandler.start()
        await self.importLdContexts()

        self.feedFollower = FeedFollower(self)
        self.feedFollowerTask = await self.scheduler.spawn(
            self.feedFollower.process())

        await self.ipfsCtx.ipfsRepositoryReady.emit()
        self.ipfsCtx._ipfsRepositoryReady.emit()

        #
        # If the application's binary name is a valid CID, pin it!
        # This happens when running the AppImage and ensures
        # self-seeding of the image!
        #

        if isinstance(self.progName, str):
            progNameClean = re.sub(r'[\.\/]*', '', self.progName)
            if cidhelpers.cidValid(progNameClean):
                self._progCid = progNameClean
                log.debug("Auto pinning program's CID: {0}".format(
                    self.progCid))
                await self.ipfsCtx.pin(joinIpfs(self.progCid),
                                       False,
                                       self.onAppReplication,
                                       qname='self-seeding')

        if self.cmdArgs.seed and self.cmdArgs.appimage:
            await self.seedAppImage()

    @ipfsOp
    async def seedAppImage(self, ipfsop):
        # Automatic AppImage seeding

        if os.path.isfile(self.cmdArgs.binarypath):
            log.info(
                'AppImage seeding: {img}'.format(img=self.cmdArgs.binarypath))

            ensure(ipfsop.addPath(self.cmdArgs.binarypath, wrap=True),
                   futcallback=self.onAppSeed)

    def onAppSeed(self, future):
        try:
            replResult = future.result()
        except Exception as err:
            log.debug('AppImage seed: failed', exc_info=err)
        else:
            if isinstance(replResult, dict):
                cid = replResult.get('Hash')

                self.appImageImported.emit(cid)

                log.info('AppImage seed OK: CID {cid}'.format(cid=cid))

    def onAppReplication(self, future):
        try:
            replResult = future.result()
        except Exception as err:
            log.debug('App replication: failed', exc_info=err)
        else:
            log.debug('App replication: success ({result})'.format(
                result=replResult))

    @ipfsOp
    async def importLdContexts(self, ipfsop):
        """
        Import the JSON-LD contexts and associate the
        directory entry with the 'galacteek.ld.contexts' key
        """

        contextsPath = ipfsop.ldContextsRootPath()

        if not os.path.isdir(contextsPath):
            log.debug('LD contexts not found')
            return

        entry = await ipfsop.addPath(contextsPath,
                                     recursive=True,
                                     hidden=False)
        if entry:
            ldKeyName = 'galacteek.ld.contexts'
            log.debug('LD contexts sitting at: {}'.format(entry.get('Hash')))
            await ipfsop.keyGen(ldKeyName, checkExisting=True)
            ensure(
                ipfsop.publish(entry['Hash'],
                               key=ldKeyName,
                               allow_offline=True))

    @ipfsOp
    async def importQtResource(self, op, path):
        rscFile = QFile(':{0}'.format(path))

        try:
            rscFile.open(QFile.ReadOnly)
            data = rscFile.readAll().data()
            entry = await op.addBytes(data)
        except Exception as e:
            log.debug('importQtResource: {}'.format(str(e)))
        else:
            return entry

    def ipfsTask(self, fn, *args, **kw):
        """ Schedule an async IPFS task """
        return self.loop.create_task(fn(self.ipfsClient, *args, **kw))

    def ipfsTaskOp(self, fn, *args, **kw):
        """ Schedule an async IPFS task using an IPFSOperator instance """
        client = self.ipfsClient
        if client:
            return self.loop.create_task(
                fn(self.getIpfsOperator(), *args, **kw))

    def getIpfsOperator(self):
        """ Returns a new IPFSOperator with the currently active IPFS client"""
        return IPFSOperator(self.ipfsClient,
                            ctx=self.ipfsCtx,
                            debug=self.debugEnabled,
                            nsCachePath=self.nsCacheLocation)

    def getIpfsConnectionParams(self):
        mgr = self.settingsMgr

        section = CFG_SECTION_IPFSD
        if mgr.isTrue(section, CFG_KEY_ENABLED):
            return IPFSConnectionParams(
                '127.0.0.1', mgr.getSetting(section, CFG_KEY_APIPORT),
                mgr.getSetting(section, CFG_KEY_HTTPGWPORT))
        else:
            section = CFG_SECTION_IPFSCONN1
            return IPFSConnectionParams(
                mgr.getSetting(section, CFG_KEY_HOST),
                mgr.getSetting(section, CFG_KEY_APIPORT),
                mgr.getSetting(section, CFG_KEY_HTTPGWPORT))

    def getEthParams(self):
        mgr = self.settingsMgr
        provType = mgr.getSetting(CFG_SECTION_ETHEREUM, CFG_KEY_PROVIDERTYPE)
        rpcUrl = mgr.getSetting(CFG_SECTION_ETHEREUM, CFG_KEY_RPCURL)
        return EthereumConnectionParams(rpcUrl, provType=provType)

    async def updateIpfsClient(self):
        from galacteek.ipfs import ConnectionError

        connParams = self.getIpfsConnectionParams()
        client = aioipfs.AsyncIPFS(host=connParams.host,
                                   port=connParams.apiPort,
                                   loop=self.loop)
        self.ipfsClient = client
        self.ipfsCtx.ipfsClient = client
        self.ipfsOpMain = self.getIpfsOperator()
        self.ipfsOpMain.ipidManager = self.ipidManager

        IPFSOpRegistry.regDefault(self.ipfsOpMain)

        try:
            await self.setupRepository()
        except ConnectionError:
            await messageBoxAsync(
                'IPFS connection error (is your daemon running ?)')

        await self.ipfsCtx.ipfsConnectionReady.emit()

    async def stopIpfsServices(self):
        try:
            await self.ipfsCtx.shutdown()
        except BaseException as err:
            log.debug(
                'Error shutting down context: {err}'.format(err=str(err)))

        if self.feedFollowerTask is not None:
            await self.feedFollowerTask.close()

    def setupDb(self):
        ensure(self.setupOrmDb(self._mainDbLocation))

    def jobsExceptionHandler(self, scheduler, context):
        pass

    async def setupOrmDb(self, dbpath):
        self.scheduler = await aiojobs.create_scheduler(close_timeout=1.0,
                                                        limit=150,
                                                        pending_limit=1000)

        # Old database, just for Atom feeds right now

        self.sqliteDb = SqliteDatabase(self._sqliteDbLocation)
        ensure(self.sqliteDb.setup())
        self.modelAtomFeeds = AtomFeedsModel(self.sqliteDb.feeds, parent=self)

        self.urlHistory = history.URLHistory(
            self.sqliteDb,
            enabled=self.settingsMgr.urlHistoryEnabled,
            parent=self)

        if not await database.initOrm(self._mainDbLocation):
            await self.dbConfigured.emit(False)
            return

        await self.setupHashmarks()
        await self.dbConfigured.emit(True)

    async def onDbConfigured(self, configured):
        if not configured:
            return

        self.debug('Database ready')

        self.setupClipboard()
        self.setupTranslator()
        self.initSystemTray()
        self.initMisc()
        self.initEthereum()
        self.initWebProfiles()
        self.initDapps()
        self.createMainWindow()
        self.clipboardInit()

        await self.setupIpfsConnection()

    async def fetchGoIpfs(self):
        ipfsPath = self.which('ipfs')
        fsMigratePath = self.which('fs-repo-migrations')

        if fsMigratePath is None or self.cmdArgs.forcegoipfsdl:
            await fetchFsMigrateWrapper(self)

        if ipfsPath is None or self.cmdArgs.forcegoipfsdl:
            path = await fetchGoIpfsWrapper(self)
            if path is None:
                self.systemTrayMessage('Galacteek', iGoIpfsFetchError())

    async def setupIpfsConnection(self):
        sManager = self.settingsMgr

        await self.fetchGoIpfs()

        if sManager.isTrue(CFG_SECTION_IPFSD, CFG_KEY_ENABLED):
            fsMigratePath = shutil.which('fs-repo-migrations')
            hasFsMigrate = fsMigratePath is not None

            if hasFsMigrate is False and self.cmdArgs.migrate is True:
                self.systemTrayMessage('Galacteek', iFsRepoMigrateNotFound())

            enableMigrate = hasFsMigrate is True and \
                self.cmdArgs.migrate is True

            ipfsPath = self.which('ipfs')

            await self.startIpfsDaemon(goIpfsPath=ipfsPath,
                                       migrateRepo=enableMigrate)
        else:
            await self.updateIpfsClient()

    def setupMainObjects(self):
        self.manuals = ManualsManager(self)
        self.mimeDb = QMimeDatabase()
        self.jinjaEnv = defaultJinjaEnv()
        self.solarSystem = SolarSystem()
        self.mimeTypeIcons = preloadMimeIcons()
        self.hmSynchronizer = HashmarksSynchronizer()
        self.ipidManager = IPIDManager(
            resolveTimeout=self.settingsMgr.ipidIpnsTimeout)

        self.towers = {
            'dags': DAGSignalsTower(self),
            'schemes': URLSchemesTower(self),
            'did': DIDTower()
        }

        self.rscAnalyzer = ResourceAnalyzer(parent=self)

        self.messageDisplayRequest.connect(
            lambda msg, title: ensure(messageBoxAsync(msg, title=title)))
        self.appImageImported.connect(lambda cid: ensure(
            messageBoxAsync('AppImage was imported in IPFS!')))

    def setupAsyncLoop(self):
        """
        Install the quamash event loop and enable debugging
        """

        loop = QEventLoop(self)
        asyncio.set_event_loop(loop)
        logging.getLogger('quamash').setLevel(logging.INFO)

        if self.debugEnabled:
            logging.getLogger('asyncio').setLevel(logging.DEBUG)
            loop.set_debug(True)
            warnings.simplefilter('always', ResourceWarning)
            warnings.simplefilter('always', BytesWarning)
            warnings.simplefilter('always', ImportWarning)

        self._executor = concurrent.futures.ThreadPoolExecutor(max_workers=5)

        self.loop = loop
        return loop

    def task(self, fn, *args, **kw):
        return self.loop.create_task(fn(*args, **kw))

    def configure(self):
        self.initSettings()
        self.setupMainObjects()
        self.setupSchemeHandlers()
        self.applyStyle()
        self.setupDb()

    def acquireLock(self):
        lpath = Path(self._pLockLocation)

        if not lpath.exists():
            lpath.touch()

        self.lock = FileLock(lpath, timeout=2)

        try:
            self.lock.acquire()
        except Exception:
            return questionBox(
                'Lock', 'The profile lock could not be acquired '
                '(another instance could be running). Ignore ?')

        return True

    def setupPaths(self):
        qtDataLocation = QStandardPaths.writableLocation(
            QStandardPaths.DataLocation)

        if not qtDataLocation:
            raise Exception('No writable data location found')

        self._dataLocation = os.path.join(qtDataLocation, self._appProfile)

        self._ipfsBinLocation = os.path.join(qtDataLocation, 'ipfs-bin')
        self._ipfsDataLocation = os.path.join(self.dataLocation, 'ipfs')
        self._orbitDataLocation = os.path.join(self.dataLocation, 'orbitdb')
        self._mHashDbLocation = os.path.join(self.dataLocation, 'mhashmetadb')
        self._sqliteDbLocation = os.path.join(self.dataLocation, 'db.sqlite')
        self._pLockLocation = os.path.join(self.dataLocation, 'profile.lock')
        self._mainDbLocation = os.path.join(self.dataLocation,
                                            'db_main.sqlite3')
        self.marksDataLocation = os.path.join(self.dataLocation, 'marks')
        self.uiDataLocation = os.path.join(self.dataLocation, 'ui')
        self.cryptoDataLocation = os.path.join(self.dataLocation, 'crypto')
        self.gpgDataLocation = os.path.join(self.cryptoDataLocation, 'gpg')
        self.localMarksFileLocation = os.path.join(self.marksDataLocation,
                                                   'ipfsmarks.local.json')
        self.networkMarksFileLocation = os.path.join(self.marksDataLocation,
                                                     'ipfsmarks.network.json')
        self.pinStatusLocation = os.path.join(self.dataLocation,
                                              'pinstatus.json')
        self._nsCacheLocation = os.path.join(self.dataLocation, 'nscache.json')

        qtConfigLocation = QStandardPaths.writableLocation(
            QStandardPaths.ConfigLocation)
        self.configDirLocation = os.path.join(qtConfigLocation, GALACTEEK_NAME,
                                              self._appProfile)
        self.settingsFileLocation = os.path.join(
            self.configDirLocation, '{}.conf'.format(GALACTEEK_NAME))

        for dir in [
                self._ipfsDataLocation, self._mHashDbLocation,
                self.ipfsBinLocation, self.marksDataLocation,
                self.cryptoDataLocation, self.gpgDataLocation,
                self.uiDataLocation, self.configDirLocation
        ]:
            if not os.path.exists(dir):
                os.makedirs(dir)

        self.defaultDownloadsLocation = QStandardPaths.writableLocation(
            QStandardPaths.DownloadLocation)

        self.debug('Datapath: {0}, config: {1}, configfile: {2}'.format(
            self._dataLocation, self.configDirLocation,
            self.settingsFileLocation))

        os.environ['PATH'] += os.pathsep + self.ipfsBinLocation

    def which(self, prog='ipfs'):
        path = self.ipfsBinLocation + os.pathsep + os.environ['PATH']
        result = shutil.which(prog, path=path)
        self.debug('Program {0} found at {1}'.format(prog, result))
        return result

    def initSettings(self):
        self.settingsMgr = SettingsManager(path=self.settingsFileLocation)
        setDefaultSettings(self)
        self.settingsMgr.sync()

    async def startIpfsDaemon(self, goIpfsPath='ipfs', migrateRepo=False):
        if self.ipfsd is not None:  # we only support one daemon for now
            return

        pubsubEnabled = True  # mandatory now ..
        corsEnabled = self.settingsMgr.isTrue(CFG_SECTION_IPFSD, CFG_KEY_CORS)

        sManager = self.settingsMgr
        section = CFG_SECTION_IPFSD

        # Instantiate an IPFS daemon using asyncipfsd and
        # start it in a task, monitoring the initialization process

        self._ipfsd = asyncipfsd.AsyncIPFSDaemon(
            self.ipfsDataLocation,
            goIpfsPath=goIpfsPath,
            apiport=sManager.getInt(section, CFG_KEY_APIPORT),
            swarmport=sManager.getInt(section, CFG_KEY_SWARMPORT),
            swarmportQuic=sManager.getInt(section, CFG_KEY_SWARMPORT_QUIC),
            swarmProtos=sManager.swarmProtosList,
            gatewayport=sManager.getInt(section, CFG_KEY_HTTPGWPORT),
            swarmLowWater=sManager.getInt(section, CFG_KEY_SWARMLOWWATER),
            swarmHighWater=sManager.getInt(section, CFG_KEY_SWARMHIGHWATER),
            storageMax=sManager.getInt(section, CFG_KEY_STORAGEMAX),
            gwWritable=sManager.isTrue(section, CFG_KEY_HTTPGWWRITABLE),
            routingMode=sManager.getSetting(section, CFG_KEY_ROUTINGMODE),
            pubsubRouter=sManager.getSetting(section, CFG_KEY_PUBSUB_ROUTER),
            namesysPubsub=sManager.isTrue(section, CFG_KEY_NAMESYS_PUBSUB),
            pubsubSigning=sManager.isTrue(section, CFG_KEY_PUBSUB_USESIGNING),
            fileStore=sManager.isTrue(section, CFG_KEY_FILESTORE),
            nice=sManager.getInt(section, CFG_KEY_NICE),
            pubsubEnable=pubsubEnabled,
            corsEnable=corsEnabled,
            migrateRepo=migrateRepo,
            debug=self.cmdArgs.goipfsdebug,
            offline=self.cmdArgs.offline,
            loop=self.loop)

        await self.scheduler.spawn(self.startIpfsdTask(self.ipfsd))

    async def startIpfsdTask(self, ipfsd):
        started = await ipfsd.start()

        if started is False:
            return self.systemTrayMessage('IPFS', iIpfsDaemonProblem())

        running = False

        logUser.info(iIpfsDaemonStarted())

        # Use asyncio.wait_for to wait for the proto.eventStarted
        # event to be fired.

        for attempt in range(1, 32):
            logUser.info(iIpfsDaemonWaiting(attempt))

            with async_timeout.timeout(1):
                try:
                    await ipfsd.proto.eventStarted.wait()
                except asyncio.CancelledError:
                    continue
                except asyncio.TimeoutError:
                    # Event not set yet, wait again
                    log.debug('IPFSD: timeout occured while waiting for '
                              'daemon to start (attempt: {0})'.format(attempt))
                    continue
                else:
                    # Event was set, good to go
                    logUser.info(iIpfsDaemonReady())
                    running = True
                    break

        if running is True:
            ensure(self.updateIpfsClient())
        else:
            logUser.info(iIpfsDaemonInitProblem())

    def initEthereum(self):
        try:
            from galacteek.dweb.ethereum.ctrl import EthereumController

            self.ethereum = EthereumController(self.getEthParams(),
                                               loop=self.loop,
                                               parent=self,
                                               executor=self.executor)
            if self.settingsMgr.ethereumEnabled:
                ensure(self.ethereum.start())
        except ImportError:
            self.ethereum = MockEthereumController()

    def normalCursor(self):
        cursor = QCursor(Qt.ArrowCursor)
        QApplication.setOverrideCursor(cursor)
        QApplication.changeOverrideCursor(cursor)

    def setupClipboard(self):
        self.appClipboard = self.clipboard()
        self.clipTracker = ClipboardTracker(self, self.appClipboard)

    def clipboardInit(self):
        self.clipTracker.clipboardInit()

    def setClipboardText(self, text):
        self.clipTracker.setText(text)

    def getClipboardText(self):
        return self.clipTracker.getText()

    def initWebProfiles(self):
        self.scriptsIpfs = ipfsClientScripts(self.getIpfsConnectionParams())

        self.webProfiles = {
            'minimal': MinimalProfile(parent=self),
            'ipfs': IPFSProfile(parent=self),
            'web3': Web3Profile(parent=self)
        }

    def availableWebProfilesNames(self):
        return [p.profileName for n, p in self.webProfiles.items()]

    def initDapps(self):
        self.dappsRegistry = DappsRegistry(self.ethereum, parent=self)

    def setupSchemeHandlers(self):
        self.dwebSchemeHandler = DWebSchemeHandlerGateway(self)
        self.ensSchemeHandler = EthDNSSchemeHandler(self)
        self.ensProxySchemeHandler = EthDNSProxySchemeHandler(self)
        self.nativeIpfsSchemeHandler = NativeIPFSSchemeHandler(
            self, noMutexes=self.cmdArgs.noipfsmutexlock)
        self.qSchemeHandler = MultiObjectHostSchemeHandler(self)

    def subUrl(self, path):
        """ Joins the gatewayUrl and path to form a new URL """
        sub = QUrl(str(self.gatewayUrl))
        sub.setPath(path)
        return sub

    def getJinjaTemplate(self, name):
        try:
            tmpl = self.jinjaEnv.get_template(name)
        except jinja2.exceptions.TemplateNotFound:
            return None
        else:
            return tmpl

    @asyncify
    async def checkReleases(self):
        self.debug('Checking for new releases')
        newR = await pypicheck.newReleaseAvailable()
        if newR:
            self.systemTrayMessage('Galacteek',
                                   iNewReleaseAvailable(),
                                   timeout=8000)

    def showTasks(self):
        for task in self.pendingTasks:
            self.debug('Pending task: {}'.format(task))

    def onShowWindow(self):
        self.mainWindow.showMaximized()

    def restart(self):
        ensure(self.restartApp())

    async def restartApp(self):
        from galacteek.guientrypoint import appStarter
        pArgs = self.arguments()

        await self.exitApp()
        time.sleep(1)
        appStarter.startProcess(pArgs)

    def onExit(self):
        ensure(self.exitApp())

    async def shutdownScheduler(self):
        # It ain't that bad. STFS with dignity

        for stry in range(0, 12):
            try:
                async with async_timeout.timeout(2):
                    await self.scheduler.close()
            except asyncio.TimeoutError:
                log.warning('Timeout shutting down the scheduler (not fooled)')
                continue
            else:
                log.debug(f'Scheduler went down (try: {stry})')
                return

    async def exitApp(self):
        self._shuttingDown = True

        self.lock.release()

        self.mainWindow.stopTimers()

        try:
            self.systemTray.hide()
        except:
            pass

        try:
            await self.sqliteDb.close()
            await database.closeOrm()
        except:
            pass

        await self.stopIpfsServices()

        await self.loop.shutdown_asyncgens()
        await self.shutdownScheduler()
        await cancelAllTasks()

        await self.ethereum.stop()

        if self.ipfsClient:
            await self.ipfsClient.close()

        if self.ipfsd:
            self.ipfsd.stop()

        self.mainWindow.close()

        if self.debug:
            self.showTasks()

        self.tempDir.remove()
        self.quit()
Пример #11
0
class _MainContainer(QWidget):

###############################################################################
# MainContainer SIGNALS
###############################################################################
    """
    newFileOpened(QString)
    allTabClosed()
    runFile(QString)
    addToProject(QString)
    showFileInExplorer(QString)
    recentTabsModified()
    currentEditorChanged(QString)
    fileOpened(QString)
    ---------migrationAnalyzed()
    findOcurrences(QString)
    ---------updateFileMetadata()
    editorKeyPressEvent(QEvent)
    locateFunction(QString, QString, bool) [functionName, filePath, isVariable]
    updateLocator(QString)
    beforeFileSaved(QString)
    fileSaved(QString)
    openPreferences()
    --------openProject(QString)
    ---------dontOpenStartPage()
    """
    newFileOpened = pyqtSignal(str)
    allTabClosed = pyqtSignal()
    runFile = pyqtSignal(str)
    addToProject = pyqtSignal(str)
    showFileInExplorer = pyqtSignal(str)
    recentTabsModified = pyqtSignal()
    currentEditorChanged = pyqtSignal(str)
    fileOpened = pyqtSignal(str)
    migrationAnalyzed = pyqtSignal()#-----------
    findOcurrences = pyqtSignal(str)
    updateFileMetadata = pyqtSignal()#-----------
    editorKeyPressEvent = pyqtSignal('QEvent*')
    locateFunction = pyqtSignal(str, str, bool)
    updateLocator = pyqtSignal(str)
    beforeFileSaved = pyqtSignal(str)
    fileSaved = pyqtSignal(str)
    openPreferences = pyqtSignal()
    openProject = pyqtSignal(str)#-----------
    dontOpenStartPage = pyqtSignal()#-----------
    closeDialog = pyqtSignal('QObject*')
    allTabsClosed = pyqtSignal()
    splitEditor = pyqtSignal('QWidget*', 'QWidget*', bool)
    closeSplit = pyqtSignal(QWidget)
    toRemovePreview = pyqtSignal()

###############################################################################

    def __init__(self, parent=None):
        super(_MainContainer, self).__init__(parent)
        self._parent = parent
        self._vbox = QVBoxLayout(self)
        self._vbox.setContentsMargins(0, 0, 0, 0)
        self._vbox.setSpacing(0)
        self.stack = QStackedLayout()
        self.stack.setStackingMode(QStackedLayout.StackAll)
        self._vbox.addLayout(self.stack)

        self.splitter = dynamic_splitter.DynamicSplitter()
        self.setAcceptDrops(True)
        # self._files_handler = files_handler.FilesHandler(self)
        self._add_file_folder = add_file_folder.AddFileFolderWidget(self)

        self.tdir = None

        #documentation browser
        self.docPage = None
        #Code Navigation
        self._locator = locator.GoToDefinition()
        self.__codeBack = []
        self.__codeForward = []
        self.__bookmarksFile = ''
        self.__bookmarksPos = -1
        self.__breakpointsFile = ''
        self.__breakpointsPos = -1
        self.__operations = {
            0: self._navigate_code_jumps,
            1: self._navigate_bookmarks,
            2: self._navigate_breakpoints}

        self.locateFunction.connect(self.locate_function)

        IDE.register_service('main_container', self)

        #Register signals connections
        connections = (
            {'target': 'menu_file',
             'signal_name': 'openFile',#(QString)
             'slot': self.open_file},
            {'target': 'explorer_container',
             'signal_name': 'goToDefinition',#(int)
             'slot': self.editor_go_to_line},
            {'target': 'explorer_container',
             'signal_name': 'pep8Activated',#(bool)
             'slot': self.reset_pep8_warnings},
            {'target': 'explorer_container',
             'signal_name': 'lintActivated',#(bool)
             'slot': self.reset_lint_warnings},
            )

        IDE.register_signals('main_container', connections)

        self.selector = main_selector.MainSelector(self)
        self._opening_dialog = False
        self.add_widget(self.selector)

        if settings.SHOW_START_PAGE:
            self.show_start_page()

        self.selector.changeCurrent[int].connect(self._change_current_stack)
        self.selector.removeWidget[int].connect(self._remove_item_from_stack)
        self.selector.ready.connect(self._selector_ready)
        self.selector.closePreviewer.connect(self._selector_Close)
        self.selector.animationCompleted.connect(self._selector_animation_completed)

        self.closeDialog.connect(self.remove_widget)
        self.stack.widgetRemoved[int].connect(lambda i:print("widgetRemoved._-", i))

    def install(self):
        ide = IDE.getInstance()
        ide.place_me_on("main_container", self, "central", top=True)

        self.combo_area = combo_editor.ComboEditor(original=True)
        self.combo_area.allFilesClosed.connect(self._files_closed)
        self.splitter.add_widget(self.combo_area)
        self.add_widget(self.splitter)

        self.current_widget = self.combo_area

        ui_tools.install_shortcuts(self, actions.ACTIONS, ide)

    def add_status_bar(self, status):
        self._vbox.addWidget(status)

    @property
    def combo_header_size(self):
        return self.combo_area.bar.height()

    def add_widget(self, widget):
        i = self.stack.addWidget(widget)
        #if not isinstance(widget, start_page.StartPage):
        self.tryMakeImagePreview(i)

    def remove_widget(self, widget):
        #self.toRemovePreview.emit(self.stack.widget(widget))
        self.stack.removeWidget(widget)

    def _close_dialog(self, widget):
        self.closeDialog.emit(widget)
        widget.finished[int].disconnect()#lambda i: self._close_dialog(widget))

    def show_dialog(self, widget):
        print("\n\nshow_dialog", self.isVisible())
        self._opening_dialog = True
        widget.finished[int].connect(lambda i: self._close_dialog(widget))
        widget.setVisible(True)
        self.show_selector()

    def show_selector(self):
        print("\n\nshow_selector::", self.selector, self.stack.currentWidget())
        if self.selector != self.stack.currentWidget():
            _dir = self.Successful_Tmp()
            if not _dir:
                print("failed!")
                return

            # temp_dir = os.path.join(QDir.tempPath(), "ninja-ide")
            # if not os.path.exists(temp_dir):
            #     os.mkdir(temp_dir)
            collected_data = []
            current = self.stack.currentIndex()
            for index in range(self.stack.count()):
                widget = self.stack.widget(index)
                if widget == self.selector:
                    continue
                closable = True
                if widget == self.splitter:
                    closable = False
                # path = os.path.join(temp_dir, "screen%s.png" % index)
                #ff = QFile(_dir, "screen%s.png" % index)
                path = _dir.absolutePath()+"/screen%s.png" % index
                pixmap = widget.grab()#widget.rect())
                pixmap.save(path)
                #path = path.replace("\\", '/')
                #print("path::", path, QFileInfo(path).exists())
                path = "file:///"+path
                if index == current:
                    self.selector.set_preview(index, path)#QUrl(path)
                    collected_data.insert(0, (index, path, closable))
                else:
                    collected_data.append((index, path, closable))
            self.selector.set_model(collected_data)
            print("self.selector.set_model()", collected_data)
            self.stack.setCurrentWidget(self.selector)
        else:
            print("\n\n_selector_Close()")
            self._selector_Close()

    def Successful_Tmp(self):# CheckTmpDir, StateTmpDir
        failed = lambda: not self.tdir or not self.tdir.isValid()
        if failed():# not successfully
            self.tdir = QTemporaryDir()
            if failed():
                QMessageBox.critical(self, "Unexpected Failurer", "The application has detected a problem trying to\nCreate or Access a Temporary File!.")
                return None
            else:
                self.tdir.setAutoRemove(True)

        d = QDir(self.tdir.path())
        if not d.exists("ninja-ide"):
            if not d.mkdir("ninja-ide"):
                self.tdir = None
        d.cd("ninja-ide")
        return d

    def tryMakeImagePreview(self, index):
        return
        d = self.Successful_Tmp()
        if d:
            self.makeImagePreview(d, index)

    def makeImagePreview(self, _dir, index):
        return
        path = _dir.absolutePath()+"/screen%s.png" % index
        widget = self.stack.widget(index)
        pixmap = widget.grab()#widget.rect()
        pixmap.save(path)

    def _selector_ready(self):
        self.stack.setCurrentWidget(self.selector)
        self.selector.GoTo_GridPreviews()

    def _selector_Close(self):
        self.stack.setCurrentWidget(self.splitter)

    def _selector_animation_completed(self):
        if self._opening_dialog:
            # We choose the last one with -2, -1 (for last one) +
            # -1 for the hidden selector widget which is in the stacked too.
            self.selector.open_item(self.stack.count() - 2)
        self._opening_dialog = False

    def _change_current_stack(self, index):
        self.stack.setCurrentIndex(index)

    def _remove_item_from_stack(self, index):
        #self.toRemovePreview.emit(index)
        widget = self.stack.takeAt(index)
        del widget

    def show_editor_area(self):
        self.stack.setCurrentWidget(self.splitter)

    def _files_closed(self):
        if settings.SHOW_START_PAGE:
            self.show_start_page()

    def change_visibility(self):
        """Show/Hide the Main Container area."""
        print("change_visibility11")
        if self.isVisible():
            self.hide()
        else:
            self.show()

    def expand_symbol_combo(self):
        self.stack.setCurrentWidget(self.splitter)
        self.current_widget.show_combo_symbol()

    def expand_file_combo(self):
        print("expand_file_combo")
        self.stack.setCurrentWidget(self.splitter)
        self.current_widget.show_combo_file()

    def locate_function(self, function, filePath, isVariable):
        """Move the cursor to the proper position in the navigate stack."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            self.__codeBack.append((editorWidget.file_path,
                                   editorWidget.getCursorPosition()))
            self.__codeForward = []
        self._locator.navigate_to(function, filePath, isVariable)

    def run_file(self, path):
        self.runFile.emit(path)

    def _add_to_project(self, path):
        self.addToProject.emit(path)

    def _show_file_in_explorer(self, path):
        self.showFileInExplorer.emit(path)

    def paste_history(self):
        """Paste the text from the copy/paste history."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            line, index = editorWidget.getCursorPosition()
            central = IDE.get_service('central_container')
            if central:
                editorWidget.insertAt(central.get_paste(), line, index)

    def copy_history(self):
        """Copy the selected text into the copy/paste history."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            copy = editorWidget.selectedText()
            central = IDE.get_service('central_container')
            if central:
                central.add_copy(copy)

    def import_from_everywhere(self):
        """Insert an import line from any place in the editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            dialog = from_import_dialog.FromImportDialog(editorWidget, self)
            dialog.show()

    def add_back_item_navigation(self):
        """Add an item to the back stack and reset the forward stack."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            self.__codeBack.append((editorWidget.file_path,
                                   editorWidget.getCursorPosition()))
            self.__codeForward = []

    def preview_in_browser(self):
        """Load the current html file in the default browser."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            if not editorWidget.file_path:
                self.save_file()
            ext = file_manager.get_file_extension(editorWidget.file_path)
            if ext in ('html', 'shpaml', 'handlebars', 'tpl'):
                webbrowser.open_new_tab(editorWidget.file_path)

    def add_bookmark_breakpoint(self):
        """Add a bookmark or breakpoint to the current file in the editor."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            if self.current_widget.bar.code_navigator.operation == 1:
                editorWidget.handle_bookmarks_breakpoints(
                    editorWidget.getCursorPosition()[0], Qt.ControlModifier)
            elif self.current_widget.bar.code_navigator.operation == 2:
                editorWidget.handle_bookmarks_breakpoints(
                    editorWidget.getCursorPosition()[0], Qt.NoModifier)

    def __navigate_with_keyboard(self, val):
        """Navigate between the positions in the jump history stack."""
        op = self.current_widget.bar.code_navigator.operation
        self.navigate_code_history(val, op)

    def navigate_code_history(self, val, op):
        """Navigate the code history."""
        self.__operations[op](val)

    def _navigate_code_jumps(self, val):
        """Navigate between the jump points."""
        node = None
        if not val and self.__codeBack:
            node = self.__codeBack.pop()
            editorWidget = self.get_current_editor()
            if editorWidget:
                self.__codeForward.append((editorWidget.file_path,
                                          editorWidget.getCursorPosition()))
        elif val and self.__codeForward:
            node = self.__codeForward.pop()
            editorWidget = self.get_current_editor()
            if editorWidget:
                self.__codeBack.append((editorWidget.file_path,
                                       editorWidget.getCursorPosition()))
        if node:
            filename = node[0]
            line, col = node[1]
            self.open_file(filename, line, col)

    def _navigate_breakpoints(self, val):
        """Navigate between the breakpoints."""
        #FIXME: put navigate breakpoints and bookmarks as one method.
        breakList = list(settings.BREAKPOINTS.keys())
        breakList.sort()
        if not breakList:
            return
        if self.__breakpointsFile not in breakList:
            self.__breakpointsFile = breakList[0]
        index = breakList.index(self.__breakpointsFile)
        breaks = settings.BREAKPOINTS.get(self.__breakpointsFile, [])
        lineNumber = 0
        #val == True: forward
        if val:
            if (len(breaks) - 1) > self.__breakpointsPos:
                self.__breakpointsPos += 1
                lineNumber = breaks[self.__breakpointsPos]
            elif len(breaks) > 0:
                if index < (len(breakList) - 1):
                    self.__breakpointsFile = breakList[index + 1]
                else:
                    self.__breakpointsFile = breakList[0]
                self.__breakpointsPos = 0
                lineNumber = settings.BREAKPOINTS[self.__breakpointsFile][0]
        else:
            if self.__breakpointsPos > 0:
                self.__breakpointsPos -= 1
                lineNumber = breaks[self.__breakpointsPos]
            elif len(breaks) > 0:
                self.__breakpointsFile = breakList[index - 1]
                breaks = settings.BREAKPOINTS[self.__breakpointsFile]
                self.__breakpointsPos = len(breaks) - 1
                lineNumber = breaks[self.__breakpointsPos]
        if file_manager.file_exists(self.__breakpointsFile):
            self.open_file(self.__breakpointsFile, lineNumber, None, True)
        else:
            settings.BREAKPOINTS.pop(self.__breakpointsFile)
            if settings.BREAKPOINTS:
                self._navigate_breakpoints(val)

    def _navigate_bookmarks(self, val):
        """Navigate between the bookmarks."""
        bookList = list(settings.BOOKMARKS.keys())
        bookList.sort()
        if not bookList:
            return
        if self.__bookmarksFile not in bookList:
            self.__bookmarksFile = bookList[0]
        index = bookList.index(self.__bookmarksFile)
        bookms = settings.BOOKMARKS.get(self.__bookmarksFile, [])
        lineNumber = 0
        #val == True: forward
        if val:
            if (len(bookms) - 1) > self.__bookmarksPos:
                self.__bookmarksPos += 1
                lineNumber = bookms[self.__bookmarksPos]
            elif len(bookms) > 0:
                if index < (len(bookList) - 1):
                    self.__bookmarksFile = bookList[index + 1]
                else:
                    self.__bookmarksFile = bookList[0]
                self.__bookmarksPos = 0
                lineNumber = settings.BOOKMARKS[self.__bookmarksFile][0]
        else:
            if self.__bookmarksPos > 0:
                self.__bookmarksPos -= 1
                lineNumber = bookms[self.__bookmarksPos]
            elif len(bookms) > 0:
                self.__bookmarksFile = bookList[index - 1]
                bookms = settings.BOOKMARKS[self.__bookmarksFile]
                self.__bookmarksPos = len(bookms) - 1
                lineNumber = bookms[self.__bookmarksPos]
        if file_manager.file_exists(self.__bookmarksFile):
            self.open_file(self.__bookmarksFile,
                           lineNumber, None, True)
        else:
            settings.BOOKMARKS.pop(self.__bookmarksFile)
            if settings.BOOKMARKS:
                self._navigate_bookmarks(val)

    def count_file_code_lines(self):
        """Count the lines of code in the current file."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            block_count = editorWidget.lines()
            blanks = re.findall('(^\n)|(^(\s+)?#)|(^( +)?($|\n))',
                                editorWidget.text(), re.M)
            blanks_count = len(blanks)
            resume = self.tr("Lines code: %s\n") % (block_count - blanks_count)
            resume += (self.tr("Blanks and commented lines: %s\n\n") %
                       blanks_count)
            resume += self.tr("Total lines: %s") % block_count
            msgBox = QMessageBox(QMessageBox.Information,
                                 self.tr("Summary of lines"), resume,
                                 QMessageBox.Ok, editorWidget)
            msgBox.exec_()

    def editor_cut(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.cut()

    def editor_copy(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.copy()

    def editor_paste(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.paste()

    def editor_upper(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.to_upper()

    def editor_lower(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.to_lower()

    def editor_title(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.to_title()

    def editor_go_to_definition(self):
        """Search the definition of the method or variable under the cursor.

        If more than one method or variable is found with the same name,
        shows a table with the results and let the user decide where to go."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.go_to_definition()

    def editor_redo(self):
        """Execute the redo action in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.redo()

    def editor_undo(self):
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.undo()

    def editor_indent_less(self):
        """Indent 1 position to the left for the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.indent_less()

    def editor_indent_more(self):
        """Indent 1 position to the right for the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.indent_more()

    def editor_insert_debugging_prints(self):
        """Insert a print statement in each selected line."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.insert_debugging_prints(editorWidget)

    def editor_insert_pdb(self):
        """Insert a pdb.set_trace() statement in tjhe current line."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.insert_pdb(editorWidget)

    def editor_comment(self):
        """Mark the current line or selection as a comment."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.comment(editorWidget)

    def editor_uncomment(self):
        """Uncomment the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.uncomment(editorWidget)

    def editor_insert_horizontal_line(self):
        """Insert an horizontal lines of comment symbols."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.insert_horizontal_line(editorWidget)

    def editor_insert_title_comment(self):
        """Insert a Title surrounded by comment symbols."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.insert_title_comment(editorWidget)

    def editor_remove_trailing_spaces(self):
        """Remove the trailing spaces in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.remove_trailing_spaces(editorWidget)

    def editor_replace_tabs_with_spaces(self):
        """Replace the Tabs with Spaces in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.replace_tabs_with_spaces(editorWidget)

    def editor_move_up(self):
        """Move the current line or selection one position up."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.move_up(editorWidget)

    def editor_move_down(self):
        """Move the current line or selection one position down."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.move_down(editorWidget)

    def editor_remove_line(self):
        """Remove the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.remove_line(editorWidget)

    def editor_duplicate(self):
        """Duplicate the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.duplicate(editorWidget)

    def editor_highlight_word(self):
        """Highlight the occurrences of the current word in the editor."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.highlight_selected_word()

    def editor_complete_declaration(self):
        """Do the opposite action that Complete Declaration expect."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.complete_declaration()

    def editor_go_to_line(self, line, select=False):#def editor_go_to_line(self, line):
        """Jump to the specified line in the current editor."""
        editorWidget = self.get_current_editor()
        print("\nluego en segundo lugar por aca")
        if editorWidget:
            editorWidget.jump_to_line(line)#select

    def editor_go_to_symbol_line(self, line, sym= "", select=False):
        """Jump to the specified line in the current editor."""
        editorWidget = self.get_current_editor()
        print("\nluego en segundo lugar por aca")
        if editorWidget:
            editorWidget.go_to_symbol(line, sym, select)#select

    def zoom_in_editor(self):
        """Increase the font size in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.zoom_in()

    def zoom_out_editor(self):
        """Decrease the font size in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.zoom_out()

    def recent_files_changed(self):
        self.recentTabsModified.emit()

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        # file_path = event.mimeData().urls()[0].toLocalFile()
        # paths = [item.toLocalFile() for item in event.mimeData().urls()]
        self.open_files_fromUrlList(event.mimeData().urls())
        # print("\n\n dropEvent", paths)
        # self.open_file(file_path)

    def setFocus(self):
        widget = self.get_current_widget()
        if widget:
            widget.setFocus()

    def current_editor_changed(self, filename):
        """Notify the new filename of the current editor."""
        if filename is None:
            filename = translations.TR_NEW_DOCUMENT
        self.currentEditorChanged.emit(filename)

    def show_split(self, orientation_vertical=False):
        #IDE.select_current(self.current_widget.currentWidget())
        self.current_widget.split_editor(orientation_vertical)

    def add_editor(self, fileName=None, ignore_checkers=False):
        print("filename::", fileName)
        ninjaide = IDE.getInstance()
        editable = ninjaide.get_or_create_editable(fileName)
        if editable.editor:
            self.current_widget.set_current(editable)
            print("\n\nreturn")
            return self.current_widget.currentWidget()
        else:
            editable.ignore_checkers = ignore_checkers

        editorWidget = self.create_editor_from_editable(editable)

        #add the tab
        keep_index = (self.splitter.count() > 1 and
                      self.combo_area.stacked.count() > 0)
        self.combo_area.add_editor(editable, keep_index)

        #emit a signal about the file open
        self.fileOpened.emit(fileName)
        if keep_index:
            self.current_widget.set_current(editable)

        self.stack.setCurrentWidget(self.splitter)
        return editorWidget

    def create_editor_from_editable(self, editable):
        editorWidget = editor.create_editor(editable)

        #Connect signals
        editable.fileSaved.connect(self._editor_tab_was_saved)
        editorWidget.openDropFile.connect(self.open_file)
        editorWidget.addBackItemNavigation.connect(self.add_back_item_navigation)
        editorWidget.locateFunction.connect(self._editor_locate_function)
        editorWidget.findOcurrences.connect(self._find_occurrences)
        #keyPressEventSignal for plugins
        editorWidget.keyPressSignal.connect(self._editor_keyPressEvent)

        return editorWidget

    def reset_pep8_warnings(self, value):
        pass
        #FIXME: check how we handle this
        #for i in range(self._tabMain.count()):
            #widget = self._tabMain.widget(i)
            #if type(widget) is editor.Editor:
                #if value:
                    #widget.syncDocErrorsSignal = True
                    #widget.pep8.check_style()
                #else:
                    #widget.hide_pep8_errors()

    def reset_lint_warnings(self, value):
        pass
        #FIXME: check how we handle this
        #for i in range(self._tabMain.count()):
            #widget = self._tabMain.widget(i)
            #if type(widget) is editor.Editor:
                #if value:
                    #widget.syncDocErrorsSignal = True
                    #widget.errors.check_errors()
                #else:
                    #widget.hide_lint_errors()

    def _find_occurrences(self, word):
        self.findOcurrences.emit(word)

    def _editor_keyPressEvent(self, event):
        self.editorKeyPressEvent.emit(event)

    def _editor_locate_function(self, function, filePath, isVariable):
        self.locateFunction.emit(function, filePath, isVariable)

    def _editor_tab_was_saved(self, editable=None):
        self.updateLocator.emit(editable.file_path)

    def get_current_widget(self):
        return self.current_widget.currentWidget()

    def get_current_editor(self):
        """Return the Actual Editor or None

        Return an instance of Editor if the Current Tab contains
        an Editor or None if it is not an instance of Editor"""
        widget = self.current_widget.currentWidget()
        if isinstance(widget, editor.Editor):
            return widget
        return None

    def reload_file(self, editorWidget=None):
        if editorWidget is None:
            editorWidget = self.get_current_editor()
            if editorWidget is not None:
                editorWidget.neditable.reload_file()

    def add_tab(self, widget, tabName, tabIndex=None):
        pass
        #return self.tabs.add_tab(widget, tabName, index=tabIndex)

    def open_image(self, fileName):
        try:
            if not self.is_open(fileName):
                viewer = image_viewer.ImageViewer(fileName)
                self.add_tab(viewer, file_manager.get_basename(fileName))
                viewer.ID = fileName
            else:
                self.move_to_open(fileName)
        except Exception as reason:
            logger.error('open_image: %s', reason)
            QMessageBox.information(self, self.tr("Incorrect File"),
                                    self.tr("The image couldn\'t be open"))

    def open_files_fromList(self, lst):
        for f in lst:
            self.open_file(f)

    def open_files_fromUrlList(self, lst):
        for f in lst:
            self.open_file(f.toLocalFile())

    def open_file(self, filename='', line=-1, col=0, ignore_checkers=False):
        logger.debug("will try to open %s" % filename)
        if not filename:
            logger.debug("has nofilename")
            if settings.WORKSPACE:
                directory = settings.WORKSPACE
            else:
                directory = os.path.expanduser("~")
                editorWidget = self.get_current_editor()
                ninjaide = IDE.getInstance()
                if ninjaide:
                    current_project = ninjaide.get_current_project()
                    if current_project is not None:
                        directory = current_project
                    elif editorWidget is not None and editorWidget.file_path:
                        directory = file_manager.get_folder(
                            editorWidget.file_path)
            extensions = ';;'.join(
                ['{}(*{})'.format(e.upper()[1:], e)
                 for e in settings.SUPPORTED_EXTENSIONS + ['.*', '']])
            fileNames = QFileDialog.getOpenFileNames(self,
                             self.tr("Open File"), directory, extensions)[0]#list()
        else:
            logger.debug("has filename")
            fileNames = [filename]
        if not fileNames:
            return

        print("\n\nopen_file")
        othersFileNames = []
        image_extensions = ('bmp', 'gif', 'jpeg', 'jpg', 'png')
        for filename in fileNames:
            print("nombre", filename)
            if QFileInfo(filename).isDir():
                othersFileNames.extend( QFileDialog.getOpenFileNames(None,
                    "Select files", filename, "Files (*.*)")[0] )
            elif file_manager.get_file_extension(filename) in image_extensions:
                logger.debug("will open as image")
                self.open_image(filename)
            elif file_manager.get_file_extension(filename).endswith('ui'):
                logger.debug("will load in ui editor")
                self.w = uic.loadUi(filename)
                self.w.show()
            else:
                logger.debug("will try to open: " + filename)
                self.__open_file(filename, line, col,
                                 ignore_checkers)

        for filename in othersFileNames:
            print("nombre", filename)
            if QFileInfo(filename).isDir():
                continue
            elif file_manager.get_file_extension(filename) in image_extensions:
                logger.debug("will open as image")
                self.open_image(filename)
            elif file_manager.get_file_extension(filename).endswith('ui'):
                logger.debug("will load in ui editor")
                self.w = uic.loadUi(filename)
                self.w.show()
            else:
                logger.debug("will try to open: " + filename)
                self.__open_file(filename, line, col,
                                 ignore_checkers)



    def __open_file(self, fileName='', line=-1, col=0, ignore_checkers=False):
        print("unio", fileName)
        try:
            editorWidget = self.add_editor(fileName,
                                           ignore_checkers=ignore_checkers)
            if line != -1:
                editorWidget.set_cursor_position(line, col)
            self.currentEditorChanged.emit(fileName)
        except file_manager.NinjaIOException as reason:
            QMessageBox.information(self,
                                    self.tr("The file couldn't be open"),
                                    str(reason))

    def is_open(self, filename):
        pass
        #return self.tabs.is_open(filename) != -1

    def move_to_open(self, filename):
        pass
        #FIXME: add in the current split?
        #if self.tabs.is_open(filename) != -1:
            #self.tabs.move_to_open(filename)
        #self.tabs.currentWidget().setFocus()
        #self.emit(SIGNAL("currentEditorChanged(QString)"), filename)

    def get_widget_for_id(self, filename):
        pass
        #widget = None
        #index = self.tabs.is_open(filename)
        #if index != -1:
            #widget = self.tabs.widget(index)
        #return widget

    def change_open_tab_id(self, idname, newId):
        """Search for the Tab with idname, and set the newId to that Tab."""
        pass
        #index = self.tabs.is_open(idname)
        #if index != -1:
            #widget = self.tabs.widget(index)
            #tabName = file_manager.get_basename(newId)
            #self.tabs.change_open_tab_name(index, tabName)
            #widget.ID = newId

    def close_deleted_file(self, idname):
        """Search for the Tab with id, and ask the user if should be closed."""
        pass
        #index = self.tabs.is_open(idname)
        #if index != -1:
            #result = QMessageBox.question(self, self.tr("Close Deleted File"),
                #self.tr("Are you sure you want to close the deleted file?\n"
                        #"The content will be completely deleted."),
                #buttons=QMessageBox.Yes | QMessageBox.No)
            #if result == QMessageBox.Yes:
                #self.tabs.removeTab(index)

    def save_file(self, editorWidget=None):
        #FIXME: check how we handle this
        if not editorWidget:
            editorWidget = self.get_current_editor()
        if not editorWidget:
            return False
        try:
            #editorWidget.just_saved = True
            if (editorWidget.nfile.is_new_file or
                    not editorWidget.nfile.has_write_permission()):
                return self.save_file_as()

            self.beforeFileSaved.emit(editorWidget.file_path)
            if settings.REMOVE_TRAILING_SPACES:
                helpers.remove_trailing_spaces(editorWidget)
            editorWidget.neditable.save_content()
            #file_manager.store_file_content(
                #fileName, content, addExtension=False)
            encoding = file_manager.get_file_encoding(editorWidget.text())
            editorWidget.encoding = encoding
            self.fileSaved.emit((self.tr("File Saved: %s") % editorWidget.file_path))
            return True
        except Exception as reason:
            logger.error('save_file: %s', reason)
            QMessageBox.information(self, self.tr("Save Error"),
                                    self.tr("The file couldn't be saved!"))
        return False

    def save_file_as(self):
        editorWidget = self.get_current_editor()
        if not editorWidget:
            return False
        try:
            filters = '(*.py);;(*.*)'
            if editorWidget.file_path:
                ext = file_manager.get_file_extension(editorWidget.file_path)
                if ext != 'py':
                    filters = '(*.%s);;(*.py);;(*.*)' % ext
            save_folder = self._get_save_folder(editorWidget.file_path)
            fileName = QFileDialog.getSaveFileName(
                self._parent, self.tr("Save File"), save_folder, filters)
            if not fileName:
                return False

            if settings.REMOVE_TRAILING_SPACES:
                helpers.remove_trailing_spaces(editorWidget)

            editorWidget.neditable.save_content(path=fileName)
            editorWidget.register_syntax(
                file_manager.get_file_extension(fileName))

            self.fileSaved.emit((self.tr("File Saved: %s") % fileName))
            self.currentEditorChanged.emit(fileName)
            return True
        except file_manager.NinjaFileExistsException as ex:
            QMessageBox.information(self, self.tr("File Already Exists"),
                                    (self.tr("Invalid Path: the file '%s' "
                                             " already exists.") %
                                    ex.filename))
        except Exception as reason:
            logger.error('save_file_as: %s', reason)
            QMessageBox.information(self, self.tr("Save Error"),
                                    self.tr("The file couldn't be saved!"))
        return False

    def _get_save_folder(self, fileName):
        """
        Returns the root directory of the 'Main Project' or the home folder
        """
        ninjaide = IDE.getInstance()
        current_project = ninjaide.get_current_project()
        if current_project:
            return current_project.path
        return os.path.expanduser("~")

    def save_project(self, projectFolder):
        pass
        #FIXME: check how we handle this
        #for i in range(self._tabMain.count()):
            #editorWidget = self._tabMain.widget(i)
            #if type(editorWidget) is editor.Editor and \
            #file_manager.belongs_to_folder(projectFolder,
                    #editorWidget.file_path):
                #reloaded = self._tabMain.check_for_external_modifications(
                    #editorWidget)
                #if not reloaded:
                    #self.save_file(editorWidget)
        #for i in range(self.tabsecondary.count()):
            #editorWidget = self.tabsecondary.widget(i)
            #if type(editorWidget) is editor.Editor and \
            #file_manager.belongs_to_folder(projectFolder,
                    #editorWidget.file_path):
                #reloaded = self.tabsecondary.check_for_external_modifications(
                    #editorWidget)
                #if not reloaded:
                    #self.save_file(editorWidget)

    def save_all(self):
        pass
        #FIXME: check how we handle this
        #for i in range(self._tabMain.count()):
            #editorWidget = self._tabMain.widget(i)
            #if type(editorWidget) is editor.Editor:
                #reloaded = self._tabMain.check_for_external_modifications(
                    #editorWidget)
                #if not reloaded:
                    #self.save_file(editorWidget)
        #for i in range(self.tabsecondary.count()):
            #editorWidget = self.tabsecondary.widget(i)
            #self.tabsecondary.check_for_external_modifications(editorWidget)
            #if type(editorWidget) is editor.Editor:
                #reloaded = self.tabsecondary.check_for_external_modifications(
                    #editorWidget)
                #if not reloaded:
                    #self.save_file(editorWidget)

    def call_editors_function(self, call_function, *arguments):
        pass
        #args = arguments[0]
        #kwargs = arguments[1]
        #for i in range(self.tabs.count()):
            #editorWidget = self.tabs.widget(i)
            #if isinstance(editorWidget, editor.Editor):
                #function = getattr(editorWidget, call_function)
                #function(*args, **kwargs)
        #TODO: add other splits

    def show_start_page(self):
        start = self.stack.widget(0)
        if isinstance(start, start_page.StartPage):
            self.stack.setCurrentIndex(0)
        else:
            startPage = start_page.StartPage(parent=self)
            startPage.openProject.connect(self.open_project)
            startPage.openPreferences.connect(self.openPreferences.emit)
            startPage.newFile.connect(self.add_editor)
            startPage.openFiles.connect(self.open_files_fromList)
            self.stack.insertWidget(0, startPage)
            self.stack.setCurrentIndex(0)

            self.tryMakeImagePreview(0)
            #"screen0.png"

    def show_python_doc(self):
        if sys.platform == 'win32':
            self.docPage = browser_widget.BrowserWidget(
                'http://docs.python.org/')
        else:
            process = runner.start_pydoc()
            self.docPage = browser_widget.BrowserWidget(process[1], process[0])
        self.add_tab(self.docPage, translations.TR_PYTHON_DOC)

    def show_report_bugs(self):
        webbrowser.open(resources.BUGS_PAGE)

    def show_plugins_doc(self):
        bugsPage = browser_widget.BrowserWidget(resources.PLUGINS_DOC, self)
        self.add_tab(bugsPage, translations.TR_HOW_TO_WRITE_PLUGINS)

    def editor_jump_to_line(self, lineno=None):
        """Jump to line *lineno* if it is not None
        otherwise ask to the user the line number to jump
        """
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.jump_to_line(lineno=lineno)

    def get_opened_documents(self):
        #return self.tabs.get_documents_data()
        return []

    def check_for_unsaved_files(self):
        pass
        #return self.tabs._check_unsaved_tabs()

    def get_unsaved_files(self):
        pass
        #return self.tabs.get_unsaved_files()

    def reset_editor_flags(self):
        pass
        #for i in range(self.tabs.count()):
            #widget = self.tabs.widget(i)
            #if isinstance(widget, editor.Editor):
                #widget.set_flags()

    def _specify_syntax(self, widget, syntaxLang):
        if isinstance(widget, editor.Editor):
            widget.restyle(syntaxLang)

    def apply_editor_theme(self, family, size):
        pass
        #for i in range(self.tabs.count()):
            #widget = self.tabs.widget(i)
            #if isinstance(widget, editor.Editor):
                #widget.restyle()
                #widget.set_font(family, size)

    def update_editor_margin_line(self):
        pass
        #for i in range(self.tabs.count()):
            #widget = self.tabs.widget(i)
            #if isinstance(widget, editor.Editor):
                #widget._update_margin_line()

    def open_project(self, path):
        print("open_project")
        self.openProject.emit(path)

    def close_python_doc(self):
        pass
        #close the python document server (if running)
        #if self.docPage:
            #index = self.tabs.indexOf(self.docPage)
            #self.tabs.removeTab(index)
            ##assign None to the browser
            #self.docPage = None

    def close_file(self):
        """Close the current tab in the current TabWidget."""
        self.current_widget.close_current_file()

    def create_file(self, base_path, project_path):
        self._add_file_folder.create_file(base_path, project_path)

    def create_folder(self, base_path, project_path):
        self._add_file_folder.create_folder(base_path, project_path)

    def change_tab(self):
        """Change the tab in the current TabWidget."""
        print("\nchange_tab")
        self.stack.setCurrentWidget(self.splitter)
        # self._files_handler.next_item()
        pass

    def change_tab_reverse(self):
        """Change the tab in the current TabWidget backwards."""
        print("\nchange_tab_reverse")
        self.stack.setCurrentWidget(self.splitter)
        # self._files_handler.previous_item()

    def toggle_tabs_and_spaces(self):
        """ Toggle Show/Hide Tabs and Spaces """

        settings.SHOW_TABS_AND_SPACES = not settings.SHOW_TABS_AND_SPACES
        qsettings = IDE.ninja_settings()
        qsettings.setValue('preferences/editor/showTabsAndSpaces',
                           settings.SHOW_TABS_AND_SPACES)

    def show_navigation_buttons(self):
        """Show Navigation menu."""
        self.stack.setCurrentWidget(self.splitter)
        self.combo_area.show_menu_navigation()

    def change_split_focus(self):
        pass
        #FIXME: check how we handle this
        #if self.actualTab == self._tabMain and self.tabsecondary.isVisible():
            #self.actualTab = self.tabsecondary
        #else:
            #self.actualTab = self._tabMain
        #widget = self.actualTab.currentWidget()
        #if widget is not None:
            #widget.setFocus()

    def shortcut_index(self, index):
        pass
        #self.tabs.setCurrentIndex(index)

    def print_file(self):
        """Call the print of ui_tool

        Call print of ui_tool depending on the focus of the application"""
        #TODO: Add funtionality for proyect tab and methods tab
        editorWidget = self.get_current_editor()
        if editorWidget is not None:
            fileName = "newDocument.pdf"
            if editorWidget.file_path:
                fileName = file_manager.get_basename(
                    editorWidget.file_path)
                fileName = fileName[:fileName.rfind('.')] + '.pdf'
            ui_tools.print_file(fileName, editorWidget.print_)

    def split_assistance(self):
        dialog = split_orientation.SplitOrientation(self)
        dialog.show()

    def close_split(self):
        if self.current_widget != self.combo_area:
            self.current_widget.bar.close_split()

    def split_vertically(self):
        self.show_split(False)

    def split_horizontally(self):
        self.show_split(True)

    def navigate_back(self):
        self.__navigate_with_keyboard(False)

    def navigate_forward(self):
        self.__navigate_with_keyboard(True)
Пример #12
0
    def __init__(self, resources):
        """
        Init Args object.
        """

        # temporary dir.
        self.global_temp_dir = QTemporaryDir()

        # global args.
        self.global_hm_rules = (
            "analogous",
            "monochromatic",
            "triad",
            "tetrad",
            "pentad",
            "complementary",
            "shades",
            "custom",
        )

        self.global_overflows = (
            "cutoff",
            "return",
            "repeat",
        )

        self.global_log = False

        # load languages.
        all_langs = (
            "en",
            "ar",
            "be",
            "bg",
            "ca",
            "cs",
            "da",
            "de",
            "el",
            "es",
            "et",
            "fi",
            "fr",
            "hr",
            "hu",
            "is",
            "it",
            "iw",
            "ja",
            "ko",
            "lt",
            "lv",
            "mk",
            "nl",
            "no",
            "pl",
            "pt",
            "ro",
            "ru",
            "sh",
            "sk",
            "sl",
            "sq",
            "sr",
            "sv",
            "th",
            "tr",
            "uk",
            "zh",
        )

        lang_paths = [
            (39, "default"),
        ]

        langs_dir = os.sep.join((resources, "langs"))
        if not os.path.isdir(langs_dir):
            os.makedirs(langs_dir)

        for lang in os.listdir(langs_dir):
            if os.path.isfile(os.sep.join(
                (langs_dir, lang))) and lang.split(".")[-1] == "qm":
                glang = re.split("\.|_|-", lang)[0]

                if glang in all_langs:
                    lang_paths.append((all_langs.index(glang), lang))

        self.lang = "default"
        self.usr_langs = tuple(lang_paths)

        # software informations.
        self.info_main_site = "https://liujiacode.github.io/DigitalPalette"
        self.info_update_site = "https://github.com/liujiacode/DigitalPalette/releases"
        self.info_version_zh = "v2.2.7-开发版"
        self.info_version_en = "v2.2.7-dev"
        self.info_author_zh = "本征喵"
        self.info_author_en = "Eigenmiao"
        self.info_date_zh = "2020年4月25日"
        self.info_date_en = "Apr. 25th, 2020"

        # init settings.
        self.usr_store = os.sep.join(
            (os.path.expanduser('~'), "Documents", "DigitalPalette"))
        self.resources = resources

        self.init_settings()

        # init setable but not initable settings.
        self.stab_ucells = tuple()
        self.stab_column = 3

        # load settings.
        if self.store_loc:
            self.load_settings(os.sep.join((self.resources, "settings.json")))

        else:
            self.load_settings(os.sep.join((self.usr_store, "settings.json")))

        # special system settings.
        self.sys_activated_idx = 0
        self.sys_color_set = ColorSet(self.h_range,
                                      self.s_range,
                                      self.v_range,
                                      overflow=self.overflow)
        self.sys_color_set.create(self.hm_rule)

        self.sys_category = 0
        self.sys_channel = 0
Пример #13
0
class Args(object):
    """
    Args object. Manage setting args.
    """
    def __init__(self, resources):
        """
        Init Args object.
        """

        # temporary dir.
        self.global_temp_dir = QTemporaryDir()

        # global args.
        self.global_hm_rules = (
            "analogous",
            "monochromatic",
            "triad",
            "tetrad",
            "pentad",
            "complementary",
            "shades",
            "custom",
        )

        self.global_overflows = (
            "cutoff",
            "return",
            "repeat",
        )

        self.global_log = False

        # load languages.
        all_langs = (
            "en",
            "ar",
            "be",
            "bg",
            "ca",
            "cs",
            "da",
            "de",
            "el",
            "es",
            "et",
            "fi",
            "fr",
            "hr",
            "hu",
            "is",
            "it",
            "iw",
            "ja",
            "ko",
            "lt",
            "lv",
            "mk",
            "nl",
            "no",
            "pl",
            "pt",
            "ro",
            "ru",
            "sh",
            "sk",
            "sl",
            "sq",
            "sr",
            "sv",
            "th",
            "tr",
            "uk",
            "zh",
        )

        lang_paths = [
            (39, "default"),
        ]

        langs_dir = os.sep.join((resources, "langs"))
        if not os.path.isdir(langs_dir):
            os.makedirs(langs_dir)

        for lang in os.listdir(langs_dir):
            if os.path.isfile(os.sep.join(
                (langs_dir, lang))) and lang.split(".")[-1] == "qm":
                glang = re.split("\.|_|-", lang)[0]

                if glang in all_langs:
                    lang_paths.append((all_langs.index(glang), lang))

        self.lang = "default"
        self.usr_langs = tuple(lang_paths)

        # software informations.
        self.info_main_site = "https://liujiacode.github.io/DigitalPalette"
        self.info_update_site = "https://github.com/liujiacode/DigitalPalette/releases"
        self.info_version_zh = "v2.2.7-开发版"
        self.info_version_en = "v2.2.7-dev"
        self.info_author_zh = "本征喵"
        self.info_author_en = "Eigenmiao"
        self.info_date_zh = "2020年4月25日"
        self.info_date_en = "Apr. 25th, 2020"

        # init settings.
        self.usr_store = os.sep.join(
            (os.path.expanduser('~'), "Documents", "DigitalPalette"))
        self.resources = resources

        self.init_settings()

        # init setable but not initable settings.
        self.stab_ucells = tuple()
        self.stab_column = 3

        # load settings.
        if self.store_loc:
            self.load_settings(os.sep.join((self.resources, "settings.json")))

        else:
            self.load_settings(os.sep.join((self.usr_store, "settings.json")))

        # special system settings.
        self.sys_activated_idx = 0
        self.sys_color_set = ColorSet(self.h_range,
                                      self.s_range,
                                      self.v_range,
                                      overflow=self.overflow)
        self.sys_color_set.create(self.hm_rule)

        self.sys_category = 0
        self.sys_channel = 0

    # ---------- ---------- ---------- Public Funcs ---------- ---------- ---------- #

    def init_settings(self):
        """
        Init default settings.
        """

        # load default language.
        self.modify_settings("lang", "default")

        # load local store tag.
        self.press_act = False
        self.store_loc = False

        if os.path.isfile(os.sep.join((self.resources, "settings.json"))):
            try:
                with open(os.sep.join((self.resources, "settings.json")),
                          "r") as sf:
                    uss = json.load(sf)

                    if isinstance(uss, dict) and "store_loc" in uss:
                        self.store_loc = bool(uss["store_loc"])

            except Exception as err:
                pass

        # need verify and mkdirs.
        if self.store_loc:
            self.usr_color = os.sep.join((self.resources, "MyColors"))
            self.usr_image = os.sep.join((self.resources, "samples"))

        else:
            self.usr_color = os.sep.join((os.path.expanduser('~'), "Documents",
                                          "DigitalPalette", "MyColors"))
            self.usr_image = os.sep.join((os.path.expanduser('~'), "Pictures"))

        if not os.path.isdir(self.usr_color):
            os.makedirs(self.usr_color)

        if not os.path.isdir(self.usr_image):
            os.makedirs(self.usr_image)

        self.hm_rule = "analogous"
        self.overflow = "return"
        self.press_move = True
        self.show_rgb = True
        self.show_hsv = True

        self.h_range = (0.0, 360.0)
        self.s_range = (0.4, 1.0)
        self.v_range = (0.6, 1.0)

        self.wheel_ratio = 0.8
        self.volum_ratio = 0.8
        self.cubic_ratio = 0.9
        self.coset_ratio = 0.8

        self.s_tag_radius = 0.09
        self.v_tag_radius = 0.09

        self.rev_direct = True

        self.zoom_step = 1.1
        self.move_step = 5

        self.rand_num = 10000
        self.circle_dist = 12

        self.positive_wid = 3
        self.negative_wid = 2
        self.wheel_ed_wid = 2

        self.positive_color = (80, 80, 80)
        self.negative_color = (245, 245, 245)
        self.wheel_ed_color = (200, 200, 200)

    def save_settings(self):
        """
        Save settings to file.
        """

        # saving args.
        settings = {
            "version": self.info_version_en,
            "site": self.info_main_site,
            "date": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
        }

        items = (
            "usr_color",
            "usr_image",
            "press_act",
            "store_loc",
            "hm_rule",
            "overflow",
            "lang",
            "press_move",
            "show_rgb",
            "show_hsv",
            "h_range",
            "s_range",
            "v_range",
            "wheel_ratio",
            "volum_ratio",
            "cubic_ratio",
            "coset_ratio",
            "rev_direct",
            "s_tag_radius",
            "v_tag_radius",
            "zoom_step",
            "move_step",
            "rand_num",
            "circle_dist",
            "positive_wid",
            "negative_wid",
            "wheel_ed_wid",
            "positive_color",
            "negative_color",
            "wheel_ed_color",
            "stab_column",
        )

        for item in items:
            value = getattr(self, item)
            if isinstance(value, (tuple, list)):
                settings[item] = list(value)

            else:
                settings[item] = value

        # saving color depot.
        stab_ucells = []

        for unit_cell in self.stab_ucells[:-1]:
            if unit_cell != None:
                hsv_set = [
                    unit_cell.color_set[0].hsv.tolist(),
                    unit_cell.color_set[1].hsv.tolist(),
                    unit_cell.color_set[2].hsv.tolist(),
                    unit_cell.color_set[3].hsv.tolist(),
                    unit_cell.color_set[4].hsv.tolist(),
                ]

                stab_ucells.append([
                    hsv_set,
                    str(unit_cell.hm_rule),
                    str(unit_cell.name),
                    str(unit_cell.desc),
                    list(unit_cell.cr_time)
                ])

        settings["stab_ucells"] = stab_ucells

        # storing.
        if self.store_loc:
            try:
                with open(os.sep.join((self.resources, "settings.json")),
                          "w") as sf:
                    json.dump(settings, sf, indent=4)

            except Exception as err:
                if self.global_log:
                    print(err)

                self.store_loc = False

        if not self.store_loc:
            try:
                with open(os.sep.join((self.usr_store, "settings.json")),
                          "w") as sf:
                    json.dump(settings, sf, indent=4)

                with open(os.sep.join((self.resources, "settings.json")),
                          "w") as sf:
                    json.dump({"store_loc": False}, sf, indent=4)

            except Exception as err:
                if self.global_log:
                    print(err)

    def modify_settings(self, item, value):
        items = {
            "usr_color":
            lambda vl: self.pfmt_path(vl, self.usr_color),
            "usr_image":
            lambda vl: self.pfmt_path(vl, self.usr_image),
            "press_act":
            lambda vl: self.pfmt_value(vl, bool, self.press_act),
            "store_loc":
            lambda vl: self.pfmt_value(vl, bool, self.store_loc),
            "hm_rule":
            lambda vl: self.pfmt_str_in_list(vl, self.global_hm_rules, self.
                                             hm_rule),
            "overflow":
            lambda vl: self.pfmt_str_in_list(vl, self.global_overflows, self.
                                             overflow),
            "lang":
            lambda vl: self.pfmt_str_in_list(
                vl, [x[1] for x in self.usr_langs], self.lang),
            "press_move":
            lambda vl: self.pfmt_value(vl, bool, self.press_move),
            "show_rgb":
            lambda vl: self.pfmt_value(vl, bool, self.show_rgb),
            "show_hsv":
            lambda vl: self.pfmt_value(vl, bool, self.show_hsv),
            "h_range":
            lambda vl: self.pfmt_num_pair_in_scope(vl, (0.0, 360.0), float,
                                                   self.h_range),
            "s_range":
            lambda vl: self.pfmt_num_pair_in_scope(vl, (0.0, 1.0), float, self.
                                                   s_range),
            "v_range":
            lambda vl: self.pfmt_num_pair_in_scope(vl, (0.0, 1.0), float, self.
                                                   v_range),
            "wheel_ratio":
            lambda vl: self.pfmt_num_in_scope(vl, (0.0, 1.0), float, self.
                                              wheel_ratio),
            "volum_ratio":
            lambda vl: self.pfmt_num_in_scope(vl, (0.0, 1.0), float, self.
                                              volum_ratio),
            "cubic_ratio":
            lambda vl: self.pfmt_num_in_scope(vl, (0.0, 1.0), float, self.
                                              cubic_ratio),
            "coset_ratio":
            lambda vl: self.pfmt_num_in_scope(vl, (0.0, 1.0), float, self.
                                              coset_ratio),
            "rev_direct":
            lambda vl: self.pfmt_value(vl, bool, self.rev_direct),
            "s_tag_radius":
            lambda vl: self.pfmt_num_in_scope(vl, (0.0, 0.2), float, self.
                                              s_tag_radius),
            "v_tag_radius":
            lambda vl: self.pfmt_num_in_scope(vl, (0.0, 0.2), float, self.
                                              v_tag_radius),
            "zoom_step":
            lambda vl: self.pfmt_num_in_scope(vl, (1.0, 10.0), float, self.
                                              zoom_step),
            "move_step":
            lambda vl: self.pfmt_num_in_scope(vl,
                                              (1, 100), int, self.move_step),
            "rand_num":
            lambda vl: self.pfmt_num_in_scope(vl, (0, 1000000000), int, self.
                                              rand_num),
            "circle_dist":
            lambda vl: self.pfmt_num_in_scope(vl,
                                              (0, 50), int, self.circle_dist),
            "positive_wid":
            lambda vl: self.pfmt_num_in_scope(vl,
                                              (0, 20), int, self.positive_wid),
            "negative_wid":
            lambda vl: self.pfmt_num_in_scope(vl,
                                              (0, 20), int, self.negative_wid),
            "wheel_ed_wid":
            lambda vl: self.pfmt_num_in_scope(vl,
                                              (0, 20), int, self.wheel_ed_wid),
            "positive_color":
            lambda vl: self.pfmt_rgb_color(vl, self.positive_color),
            "negative_color":
            lambda vl: self.pfmt_rgb_color(vl, self.negative_color),
            "wheel_ed_color":
            lambda vl: self.pfmt_rgb_color(vl, self.wheel_ed_color),
            "stab_column":
            lambda vl: self.pfmt_num_in_scope(vl,
                                              (1, 12), int, self.stab_column),
            "stab_ucells":
            lambda vl: self.pfmt_stab_ucells(vl),
        }

        if item in items:
            setattr(self, item, items[item](value))

    def load_settings(self, settings_file):
        """
        Modify default settings by user settings.

        Parameters:
          uss - dict. user settings.
        """

        uss = {}
        if os.path.isfile(settings_file):
            try:
                with open(settings_file, "r") as sf:
                    uss = json.load(sf)

            except Exception as err:
                pass

        if isinstance(uss, dict):
            if "version" in uss:
                if not self.check_version(uss["version"]):
                    uss = {}

            else:
                uss = {}

        else:
            uss = {}

        for item in uss:
            self.modify_settings(item, uss[item])

    # ---------- ---------- ---------- Classmethods ---------- ---------- ---------- #

    def pfmt_path(self, value, default):
        """
        Parse directory path.
        """

        try:
            ans = str(value)

            if os.path.isdir(ans):
                return ans

        except Exception as err:
            if self.global_log:
                print(err)

        return default

    def pfmt_num_pair_in_scope(self, value, scope, dtype, default):
        """
        Parse number pair in scope.
        """

        try:
            ans = (dtype(value[0]), dtype(value[1]))

            if scope[0] <= ans[0] <= scope[1] and scope[0] <= ans[1] <= scope[
                    1] and ans[0] <= ans[1]:
                return ans

        except Exception as err:
            if self.global_log:
                print(err)

        return default

    def pfmt_str_in_list(self, value, lst, default):
        """
        Parse string in list.
        """

        try:
            ans = str(value)

            if ans in lst:
                return ans

        except Exception as err:
            if self.global_log:
                print(err)

        return default

    def pfmt_num_in_scope(self, value, scope, dtype, default):
        """
        Parse number in scope.
        """

        try:
            ans = dtype(value)

            if scope[0] <= ans <= scope[1]:
                return ans

        except Exception as err:
            if self.global_log:
                print(err)

        return default

    def pfmt_value(self, value, dtype, default):
        """
        Parse value in designed dtype.
        """

        try:
            ans = dtype(value)

            return ans

        except Exception as err:
            if self.global_log:
                print(err)

        return default

    def pfmt_rgb_color(self, value, default):
        """
        Parse value in designed color.
        """

        try:
            ans = (int(value[0]), int(value[1]), int(value[2]))

            if 0 <= ans[0] <= 255 and 0 <= ans[2] <= 255 and 0 <= ans[2] <= 255:
                return ans

        except Exception as err:
            if self.global_log:
                print(err)

        return default

    def pfmt_stab_ucells(self, value):
        """
        Parse value in designed color.
        """

        stab_ucells = []

        try:
            for cslst in value:
                colors = []

                for color in cslst[0]:
                    ans = (float(color[0]), float(color[1]), float(color[2]))

                    if 0.0 <= ans[0] <= 360.0 and 0.0 <= ans[
                            2] <= 1.0 and 0.0 <= ans[2] <= 1.0:
                        colors.append(ans)

                    else:
                        break

                hm_rule = str(cslst[1])

                if hm_rule not in self.global_hm_rules:
                    hm_rule = ""

                if len(colors) == 5 and hm_rule:
                    cr_name = "" if len(cslst) < 3 else str(cslst[2])
                    cr_desc = "" if len(cslst) < 4 else str(cslst[3])
                    cr_time = (-1.0, -1.0) if len(cslst) < 5 else (float(
                        cslst[4][0]), float(cslst[4][1]))
                    stab_ucells.append(
                        (tuple(colors), hm_rule, cr_name, cr_desc, cr_time))

        except Exception as err:
            if self.global_log:
                print(err)

        return stab_ucells

    def check_version(self, version):
        """
        Check if version is compatible.
        """

        try:
            for vre in (r"^v2\.[12].*", ):
                if re.match(vre, version):
                    return True

        except Exception as err:
            if self.global_log:
                print(err)

        return False

    def check_temp_dir(self):
        """
        Check if temporary directory valid.
        """

        return self.global_temp_dir.isValid() and os.path.isdir(
            self.global_temp_dir.path())

    def remove_temp_dir(self):
        """
        Remove temporary directory.
        """

        temp_dir = self.global_temp_dir.path()
        self.global_temp_dir.remove()

        if os.path.isdir(temp_dir):
            try:
                for doc in os.listdir(temp_dir):
                    os.remove(os.sep.join((temp_dir, doc)))

                os.rmdir(temp_dir)

            except Exception as err:
                if self.global_log:
                    print(err)
Пример #14
0
class _MainContainer(QWidget):

    ###############################################################################
    # MainContainer SIGNALS
    ###############################################################################
    """
    newFileOpened(QString)
    allTabClosed()
    runFile(QString)
    addToProject(QString)
    showFileInExplorer(QString)
    recentTabsModified()
    currentEditorChanged(QString)
    fileOpened(QString)
    ---------migrationAnalyzed()
    findOcurrences(QString)
    ---------updateFileMetadata()
    editorKeyPressEvent(QEvent)
    locateFunction(QString, QString, bool) [functionName, filePath, isVariable]
    updateLocator(QString)
    beforeFileSaved(QString)
    fileSaved(QString)
    openPreferences()
    --------openProject(QString)
    ---------dontOpenStartPage()
    """
    newFileOpened = pyqtSignal(str)
    allTabClosed = pyqtSignal()
    runFile = pyqtSignal(str)
    addToProject = pyqtSignal(str)
    showFileInExplorer = pyqtSignal(str)
    recentTabsModified = pyqtSignal()
    currentEditorChanged = pyqtSignal(str)
    fileOpened = pyqtSignal(str)
    migrationAnalyzed = pyqtSignal()  #-----------
    findOcurrences = pyqtSignal(str)
    updateFileMetadata = pyqtSignal()  #-----------
    editorKeyPressEvent = pyqtSignal('QEvent*')
    locateFunction = pyqtSignal(str, str, bool)
    updateLocator = pyqtSignal(str)
    beforeFileSaved = pyqtSignal(str)
    fileSaved = pyqtSignal(str)
    openPreferences = pyqtSignal()
    openProject = pyqtSignal(str)  #-----------
    dontOpenStartPage = pyqtSignal()  #-----------
    closeDialog = pyqtSignal('QObject*')
    allTabsClosed = pyqtSignal()
    splitEditor = pyqtSignal('QWidget*', 'QWidget*', bool)
    closeSplit = pyqtSignal(QWidget)
    toRemovePreview = pyqtSignal()

    ###############################################################################

    def __init__(self, parent=None):
        super(_MainContainer, self).__init__(parent)
        self._parent = parent
        self._vbox = QVBoxLayout(self)
        self._vbox.setContentsMargins(0, 0, 0, 0)
        self._vbox.setSpacing(0)
        self.stack = QStackedLayout()
        self.stack.setStackingMode(QStackedLayout.StackAll)
        self._vbox.addLayout(self.stack)

        self.splitter = dynamic_splitter.DynamicSplitter()
        self.setAcceptDrops(True)
        # self._files_handler = files_handler.FilesHandler(self)
        self._add_file_folder = add_file_folder.AddFileFolderWidget(self)

        self.tdir = None

        #documentation browser
        self.docPage = None
        #Code Navigation
        self._locator = locator.GoToDefinition()
        self.__codeBack = []
        self.__codeForward = []
        self.__bookmarksFile = ''
        self.__bookmarksPos = -1
        self.__breakpointsFile = ''
        self.__breakpointsPos = -1
        self.__operations = {
            0: self._navigate_code_jumps,
            1: self._navigate_bookmarks,
            2: self._navigate_breakpoints
        }

        self.locateFunction.connect(self.locate_function)

        IDE.register_service('main_container', self)

        #Register signals connections
        connections = (
            {
                'target': 'menu_file',
                'signal_name': 'openFile',  #(QString)
                'slot': self.open_file
            },
            {
                'target': 'explorer_container',
                'signal_name': 'goToDefinition',  #(int)
                'slot': self.editor_go_to_line
            },
            {
                'target': 'explorer_container',
                'signal_name': 'pep8Activated',  #(bool)
                'slot': self.reset_pep8_warnings
            },
            {
                'target': 'explorer_container',
                'signal_name': 'lintActivated',  #(bool)
                'slot': self.reset_lint_warnings
            },
        )

        IDE.register_signals('main_container', connections)

        self.selector = main_selector.MainSelector(self)
        self._opening_dialog = False
        self.add_widget(self.selector)

        if settings.SHOW_START_PAGE:
            self.show_start_page()

        self.selector.changeCurrent[int].connect(self._change_current_stack)
        self.selector.removeWidget[int].connect(self._remove_item_from_stack)
        self.selector.ready.connect(self._selector_ready)
        self.selector.closePreviewer.connect(self._selector_Close)
        self.selector.animationCompleted.connect(
            self._selector_animation_completed)

        self.closeDialog.connect(self.remove_widget)
        self.stack.widgetRemoved[int].connect(
            lambda i: print("widgetRemoved._-", i))

    def install(self):
        ide = IDE.getInstance()
        ide.place_me_on("main_container", self, "central", top=True)

        self.combo_area = combo_editor.ComboEditor(original=True)
        self.combo_area.allFilesClosed.connect(self._files_closed)
        self.splitter.add_widget(self.combo_area)
        self.add_widget(self.splitter)

        self.current_widget = self.combo_area

        ui_tools.install_shortcuts(self, actions.ACTIONS, ide)

    def add_status_bar(self, status):
        self._vbox.addWidget(status)

    @property
    def combo_header_size(self):
        return self.combo_area.bar.height()

    def add_widget(self, widget):
        i = self.stack.addWidget(widget)
        #if not isinstance(widget, start_page.StartPage):
        self.tryMakeImagePreview(i)

    def remove_widget(self, widget):
        #self.toRemovePreview.emit(self.stack.widget(widget))
        self.stack.removeWidget(widget)

    def _close_dialog(self, widget):
        self.closeDialog.emit(widget)
        widget.finished[int].disconnect(
        )  #lambda i: self._close_dialog(widget))

    def show_dialog(self, widget):
        print("\n\nshow_dialog", self.isVisible())
        self._opening_dialog = True
        widget.finished[int].connect(lambda i: self._close_dialog(widget))
        widget.setVisible(True)
        self.show_selector()

    def show_selector(self):
        print("\n\nshow_selector::", self.selector, self.stack.currentWidget())
        if self.selector != self.stack.currentWidget():
            _dir = self.Successful_Tmp()
            if not _dir:
                print("failed!")
                return

            # temp_dir = os.path.join(QDir.tempPath(), "ninja-ide")
            # if not os.path.exists(temp_dir):
            #     os.mkdir(temp_dir)
            collected_data = []
            current = self.stack.currentIndex()
            for index in range(self.stack.count()):
                widget = self.stack.widget(index)
                if widget == self.selector:
                    continue
                closable = True
                if widget == self.splitter:
                    closable = False
                # path = os.path.join(temp_dir, "screen%s.png" % index)
                #ff = QFile(_dir, "screen%s.png" % index)
                path = _dir.absolutePath() + "/screen%s.png" % index
                pixmap = widget.grab()  #widget.rect())
                pixmap.save(path)
                #path = path.replace("\\", '/')
                #print("path::", path, QFileInfo(path).exists())
                path = "file:///" + path
                if index == current:
                    self.selector.set_preview(index, path)  #QUrl(path)
                    collected_data.insert(0, (index, path, closable))
                else:
                    collected_data.append((index, path, closable))
            self.selector.set_model(collected_data)
            print("self.selector.set_model()", collected_data)
            self.stack.setCurrentWidget(self.selector)
        else:
            print("\n\n_selector_Close()")
            self._selector_Close()

    def Successful_Tmp(self):  # CheckTmpDir, StateTmpDir
        failed = lambda: not self.tdir or not self.tdir.isValid()
        if failed():  # not successfully
            self.tdir = QTemporaryDir()
            if failed():
                QMessageBox.critical(
                    self, "Unexpected Failurer",
                    "The application has detected a problem trying to\nCreate or Access a Temporary File!."
                )
                return None
            else:
                self.tdir.setAutoRemove(True)

        d = QDir(self.tdir.path())
        if not d.exists("ninja-ide"):
            if not d.mkdir("ninja-ide"):
                self.tdir = None
        d.cd("ninja-ide")
        return d

    def tryMakeImagePreview(self, index):
        return
        d = self.Successful_Tmp()
        if d:
            self.makeImagePreview(d, index)

    def makeImagePreview(self, _dir, index):
        return
        path = _dir.absolutePath() + "/screen%s.png" % index
        widget = self.stack.widget(index)
        pixmap = widget.grab()  #widget.rect()
        pixmap.save(path)

    def _selector_ready(self):
        self.stack.setCurrentWidget(self.selector)
        self.selector.GoTo_GridPreviews()

    def _selector_Close(self):
        self.stack.setCurrentWidget(self.splitter)

    def _selector_animation_completed(self):
        if self._opening_dialog:
            # We choose the last one with -2, -1 (for last one) +
            # -1 for the hidden selector widget which is in the stacked too.
            self.selector.open_item(self.stack.count() - 2)
        self._opening_dialog = False

    def _change_current_stack(self, index):
        self.stack.setCurrentIndex(index)

    def _remove_item_from_stack(self, index):
        #self.toRemovePreview.emit(index)
        widget = self.stack.takeAt(index)
        del widget

    def show_editor_area(self):
        self.stack.setCurrentWidget(self.splitter)

    def _files_closed(self):
        if settings.SHOW_START_PAGE:
            self.show_start_page()

    def change_visibility(self):
        """Show/Hide the Main Container area."""
        print("change_visibility11")
        if self.isVisible():
            self.hide()
        else:
            self.show()

    def expand_symbol_combo(self):
        self.stack.setCurrentWidget(self.splitter)
        self.current_widget.show_combo_symbol()

    def expand_file_combo(self):
        print("expand_file_combo")
        self.stack.setCurrentWidget(self.splitter)
        self.current_widget.show_combo_file()

    def locate_function(self, function, filePath, isVariable):
        """Move the cursor to the proper position in the navigate stack."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            self.__codeBack.append(
                (editorWidget.file_path, editorWidget.getCursorPosition()))
            self.__codeForward = []
        self._locator.navigate_to(function, filePath, isVariable)

    def run_file(self, path):
        self.runFile.emit(path)

    def _add_to_project(self, path):
        self.addToProject.emit(path)

    def _show_file_in_explorer(self, path):
        self.showFileInExplorer.emit(path)

    def paste_history(self):
        """Paste the text from the copy/paste history."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            line, index = editorWidget.getCursorPosition()
            central = IDE.get_service('central_container')
            if central:
                editorWidget.insertAt(central.get_paste(), line, index)

    def copy_history(self):
        """Copy the selected text into the copy/paste history."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            copy = editorWidget.selectedText()
            central = IDE.get_service('central_container')
            if central:
                central.add_copy(copy)

    def import_from_everywhere(self):
        """Insert an import line from any place in the editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            dialog = from_import_dialog.FromImportDialog(editorWidget, self)
            dialog.show()

    def add_back_item_navigation(self):
        """Add an item to the back stack and reset the forward stack."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            self.__codeBack.append(
                (editorWidget.file_path, editorWidget.getCursorPosition()))
            self.__codeForward = []

    def preview_in_browser(self):
        """Load the current html file in the default browser."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            if not editorWidget.file_path:
                self.save_file()
            ext = file_manager.get_file_extension(editorWidget.file_path)
            if ext in ('html', 'shpaml', 'handlebars', 'tpl'):
                webbrowser.open_new_tab(editorWidget.file_path)

    def add_bookmark_breakpoint(self):
        """Add a bookmark or breakpoint to the current file in the editor."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            if self.current_widget.bar.code_navigator.operation == 1:
                editorWidget.handle_bookmarks_breakpoints(
                    editorWidget.getCursorPosition()[0], Qt.ControlModifier)
            elif self.current_widget.bar.code_navigator.operation == 2:
                editorWidget.handle_bookmarks_breakpoints(
                    editorWidget.getCursorPosition()[0], Qt.NoModifier)

    def __navigate_with_keyboard(self, val):
        """Navigate between the positions in the jump history stack."""
        op = self.current_widget.bar.code_navigator.operation
        self.navigate_code_history(val, op)

    def navigate_code_history(self, val, op):
        """Navigate the code history."""
        self.__operations[op](val)

    def _navigate_code_jumps(self, val):
        """Navigate between the jump points."""
        node = None
        if not val and self.__codeBack:
            node = self.__codeBack.pop()
            editorWidget = self.get_current_editor()
            if editorWidget:
                self.__codeForward.append(
                    (editorWidget.file_path, editorWidget.getCursorPosition()))
        elif val and self.__codeForward:
            node = self.__codeForward.pop()
            editorWidget = self.get_current_editor()
            if editorWidget:
                self.__codeBack.append(
                    (editorWidget.file_path, editorWidget.getCursorPosition()))
        if node:
            filename = node[0]
            line, col = node[1]
            self.open_file(filename, line, col)

    def _navigate_breakpoints(self, val):
        """Navigate between the breakpoints."""
        #FIXME: put navigate breakpoints and bookmarks as one method.
        breakList = list(settings.BREAKPOINTS.keys())
        breakList.sort()
        if not breakList:
            return
        if self.__breakpointsFile not in breakList:
            self.__breakpointsFile = breakList[0]
        index = breakList.index(self.__breakpointsFile)
        breaks = settings.BREAKPOINTS.get(self.__breakpointsFile, [])
        lineNumber = 0
        #val == True: forward
        if val:
            if (len(breaks) - 1) > self.__breakpointsPos:
                self.__breakpointsPos += 1
                lineNumber = breaks[self.__breakpointsPos]
            elif len(breaks) > 0:
                if index < (len(breakList) - 1):
                    self.__breakpointsFile = breakList[index + 1]
                else:
                    self.__breakpointsFile = breakList[0]
                self.__breakpointsPos = 0
                lineNumber = settings.BREAKPOINTS[self.__breakpointsFile][0]
        else:
            if self.__breakpointsPos > 0:
                self.__breakpointsPos -= 1
                lineNumber = breaks[self.__breakpointsPos]
            elif len(breaks) > 0:
                self.__breakpointsFile = breakList[index - 1]
                breaks = settings.BREAKPOINTS[self.__breakpointsFile]
                self.__breakpointsPos = len(breaks) - 1
                lineNumber = breaks[self.__breakpointsPos]
        if file_manager.file_exists(self.__breakpointsFile):
            self.open_file(self.__breakpointsFile, lineNumber, None, True)
        else:
            settings.BREAKPOINTS.pop(self.__breakpointsFile)
            if settings.BREAKPOINTS:
                self._navigate_breakpoints(val)

    def _navigate_bookmarks(self, val):
        """Navigate between the bookmarks."""
        bookList = list(settings.BOOKMARKS.keys())
        bookList.sort()
        if not bookList:
            return
        if self.__bookmarksFile not in bookList:
            self.__bookmarksFile = bookList[0]
        index = bookList.index(self.__bookmarksFile)
        bookms = settings.BOOKMARKS.get(self.__bookmarksFile, [])
        lineNumber = 0
        #val == True: forward
        if val:
            if (len(bookms) - 1) > self.__bookmarksPos:
                self.__bookmarksPos += 1
                lineNumber = bookms[self.__bookmarksPos]
            elif len(bookms) > 0:
                if index < (len(bookList) - 1):
                    self.__bookmarksFile = bookList[index + 1]
                else:
                    self.__bookmarksFile = bookList[0]
                self.__bookmarksPos = 0
                lineNumber = settings.BOOKMARKS[self.__bookmarksFile][0]
        else:
            if self.__bookmarksPos > 0:
                self.__bookmarksPos -= 1
                lineNumber = bookms[self.__bookmarksPos]
            elif len(bookms) > 0:
                self.__bookmarksFile = bookList[index - 1]
                bookms = settings.BOOKMARKS[self.__bookmarksFile]
                self.__bookmarksPos = len(bookms) - 1
                lineNumber = bookms[self.__bookmarksPos]
        if file_manager.file_exists(self.__bookmarksFile):
            self.open_file(self.__bookmarksFile, lineNumber, None, True)
        else:
            settings.BOOKMARKS.pop(self.__bookmarksFile)
            if settings.BOOKMARKS:
                self._navigate_bookmarks(val)

    def count_file_code_lines(self):
        """Count the lines of code in the current file."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            block_count = editorWidget.lines()
            blanks = re.findall('(^\n)|(^(\s+)?#)|(^( +)?($|\n))',
                                editorWidget.text(), re.M)
            blanks_count = len(blanks)
            resume = self.tr("Lines code: %s\n") % (block_count - blanks_count)
            resume += (self.tr("Blanks and commented lines: %s\n\n") %
                       blanks_count)
            resume += self.tr("Total lines: %s") % block_count
            msgBox = QMessageBox(QMessageBox.Information,
                                 self.tr("Summary of lines"), resume,
                                 QMessageBox.Ok, editorWidget)
            msgBox.exec_()

    def editor_cut(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.cut()

    def editor_copy(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.copy()

    def editor_paste(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.paste()

    def editor_upper(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.to_upper()

    def editor_lower(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.to_lower()

    def editor_title(self):
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.to_title()

    def editor_go_to_definition(self):
        """Search the definition of the method or variable under the cursor.

        If more than one method or variable is found with the same name,
        shows a table with the results and let the user decide where to go."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.go_to_definition()

    def editor_redo(self):
        """Execute the redo action in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.redo()

    def editor_undo(self):
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.undo()

    def editor_indent_less(self):
        """Indent 1 position to the left for the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.indent_less()

    def editor_indent_more(self):
        """Indent 1 position to the right for the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.indent_more()

    def editor_insert_debugging_prints(self):
        """Insert a print statement in each selected line."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.insert_debugging_prints(editorWidget)

    def editor_insert_pdb(self):
        """Insert a pdb.set_trace() statement in tjhe current line."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.insert_pdb(editorWidget)

    def editor_comment(self):
        """Mark the current line or selection as a comment."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.comment(editorWidget)

    def editor_uncomment(self):
        """Uncomment the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.uncomment(editorWidget)

    def editor_insert_horizontal_line(self):
        """Insert an horizontal lines of comment symbols."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.insert_horizontal_line(editorWidget)

    def editor_insert_title_comment(self):
        """Insert a Title surrounded by comment symbols."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.insert_title_comment(editorWidget)

    def editor_remove_trailing_spaces(self):
        """Remove the trailing spaces in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.remove_trailing_spaces(editorWidget)

    def editor_replace_tabs_with_spaces(self):
        """Replace the Tabs with Spaces in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            helpers.replace_tabs_with_spaces(editorWidget)

    def editor_move_up(self):
        """Move the current line or selection one position up."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.move_up(editorWidget)

    def editor_move_down(self):
        """Move the current line or selection one position down."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.move_down(editorWidget)

    def editor_remove_line(self):
        """Remove the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.remove_line(editorWidget)

    def editor_duplicate(self):
        """Duplicate the current line or selection."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            helpers.duplicate(editorWidget)

    def editor_highlight_word(self):
        """Highlight the occurrences of the current word in the editor."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.highlight_selected_word()

    def editor_complete_declaration(self):
        """Do the opposite action that Complete Declaration expect."""
        editorWidget = self.get_current_editor()
        if editorWidget and editorWidget.hasFocus():
            editorWidget.complete_declaration()

    def editor_go_to_line(self,
                          line,
                          select=False):  #def editor_go_to_line(self, line):
        """Jump to the specified line in the current editor."""
        editorWidget = self.get_current_editor()
        print("\nluego en segundo lugar por aca")
        if editorWidget:
            editorWidget.jump_to_line(line)  #select

    def editor_go_to_symbol_line(self, line, sym="", select=False):
        """Jump to the specified line in the current editor."""
        editorWidget = self.get_current_editor()
        print("\nluego en segundo lugar por aca")
        if editorWidget:
            editorWidget.go_to_symbol(line, sym, select)  #select

    def zoom_in_editor(self):
        """Increase the font size in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.zoom_in()

    def zoom_out_editor(self):
        """Decrease the font size in the current editor."""
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.zoom_out()

    def recent_files_changed(self):
        self.recentTabsModified.emit()

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        # file_path = event.mimeData().urls()[0].toLocalFile()
        # paths = [item.toLocalFile() for item in event.mimeData().urls()]
        self.open_files_fromUrlList(event.mimeData().urls())
        # print("\n\n dropEvent", paths)
        # self.open_file(file_path)

    def setFocus(self):
        widget = self.get_current_widget()
        if widget:
            widget.setFocus()

    def current_editor_changed(self, filename):
        """Notify the new filename of the current editor."""
        if filename is None:
            filename = translations.TR_NEW_DOCUMENT
        self.currentEditorChanged.emit(filename)

    def show_split(self, orientation_vertical=False):
        #IDE.select_current(self.current_widget.currentWidget())
        self.current_widget.split_editor(orientation_vertical)

    def add_editor(self, fileName=None, ignore_checkers=False):
        print("filename::", fileName)
        ninjaide = IDE.getInstance()
        editable = ninjaide.get_or_create_editable(fileName)
        if editable.editor:
            self.current_widget.set_current(editable)
            print("\n\nreturn")
            return self.current_widget.currentWidget()
        else:
            editable.ignore_checkers = ignore_checkers

        editorWidget = self.create_editor_from_editable(editable)

        #add the tab
        keep_index = (self.splitter.count() > 1
                      and self.combo_area.stacked.count() > 0)
        self.combo_area.add_editor(editable, keep_index)

        #emit a signal about the file open
        self.fileOpened.emit(fileName)
        if keep_index:
            self.current_widget.set_current(editable)

        self.stack.setCurrentWidget(self.splitter)
        return editorWidget

    def create_editor_from_editable(self, editable):
        editorWidget = editor.create_editor(editable)

        #Connect signals
        editable.fileSaved.connect(self._editor_tab_was_saved)
        editorWidget.openDropFile.connect(self.open_file)
        editorWidget.addBackItemNavigation.connect(
            self.add_back_item_navigation)
        editorWidget.locateFunction.connect(self._editor_locate_function)
        editorWidget.findOcurrences.connect(self._find_occurrences)
        #keyPressEventSignal for plugins
        editorWidget.keyPressSignal.connect(self._editor_keyPressEvent)

        return editorWidget

    def reset_pep8_warnings(self, value):
        pass
        #FIXME: check how we handle this
        #for i in range(self._tabMain.count()):
        #widget = self._tabMain.widget(i)
        #if type(widget) is editor.Editor:
        #if value:
        #widget.syncDocErrorsSignal = True
        #widget.pep8.check_style()
        #else:
        #widget.hide_pep8_errors()

    def reset_lint_warnings(self, value):
        pass
        #FIXME: check how we handle this
        #for i in range(self._tabMain.count()):
        #widget = self._tabMain.widget(i)
        #if type(widget) is editor.Editor:
        #if value:
        #widget.syncDocErrorsSignal = True
        #widget.errors.check_errors()
        #else:
        #widget.hide_lint_errors()

    def _find_occurrences(self, word):
        self.findOcurrences.emit(word)

    def _editor_keyPressEvent(self, event):
        self.editorKeyPressEvent.emit(event)

    def _editor_locate_function(self, function, filePath, isVariable):
        self.locateFunction.emit(function, filePath, isVariable)

    def _editor_tab_was_saved(self, editable=None):
        self.updateLocator.emit(editable.file_path)

    def get_current_widget(self):
        return self.current_widget.currentWidget()

    def get_current_editor(self):
        """Return the Actual Editor or None

        Return an instance of Editor if the Current Tab contains
        an Editor or None if it is not an instance of Editor"""
        widget = self.current_widget.currentWidget()
        if isinstance(widget, editor.Editor):
            return widget
        return None

    def reload_file(self, editorWidget=None):
        if editorWidget is None:
            editorWidget = self.get_current_editor()
            if editorWidget is not None:
                editorWidget.neditable.reload_file()

    def add_tab(self, widget, tabName, tabIndex=None):
        pass
        #return self.tabs.add_tab(widget, tabName, index=tabIndex)

    def open_image(self, fileName):
        try:
            if not self.is_open(fileName):
                viewer = image_viewer.ImageViewer(fileName)
                self.add_tab(viewer, file_manager.get_basename(fileName))
                viewer.ID = fileName
            else:
                self.move_to_open(fileName)
        except Exception as reason:
            logger.error('open_image: %s', reason)
            QMessageBox.information(self, self.tr("Incorrect File"),
                                    self.tr("The image couldn\'t be open"))

    def open_files_fromList(self, lst):
        for f in lst:
            self.open_file(f)

    def open_files_fromUrlList(self, lst):
        for f in lst:
            self.open_file(f.toLocalFile())

    def open_file(self, filename='', line=-1, col=0, ignore_checkers=False):
        logger.debug("will try to open %s" % filename)
        if not filename:
            logger.debug("has nofilename")
            if settings.WORKSPACE:
                directory = settings.WORKSPACE
            else:
                directory = os.path.expanduser("~")
                editorWidget = self.get_current_editor()
                ninjaide = IDE.getInstance()
                if ninjaide:
                    current_project = ninjaide.get_current_project()
                    if current_project is not None:
                        directory = current_project
                    elif editorWidget is not None and editorWidget.file_path:
                        directory = file_manager.get_folder(
                            editorWidget.file_path)
            extensions = ';;'.join([
                '{}(*{})'.format(e.upper()[1:], e)
                for e in settings.SUPPORTED_EXTENSIONS + ['.*', '']
            ])
            fileNames = QFileDialog.getOpenFileNames(self,
                                                     self.tr("Open File"),
                                                     directory,
                                                     extensions)[0]  #list()
        else:
            logger.debug("has filename")
            fileNames = [filename]
        if not fileNames:
            return

        print("\n\nopen_file")
        othersFileNames = []
        image_extensions = ('bmp', 'gif', 'jpeg', 'jpg', 'png')
        for filename in fileNames:
            print("nombre", filename)
            if QFileInfo(filename).isDir():
                othersFileNames.extend(
                    QFileDialog.getOpenFileNames(None, "Select files",
                                                 filename, "Files (*.*)")[0])
            elif file_manager.get_file_extension(filename) in image_extensions:
                logger.debug("will open as image")
                self.open_image(filename)
            elif file_manager.get_file_extension(filename).endswith('ui'):
                logger.debug("will load in ui editor")
                self.w = uic.loadUi(filename)
                self.w.show()
            else:
                logger.debug("will try to open: " + filename)
                self.__open_file(filename, line, col, ignore_checkers)

        for filename in othersFileNames:
            print("nombre", filename)
            if QFileInfo(filename).isDir():
                continue
            elif file_manager.get_file_extension(filename) in image_extensions:
                logger.debug("will open as image")
                self.open_image(filename)
            elif file_manager.get_file_extension(filename).endswith('ui'):
                logger.debug("will load in ui editor")
                self.w = uic.loadUi(filename)
                self.w.show()
            else:
                logger.debug("will try to open: " + filename)
                self.__open_file(filename, line, col, ignore_checkers)

    def __open_file(self, fileName='', line=-1, col=0, ignore_checkers=False):
        print("unio", fileName)
        try:
            editorWidget = self.add_editor(fileName,
                                           ignore_checkers=ignore_checkers)
            if line != -1:
                editorWidget.set_cursor_position(line, col)
            self.currentEditorChanged.emit(fileName)
        except file_manager.NinjaIOException as reason:
            QMessageBox.information(self, self.tr("The file couldn't be open"),
                                    str(reason))

    def is_open(self, filename):
        pass
        #return self.tabs.is_open(filename) != -1

    def move_to_open(self, filename):
        pass
        #FIXME: add in the current split?
        #if self.tabs.is_open(filename) != -1:
        #self.tabs.move_to_open(filename)
        #self.tabs.currentWidget().setFocus()
        #self.emit(SIGNAL("currentEditorChanged(QString)"), filename)

    def get_widget_for_id(self, filename):
        pass
        #widget = None
        #index = self.tabs.is_open(filename)
        #if index != -1:
        #widget = self.tabs.widget(index)
        #return widget

    def change_open_tab_id(self, idname, newId):
        """Search for the Tab with idname, and set the newId to that Tab."""
        pass
        #index = self.tabs.is_open(idname)
        #if index != -1:
        #widget = self.tabs.widget(index)
        #tabName = file_manager.get_basename(newId)
        #self.tabs.change_open_tab_name(index, tabName)
        #widget.ID = newId

    def close_deleted_file(self, idname):
        """Search for the Tab with id, and ask the user if should be closed."""
        pass
        #index = self.tabs.is_open(idname)
        #if index != -1:
        #result = QMessageBox.question(self, self.tr("Close Deleted File"),
        #self.tr("Are you sure you want to close the deleted file?\n"
        #"The content will be completely deleted."),
        #buttons=QMessageBox.Yes | QMessageBox.No)
        #if result == QMessageBox.Yes:
        #self.tabs.removeTab(index)

    def save_file(self, editorWidget=None):
        #FIXME: check how we handle this
        if not editorWidget:
            editorWidget = self.get_current_editor()
        if not editorWidget:
            return False
        try:
            #editorWidget.just_saved = True
            if (editorWidget.nfile.is_new_file
                    or not editorWidget.nfile.has_write_permission()):
                return self.save_file_as()

            self.beforeFileSaved.emit(editorWidget.file_path)
            if settings.REMOVE_TRAILING_SPACES:
                helpers.remove_trailing_spaces(editorWidget)
            editorWidget.neditable.save_content()
            #file_manager.store_file_content(
            #fileName, content, addExtension=False)
            encoding = file_manager.get_file_encoding(editorWidget.text())
            editorWidget.encoding = encoding
            self.fileSaved.emit(
                (self.tr("File Saved: %s") % editorWidget.file_path))
            return True
        except Exception as reason:
            logger.error('save_file: %s', reason)
            QMessageBox.information(self, self.tr("Save Error"),
                                    self.tr("The file couldn't be saved!"))
        return False

    def save_file_as(self):
        editorWidget = self.get_current_editor()
        if not editorWidget:
            return False
        try:
            filters = '(*.py);;(*.*)'
            if editorWidget.file_path:
                ext = file_manager.get_file_extension(editorWidget.file_path)
                if ext != 'py':
                    filters = '(*.%s);;(*.py);;(*.*)' % ext
            save_folder = self._get_save_folder(editorWidget.file_path)
            fileName = QFileDialog.getSaveFileName(self._parent,
                                                   self.tr("Save File"),
                                                   save_folder, filters)
            if not fileName:
                return False

            if settings.REMOVE_TRAILING_SPACES:
                helpers.remove_trailing_spaces(editorWidget)

            editorWidget.neditable.save_content(path=fileName)
            editorWidget.register_syntax(
                file_manager.get_file_extension(fileName))

            self.fileSaved.emit((self.tr("File Saved: %s") % fileName))
            self.currentEditorChanged.emit(fileName)
            return True
        except file_manager.NinjaFileExistsException as ex:
            QMessageBox.information(
                self, self.tr("File Already Exists"),
                (self.tr("Invalid Path: the file '%s' "
                         " already exists.") % ex.filename))
        except Exception as reason:
            logger.error('save_file_as: %s', reason)
            QMessageBox.information(self, self.tr("Save Error"),
                                    self.tr("The file couldn't be saved!"))
        return False

    def _get_save_folder(self, fileName):
        """
        Returns the root directory of the 'Main Project' or the home folder
        """
        ninjaide = IDE.getInstance()
        current_project = ninjaide.get_current_project()
        if current_project:
            return current_project.path
        return os.path.expanduser("~")

    def save_project(self, projectFolder):
        pass
        #FIXME: check how we handle this
        #for i in range(self._tabMain.count()):
        #editorWidget = self._tabMain.widget(i)
        #if type(editorWidget) is editor.Editor and \
        #file_manager.belongs_to_folder(projectFolder,
        #editorWidget.file_path):
        #reloaded = self._tabMain.check_for_external_modifications(
        #editorWidget)
        #if not reloaded:
        #self.save_file(editorWidget)
        #for i in range(self.tabsecondary.count()):
        #editorWidget = self.tabsecondary.widget(i)
        #if type(editorWidget) is editor.Editor and \
        #file_manager.belongs_to_folder(projectFolder,
        #editorWidget.file_path):
        #reloaded = self.tabsecondary.check_for_external_modifications(
        #editorWidget)
        #if not reloaded:
        #self.save_file(editorWidget)

    def save_all(self):
        pass
        #FIXME: check how we handle this
        #for i in range(self._tabMain.count()):
        #editorWidget = self._tabMain.widget(i)
        #if type(editorWidget) is editor.Editor:
        #reloaded = self._tabMain.check_for_external_modifications(
        #editorWidget)
        #if not reloaded:
        #self.save_file(editorWidget)
        #for i in range(self.tabsecondary.count()):
        #editorWidget = self.tabsecondary.widget(i)
        #self.tabsecondary.check_for_external_modifications(editorWidget)
        #if type(editorWidget) is editor.Editor:
        #reloaded = self.tabsecondary.check_for_external_modifications(
        #editorWidget)
        #if not reloaded:
        #self.save_file(editorWidget)

    def call_editors_function(self, call_function, *arguments):
        pass
        #args = arguments[0]
        #kwargs = arguments[1]
        #for i in range(self.tabs.count()):
        #editorWidget = self.tabs.widget(i)
        #if isinstance(editorWidget, editor.Editor):
        #function = getattr(editorWidget, call_function)
        #function(*args, **kwargs)
        #TODO: add other splits

    def show_start_page(self):
        start = self.stack.widget(0)
        if isinstance(start, start_page.StartPage):
            self.stack.setCurrentIndex(0)
        else:
            startPage = start_page.StartPage(parent=self)
            startPage.openProject.connect(self.open_project)
            startPage.openPreferences.connect(self.openPreferences.emit)
            startPage.newFile.connect(self.add_editor)
            startPage.openFiles.connect(self.open_files_fromList)
            self.stack.insertWidget(0, startPage)
            self.stack.setCurrentIndex(0)

            self.tryMakeImagePreview(0)
            #"screen0.png"

    def show_python_doc(self):
        if sys.platform == 'win32':
            self.docPage = browser_widget.BrowserWidget(
                'http://docs.python.org/')
        else:
            process = runner.start_pydoc()
            self.docPage = browser_widget.BrowserWidget(process[1], process[0])
        self.add_tab(self.docPage, translations.TR_PYTHON_DOC)

    def show_report_bugs(self):
        webbrowser.open(resources.BUGS_PAGE)

    def show_plugins_doc(self):
        bugsPage = browser_widget.BrowserWidget(resources.PLUGINS_DOC, self)
        self.add_tab(bugsPage, translations.TR_HOW_TO_WRITE_PLUGINS)

    def editor_jump_to_line(self, lineno=None):
        """Jump to line *lineno* if it is not None
        otherwise ask to the user the line number to jump
        """
        editorWidget = self.get_current_editor()
        if editorWidget:
            editorWidget.jump_to_line(lineno=lineno)

    def get_opened_documents(self):
        #return self.tabs.get_documents_data()
        return []

    def check_for_unsaved_files(self):
        pass
        #return self.tabs._check_unsaved_tabs()

    def get_unsaved_files(self):
        pass
        #return self.tabs.get_unsaved_files()

    def reset_editor_flags(self):
        pass
        #for i in range(self.tabs.count()):
        #widget = self.tabs.widget(i)
        #if isinstance(widget, editor.Editor):
        #widget.set_flags()

    def _specify_syntax(self, widget, syntaxLang):
        if isinstance(widget, editor.Editor):
            widget.restyle(syntaxLang)

    def apply_editor_theme(self, family, size):
        pass
        #for i in range(self.tabs.count()):
        #widget = self.tabs.widget(i)
        #if isinstance(widget, editor.Editor):
        #widget.restyle()
        #widget.set_font(family, size)

    def update_editor_margin_line(self):
        pass
        #for i in range(self.tabs.count()):
        #widget = self.tabs.widget(i)
        #if isinstance(widget, editor.Editor):
        #widget._update_margin_line()

    def open_project(self, path):
        print("open_project")
        self.openProject.emit(path)

    def close_python_doc(self):
        pass
        #close the python document server (if running)
        #if self.docPage:
        #index = self.tabs.indexOf(self.docPage)
        #self.tabs.removeTab(index)
        ##assign None to the browser
        #self.docPage = None

    def close_file(self):
        """Close the current tab in the current TabWidget."""
        self.current_widget.close_current_file()

    def create_file(self, base_path, project_path):
        self._add_file_folder.create_file(base_path, project_path)

    def create_folder(self, base_path, project_path):
        self._add_file_folder.create_folder(base_path, project_path)

    def change_tab(self):
        """Change the tab in the current TabWidget."""
        print("\nchange_tab")
        self.stack.setCurrentWidget(self.splitter)
        # self._files_handler.next_item()
        pass

    def change_tab_reverse(self):
        """Change the tab in the current TabWidget backwards."""
        print("\nchange_tab_reverse")
        self.stack.setCurrentWidget(self.splitter)
        # self._files_handler.previous_item()

    def toggle_tabs_and_spaces(self):
        """ Toggle Show/Hide Tabs and Spaces """

        settings.SHOW_TABS_AND_SPACES = not settings.SHOW_TABS_AND_SPACES
        qsettings = IDE.ninja_settings()
        qsettings.setValue('preferences/editor/showTabsAndSpaces',
                           settings.SHOW_TABS_AND_SPACES)

    def show_navigation_buttons(self):
        """Show Navigation menu."""
        self.stack.setCurrentWidget(self.splitter)
        self.combo_area.show_menu_navigation()

    def change_split_focus(self):
        pass
        #FIXME: check how we handle this
        #if self.actualTab == self._tabMain and self.tabsecondary.isVisible():
        #self.actualTab = self.tabsecondary
        #else:
        #self.actualTab = self._tabMain
        #widget = self.actualTab.currentWidget()
        #if widget is not None:
        #widget.setFocus()

    def shortcut_index(self, index):
        pass
        #self.tabs.setCurrentIndex(index)

    def print_file(self):
        """Call the print of ui_tool

        Call print of ui_tool depending on the focus of the application"""
        #TODO: Add funtionality for proyect tab and methods tab
        editorWidget = self.get_current_editor()
        if editorWidget is not None:
            fileName = "newDocument.pdf"
            if editorWidget.file_path:
                fileName = file_manager.get_basename(editorWidget.file_path)
                fileName = fileName[:fileName.rfind('.')] + '.pdf'
            ui_tools.print_file(fileName, editorWidget.print_)

    def split_assistance(self):
        dialog = split_orientation.SplitOrientation(self)
        dialog.show()

    def close_split(self):
        if self.current_widget != self.combo_area:
            self.current_widget.bar.close_split()

    def split_vertically(self):
        self.show_split(False)

    def split_horizontally(self):
        self.show_split(True)

    def navigate_back(self):
        self.__navigate_with_keyboard(False)

    def navigate_forward(self):
        self.__navigate_with_keyboard(True)
Пример #15
0
class Engine(QThread):

    error = pyqtSignal(str)
    WALLHAVEN_SEARCH = "https://alpha.wallhaven.cc/search?q={}&search_image=&categories={}&purity={}" \
                       "&sorting=random&order=desc&ratios=4x3,5x4,16x9,16x10"

    def __init__(self):
        super().__init__()
        self.settings = SettingsModel.getSettingsModel()

    def run(self):
        try:
            picBytes = self.wallhaven_random(search=self.settings.interests,
                                             people=self.settings.people,
                                             anime=self.settings.anime,
                                             general=self.settings.general,
                                             nsfw=self.settings.nsfw)

            if picBytes is None:
                print("Pic fetch failed...")
                return

            print("Writing pic to {}/wp.jpg".format(QDir.temp().path()))
            tempfile = open(QDir.temp().path() + "/wp.jpg", "wb+")
            tempfile.write(picBytes)
            tempfile.close()
            self.change_wallpaper()
            print("Wallpaper changed")

        except Exception as ex:
            print("Exception occured: " + str(ex))
            self.error.emit(str(ex))

    def next_wallpaper(self):
        self.temp = QTemporaryDir()

        if not self.temp.isValid():
            print("tmp dir not valid...")
            return

        self.start()

    def change_wallpaper(self):

        if platform.system() == "Linux":
            if subprocess.check_call([
                    "gsettings", "set", "org.gnome.desktop.background",
                    "picture-uri", "file:///tmp/wp.jpg"
            ]) != 0:
                raise Exception("Wallpaper setting failed!")
            return

        if platform.system() == "Windows":
            import ctypes
            ctypes.windll.user32.SystemParametersInfoW(
                20, 0,
                QDir.temp().path() + "/wp.jpg", 0)

    def wallhaven_random(self,
                         search="",
                         people=True,
                         general=True,
                         anime=True,
                         nsfw=False):

        categories = ["0", "0", "0"]
        purity = "101"

        if general:
            categories[0] = "1"
        if anime:
            categories[1] = "1"
        if people:
            categories[2] = "1"
        if nsfw:
            purity = "010"

        categories = "".join(categories)
        print("Searching wallpapers")
        url = self.WALLHAVEN_SEARCH.format(search, categories, purity)
        response = requests.get(url, timeout=20)

        if response.status_code != 200:
            raise Exception("No internet connection or fetch failed.")

        html = BeautifulSoup(response.text, "lxml")
        data = html.find_all(attrs={"class": "preview"})

        if (len(data)) == 0:
            raise Exception(
                "No pictures found matching your interest \"{}\".".format(
                    search))

        print("Downloading image")
        url = data[randint(0, len(data) - 1)].attrs["href"].split("/")[-1]
        response = requests.get(
            "https://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-{}.jpg".
            format(url),
            timeout=90)

        if response.status_code != 200:
            raise Exception("Wallpaper download failed with code {}".format(
                response.status_code))

        return response.content