def next_wallpaper(self): self.temp = QTemporaryDir() if not self.temp.isValid(): print("tmp dir not valid...") return self.start()
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 __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())
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 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)
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 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)
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)
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)
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()
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)
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
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)
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)
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