@@ -13,26 +13,33 @@ import com.intellij.ui.dsl.builder.LabelPosition
13
13
import com.intellij.ui.dsl.builder.Panel
14
14
import com.intellij.ui.dsl.builder.Row
15
15
import com.intellij.ui.dsl.builder.bindIntText
16
+ import com.intellij.ui.dsl.builder.bindIntValue
16
17
import com.intellij.ui.dsl.builder.bindSelected
17
18
import com.intellij.ui.dsl.builder.bindText
18
19
import com.intellij.ui.dsl.builder.columns
19
20
import com.intellij.ui.dsl.builder.panel
21
+ import com.intellij.ui.layout.ComponentPredicate
20
22
import kotlin.reflect.KMutableProperty0
21
23
import org.utbot.cpp.clion.plugin.UTBot
22
24
import org.utbot.cpp.clion.plugin.listeners.UTBotSettingsChangedListener
25
+ import org.utbot.cpp.clion.plugin.ui.ObservableValue
23
26
import org.utbot.cpp.clion.plugin.ui.sourceFoldersView.UTBotProjectViewPaneForSettings
24
27
import org.utbot.cpp.clion.plugin.utils.commandLineEditor
28
+ import org.utbot.cpp.clion.plugin.utils.isWindows
29
+ import org.utbot.cpp.clion.plugin.utils.toWslFormat
25
30
import java.awt.Dimension
26
31
27
32
class UTBotConfigurable (private val myProject : Project ) : BoundConfigurable(
28
- " Project Settings to generate tests "
33
+ " Project Settings to Generate Tests "
29
34
) {
30
35
private val logger = Logger .getInstance(" ProjectConfigurable" )
31
36
private val panel by lazy { createMainPanel() }
32
37
33
38
private val settings: UTBotProjectStoredSettings .State
34
39
get() = myProject.settings.storedSettings
35
40
41
+ private val isLocalOrWsl = ObservableValue (settings.isLocalOrWslScenario)
42
+
36
43
init {
37
44
myProject.messageBus.connect()
38
45
.subscribe(UTBotSettingsChangedListener .TOPIC , UTBotSettingsChangedListener {
@@ -55,130 +62,169 @@ class UTBotConfigurable(private val myProject: Project) : BoundConfigurable(
55
62
private fun createMainPanel (): DialogPanel {
56
63
logger.trace(" createPanel was called" )
57
64
return panel {
58
- group(" Connection Settings" ) {
59
- row(UTBot .message(" settings.project.port" )) {
60
- intTextField().bindIntText(projectIndependentSettings::port).applyToComponent {
61
- maximumSize = TEXT_FIELD_MAX_SIZE
62
- }
63
- }.rowComment(UTBot .message(" deployment.utbotPort.description" ))
64
- row(UTBot .message(" settings.project.serverName" )) {
65
- textField().bindText(projectIndependentSettings::serverName)
66
- }.rowComment(UTBot .message(" deployment.utbotHost.description" ))
67
- row(UTBot .message(" settings.project.remotePath" )) {
68
- textField().bindText(settings::remotePath).columns(COLUMNS_LARGE )
69
- }.rowComment(UTBot .message(" deployment.remotePath.description" ))
70
- }
65
+ group(" Connection Settings" ) { this .createConnectionSettings() }
66
+ group(" Paths" ) { this .createPathsSettings() }
67
+ group(" CMake" ) { this .createCMakeSettings() }
68
+ group(" Generator Settings" ) { this .createGeneratorSettings() }
69
+ }
70
+ }
71
71
72
- group(" Paths" ) {
73
- row(UTBot .message(" settings.project.projectPath" )) {
74
- textFieldWithBrowseButton(
75
- UTBot .message(" settings.project.projectPath.title" ),
76
- myProject,
77
- FileChooserDescriptorFactory .createSingleFileDescriptor()
78
- ).bindText(
79
- getter = { myProject.settings.projectPath },
80
- setter = { value -> myProject.settings.projectPath = value })
81
- .columns(COLUMNS_LARGE )
82
- }.rowComment(UTBot .message(" settings.project.projectPath.info" ))
83
- createPathChooser(
84
- settings::buildDirRelativePath,
85
- UTBot .message(" settings.project.buildDir" ),
86
- UTBot .message(" settings.project.buildDir.browse.title" )
87
- ).rowComment(UTBot .message(" paths.buildDirectory.description" ))
88
- createPathChooser(
89
- settings::targetPath,
90
- UTBot .message(" settings.project.target" ),
91
- UTBot .message(" settings.project.target.browse.title" )
92
- ).rowComment(UTBot .message(" paths.target.description" ))
93
- createPathChooser(
94
- settings::testDirPath,
95
- UTBot .message(" settings.project.testsDir" ),
96
- UTBot .message(" settings.project.testsDir.browse.title" )
97
- ).rowComment(UTBot .message(" paths.testsDirectory.description" ))
98
-
99
- row {
100
- val pane = UTBotProjectViewPaneForSettings (myProject)
101
- cell(pane.createComponent()).onApply {
102
- pane.apply ()
103
- }.onReset {
104
- pane.reset()
105
- }.onIsModified {
106
- pane.isModified()
107
- }.label(UTBot .message(" settings.project.sourcePaths" ), LabelPosition .TOP )
108
- }.bottomGap(BottomGap .SMALL ).rowComment(UTBot .message(" paths.sourceDirectories.description" ))
109
-
110
-
111
- row {
112
- label(" Try to get paths from CMake model: " )
113
- button(" Detect Paths" ) {
114
- myProject.settings.predictPaths()
115
- myProject.settings.fireUTBotSettingsChanged()
116
- }
117
- }.rowComment(" Queries CMake configurations to get source paths and build path. Also predicts tests folder" )
72
+ private fun Panel.createConnectionSettings () {
73
+ row(UTBot .message(" settings.project.port" )) {
74
+ intTextField().bindIntText(projectIndependentSettings::port).applyToComponent {
75
+ maximumSize = TEXT_FIELD_MAX_SIZE
118
76
}
77
+ }.rowComment(UTBot .message(" deployment.utbotPort.description" ))
78
+
79
+ row {
80
+ checkBox(" Local or WSL scenario" )
81
+ .bindSelected(settings::isLocalOrWslScenario)
82
+ .applyToComponent {
83
+ this .addActionListener {
84
+ isLocalOrWsl.value = ! isLocalOrWsl.value
85
+ }
86
+ }
87
+ }
119
88
120
- group(" CMake" ) {
121
- row(UTBot .message(" settings.project.cmakeOptions" )) {
122
- commandLineEditor(
123
- { settings.cmakeOptions },
124
- { settings.cmakeOptions = it }
125
- )
126
- }.rowComment(UTBot .message(" paths.cmakeOptions.description" ))
127
- }
89
+ val enabledIfNotLocalOrWslScenario = object : ComponentPredicate () {
90
+ override fun invoke (): Boolean = ! isLocalOrWsl.value
91
+ override fun addListener (listener : (Boolean ) -> Unit ) =
92
+ isLocalOrWsl.addOnChangeListener { value -> listener(! value) }
93
+ }
128
94
129
- data class CheckBoxInfo (
130
- val boolProperty : KMutableProperty0 <Boolean >,
131
- val title : String ,
132
- val description : String
133
- ) {
134
- fun add (panel : Panel ) {
135
- panel.row {
136
- checkBox(title).bindSelected(boolProperty)
137
- }.rowComment(description)
95
+ row(UTBot .message(" settings.project.serverName" )) {
96
+ textField().bindText(projectIndependentSettings::serverName).applyToComponent {
97
+ isLocalOrWsl.addOnChangeListener { newValue ->
98
+ if (newValue)
99
+ this .text = " localhost"
138
100
}
139
- }
101
+ }.enabledIf(enabledIfNotLocalOrWslScenario)
102
+ }.rowComment(UTBot .message(" deployment.utbotHost.description" ))
103
+
104
+ row(UTBot .message(" settings.project.remotePath" )) {
105
+ textField().bindText(settings::remotePath).columns(COLUMNS_LARGE )
106
+ .applyToComponent {
107
+ isLocalOrWsl.addOnChangeListener { newValue ->
108
+ if (newValue)
109
+ this .text = if (isWindows) myProject.settings.projectPath.toWslFormat() else " "
110
+ }
111
+ }.enabledIf(enabledIfNotLocalOrWslScenario)
112
+ }.rowComment(UTBot .message(" deployment.remotePath.description" ))
113
+ }
140
114
141
- group(" Generator settings" ) {
142
- val checkBoxes = listOf (
143
- CheckBoxInfo (
144
- settings::useStubs,
145
- UTBot .message(" stubs.useStubs.title" ),
146
- UTBot .message(" stubs.useStubs.description" )
147
- ),
148
- CheckBoxInfo (
149
- settings::verbose,
150
- UTBot .message(" testsGeneration.verboseFormatting.title" ),
151
- UTBot .message(" testsGeneration.verboseFormatting.description" )
152
- ),
153
- CheckBoxInfo (
154
- settings::useDeterministicSearcher,
155
- UTBot .message(" advanced.useDeterministicSearcher.title" ),
156
- UTBot .message(" advanced.useDeterministicSearcher.description" )
157
- ),
158
- CheckBoxInfo (
159
- settings::generateForStaticFunctions,
160
- UTBot .message(" testsGeneration.generateForStaticFunctions.title" ),
161
- UTBot .message(" testsGeneration.generateForStaticFunctions.description" )
162
- )
163
- )
164
- checkBoxes.forEach {
165
- it.add(this )
166
- }
115
+ private fun Panel.createPathsSettings () {
116
+ row(UTBot .message(" settings.project.projectPath" )) {
117
+ textFieldWithBrowseButton(
118
+ UTBot .message(" settings.project.projectPath.title" ),
119
+ myProject,
120
+ FileChooserDescriptorFactory .createSingleFileDescriptor()
121
+ ).bindText(
122
+ getter = { myProject.settings.projectPath },
123
+ setter = { value -> myProject.settings.projectPath = value })
124
+ .columns(COLUMNS_LARGE )
125
+ }.rowComment(UTBot .message(" settings.project.projectPath.info" ))
126
+ createPathChooser(
127
+ settings::buildDirRelativePath,
128
+ UTBot .message(" settings.project.buildDir" ),
129
+ UTBot .message(" settings.project.buildDir.browse.title" )
130
+ ).rowComment(UTBot .message(" paths.buildDirectory.description" ))
131
+ createPathChooser(
132
+ settings::targetPath,
133
+ UTBot .message(" settings.project.target" ),
134
+ UTBot .message(" settings.project.target.browse.title" )
135
+ ).rowComment(UTBot .message(" paths.target.description" ))
136
+ createPathChooser(
137
+ settings::testDirPath,
138
+ UTBot .message(" settings.project.testsDir" ),
139
+ UTBot .message(" settings.project.testsDir.browse.title" )
140
+ ).rowComment(UTBot .message(" paths.testsDirectory.description" ))
141
+
142
+ row {
143
+ val pane = UTBotProjectViewPaneForSettings (myProject)
144
+ cell(pane.createComponent()).onApply {
145
+ pane.apply ()
146
+ }.onReset {
147
+ pane.reset()
148
+ }.onIsModified {
149
+ pane.isModified()
150
+ }.label(UTBot .message(" settings.project.sourcePaths" ), LabelPosition .TOP )
151
+ }.bottomGap(BottomGap .SMALL ).rowComment(UTBot .message(" paths.sourceDirectories.description" ))
152
+
153
+
154
+ row {
155
+ label(" Try to get paths from CMake model: " )
156
+ button(" Detect Paths" ) {
157
+ myProject.settings.predictPaths()
158
+ myProject.settings.fireUTBotSettingsChanged()
159
+ }
160
+ }.rowComment(" Queries CMake configurations to get source paths and build path. Also predicts tests folder" )
161
+ }
167
162
168
- row(UTBot .message(" advanced.timeoutPerFunction.title" )) {
169
- intTextField().bindIntText(settings::timeoutPerFunction).applyToComponent {
170
- maximumSize = TEXT_FIELD_MAX_SIZE
171
- }
172
- }.rowComment(UTBot .message(" advanced.timeoutPerFunction.description" ))
163
+ private fun Panel.createCMakeSettings () {
164
+ row(UTBot .message(" settings.project.cmakeOptions" )) {
165
+ commandLineEditor(
166
+ { settings.cmakeOptions },
167
+ { settings.cmakeOptions = it }
168
+ )
169
+ }.rowComment(UTBot .message(" paths.cmakeOptions.description" ))
170
+ }
173
171
174
- row(UTBot .message(" advanced.timeoutPerTest.title" )) {
175
- intTextField().bindIntText(settings::timeoutPerFunction).applyToComponent {
176
- maximumSize = TEXT_FIELD_MAX_SIZE
177
- }
178
- }.rowComment(UTBot .message(" advanced.timeoutPerTest.description" ))
172
+ private fun Panel.createGeneratorSettings () {
173
+ data class CheckBoxInfo (
174
+ val boolProperty : KMutableProperty0 <Boolean >,
175
+ val title : String ,
176
+ val description : String
177
+ ) {
178
+ fun add (panel : Panel ) {
179
+ panel.row {
180
+ checkBox(title).bindSelected(boolProperty)
181
+ }.rowComment(description)
179
182
}
183
+ }
180
184
185
+ val checkBoxes = listOf (
186
+ CheckBoxInfo (
187
+ settings::useStubs,
188
+ UTBot .message(" stubs.useStubs.title" ),
189
+ UTBot .message(" stubs.useStubs.description" )
190
+ ),
191
+ CheckBoxInfo (
192
+ settings::verbose,
193
+ UTBot .message(" testsGeneration.verboseFormatting.title" ),
194
+ UTBot .message(" testsGeneration.verboseFormatting.description" )
195
+ ),
196
+ CheckBoxInfo (
197
+ settings::useDeterministicSearcher,
198
+ UTBot .message(" advanced.useDeterministicSearcher.title" ),
199
+ UTBot .message(" advanced.useDeterministicSearcher.description" )
200
+ ),
201
+ CheckBoxInfo (
202
+ settings::generateForStaticFunctions,
203
+ UTBot .message(" testsGeneration.generateForStaticFunctions.title" ),
204
+ UTBot .message(" testsGeneration.generateForStaticFunctions.description" )
205
+ )
206
+ )
207
+ checkBoxes.forEach {
208
+ it.add(this )
181
209
}
210
+
211
+ row(UTBot .message(" advanced.timeoutPerFunction.title" )) {
212
+ spinner(
213
+ UTBotProjectStoredSettings .TIMEOUT_PER_FUNCTION_MIN_VALUE ..
214
+ UTBotProjectStoredSettings .TIMEOUT_PER_FUNCTION_MAX_VALUE
215
+ ).bindIntValue(settings::timeoutPerFunction).applyToComponent {
216
+ maximumSize = TEXT_FIELD_MAX_SIZE
217
+ }
218
+ }.rowComment(UTBot .message(" advanced.timeoutPerFunction.description" ))
219
+
220
+ row(UTBot .message(" advanced.timeoutPerTest.title" )) {
221
+ spinner(
222
+ UTBotProjectStoredSettings .TIMEOUT_PER_TEST_MIN_VALUE ..
223
+ UTBotProjectStoredSettings .TIMEOUT_PER_TEST_MAX_VALUE
224
+ ).bindIntValue(settings::timeoutPerFunction).applyToComponent {
225
+ maximumSize = TEXT_FIELD_MAX_SIZE
226
+ }
227
+ }.rowComment(UTBot .message(" advanced.timeoutPerTest.description" ))
182
228
}
183
229
184
230
override fun isModified (): Boolean {
0 commit comments