def __init__(self, parent=None): channels = self.get_option('channels', ['anaconda', 'spyder-ide']) active_channels = self.get_option('active_channels', ['anaconda', 'spyder-ide']) CondaPackagesWidget.__init__( self, parent=parent, channels=channels, active_channels=active_channels, ) SpyderPluginMixin.__init__(self, parent) self.root_env = 'root' self._prefix_to_set = self.get_environment_prefix() # Initialize plugin self.initialize_plugin()
def __init__(self): super(PackagesTab, self).__init__() self.api = AnacondaAPI() self.path = None self.project = None # Widgets self.list_environments = EditableList(title='Environments') self.list_commands = EditableList(title='Commands', min_items=0) self.package_manager = CondaPackagesWidget( self, setup=False, data_directory=CHANNELS_PATH, ) # Widget setup self.list_environments.button_add.clicked.disconnect() self.list_environments.button_edit.setVisible(False) # Layout top_layout = QHBoxLayout() top_layout.addWidget(self.list_environments) top_layout.addStretch() top_layout.addWidget(self.list_commands) top_layout.addStretch() main_layout = QVBoxLayout() main_layout.addLayout(top_layout) main_layout.addWidget(self.package_manager) self.setLayout(main_layout) # Signals self.list_commands.sig_item_removed.connect(self.edit_commands) self.list_commands.sig_item_edited.connect(self.add_command) self.list_commands.sig_item_selected.connect(self.select_command) self.list_environments.button_add.clicked.connect(self.add_environment) self.list_environments.sig_item_removed.connect( self.remove_environment) self.list_environments.sig_item_selected.connect( self.choose_environment) self.package_manager.sig_channels_updated.connect(self.set_channels)
def __init__(self): super(MainWindow, self).__init__() # Variables self.file_menu = None self.file_menu_actions = [] self.tools_menu = None self.tools_menu_actions = [] self.help_menu = None self.help_menu_actions = [] self.menulist = [] # Widgets self.packages = CondaPackagesWidget(self) # Widget setup self.setWindowTitle('Conda Package Manager {0}'.format(__version__)) self.setCentralWidget(self.packages) self.setup_window()
class MainWindow(QMainWindow): def __init__(self): super(MainWindow, self).__init__() # Variables self.file_menu = None self.file_menu_actions = [] self.tools_menu = None self.tools_menu_actions = [] self.help_menu = None self.help_menu_actions = [] self.menulist = [] # Widgets self.packages = CondaPackagesWidget(self) # Widget setup self.setWindowTitle('Conda Package Manager {0}'.format(__version__)) self.setCentralWidget(self.packages) self.setup_window() def setup_window(self): """ """ self.close_action = create_action(self, _("&Quit"), triggered=self.close) self.file_menu_actions.append(self.close_action) self.file_menu = self.menuBar().addMenu(_("&File")) add_actions(self.file_menu, self.file_menu_actions) # Environments self.add_env_action = create_action(self, _("&Add"), triggered=self.add_env) self.clone_env_action = create_action(self, _("&Clone"), triggered=self.clone_env) self.remove_env_action = create_action(self, _("&Remove"), triggered=self.remove_env) self.envs_list_menu = QMenu(_('Environments')) self.envs_menu_actions = [self.add_env_action, self.clone_env_action, self.remove_env_action, None, self.envs_list_menu] self.envs_menu = self.menuBar().addMenu(_("&Environments")) add_actions(self.envs_menu, self.envs_menu_actions) self.update_env_menu() # Channels self.envs_menu = self.menuBar().addMenu(_("&Channels")) # Tools self.preferences_action = create_action(self, _("&Preferences"), triggered=self.preferences) self.tools_menu_actions.append(self.preferences_action) self.tools_menu = self.menuBar().addMenu(_("&Tools")) add_actions(self.tools_menu, self.tools_menu_actions) # Help self.report_action = create_action(self, _("&Report issue"), triggered=self.report_issue) self.about_action = create_action(self, _("&About"), triggered=self.about) self.help_menu_actions.append(self.report_action) self.help_menu_actions.append(self.about_action) self.help_menu = self.menuBar().addMenu(_("&Help")) add_actions(self.help_menu, self.help_menu_actions) self.setWindowIcon(get_icon('condapackages.png')) def update_env_menu(self): """ """ envs_list_actions = [] envs = self.get_enviroments() self.envs_list_menu.clear() for env in envs: def trigger(value=False, e=env): return lambda: self.set_environments(e) a = create_action(self, env, triggered=trigger()) envs_list_actions.append(a) add_actions(self.envs_list_menu, envs_list_actions) def get_enviroments(self, path=None): """ """ return ['root'] + self.packages.get_environments() def set_environments(self, prefix): """ """ self.packages.set_environment(prefix=prefix) def add_env(self): """ """ # TODO: def clone_env(self): """ """ # TODO: def remove_env(self): """ """ # TODO: def preferences(self): """ """ # TODO: def report_issue(self): if PY3: from urllib.parse import quote else: from urllib import quote # analysis:ignore issue_template = """\ ## Description - *What steps will reproduce the problem?* 1. 2. 3. - *What is the expected output? What do you see instead?* - *Please provide any additional information below* ## Version and main components - Conda Package Manager Version: {version} - Conda Version: {conda version} - Python Version: {python version} - Qt Version : {Qt version} - QtPy Version : {QtPy version} """ url = QUrl("https://github.com/spyder-ide/conda-manager/issues/new") url.addEncodedQueryItem("body", quote(issue_template)) QDesktopServices.openUrl(url) def about(self): """About Conda Package Manager.""" var = {'github': 'https://github.com/spyder-ide/conda-manager'} QMessageBox.about(self, _("About"), """ <p><b>Conda Package Manager</b></p> <p>Copyright © 2015 The Spyder Development Team<br> Licensed under the terms of the MIT License</p> <p>Created by Gonzalo Peña-Castellanos<br> Developed and maintained by the Spyder Development Team.</p> <p>For bug reports and feature requests, please go to our <a href="{github}">Github website</a>.</p> <p>This project is part of a larger effort to promote and facilitate the use of Python for scientific and engineering software development. The popular Python distributions <a href="http://continuum.io/downloads">Anaconda</a>, <a href="https://winpython.github.io/">WinPython</a> and <a href="http://code.google.com/p/pythonxy/">Python(x,y)</a> also contribute to this plan.</p> """.format(**var)) def closeEvent(self, event): """ """ if self.packages.busy: answer = QMessageBox.question( self, 'Quit Conda Manager?', 'Conda is still busy.\n\nDo you want to quit?', buttons=QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.Yes: QMainWindow.closeEvent(self, event) # Do some cleanup? else: event.ignore() else: QMainWindow.closeEvent(self, event)
def __init__(self, parent=None): super(EnvironmentsTab, self).__init__(parent) self.api = AnacondaAPI() self.last_env_prefix = None self.last_env_name = None self.previous_environments = None self.tracker = GATracker() self.metadata = {} active_channels = CONF.get('main', 'conda_active_channels', tuple()) channels = CONF.get('main', 'conda_channels', tuple()) conda_url = CONF.get('main', 'conda_url', 'https:/conda.anaconda.org') conda_api_url = CONF.get('main', 'anaconda_api_url', 'https://api.anaconda.org') # Widgets self.button_clone = ButtonEnvironmentPrimary("Clone") self.button_create = ButtonEnvironmentPrimary("Create") self.button_remove = ButtonEnvironmentCancel("Remove") self.frame_environments = FrameEnvironments(self) self.frame_environments_list = FrameEnvironmentsList(self) self.frame_environments_list_buttons = FrameEnvironmentsListButtons(self) self.frame_environments_packages = FrameEnvironmentsPackages(self) self.list_environments = ListWidgetEnvironment() self.packages_widget = CondaPackagesWidget( self, setup=False, active_channels=active_channels, channels=channels, data_directory=CHANNELS_PATH, conda_api_url=conda_api_url, conda_url=conda_url) self.menu_list = QMenu() self.text_search = LineEditSearch() self.timer_environments = QTimer() # Widgets setup self.list_environments.setAttribute(Qt.WA_MacShowFocusRect, False) self.list_environments.setContextMenuPolicy(Qt.CustomContextMenu) self.packages_widget.textbox_search.setAttribute( Qt.WA_MacShowFocusRect, False) self.packages_widget.textbox_search.set_icon_visibility(False) self.text_search.setPlaceholderText("Search Environments") self.text_search.setAttribute(Qt.WA_MacShowFocusRect, False) self.timer_environments.setInterval(5000) # Layouts environments_layout = QVBoxLayout() environments_layout.addWidget(self.text_search) buttons_layout = QHBoxLayout() buttons_layout.addWidget(self.button_create) buttons_layout.addWidget(self.button_clone) buttons_layout.addWidget(self.button_remove) buttons_layout.setContentsMargins(0, 0, 0, 0) list_buttons_layout = QVBoxLayout() list_buttons_layout.addWidget(self.list_environments) list_buttons_layout.addLayout(buttons_layout) self.frame_environments_list_buttons.setLayout(list_buttons_layout) list_buttons_layout.setContentsMargins(0, 0, 0, 0) environments_layout.addWidget(self.frame_environments_list_buttons) self.frame_environments_list.setLayout(environments_layout) packages_layout = QHBoxLayout() packages_layout.addWidget(self.packages_widget) packages_layout.setContentsMargins(0, 0, 0, 0) self.frame_environments_packages.setLayout(packages_layout) main_layout = QHBoxLayout() main_layout.addWidget(self.frame_environments_list, 1) main_layout.addWidget(self.frame_environments_packages, 3) main_layout.setContentsMargins(0, 0, 0, 0) self.frame_environments.setLayout(main_layout) layout = QHBoxLayout() layout.addWidget(self.frame_environments) self.setLayout(layout) # Signals self.button_clone.clicked.connect(self.clone_environment) self.button_create.clicked.connect(self.create_environment) self.button_remove.clicked.connect(self.remove_environment) self.list_environments.sig_item_selected.connect( self.load_environment) self.packages_widget.sig_packages_ready.connect(self.refresh) self.packages_widget.sig_channels_updated.connect(self.update_channels) # self.packages_widget.sig_environment_cloned.connect( # self._environment_created) # self.packages_widget.sig_environment_created.connect( # self._environment_created) # self.packages_widget.sig_environment_removed.connect( # self._environment_removed) self.text_search.textChanged.connect(self.filter_environments) self.timer_environments.timeout.connect(self.refresh_environments) self.packages_widget.sig_process_cancelled.connect( lambda: self.update_visibility(True))
class EnvironmentsTab(WidgetBase): """ This tab holds the list of named and application environments in the local machine. Available options include, `create`, `clone` and `remove` and package management. """ BLACKLIST = ['anaconda-navigator'] # Do not show in package manager. sig_status_updated = Signal(object, object, object, object) def __init__(self, parent=None): super(EnvironmentsTab, self).__init__(parent) self.api = AnacondaAPI() self.last_env_prefix = None self.last_env_name = None self.previous_environments = None self.tracker = GATracker() self.metadata = {} active_channels = CONF.get('main', 'conda_active_channels', tuple()) channels = CONF.get('main', 'conda_channels', tuple()) conda_url = CONF.get('main', 'conda_url', 'https:/conda.anaconda.org') conda_api_url = CONF.get('main', 'anaconda_api_url', 'https://api.anaconda.org') # Widgets self.button_clone = ButtonEnvironmentPrimary("Clone") self.button_create = ButtonEnvironmentPrimary("Create") self.button_remove = ButtonEnvironmentCancel("Remove") self.frame_environments = FrameEnvironments(self) self.frame_environments_list = FrameEnvironmentsList(self) self.frame_environments_list_buttons = FrameEnvironmentsListButtons(self) self.frame_environments_packages = FrameEnvironmentsPackages(self) self.list_environments = ListWidgetEnvironment() self.packages_widget = CondaPackagesWidget( self, setup=False, active_channels=active_channels, channels=channels, data_directory=CHANNELS_PATH, conda_api_url=conda_api_url, conda_url=conda_url) self.menu_list = QMenu() self.text_search = LineEditSearch() self.timer_environments = QTimer() # Widgets setup self.list_environments.setAttribute(Qt.WA_MacShowFocusRect, False) self.list_environments.setContextMenuPolicy(Qt.CustomContextMenu) self.packages_widget.textbox_search.setAttribute( Qt.WA_MacShowFocusRect, False) self.packages_widget.textbox_search.set_icon_visibility(False) self.text_search.setPlaceholderText("Search Environments") self.text_search.setAttribute(Qt.WA_MacShowFocusRect, False) self.timer_environments.setInterval(5000) # Layouts environments_layout = QVBoxLayout() environments_layout.addWidget(self.text_search) buttons_layout = QHBoxLayout() buttons_layout.addWidget(self.button_create) buttons_layout.addWidget(self.button_clone) buttons_layout.addWidget(self.button_remove) buttons_layout.setContentsMargins(0, 0, 0, 0) list_buttons_layout = QVBoxLayout() list_buttons_layout.addWidget(self.list_environments) list_buttons_layout.addLayout(buttons_layout) self.frame_environments_list_buttons.setLayout(list_buttons_layout) list_buttons_layout.setContentsMargins(0, 0, 0, 0) environments_layout.addWidget(self.frame_environments_list_buttons) self.frame_environments_list.setLayout(environments_layout) packages_layout = QHBoxLayout() packages_layout.addWidget(self.packages_widget) packages_layout.setContentsMargins(0, 0, 0, 0) self.frame_environments_packages.setLayout(packages_layout) main_layout = QHBoxLayout() main_layout.addWidget(self.frame_environments_list, 1) main_layout.addWidget(self.frame_environments_packages, 3) main_layout.setContentsMargins(0, 0, 0, 0) self.frame_environments.setLayout(main_layout) layout = QHBoxLayout() layout.addWidget(self.frame_environments) self.setLayout(layout) # Signals self.button_clone.clicked.connect(self.clone_environment) self.button_create.clicked.connect(self.create_environment) self.button_remove.clicked.connect(self.remove_environment) self.list_environments.sig_item_selected.connect( self.load_environment) self.packages_widget.sig_packages_ready.connect(self.refresh) self.packages_widget.sig_channels_updated.connect(self.update_channels) # self.packages_widget.sig_environment_cloned.connect( # self._environment_created) # self.packages_widget.sig_environment_created.connect( # self._environment_created) # self.packages_widget.sig_environment_removed.connect( # self._environment_removed) self.text_search.textChanged.connect(self.filter_environments) self.timer_environments.timeout.connect(self.refresh_environments) self.packages_widget.sig_process_cancelled.connect( lambda: self.update_visibility(True)) # --- Helpers # ------------------------------------------------------------------------- def update_visibility(self, enabled=True): self.button_create.setDisabled(not enabled) self.button_remove.setDisabled(not enabled) self.button_clone.setDisabled(not enabled) self.list_environments.setDisabled(not enabled) update_pointer() def update_style_sheet(self, style_sheet=None): if style_sheet is None: style_sheet = load_style_sheet() self.setStyleSheet(style_sheet) self.menu_list.setStyleSheet(style_sheet) self.list_environments.setFrameStyle(QFrame.NoFrame) self.list_environments.setFrameShape(QFrame.NoFrame) self.packages_widget.table.setFrameStyle(QFrame.NoFrame) self.packages_widget.table.setFrameShape(QFrame.NoFrame) self.packages_widget.layout().setContentsMargins(0, 0, 0, 0) size = QSize(16, 16) palette = { 'icon.action.not_installed': QIcon(images.CONDA_MANAGER_NOT_INSTALLED).pixmap(size), 'icon.action.installed': QIcon(images.CONDA_MANAGER_INSTALLED).pixmap(size), 'icon.action.remove': QIcon(images.CONDA_MANAGER_REMOVE).pixmap(size), 'icon.action.add': QIcon(images.CONDA_MANAGER_ADD).pixmap(size), 'icon.action.upgrade': QIcon(images.CONDA_MANAGER_UPGRADE).pixmap(size), 'icon.action.downgrade': QIcon(images.CONDA_MANAGER_DOWNGRADE).pixmap(size), 'icon.upgrade.arrow': QIcon(images.CONDA_MANAGER_UPGRADE_ARROW).pixmap(size), 'background.remove': QColor(0, 0, 0, 0), 'background.install': QColor(0, 0, 0, 0), 'background.upgrade': QColor(0, 0, 0, 0), 'background.downgrade': QColor(0, 0, 0, 0), 'foreground.not.installed': QColor("#666"), 'foreground.upgrade': QColor("#0071a0"), } self.packages_widget.update_style_sheet( style_sheet=style_sheet, extra_dialogs={'cancel_dialog': ClosePackageManagerDialog, 'apply_actions_dialog': ActionsDialog, 'message_box_error': MessageBoxError, }, palette=palette, ) def get_environments(self): """ Return an ordered dictionary of all existing named environments as keys and the prefix as items. The dictionary includes the root environment as the first entry. """ environments = OrderedDict() environments_prefix = sorted(self.api.conda_get_envs()) environments['root'] = self.api.ROOT_PREFIX for prefix in environments_prefix: name = os.path.basename(prefix) environments[name] = prefix return environments def refresh_environments(self): """ Check every `timer_refresh_envs` amount of miliseconds for newly created environments and update the list if new ones are found. """ environments = self.get_environments() if self.previous_environments is None: self.previous_environments = environments.copy() if self.previous_environments != environments: self.previous_environments = environments.copy() self.setup_tab() def open_environment_in(self, which): environment_prefix = self.list_environments.currentItem().prefix() environment_name = self.list_environments.currentItem().text() logger.debug("%s, %s", which, environment_prefix) if environment_name == 'root': environment_prefix = None if which == 'terminal': launch.console(environment_prefix) else: launch.py_in_console(environment_prefix, which) def set_last_active_prefix(self): current_item = self.list_environments.currentItem() if current_item: self.last_env_prefix = getattr(current_item, '_prefix') else: self.last_env_prefix = self.api.ROOT_PREFIX CONF.set('main', 'last_active_prefix', self.last_env_prefix) def setup_tab(self, metadata={}, load_environment=True): if metadata: self.metadata = metadata # show_apps = CONF.get('main', 'show_application_environments') envs = self.get_environments() self.timer_environments.start() self.menu_list.clear() menu_item = self.menu_list.addAction('Open Terminal') menu_item.triggered.connect( lambda: self.open_environment_in('terminal')) for word in ['Python', 'IPython', 'Jupyter Notebook']: menu_item = self.menu_list.addAction("Open with " + word) menu_item.triggered.connect( lambda x, w=word: self.open_environment_in(w.lower())) def select(value=None, position=None): current_item = self.list_environments.currentItem() prefix = current_item.prefix() if isinstance(position, bool) or position is None: width = current_item.button_options.width() position = QPoint(width, 0) # parent_position = self.list_environments.mapToGlobal(QPoint(0, 0)) point = QPoint(0, 0) parent_position = current_item.button_options.mapToGlobal(point) self.menu_list.move(parent_position + position) self.menu_list.actions()[2].setEnabled( launch.check_prog('ipython', prefix)) self.menu_list.actions()[3].setEnabled( launch.check_prog('notebook', prefix)) self.menu_list.exec_() self.set_last_active_prefix() self.list_environments.clear() # if show_apps: # separator_item = ListItemSeparator('My environments:') # self.list_environments.addItem(separator_item) for env in envs: prefix = envs[env] item = ListItemEnvironment(env, prefix=prefix) item.button_options.clicked.connect(select) self.list_environments.addItem(item) # if show_apps: # application_envs = self.api.get_application_environments() # separator_item = ListItemSeparator('Application environments:') # self.list_environments.addItem(separator_item) # for app in application_envs: # env_prefix = application_envs[app] # item = ListItemEnvironment(name=app, prefix=env_prefix) # item.button_options.clicked.connect(select) # self.list_environments.addItem(item) if load_environment: self.load_environment() else: return # Adjust Tab Order self.setTabOrder(self.text_search, self.list_environments._items[0].widget) for i in range(len(self.list_environments._items) - 1): self.setTabOrder(self.list_environments._items[i].widget, self.list_environments._items[i+1].widget) self.setTabOrder(self.list_environments._items[-1].button_name, self.button_create) self.setTabOrder(self.button_create, self.button_clone) self.setTabOrder(self.button_clone, self.button_remove) self.setTabOrder(self.button_remove, self.packages_widget.combobox_filter) self.setTabOrder(self.packages_widget.combobox_filter, self.packages_widget.button_channels) self.setTabOrder(self.packages_widget.button_channels, self.packages_widget.button_update) self.setTabOrder(self.packages_widget.button_update, self.packages_widget.textbox_search) self.setTabOrder(self.packages_widget.textbox_search, self.packages_widget.table_first_row) self.setTabOrder(self.packages_widget.table_last_row, self.packages_widget.button_apply) self.setTabOrder(self.packages_widget.button_apply, self.packages_widget.button_clear) self.setTabOrder(self.packages_widget.button_clear, self.packages_widget.button_cancel) def filter_environments(self): """ Filter displayed environments by matching search text. """ text = self.text_search.text().lower() for i in range(self.list_environments.count()): item = self.list_environments.item(i) item.setHidden(text not in item.text().lower()) if not item.widget.isVisible(): item.widget.repaint() def load_environment(self, item=None): self.update_visibility(False) if item is None: item = self.list_environments.currentItem() if item is None or not isinstance(item, ListItemEnvironment): prefix = self.api.ROOT_PREFIX index = 0 elif item and isinstance(item, ListItemEnvironment): prefix = item.prefix() else: prefix = self.last_env_prefix if self.last_env_prefix else None index = [i for i, it in enumerate(self.list_environments._items) if prefix in it.prefix()] index = index[0] if len(index) else 0 self.list_environments.setCurrentRow(index) self.packages_widget.set_environment(prefix=prefix) self.packages_widget.setup(check_updates=False, blacklist=self.BLACKLIST, metadata=self.metadata) self.list_environments.setDisabled(True) self.update_visibility(False) self.set_last_active_prefix() # update_pointer(Qt.BusyCursor) def refresh(self): self.update_visibility(True) self.list_environments.setDisabled(False) item = self.list_environments.currentItem() try: item.set_loading(False) except RuntimeError: pass # C/C++ object not found is_root = item.text() == 'root' self.button_remove.setDisabled(is_root) self.button_clone.setDisabled(is_root) def update_channels(self, channels, active_channels): """ Save updated channels to the CONF. """ CONF.set('main', 'conda_active_channels', active_channels) CONF.set('main', 'conda_channels', channels) # --- Callbacks # ------------------------------------------------------------------------- def _environment_created(self, worker, output, error): if error: logger.error(str(error)) self.update_visibility(False) for row, environment in enumerate(self.get_environments()): if worker.name == environment: break self.last_env_prefix = self.api.conda_get_prefix_envname(environment) self.setup_tab(load_environment=False) self.list_environments.setCurrentRow(row) self.load_environment() self.refresh() self.update_visibility(True) update_pointer() def _environment_removed(self, worker, output, error): self.update_visibility(True) if error: logger.error(str(error)) self.setup_tab() self.list_environments.setCurrentRow(0) # --- Public API # ------------------------------------------------------------------------- def update_domains(self, anaconda_api_url, conda_url): self.packages_widget.update_domains( anaconda_api_url=anaconda_api_url, conda_url=conda_url, ) def create_environment(self): """ Create new basic environment with selectable python version. Actually makes new env on disc, in directory within the project whose name depends on the env name. New project state is saved. Should also sync to spec file. """ dlg = CreateEnvironmentDialog(parent=self, environments=self.get_environments()) self.tracker.track_page('/environments/create', pagetitle='Create new environment dialog') if dlg.exec_(): name = dlg.text_name.text().strip() pyver = dlg.combo_version.currentText() if name: logger.debug(str('{0}, {1}'.format(name, pyver))) self.update_visibility(False) update_pointer(Qt.BusyCursor) if pyver: pkgs = ['python=' + pyver, 'jupyter'] else: pkgs = ['jupyter'] channels = self.packages_widget._active_channels logger.debug(str((name, pkgs, channels))) self.update_visibility(False) worker = self.packages_widget.create_environment(name=name, packages=pkgs) # worker = self.api.conda_create(name=name, pkgs=pkgs, # channels=channels) worker.name = name worker.sig_finished.connect(self._environment_created) self.tracker.track_page('/environments') def remove_environment(self): """ Clone currently selected environment. """ current_item = self.list_environments.currentItem() if current_item is not None: name = current_item.text() if name == 'root': return dlg = RemoveEnvironmentDialog(environment=name) self.tracker.track_page('/environments/remove', pagetitle='Remove environment dialog') if dlg.exec_(): logger.debug(str(name)) self.update_visibility(False) update_pointer(Qt.BusyCursor) worker = self.packages_widget.remove_environment(name=name) # worker = self.api.conda_remove(name=name, all_=True) worker.sig_finished.connect(self._environment_removed) # self.sig_status_updated.emit('Deleting environment ' # '"{0}"'.format(name), # 0, -1, -1) self.tracker.track_page('/environments') def clone_environment(self): """ Clone currently selected environment. """ current_item = self.list_environments.currentItem() if current_item is not None: current_name = current_item.text() dlg = CloneEnvironmentDialog(parent=self, environments=self.get_environments()) self.tracker.track_page('/environments/clone', pagetitle='Clone environment dialog') if dlg.exec_(): name = dlg.text_name.text().strip() if name and current_name: logger.debug(str("{0}, {1}".format(current_name, name))) self.update_visibility(False) update_pointer(Qt.BusyCursor) worker = self.packages_widget.clone_environment(clone=current_name, name=name) # worker = self.api.conda_clone(current_name, name=name) worker.name = name worker.sig_finished.connect(self._environment_created) self.tracker.track_page('/environments') def import_environment(self): """
class PackagesTab(QWidget): """ Packages, environments and commands tab widget. """ sig_status_updated = Signal(object, object, object, object) sig_updated = Signal(object, object) sig_project_commands_updated = Signal(object, object) sig_apps_updated = Signal() def __init__(self): super(PackagesTab, self).__init__() self.api = AnacondaAPI() self.path = None self.project = None # Widgets self.list_environments = EditableList(title='Environments') self.list_commands = EditableList(title='Commands', min_items=0) self.package_manager = CondaPackagesWidget( self, setup=False, data_directory=CHANNELS_PATH, ) # Widget setup self.list_environments.button_add.clicked.disconnect() self.list_environments.button_edit.setVisible(False) # Layout top_layout = QHBoxLayout() top_layout.addWidget(self.list_environments) top_layout.addStretch() top_layout.addWidget(self.list_commands) top_layout.addStretch() main_layout = QVBoxLayout() main_layout.addLayout(top_layout) main_layout.addWidget(self.package_manager) self.setLayout(main_layout) # Signals self.list_commands.sig_item_removed.connect(self.edit_commands) self.list_commands.sig_item_edited.connect(self.add_command) self.list_commands.sig_item_selected.connect(self.select_command) self.list_environments.button_add.clicked.connect(self.add_environment) self.list_environments.sig_item_removed.connect( self.remove_environment) self.list_environments.sig_item_selected.connect( self.choose_environment) self.package_manager.sig_channels_updated.connect(self.set_channels) def load_information(self, path, project=None): """ """ self.path = path if project is None: project = self.api.load_project(path) logger.debug(str((path, project.name))) self.project = project # Load commands commands = project.commands self.list_commands.clear() for command in commands: item = QListWidgetItem(command) self.list_commands.add(item) self.list_commands.setCurrentRow(0) # Load environments environments = project.environments self.list_environments.clear() selected_row = 0 for i, environment in enumerate(environments): item = QListWidgetItem(environment) self.list_environments.add(item) if environment == project.default_environment: selected_row = i self.list_environments.setCurrentRow(selected_row) # Load channels self.package_manager.set_environment(prefix=project.env_prefix(path)) self.package_manager.update_channels(project.default_channels, project.default_channels) def set_channels(self, channels, active_channels): """ """ logger.debug(channels) self.project.default_channels = list(active_channels) self.project.save(self.path) # --- Environments # ------------------------------------------------------------------------- def add_environment(self, text=None, pyver=None): """ Create new basic environment with selectable python version. Actually makes new env on disc, in directory within the project whose name depends on the env name. New project state is saved. Should also sync to spec file. """ dlg = CreateEnvironmentDialog(parent=self, envs=self.project.environments) if dlg.exec_(): text = dlg.text_name.text().strip() pyver = dlg.combo_version.currentText() if text: self.setEnabled(False) QApplication.setOverrideCursor(Qt.BusyCursor) # FIXME: This does not seem like a very safe way. What if it fails? self.project.default_environment = text self.project.environments[text] = "{0}.yaml".format(text) prefix = self.project.env_prefix(self.path) if pyver: pkgs = ['python=' + pyver, 'jupyter'] else: pkgs = ['jupyter'] channels = self.project.default_channels logger.debug(str((prefix, pkgs, channels))) worker = self.api.conda_create(prefix=prefix, pkgs=pkgs, channels=channels) worker.text = text worker.sig_finished.connect(self._environment_added) def _environment_added(self, worker, output, error): """ Callback for worker after envrionemnt creation has finished. """ text = worker.text item = QListWidgetItem(text) self.list_environments.add(item) self.list_environments.setCurrentRow( len(self.project.environments) - 1) self.setEnabled(True) self.project.save(self.path) self.choose_environment() QApplication.restoreOverrideCursor() def remove_environment(self, item): """ Delete environment from project and project directory. """ text = item.text() self.project.default_environment = text path = self.project.env_prefix(self.path) logger.debug(str((path, text))) shutil.rmtree(path) self.project.environments.pop(text) self.project.save(self.path) self.choose_environment() def choose_environment(self): """ The user has picked a different environment. Refresh the package list and save the new state of the project. """ current_item_text = self.list_environments.currentItem().text() logger.debug(current_item_text) self.project.default_environment = current_item_text self.project.save(self.path) prefix = self.project.env_prefix(self.path) self.package_manager.set_environment(prefix=prefix) self.package_manager.setup() # --- Commands # ------------------------------------------------------------------------- def add_command(self, command=None): """ Add a new command in the commands list. Adds to the bottom of the list. """ if command: item = QListWidgetItem(command) self.list_commands.add(item) commands = [ self.list_commands.item(i).text() for i in range(self.list_commands.count()) ] self.project.commands = commands self.project.save(self.path) self.sig_project_commands_updated.emit(self.path, self.project.commands) logger.debug(self.project.commands) def edit_commands(self): """ """ commands = [ self.list_commands.item(i).text() for i in range(self.list_commands.count()) ] self.project.commands = commands self.project.save(self.path) self.sig_project_commands_updated.emit(self.path, self.project.commands) logger.debug(self.project.commands) def select_command(self): """ """ self.sig_apps_updated.emit() logger.debug(self.project.commands)