Skip to content

Commit 1270613

Browse files
committed
WIP
[ci skip]
1 parent 61bdf7d commit 1270613

File tree

5 files changed

+157
-13
lines changed

5 files changed

+157
-13
lines changed

spyder/plugins/remoteclient/plugin.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class RemoteClient(SpyderPluginV2):
7171
"""
7272

7373
NAME = "remoteclient"
74-
OPTIONAL = [Plugins.IPythonConsole, Plugins.MainMenu]
74+
OPTIONAL = [Plugins.MainMenu]
7575
CONF_SECTION = NAME
7676
CONTAINER_CLASS = RemoteClientContainer
7777
CONF_FILE = False
@@ -90,6 +90,20 @@ class RemoteClient(SpyderPluginV2):
9090

9191
sig_version_mismatch = Signal(str, str)
9292

93+
# For remote envs
94+
sig_import_env_requested = Signal(str, str, str)
95+
"""
96+
Signal to request importing an environment in the remote machine.
97+
98+
Parameters
99+
----------
100+
config_id: str
101+
Machine identifier.
102+
import_file_path: str
103+
Path to the file that will be used to import the environment.
104+
env_name: str
105+
Environment name.
106+
"""
93107

94108
def __init__(self, *args, **kwargs):
95109
super().__init__(*args, **kwargs)
@@ -120,6 +134,9 @@ def on_initialize(self):
120134
container.sig_stop_server_requested.connect(self.sig_server_stopped)
121135
container.sig_server_renamed.connect(self.sig_server_renamed)
122136
container.sig_server_changed.connect(self.sig_server_changed)
137+
container.sig_import_env_requested.connect(
138+
self.sig_import_env_requested
139+
)
123140

124141
# Plugin signals
125142
self.sig_connection_status_changed.connect(

spyder/plugins/remoteclient/widgets/connectiondialog.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class ConnectionDialog(SidebarDialog):
5252
sig_stop_server_requested = Signal(str)
5353
sig_server_renamed = Signal(str)
5454
sig_connections_changed = Signal()
55+
sig_import_env_requested = Signal(str, str, str)
5556

5657
def __init__(self, parent=None):
5758
self.ICON = ima.icon('remote_server')
@@ -187,9 +188,11 @@ def _save_connection_info(self):
187188
"""Save the connection info stored in a page."""
188189
page = self.get_page()
189190

190-
# Validate info
191-
if not page.validate_page():
192-
return
191+
# Validation is done in _on_button_next_clicked in this case
192+
if not(ENV_MANAGER and page.NEW_CONNECTION):
193+
# Validate info
194+
if not page.validate_page():
195+
return
193196

194197
if page.NEW_CONNECTION:
195198
# Save info provided by users
@@ -265,7 +268,10 @@ def _start_server(self):
265268
page = self.get_page()
266269

267270
# Validate info
268-
if not page.validate_page():
271+
if ENV_MANAGER and page.NEW_CONNECTION:
272+
if not self._new_connection_page.validate_env_creation():
273+
return
274+
elif not page.validate_page():
269275
return
270276

271277
# This uses the current host_id in case users want to start a
@@ -280,7 +286,23 @@ def _start_server(self):
280286
# TODO: Handle the case when the connection info is active and
281287
# users change its info.
282288

283-
self.sig_start_server_requested.emit(host_id)
289+
if ENV_MANAGER and page.NEW_CONNECTION:
290+
if page.selected_env_creation_method() == CreateEnvMethods.NewEnv:
291+
# TODO! Implement later
292+
pass
293+
elif (
294+
page.selected_env_creation_method()
295+
== CreateEnvMethods.ImportEnv
296+
):
297+
import_file_path, env_name = page.get_create_env_info()
298+
print(import_file_path, env_name)
299+
self.sig_import_env_requested.emit(
300+
host_id, import_file_path, env_name
301+
)
302+
elif page.selected_env_creation_method() == CreateEnvMethods.NoEnv:
303+
self.sig_start_server_requested.emit(host_id)
304+
else:
305+
self.sig_start_server_requested.emit(host_id)
284306

285307
def _stop_server(self):
286308
"""Stop the server corresponding to a given page."""

spyder/plugins/remoteclient/widgets/connectionpages.py

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
from spyder.widgets.helperwidgets import MessageLabel, TipWidget
5050

5151
try:
52-
import spyder_env_manager # noqa
52+
from spyder_env_manager.spyder.widgets.new_environment import NewEnvironment
5353
ENV_MANAGER = True
5454
except Exception:
5555
ENV_MANAGER = False
@@ -707,6 +707,13 @@ def get_name(self):
707707
return _("New connection")
708708

709709
def setup_page(self):
710+
# Attributes
711+
self.env_method_group = QButtonGroup(self)
712+
self._radio_buttons_to_info_widgets: dict[
713+
CreateEnvMethods, QWidget
714+
] = {}
715+
716+
# Widgets
710717
self.ssh_info_widget = self.create_ssh_connection_info_widget()
711718
jupyterhub_info_widget = self.create_jupyterhub_connection_info_widget()
712719

@@ -807,6 +814,29 @@ def is_ssh_info_widget_shown(self) -> bool:
807814
def selected_env_creation_method(self) -> CreateEnvMethods:
808815
return self.env_method_group.checkedId()
809816

817+
def validate_env_creation(self):
818+
method_id = self.env_method_group.checkedId()
819+
if method_id != CreateEnvMethods.NoEnv:
820+
env_method_widget = self._radio_buttons_to_info_widgets[method_id]
821+
if env_method_widget.validate_page(env_names=[]):
822+
return True
823+
else:
824+
return False
825+
826+
return True
827+
828+
def get_create_env_info(self):
829+
method_id = self.env_method_group.checkedId()
830+
env_method_widget = self._radio_buttons_to_info_widgets[method_id]
831+
if method_id == CreateEnvMethods.NewEnv:
832+
# TODO! Implement later
833+
pass
834+
elif method_id == CreateEnvMethods.ImportEnv:
835+
return (
836+
env_method_widget.get_zip_file(),
837+
env_method_widget.get_env_name()
838+
)
839+
810840
# ---- Private API
811841
# -------------------------------------------------------------------------
812842
def _create_env_creation_widget(self):
@@ -842,7 +872,9 @@ def _create_env_creation_widget(self):
842872
# Available methods
843873
methods_group = QGroupBox(_("Available methods"))
844874

845-
self.env_method_group = QButtonGroup(self)
875+
self.env_method_group.idToggled.connect(
876+
self._on_env_creation_method_changed
877+
)
846878

847879
new_env_radio = self.create_radiobutton(
848880
_("Create a new environment"),
@@ -863,15 +895,60 @@ def _create_env_creation_widget(self):
863895
id_=CreateEnvMethods.NoEnv,
864896
)
865897

866-
new_env_radio.radiobutton.setChecked(True)
867-
868898
methods_layout = QVBoxLayout()
869899
methods_layout.addSpacing(3)
870900
methods_layout.addWidget(new_env_radio)
871901
methods_layout.addWidget(import_env_radio)
872902
methods_layout.addWidget(no_env_radio)
873903
methods_group.setLayout(methods_layout)
874904

905+
# Required info
906+
info_group = QGroupBox(_("Required information"))
907+
908+
new_env_info = NewEnvironment(
909+
self,
910+
max_width_for_content=470,
911+
show_in_remote_connections_dialog=True
912+
)
913+
new_env_info.setMaximumWidth(470)
914+
915+
import_env_info = NewEnvironment(
916+
self,
917+
max_width_for_content=470,
918+
import_env=True,
919+
show_in_remote_connections_dialog=True
920+
)
921+
import_env_info.setMaximumWidth(470)
922+
923+
no_env_info = QLabel(
924+
_(
925+
"You can set up an environment later by going to the menu "
926+
"entry <i>Tools > Environment manager</i>."
927+
)
928+
)
929+
no_env_info.setWordWrap(True)
930+
931+
info_layout = QVBoxLayout()
932+
info_layout.addWidget(new_env_info)
933+
info_layout.addWidget(import_env_info)
934+
info_layout.addWidget(no_env_info)
935+
info_group.setLayout(info_layout)
936+
937+
# Hide all info widgets to show
938+
for widget in [new_env_info, import_env_info, no_env_info]:
939+
widget.setVisible(False)
940+
941+
# Use the following mapping to show/hide info widgets when the
942+
# corresponding radio button is toggled
943+
self._radio_buttons_to_info_widgets = {
944+
CreateEnvMethods.NewEnv: new_env_info,
945+
CreateEnvMethods.ImportEnv: import_env_info,
946+
CreateEnvMethods.NoEnv: no_env_info,
947+
}
948+
949+
# Set new env as the default method
950+
new_env_radio.radiobutton.setChecked(True)
951+
875952
# Final layout
876953
layout = QVBoxLayout()
877954
layout.setContentsMargins(
@@ -880,13 +957,19 @@ def _create_env_creation_widget(self):
880957
layout.addLayout(intro_layout)
881958
layout.addSpacing(8 * AppStyle.MarginSize)
882959
layout.addWidget(methods_group)
960+
layout.addWidget(info_group)
883961
layout.addStretch()
884962

885963
env_creation_widget = QWidget(self)
886964
env_creation_widget.setLayout(layout)
887965

888966
return env_creation_widget
889967

968+
def _on_env_creation_method_changed(
969+
self, id_: CreateEnvMethods, checked: bool
970+
):
971+
self._radio_buttons_to_info_widgets[id_].setVisible(checked)
972+
890973

891974
class ConnectionPage(BaseConnectionPage):
892975
"""Page to display connection status and info for a remote machine."""

spyder/plugins/remoteclient/widgets/container.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
# Standard library imports
1111
from __future__ import annotations
1212
from collections import deque
13-
import functools
1413

1514
# Third-party imports
1615
from qtpy.QtCore import Signal
@@ -31,6 +30,7 @@
3130

3231

3332
class RemoteClientContainer(PluginMainContainer):
33+
3434
sig_start_server_requested = Signal(str)
3535
"""
3636
This signal is used to request starting a remote server.
@@ -88,6 +88,20 @@ class RemoteClientContainer(PluginMainContainer):
8888
Dictionary that contains the log message and its metadata.
8989
"""
9090

91+
sig_import_env_requested = Signal(str, str, str)
92+
"""
93+
Signal to request importing an environment in the remote machine.
94+
95+
Parameters
96+
----------
97+
config_id: str
98+
Machine identifier.
99+
import_file_path: str
100+
Path to the file that will be used to import the environment.
101+
env_name: str
102+
Environment name.
103+
"""
104+
91105
# ---- PluginMainContainer API
92106
# -------------------------------------------------------------------------
93107
def setup(self):
@@ -153,6 +167,9 @@ def _show_connection_dialog(self):
153167
self.sig_server_changed
154168
)
155169
connection_dialog.sig_server_renamed.connect(self.sig_server_renamed)
170+
connection_dialog.sig_import_env_requested.connect(
171+
self.sig_import_env_requested
172+
)
156173

157174
connection_dialog.show()
158175

spyder/widgets/config.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,11 @@ def create_radiobutton(self, text, option, default=NoDefault,
549549
radiobutton = QRadioButton(text)
550550
layout.addWidget(radiobutton)
551551

552-
if section is not None and section != self.CONF_SECTION:
552+
if (
553+
option is not None
554+
and section is not None
555+
and section != self.CONF_SECTION
556+
):
553557
self.cross_section_options[option] = section
554558

555559
if button_group is None:
@@ -562,7 +566,8 @@ def create_radiobutton(self, text, option, default=NoDefault,
562566
else:
563567
button_group.addButton(radiobutton, id=id_)
564568

565-
self.radiobuttons[radiobutton] = (section, option, default)
569+
if option is not None:
570+
self.radiobuttons[radiobutton] = (section, option, default)
566571

567572
if msg_warning is not None or msg_info is not None:
568573
def show_message(is_checked):

0 commit comments

Comments
 (0)