def _set_initial_cwd(self): """Set initial cwd according to preferences.""" logger.debug("Setting initial working directory") cwd_path = get_home_dir() project_path = self.container.get_active_project_path() # This is for the first client if self.id_['int_id'] == '1': if self.get_conf('startup/use_project_or_home_directory', section='workingdir'): cwd_path = get_home_dir() if project_path is not None: cwd_path = project_path elif self.get_conf('startup/use_fixed_directory', section='workingdir'): cwd_path = self.get_conf('startup/fixed_directory', default=get_home_dir(), section='workingdir') else: # For new clients if self.get_conf('console/use_project_or_home_directory', section='workingdir'): cwd_path = get_home_dir() if project_path is not None: cwd_path = project_path elif self.get_conf('console/use_cwd', section='workingdir'): cwd_path = self.container.get_working_directory() elif self.get_conf('console/use_fixed_directory', section='workingdir'): cwd_path = self.get_conf('console/fixed_directory', default=get_home_dir(), section='workingdir') if osp.isdir(cwd_path): self.shellwidget.set_cwd(cwd_path)
def get_workdir(self): """Get current workdir from the CONF file.""" if self.get_option('startup/use_fixed_directory'): workdir = self.get_option('startup/fixed_directory', default='') elif self.get_option('console/use_project_or_home_directory'): workdir = get_home_dir() else: workdir = self.get_option('console/fixed_directory', default='') if not osp.isdir(workdir): workdir = get_home_dir() return workdir
def setup_menu_actions(self): """Setup and update the menu actions.""" if self.recent_projects: for project in self.recent_projects: if self.is_valid_project(project): if os.name == 'nt': name = project else: name = project.replace(get_home_dir(), '~') try: action = self.get_action(name) except KeyError: action = self.create_action( name, text=name, icon=ima.icon('project'), triggered=self.build_opener(project), ) self.get_widget().add_item_to_menu( action, menu=self.recent_project_menu, section=RecentProjectsMenuSections.Recent) for item in [self.clear_recent_projects_action, self.max_recent_action]: self.get_widget().add_item_to_menu( item, menu=self.recent_project_menu, section=RecentProjectsMenuSections.Extras) self.update_project_actions()
def setup_menu_actions(self): """Setup and update the menu actions.""" self.recent_project_menu.clear() self.recent_projects_actions = [] if self.recent_projects: for project in self.recent_projects: if self.is_valid_project(project): name = project.replace(get_home_dir(), '~') action = create_action( self, name, icon=ima.icon('project'), triggered=self.build_opener(project), ) self.recent_projects_actions.append(action) else: self.recent_projects.remove(project) self.recent_projects_actions += [ None, self.clear_recent_projects_action, self.max_recent_action ] else: self.recent_projects_actions = [ self.clear_recent_projects_action, self.max_recent_action ] add_actions(self.recent_project_menu, self.recent_projects_actions) self.update_project_actions()
def open_project(self, path=None, restart_consoles=True, save_previous_files=True): """Open the project located in `path`""" if path is None: basedir = get_home_dir() path = getexistingdirectory(parent=self, caption=_("Open project"), basedir=basedir) if not self.is_valid_project(path): if path: QMessageBox.critical(self, _('Error'), _("<b>%s</b> is not a Spyder project!") % path) return else: self.add_to_recent(path) # A project was not open before if self.current_active_project is None: if save_previous_files: self.editor.save_open_files() self.editor.set_option('last_working_dir', getcwd_or_home()) self.show_explorer() else: # we are switching projects self.set_project_filenames(self.editor.get_open_filenames()) self.current_active_project = EmptyProject(path) self.latest_project = EmptyProject(path) self.set_option('current_project_path', self.get_active_project_path()) self.setup_menu_actions() self.sig_project_loaded.emit(path) self.pythonpath_changed.emit() if restart_consoles: self.restart_consoles()
def setup_menu_actions(self): """Setup and update the menu actions.""" self.recent_project_menu.clear() self.recent_projects_actions = [] if self.recent_projects: for project in self.recent_projects: if self.is_valid_project(project): name = project.replace(get_home_dir(), '~') def slot(): self.switch_to_plugin() self.open_project(path=project) action = create_action(self, name, icon=ima.icon('project'), triggered=slot) self.recent_projects_actions.append(action) else: self.recent_projects.remove(project) self.recent_projects_actions += [ None, self.clear_recent_projects_action ] else: self.recent_projects_actions = [self.clear_recent_projects_action] add_actions(self.recent_project_menu, self.recent_projects_actions) self.update_project_actions()
def set_history(self, history, cli_workdir=None): """ Set the current history list. Parameters ---------- history: list List of string paths. cli_workdir: str or None Working directory passed on the command line. """ self.set_conf('history', history) if history: self.pathedit.addItems(history) if cli_workdir is None: workdir = self._get_init_workdir() else: logger.debug('Setting cwd passed from the command line') workdir = cli_workdir # In case users pass an invalid directory on the command line if not osp.isdir(workdir): workdir = get_home_dir() self.chdir(workdir)
def open_project(self, path=None, restart_consoles=True): """Open the project located in `path`""" if path is None: basedir = get_home_dir() path = getexistingdirectory(parent=self, caption=_("Open project"), basedir=basedir) if not self.is_valid_project(path): if path: QMessageBox.critical( self, _('Error'), _("<b>%s</b> is not a Spyder project!" % path)) return else: self.add_to_recent(path) # A project was not open before if self.current_active_project is None: self.editor.save_open_files() self.editor.set_option('last_working_dir', getcwd()) self.show_explorer() else: # we are switching projects self.set_project_filenames(self.editor.get_open_filenames()) self.current_active_project = EmptyProject(path) self.latest_project = EmptyProject(path) self.set_option('current_project_path', self.get_active_project_path()) self.setup_menu_actions() self.sig_project_loaded.emit(path) self.pythonpath_changed.emit() if restart_consoles: self.restart_consoles()
def setup_menu_actions(self): """Setup and update the menu actions.""" self.recent_project_menu.clear() self.recent_projects_actions = [] if self.recent_projects: for project in self.recent_projects: if self.is_valid_project(project): name = project.replace(get_home_dir(), '~') def slot(): self.switch_to_plugin() self.open_project(path=project) action = create_action(self, name, icon = ima.icon('project'), triggered=slot) self.recent_projects_actions.append(action) else: self.recent_projects.remove(project) self.recent_projects_actions += [None, self.clear_recent_projects_action] else: self.recent_projects_actions = [self.clear_recent_projects_action] add_actions(self.recent_project_menu, self.recent_projects_actions) self.update_project_actions()
def nbopen(filename, dark_theme=False): """ Open a notebook using the best available server. Returns information about the selected server. """ filename = osp.abspath(filename) home_dir = get_home_dir() server_info = find_best_server(filename) if server_info is not None: logger.debug('Using existing server at %s', server_info['notebook_dir']) return server_info else: if filename.startswith(home_dir): nbdir = home_dir else: nbdir = osp.dirname(filename) logger.debug("Starting new server") serverscript = osp.join(osp.dirname(__file__), '../server/main.py') command = [sys.executable, serverscript, '--no-browser', '--notebook-dir={}'.format(nbdir), '--NotebookApp.password='******'{}'".format( KERNELSPEC)] if dark_theme: command.append('--dark') if os.name == 'nt': creation_flag = 0x08000000 # CREATE_NO_WINDOW else: creation_flag = 0 # Default value if DEV: env = os.environ.copy() env["PYTHONPATH"] = osp.dirname(get_module_path('spyder')) subprocess.Popen(command, creationflags=creation_flag, env=env) else: subprocess.Popen(command, creationflags=creation_flag) # Wait ~25 secs for the server to be up for _x in range(100): server_info = find_best_server(filename) if server_info is not None: break else: time.sleep(0.25) if server_info is None: raise NBServerError() # Kill the server at exit atexit.register(notebookapp.shutdown_server, server_info, log=logger) return server_info
def load_wdhistory(self, workdir=None): """Load history from a text file in user home directory""" if osp.isfile(self.LOG_PATH): wdhistory, _ = encoding.readlines(self.LOG_PATH) wdhistory = [name for name in wdhistory if os.path.isdir(name)] else: if workdir is None: workdir = get_home_dir() wdhistory = [workdir] return wdhistory
def load_wdhistory(self, workdir=None): """Load history from a text file in user home directory""" if osp.isfile(self.LOG_PATH): wdhistory, _ = encoding.readlines(self.LOG_PATH) wdhistory = [name for name in wdhistory if os.path.isdir(name)] else: if workdir is None: workdir = get_home_dir() wdhistory = [ workdir ] return wdhistory
def is_program_installed(basename): """ Return program absolute path if installed in PATH. Otherwise, return None. Also searches specific platform dependent paths that are not already in PATH. This permits general use without assuming user profiles are sourced (e.g. .bash_Profile), such as when login shells are not used to launch Spyder. On macOS systems, a .app is considered installed if it exists. """ home = get_home_dir() req_paths = [] if sys.platform == 'darwin': if basename.endswith('.app') and osp.exists(basename): return basename pyenv = [ osp.join('/usr', 'local', 'bin'), osp.join(home, '.pyenv', 'bin') ] # Prioritize Anaconda before Miniconda; local before global. a = [osp.join(home, 'opt'), '/opt'] b = ['anaconda', 'miniconda', 'anaconda3', 'miniconda3'] conda = [osp.join(*p, 'condabin') for p in itertools.product(a, b)] req_paths.extend(pyenv + conda) elif sys.platform.startswith('linux'): pyenv = [ osp.join('/usr', 'local', 'bin'), osp.join(home, '.pyenv', 'bin') ] a = [home, '/opt'] b = ['anaconda', 'miniconda', 'anaconda3', 'miniconda3'] conda = [osp.join(*p, 'condabin') for p in itertools.product(a, b)] req_paths.extend(pyenv + conda) elif os.name == 'nt': pyenv = [osp.join(home, '.pyenv', 'pyenv-win', 'bin')] a = [home, 'C:\\', osp.join('C:\\', 'ProgramData')] b = ['Anaconda', 'Miniconda', 'Anaconda3', 'Miniconda3'] conda = [osp.join(*p, 'condabin') for p in itertools.product(a, b)] req_paths.extend(pyenv + conda) for path in os.environ['PATH'].split(os.pathsep) + req_paths: abspath = osp.join(path, basename) if osp.isfile(abspath): return abspath
def start_server(self, filename, interpreter): """ Start a notebook server asynchronously. Start a server which can render the given notebook and return immediately. Assume the server uses the given interpreter. The manager will check periodically whether the server is accepting requests and emit `sig_server_started` or `sig_server_timed_out` when appropriate. Parameters ---------- filename : str File name of notebook to be rendered by the server. interpreter : str File name of Python interpreter to be used. """ home_dir = get_home_dir() if filename.startswith(home_dir): nbdir = home_dir else: nbdir = osp.dirname(filename) logger.debug('Starting new notebook server for %s', nbdir) process = QProcess(None) serverscript = osp.join(osp.dirname(__file__), '../server/main.py') serverscript = osp.normpath(serverscript) arguments = [ serverscript, '--no-browser', '--notebook-dir={}'.format(nbdir), '--NotebookApp.password='******'--KernelSpecManager.kernel_spec_class={}'.format(KERNELSPEC) ] if self.dark_theme: arguments.append('--dark') logger.debug('Arguments: %s', repr(arguments)) if DEV: env = QProcessEnvironment.systemEnvironment() env.insert('PYTHONPATH', osp.dirname(get_module_path('spyder'))) process.setProcessEnvironment(env) server_process = ServerProcess(process, notebook_dir=nbdir, interpreter=interpreter) process.setProcessChannelMode(QProcess.MergedChannels) process.readyReadStandardOutput.connect( lambda: self.read_server_output(server_process)) process.errorOccurred.connect( lambda error: self.handle_error(server_process, error)) process.finished.connect(lambda code, status: self.handle_finished( server_process, code, status)) process.start(sys.executable, arguments) self.servers.append(server_process) self._check_server_started(server_process)
def open_project(self, path=None, restart_consoles=True, save_previous_files=True): """Open the project located in `path`""" self.notify_project_open(path) self.unmaximize() if path is None: basedir = get_home_dir() path = getexistingdirectory(parent=self, caption=_("Open project"), basedir=basedir) path = encoding.to_unicode_from_fs(path) if not self.is_valid_project(path): if path: QMessageBox.critical( self, _('Error'), _("<b>%s</b> is not a Spyder project!") % path) return else: path = encoding.to_unicode_from_fs(path) self.add_to_recent(path) # A project was not open before if self.current_active_project is None: if save_previous_files and self.main.editor is not None: self.main.editor.save_open_files() if self.main.editor is not None: self.main.editor.set_option('last_working_dir', getcwd_or_home()) if self.get_option('visible_if_project_open'): self.show_explorer() else: # We are switching projects if self.main.editor is not None: self.set_project_filenames( self.main.editor.get_open_filenames()) # TODO: Don't emit sig_project_closed when we support # multiple workspaces. self.sig_project_closed.emit(self.current_active_project.root_path) project = EmptyProject(path) self.current_active_project = project self.latest_project = project self.set_option('current_project_path', self.get_active_project_path()) self.setup_menu_actions() self.sig_project_loaded.emit(path) self.sig_pythonpath_changed.emit() self.watcher.start(path) if restart_consoles: self.restart_consoles()
def get_pyenv_path(name): """Return the complete path of the pyenv.""" home = get_home_dir() if os.name == 'nt': path = osp.join(home, '.pyenv', 'pyenv-win', 'versions', name, 'python.exe') elif name == '': path = osp.join(home, '.pyenv', 'shims', 'python') else: path = osp.join(home, '.pyenv', 'versions', name, 'bin', 'python') return path
def nbopen(filename): """ Open a notebook using the best available server. Returns information about the selected server. """ filename = osp.abspath(filename) home_dir = get_home_dir() server_info = find_best_server(filename) if server_info is not None: print("Using existing server at", server_info['notebook_dir']) return server_info else: if filename.startswith(home_dir): nbdir = home_dir else: nbdir = osp.dirname(filename) print("Starting new server") kernelspec = 'spyder.utils.ipython.kernelspec.SpyderKernelSpec' command = [ 'jupyter', 'notebook', '--no-browser', '--notebook-dir={}'.format(nbdir), '--NotebookApp.password='******'{}'".format(kernelspec) ] if os.name == 'nt': creation_flag = 0x08000000 # CREATE_NO_WINDOW else: creation_flag = 0 # Default value if DEV: env = os.environ.copy() env["PYTHONPATH"] = osp.dirname(get_module_path('spyder')) proc = subprocess.Popen(command, creationflags=creation_flag, env=env) else: proc = subprocess.Popen(command, creationflags=creation_flag) atexit.register(proc.terminate) # Wait ~10 secs for the server to be up for _x in range(40): server_info = find_best_server(filename) if server_info is not None: break else: time.sleep(0.25) if server_info is None: raise NBServerError() return server_info
def get_workdir(self): """ Get the working directory from our config system or return the user home directory if none could be found. Returns ------- str: The current working directory. """ if self.get_option('startup/use_fixed_directory'): workdir = self.get_option('startup/fixed_directory') elif self.get_option('console/use_project_or_home_directory'): workdir = get_home_dir() else: workdir = self.get_option('console/fixed_directory') if not osp.isdir(workdir): workdir = get_home_dir() return workdir
def getcwd_or_home(): """Safe version of getcwd that will fallback to home user dir. This will catch the error raised when the current working directory was removed for an external program. """ try: return getcwd() except OSError: logger.debug("WARNING: Current working directory was deleted, " "falling back to home dirertory") return get_home_dir()
def test_runconfig_workdir(main_window, qtbot, tmpdir): """Test runconfig workdir options.""" CONF.set('run', 'configurations', []) # ---- Load test file ---- test_file = osp.join(LOCATION, 'script.py') main_window.editor.load(test_file) code_editor = main_window.editor.get_focus_widget() # --- Use cwd for this file --- rc = RunConfiguration().get() rc['file_dir'] = False rc['cw_dir'] = True config_entry = (test_file, rc) CONF.set('run', 'configurations', [config_entry]) # --- Run test file --- shell = main_window.ipyconsole.get_current_shellwidget() qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT) qtbot.keyClick(code_editor, Qt.Key_F5) qtbot.wait(500) # --- Assert we're in cwd after execution --- with qtbot.waitSignal(shell.executed): shell.execute('import os; current_dir = os.getcwd()') assert shell.get_value('current_dir') == get_home_dir() # --- Use fixed execution dir for test file --- temp_dir = str(tmpdir.mkdir("test_dir")) rc['file_dir'] = False rc['cw_dir'] = False rc['fixed_dir'] = True rc['dir'] = temp_dir config_entry = (test_file, rc) CONF.set('run', 'configurations', [config_entry]) # --- Run test file --- shell = main_window.ipyconsole.get_current_shellwidget() qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=SHELL_TIMEOUT) qtbot.keyClick(code_editor, Qt.Key_F5) qtbot.wait(500) # --- Assert we're in fixed dir after execution --- with qtbot.waitSignal(shell.executed): shell.execute('import os; current_dir = os.getcwd()') assert shell.get_value('current_dir') == temp_dir # ---- Closing test file and resetting config ---- main_window.editor.close_file() CONF.set('run', 'configurations', [])
def _get_init_workdir(self): """ Get the working directory from our config system or return the user home directory if none can be found. Returns ------- str: The initial working directory. """ workdir = get_home_dir() if self.get_conf('startup/use_project_or_home_directory'): workdir = get_home_dir() elif self.get_conf('startup/use_fixed_directory'): workdir = self.get_conf('startup/fixed_directory') # If workdir can't be found, restore default options. if not osp.isdir(workdir): self.set_conf('startup/use_project_or_home_directory', True) self.set_conf('startup/use_fixed_directory', False) workdir = get_home_dir() return workdir
def _filename_global(self): """Create a .ini filename located in user home directory. This .ini files stores the global spyder preferences. """ if self.subfolder is None: config_file = osp.join(get_home_dir(), '.%s.ini' % self.name) return config_file else: folder = get_conf_path() # Save defaults in a "defaults" dir of .spyder2 to not pollute it if 'defaults' in self.name: folder = osp.join(folder, 'defaults') if not osp.isdir(folder): os.mkdir(folder) config_file = osp.join(folder, '%s.ini' % self.name) return config_file
def filename(self): """ Return the name of a .ini filename to save config settings """ if self.subfolder is None: config_file = osp.join(get_home_dir(), '.%s.ini' % self.name) return config_file else: folder = get_conf_path() # Save defaults in a "defaults" dir of .spyder2 to not pollute it if 'defaults' in self.name: folder = osp.join(folder, 'defaults') if not osp.isdir(folder): os.mkdir(folder) config_file = osp.join(folder, '%s.ini' % self.name) return config_file
def setup_workingdirectory(request): """Setup working directory plugin.""" CONF.reset_to_defaults() use_startup_wdir = request.node.get_closest_marker('use_startup_wdir') if use_startup_wdir: new_wdir = osp.join(os.getcwd(), NEW_DIR) if not osp.exists(new_wdir): os.mkdir(new_wdir) CONF.set('workingdir', 'startup/use_fixed_directory', True) CONF.set('workingdir', 'startup/fixed_directory', new_wdir) else: CONF.set('workingdir', 'startup/use_fixed_directory', False) CONF.set('workingdir', 'console/use_fixed_directory', False) CONF.set('workingdir', 'startup/fixed_directory', get_home_dir()) workingdirectory = WorkingDirectory(None, configuration=CONF) workingdirectory.close = lambda: True return workingdirectory
def setup_workingdirectory(qtbot, request): """Setup working directory plugin.""" CONF.reset_to_defaults() use_startup_wdir = request.node.get_closest_marker('use_startup_wdir') if use_startup_wdir: new_wdir = osp.join(os.getcwd(), NEW_DIR) if not osp.exists(new_wdir): os.mkdir(new_wdir) CONF.set('workingdir', 'startup/use_fixed_directory', True) CONF.set('workingdir', 'startup/fixed_directory', new_wdir) else: CONF.set('workingdir', 'startup/use_fixed_directory', False) CONF.set('workingdir', 'console/use_fixed_directory', False) CONF.set('workingdir', 'startup/fixed_directory', get_home_dir()) workingdirectory = WorkingDirectory(None) qtbot.addWidget(workingdirectory) workingdirectory.show() return workingdirectory, qtbot
def alter_subprocess_kwargs_by_platform(**kwargs): """ Given a dict, populate kwargs to create a generally useful default setup for running subprocess processes on different platforms. For example, `close_fds` is set on posix and creation of a new console window is disabled on Windows. This function will alter the given kwargs and return the modified dict. """ kwargs.setdefault('close_fds', os.name == 'posix') if os.name == 'nt': CONSOLE_CREATION_FLAGS = 0 # Default value # See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863%28v=vs.85%29.aspx CREATE_NO_WINDOW = 0x08000000 # We "or" them together CONSOLE_CREATION_FLAGS |= CREATE_NO_WINDOW kwargs.setdefault('creationflags', CONSOLE_CREATION_FLAGS) # ensure Windows subprocess environment has SYSTEMROOT if kwargs.get('env') is not None: # Is SYSTEMROOT in env? case insensitive if 'SYSTEMROOT' not in map(str.upper, kwargs['env'].keys()): # Add SYSTEMROOT from os.environ sys_root_key = None for k, v in os.environ.items(): if 'SYSTEMROOT' == k.upper(): sys_root_key = k break # don't risk multiple values if sys_root_key is not None: kwargs['env'].update( {sys_root_key: os.environ[sys_root_key]}) else: # linux and macOS if kwargs.get('env') is not None: if 'HOME' not in kwargs['env']: kwargs['env'].update({'HOME': get_home_dir()}) return kwargs
def setup_menu_actions(self): """Setup and update the menu actions.""" self.recent_project_menu.clear() self.recent_projects_actions = [] if self.recent_projects: for project in self.recent_projects: if self.is_valid_project(project): name = project.replace(get_home_dir(), "~") action = create_action( self, name, icon=ima.icon("project"), triggered=lambda v, path=project: self.open_project(path=path), ) self.recent_projects_actions.append(action) else: self.recent_projects.remove(project) self.recent_projects_actions += [None, self.clear_recent_projects_action] else: self.recent_projects_actions = [self.clear_recent_projects_action] add_actions(self.recent_project_menu, self.recent_projects_actions) self.update_project_actions()
def remove_deprecated_config_locations(self): """Removing old .spyder.ini location.""" old_location = osp.join(get_home_dir(), '.spyder.ini') if osp.isfile(old_location): os.remove(old_location)
def __init__(self, parent): """Project creation dialog.""" super(ProjectDialog, self).__init__(parent=parent) # Variables current_python_version = '.'.join([to_text_string(sys.version_info[0]), to_text_string(sys.version_info[1])]) python_versions = ['2.7', '3.4', '3.5'] if current_python_version not in python_versions: python_versions.append(current_python_version) python_versions = sorted(python_versions) self.project_name = None self.location = get_home_dir() # Widgets self.groupbox = QGroupBox() self.radio_new_dir = QRadioButton(_("New directory")) self.radio_from_dir = QRadioButton(_("Existing directory")) self.label_project_name = QLabel(_('Project name')) self.label_location = QLabel(_('Location')) self.label_project_type = QLabel(_('Project type')) self.label_python_version = QLabel(_('Python version')) self.text_project_name = QLineEdit() self.text_location = QLineEdit(get_home_dir()) self.combo_project_type = QComboBox() self.combo_python_version = QComboBox() self.button_select_location = QToolButton() self.button_cancel = QPushButton(_('Cancel')) self.button_create = QPushButton(_('Create')) self.bbox = QDialogButtonBox(Qt.Horizontal) self.bbox.addButton(self.button_cancel, QDialogButtonBox.ActionRole) self.bbox.addButton(self.button_create, QDialogButtonBox.ActionRole) # Widget setup self.combo_python_version.addItems(python_versions) self.radio_new_dir.setChecked(True) self.text_location.setEnabled(True) self.text_location.setReadOnly(True) self.button_select_location.setIcon(get_std_icon('DirOpenIcon')) self.button_cancel.setDefault(True) self.button_cancel.setAutoDefault(True) self.button_create.setEnabled(False) self.combo_project_type.addItems(self._get_project_types()) self.combo_python_version.setCurrentIndex( python_versions.index(current_python_version)) self.setWindowTitle(_('Create new project')) self.setFixedWidth(500) self.label_python_version.setVisible(False) self.combo_python_version.setVisible(False) # Layouts layout_top = QHBoxLayout() layout_top.addWidget(self.radio_new_dir) layout_top.addWidget(self.radio_from_dir) layout_top.addStretch(1) self.groupbox.setLayout(layout_top) layout_grid = QGridLayout() layout_grid.addWidget(self.label_project_name, 0, 0) layout_grid.addWidget(self.text_project_name, 0, 1, 1, 2) layout_grid.addWidget(self.label_location, 1, 0) layout_grid.addWidget(self.text_location, 1, 1) layout_grid.addWidget(self.button_select_location, 1, 2) layout_grid.addWidget(self.label_project_type, 2, 0) layout_grid.addWidget(self.combo_project_type, 2, 1, 1, 2) layout_grid.addWidget(self.label_python_version, 3, 0) layout_grid.addWidget(self.combo_python_version, 3, 1, 1, 2) layout = QVBoxLayout() layout.addWidget(self.groupbox) layout.addSpacing(10) layout.addLayout(layout_grid) layout.addStretch() layout.addSpacing(20) layout.addWidget(self.bbox) self.setLayout(layout) # Signals and slots self.button_select_location.clicked.connect(self.select_location) self.button_create.clicked.connect(self.create_project) self.button_cancel.clicked.connect(self.close) self.radio_from_dir.clicked.connect(self.update_location) self.radio_new_dir.clicked.connect(self.update_location) self.text_project_name.textChanged.connect(self.update_location)
def __init__(self, parent, workdir=None, **kwds): if PYQT5: super(WorkingDirectory, self).__init__(parent, **kwds) else: QToolBar.__init__(self, parent) SpyderPluginMixin.__init__(self, parent) # Initialize plugin self.initialize_plugin() self.setWindowTitle(self.get_plugin_title()) # Toolbar title self.setObjectName( self.get_plugin_title()) # Used to save Window state # Previous dir action self.history = [] self.histindex = None self.previous_action = create_action(self, "previous", None, ima.icon('previous'), _('Back'), triggered=self.previous_directory) self.addAction(self.previous_action) # Next dir action self.history = [] self.histindex = None self.next_action = create_action(self, "next", None, ima.icon('next'), _('Next'), triggered=self.next_directory) self.addAction(self.next_action) # Enable/disable previous/next actions self.set_previous_enabled.connect(self.previous_action.setEnabled) self.set_next_enabled.connect(self.next_action.setEnabled) # Path combo box adjust = self.get_option('working_dir_adjusttocontents') self.pathedit = PathComboBox(self, adjust_to_contents=adjust) self.pathedit.setToolTip( _("This is the working directory for newly\n" "opened consoles (Python/IPython consoles and\n" "terminals), for the file explorer, for the\n" "find in files plugin and for new files\n" "created in the editor")) self.pathedit.open_dir.connect(self.chdir) self.pathedit.activated[str].connect(self.chdir) self.pathedit.setMaxCount(self.get_option('working_dir_history')) wdhistory = self.load_wdhistory(workdir) if workdir is None: if self.get_option('console/use_project_or_home_directory'): workdir = get_home_dir() else: workdir = self.get_option('console/fixed_directory', default='') if not osp.isdir(workdir): workdir = get_home_dir() self.chdir(workdir) self.pathedit.addItems(wdhistory) self.pathedit.selected_text = self.pathedit.currentText() self.refresh_plugin() self.addWidget(self.pathedit) # Browse action browse_action = create_action(self, "browse", None, ima.icon('DirOpenIcon'), _('Browse a working directory'), triggered=self.select_directory) self.addAction(browse_action) # Parent dir action parent_action = create_action(self, "parent", None, ima.icon('up'), _('Change to parent directory'), triggered=self.parent_directory) self.addAction(parent_action)
recent_file, self.root_path) processed_recent_files.append(relative_recent_file) except ValueError: processed_recent_files.append(recent_file) files = list(OrderedDict.fromkeys(processed_recent_files)) self.config.set('main', 'recent_files', files) def get_recent_files(self): """Return a list of files opened by the project.""" recent_files = self.config.get('main', 'recent_files', default=[]) recent_files = [recent_file if os.path.isabs(recent_file) else os.path.join(self.root_path, recent_file) for recent_file in recent_files] for recent_file in recent_files[:]: if not os.path.isfile(recent_file): recent_files.remove(recent_file) return list(OrderedDict.fromkeys(recent_files)) class EmptyProject(BaseProject): """Empty Project""" PROJECT_TYPE_NAME = _('Empty project') PROJECT_TYPE = 'empty' if __name__ == '__main__': from spyder.config.base import get_home_dir project_path = osp.join(get_home_dir(), 'test_project') project = EmptyProject(project_path)
def __init__(self, parent, project_types): """Project creation dialog.""" super(ProjectDialog, self).__init__(parent=parent) self.plugin = parent self._project_types = project_types self.project_data = {} # Variables current_python_version = '.'.join([to_text_string(sys.version_info[0]), to_text_string(sys.version_info[1])]) python_versions = ['2.7', '3.4', '3.5'] if current_python_version not in python_versions: python_versions.append(current_python_version) python_versions = sorted(python_versions) self.project_name = None self.location = get_home_dir() # Widgets self.groupbox = QGroupBox() self.radio_new_dir = QRadioButton(_("New directory")) self.radio_from_dir = QRadioButton(_("Existing directory")) self.label_project_name = QLabel(_('Project name')) self.label_location = QLabel(_('Location')) self.label_project_type = QLabel(_('Project type')) self.label_python_version = QLabel(_('Python version')) self.text_project_name = QLineEdit() self.text_location = QLineEdit(get_home_dir()) self.combo_project_type = QComboBox() self.combo_python_version = QComboBox() self.label_information = QLabel("") self.button_select_location = QToolButton() self.button_cancel = QPushButton(_('Cancel')) self.button_create = QPushButton(_('Create')) self.bbox = QDialogButtonBox(Qt.Horizontal) self.bbox.addButton(self.button_cancel, QDialogButtonBox.ActionRole) self.bbox.addButton(self.button_create, QDialogButtonBox.ActionRole) # Widget setup self.combo_python_version.addItems(python_versions) self.radio_new_dir.setChecked(True) self.text_location.setEnabled(True) self.text_location.setReadOnly(True) self.button_select_location.setIcon(get_std_icon('DirOpenIcon')) self.button_cancel.setDefault(True) self.button_cancel.setAutoDefault(True) self.button_create.setEnabled(False) for (id_, name) in [(pt_id, pt.get_name()) for pt_id, pt in project_types.items()]: self.combo_project_type.addItem(name, id_) self.combo_python_version.setCurrentIndex( python_versions.index(current_python_version)) self.setWindowTitle(_('Create new project')) self.setFixedWidth(500) self.label_python_version.setVisible(False) self.combo_python_version.setVisible(False) # Layouts layout_top = QHBoxLayout() layout_top.addWidget(self.radio_new_dir) layout_top.addWidget(self.radio_from_dir) layout_top.addStretch(1) self.groupbox.setLayout(layout_top) layout_grid = QGridLayout() layout_grid.addWidget(self.label_project_name, 0, 0) layout_grid.addWidget(self.text_project_name, 0, 1, 1, 2) layout_grid.addWidget(self.label_location, 1, 0) layout_grid.addWidget(self.text_location, 1, 1) layout_grid.addWidget(self.button_select_location, 1, 2) layout_grid.addWidget(self.label_project_type, 2, 0) layout_grid.addWidget(self.combo_project_type, 2, 1, 1, 2) layout_grid.addWidget(self.label_python_version, 3, 0) layout_grid.addWidget(self.combo_python_version, 3, 1, 1, 2) layout_grid.addWidget(self.label_information, 4, 0, 1, 3) layout = QVBoxLayout() layout.addWidget(self.groupbox) layout.addSpacing(10) layout.addLayout(layout_grid) layout.addStretch() layout.addSpacing(20) layout.addWidget(self.bbox) self.setLayout(layout) # Signals and slots self.button_select_location.clicked.connect(self.select_location) self.button_create.clicked.connect(self.create_project) self.button_cancel.clicked.connect(self.close) self.radio_from_dir.clicked.connect(self.update_location) self.radio_new_dir.clicked.connect(self.update_location) self.text_project_name.textChanged.connect(self.update_location)
def select_ssh_key(self): kf = getopenfilename(self, _('Select SSH keyfile'), get_home_dir(), '*.pem;;*')[0] self.kf.setText(kf)
def __init__(self, parent, workdir=None, **kwds): SpyderPluginWidget.__init__(self, parent) self.hide() self.toolbar = QToolBar(self) # Initialize plugin self.initialize_plugin() self.options_button.hide() self.toolbar.setWindowTitle(self.get_plugin_title()) # Used to save Window state self.toolbar.setObjectName(self.get_plugin_title()) # Previous dir action self.history = [] self.histindex = None self.previous_action = create_action(self, "previous", None, ima.icon('previous'), _('Back'), triggered=self.previous_directory) self.toolbar.addAction(self.previous_action) # Next dir action self.next_action = create_action(self, "next", None, ima.icon('next'), _('Next'), triggered=self.next_directory) self.toolbar.addAction(self.next_action) # Enable/disable previous/next actions self.set_previous_enabled.connect(self.previous_action.setEnabled) self.set_next_enabled.connect(self.next_action.setEnabled) # Path combo box adjust = self.get_option('working_dir_adjusttocontents') self.pathedit = PathComboBox(self, adjust_to_contents=adjust) self.pathedit.setToolTip(_("This is the working directory for newly\n" "opened consoles (Python/IPython consoles and\n" "terminals), for the file explorer, for the\n" "find in files plugin and for new files\n" "created in the editor")) self.pathedit.open_dir.connect(self.chdir) self.pathedit.activated[str].connect(self.chdir) self.pathedit.setMaxCount(self.get_option('working_dir_history')) wdhistory = self.load_wdhistory(workdir) if workdir is None: if self.get_option('console/use_project_or_home_directory'): workdir = get_home_dir() else: workdir = self.get_option('console/fixed_directory', default='') if not osp.isdir(workdir): workdir = get_home_dir() self.chdir(workdir) self.pathedit.addItems(wdhistory) self.pathedit.selected_text = self.pathedit.currentText() self.refresh_plugin() self.toolbar.addWidget(self.pathedit) # Browse action browse_action = create_action(self, "browse", None, ima.icon('DirOpenIcon'), _('Browse a working directory'), triggered=self.select_directory) self.toolbar.addAction(browse_action) # Parent dir action parent_action = create_action(self, "parent", None, ima.icon('up'), _('Change to parent directory'), triggered=self.parent_directory) self.toolbar.addAction(parent_action)
}) ] #============================================================================== # Config instance #============================================================================== # IMPORTANT NOTES: # 1. If you want to *change* the default value of a current option, you need to # do a MINOR update in config version, e.g. from 3.0.0 to 3.1.0 # 2. If you want to *remove* options that are no longer needed in our codebase, # or if you want to *rename* options, then you need to do a MAJOR update in # version, e.g. from 3.0.0 to 4.0.0 # 3. You don't need to touch this value if you're just adding a new option CONF_VERSION = '40.3.0' # Main configuration instance try: CONF = UserConfig('spyder', defaults=DEFAULTS, load=(not TEST), version=CONF_VERSION, subfolder=SUBFOLDER, backup=True, raw_mode=True) except: CONF = UserConfig('spyder', defaults=DEFAULTS, load=False, version=CONF_VERSION, subfolder=SUBFOLDER, backup=True, raw_mode=True) # Removing old .spyder.ini location: old_location = osp.join(get_home_dir(), '.spyder.ini') if osp.isfile(old_location): os.remove(old_location)
# 1. If you want to *change* the default value of a current option, you need to # do a MINOR update in config version, e.g. from 3.0.0 to 3.1.0 # 2. If you want to *remove* options that are no longer needed in our codebase, # or if you want to *rename* options, then you need to do a MAJOR update in # version, e.g. from 3.0.0 to 4.0.0 # 3. You don't need to touch this value if you're just adding a new option CONF_VERSION = '47.7.0' # Main configuration instance try: CONF = UserConfig('spyder', defaults=DEFAULTS, load=True, version=CONF_VERSION, subfolder=SUBFOLDER, backup=True, raw_mode=True) except Exception: CONF = UserConfig('spyder', defaults=DEFAULTS, load=False, version=CONF_VERSION, subfolder=SUBFOLDER, backup=True, raw_mode=True) # Removing old .spyder.ini location: old_location = osp.join(get_home_dir(), '.spyder.ini') if osp.isfile(old_location): os.remove(old_location)
def open_project(self, path=None, project=None, restart_consoles=True, save_previous_files=True, workdir=None): """Open the project located in `path`.""" self.unmaximize() if path is None: basedir = get_home_dir() path = getexistingdirectory(parent=self.get_widget(), caption=_("Open project"), basedir=basedir) path = encoding.to_unicode_from_fs(path) if not self.is_valid_project(path): if path: QMessageBox.critical( self.get_widget(), _('Error'), _("<b>%s</b> is not a Spyder project!") % path, ) return else: path = encoding.to_unicode_from_fs(path) logger.debug(f'Opening project located at {path}') if project is None: project_type_class = self._load_project_type_class(path) project = project_type_class( root_path=path, parent_plugin=project_type_class._PARENT_PLUGIN, ) # A project was not open before if self.current_active_project is None: if save_previous_files and self.editor is not None: self.editor.save_open_files() if self.editor is not None: self.set_conf('last_working_dir', getcwd_or_home(), section='editor') if self.get_conf('visible_if_project_open'): self.show_explorer() else: # We are switching projects if self.editor is not None: self.set_project_filenames(self.editor.get_open_filenames()) # TODO: Don't emit sig_project_closed when we support # multiple workspaces. self.sig_project_closed.emit( self.current_active_project.root_path) self.watcher.stop() self.current_active_project = project self.latest_project = project self.add_to_recent(path) self.set_conf('current_project_path', self.get_active_project_path()) self.setup_menu_actions() if workdir and osp.isdir(workdir): self.sig_project_loaded.emit(workdir) else: self.sig_project_loaded.emit(path) self.sig_pythonpath_changed.emit() self.watcher.start(path) if restart_consoles: self.restart_consoles() open_successfully, message = project.open_project() if not open_successfully: QMessageBox.warning(self.get_widget(), "Project open", message)