skeleton of setup wizard
This commit is contained in:
@ -141,4 +141,9 @@ mvcGroups {
|
||||
view = 'com.muwire.gui.SignView'
|
||||
controller = 'com.muwire.gui.SignController'
|
||||
}
|
||||
'wizard' {
|
||||
model = 'com.muwire.gui.wizard.WizardModel'
|
||||
view = 'com.muwire.gui.wizard.WizardView'
|
||||
controller = 'com.muwire.gui.wizard.WizardController'
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
package com.muwire.gui.wizard
|
||||
|
||||
import griffon.core.artifact.GriffonController
|
||||
import griffon.core.controller.ControllerAction
|
||||
import griffon.inject.MVCMember
|
||||
import griffon.metadata.ArtifactProviderFor
|
||||
import javax.annotation.Nonnull
|
||||
import javax.swing.JOptionPane
|
||||
|
||||
@ArtifactProviderFor(GriffonController)
|
||||
class WizardController {
|
||||
@MVCMember @Nonnull
|
||||
WizardModel model
|
||||
@MVCMember @Nonnull
|
||||
WizardView view
|
||||
|
||||
@ControllerAction
|
||||
void previous() {
|
||||
model.currentStep--
|
||||
recalcButtons()
|
||||
view.updateLayout()
|
||||
}
|
||||
|
||||
@ControllerAction
|
||||
void next() {
|
||||
def errors = model.steps[model.currentStep].validate()
|
||||
if (errors) {
|
||||
String errorMessage = String.join("\n", errors)
|
||||
JOptionPane.showMessageDialog(model.parent, errorMessage, "Invalid Input", JOptionPane.ERROR_MESSAGE)
|
||||
} else {
|
||||
model.currentStep++
|
||||
recalcButtons()
|
||||
view.updateLayout()
|
||||
}
|
||||
}
|
||||
|
||||
@ControllerAction
|
||||
void finish() {
|
||||
|
||||
}
|
||||
|
||||
private void recalcButtons() {
|
||||
model.previousButtonEnabled = model.currentStep > 0
|
||||
model.nextButtonEnabled = model.steps.size() > (model.currentStep + 1)
|
||||
model.finishButtonEnabled = model.steps.size() == (model.currentStep + 1)
|
||||
}
|
||||
}
|
@ -54,27 +54,41 @@ class Ready extends AbstractLifecycleHandler {
|
||||
} else {
|
||||
log.info("creating new properties")
|
||||
props = new MuWireSettings()
|
||||
props.incompleteLocation = new File(home, "incompletes")
|
||||
props.embeddedRouter = Boolean.parseBoolean(System.getProperties().getProperty("embeddedRouter"))
|
||||
props.updateType = System.getProperty("updateType","jar")
|
||||
props.setNickname(selectNickname())
|
||||
|
||||
|
||||
def portableDownloads = System.getProperty("portable.downloads")
|
||||
if (portableDownloads != null) {
|
||||
props.downloadLocation = new File(portableDownloads)
|
||||
} else {
|
||||
def chooser = new JFileChooser()
|
||||
chooser.setFileHidingEnabled(false)
|
||||
chooser.setDialogTitle("Select a directory where downloads will be saved")
|
||||
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)
|
||||
int rv = chooser.showOpenDialog(null)
|
||||
if (rv != JFileChooser.APPROVE_OPTION) {
|
||||
JOptionPane.showMessageDialog(null, "MuWire will now exit")
|
||||
System.exit(0)
|
||||
}
|
||||
props.downloadLocation = chooser.getSelectedFile()
|
||||
}
|
||||
boolean embeddedRouterAvailable = Boolean.parseBoolean(System.getProperties().getProperty("embeddedRouter"))
|
||||
|
||||
def parent = application.windowManager.findWindow("event-list")
|
||||
Properties i2pProps = new Properties()
|
||||
|
||||
def params = [:]
|
||||
params['parent'] = parent
|
||||
params['embeddedRouterAvailable'] = embeddedRouterAvailable
|
||||
params['muSettings'] = props
|
||||
params['i2pProps'] = i2pProps
|
||||
|
||||
application.mvcGroupManager.createMVCGroup("wizard", params)
|
||||
|
||||
|
||||
// props.incompleteLocation = new File(home, "incompletes")
|
||||
// props.embeddedRouter = Boolean.parseBoolean(System.getProperties().getProperty("embeddedRouter"))
|
||||
// props.updateType = System.getProperty("updateType","jar")
|
||||
// props.setNickname(selectNickname())
|
||||
//
|
||||
//
|
||||
// def portableDownloads = System.getProperty("portable.downloads")
|
||||
// if (portableDownloads != null) {
|
||||
// props.downloadLocation = new File(portableDownloads)
|
||||
// } else {
|
||||
// def chooser = new JFileChooser()
|
||||
// chooser.setFileHidingEnabled(false)
|
||||
// chooser.setDialogTitle("Select a directory where downloads will be saved")
|
||||
// chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)
|
||||
// int rv = chooser.showOpenDialog(null)
|
||||
// if (rv != JFileChooser.APPROVE_OPTION) {
|
||||
// JOptionPane.showMessageDialog(null, "MuWire will now exit")
|
||||
// System.exit(0)
|
||||
// }
|
||||
// props.downloadLocation = chooser.getSelectedFile()
|
||||
// }
|
||||
|
||||
propsFile.withPrintWriter("UTF-8", {
|
||||
props.write(it)
|
||||
|
@ -0,0 +1,32 @@
|
||||
package com.muwire.gui.wizard
|
||||
|
||||
import java.awt.Component
|
||||
|
||||
import com.muwire.core.MuWireSettings
|
||||
|
||||
import griffon.core.artifact.GriffonModel
|
||||
import griffon.transform.Observable
|
||||
import griffon.metadata.ArtifactProviderFor
|
||||
|
||||
@ArtifactProviderFor(GriffonModel)
|
||||
class WizardModel {
|
||||
Component parent
|
||||
boolean embeddedRouterAvailable
|
||||
MuWireSettings muSettings
|
||||
Properties i2pProps
|
||||
|
||||
final List<WizardStep> steps = [new NicknameStep(),
|
||||
new DirectoriesStep()]
|
||||
int currentStep
|
||||
|
||||
@Observable boolean finishButtonEnabled
|
||||
@Observable boolean previousButtonEnabled
|
||||
@Observable boolean nextButtonEnabled
|
||||
|
||||
void mvcGroupInit(Map<String,String> args) {
|
||||
currentStep = 0
|
||||
previousButtonEnabled = false
|
||||
nextButtonEnabled = steps.size() > (currentStep + 1)
|
||||
finishButtonEnabled = steps.size() == currentStep + 1
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package com.muwire.gui.wizard
|
||||
|
||||
import griffon.core.artifact.GriffonView
|
||||
import griffon.inject.MVCMember
|
||||
import griffon.metadata.ArtifactProviderFor
|
||||
|
||||
import javax.swing.JDialog
|
||||
import javax.swing.SwingConstants
|
||||
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.event.WindowAdapter
|
||||
import java.awt.event.WindowEvent
|
||||
|
||||
import javax.annotation.Nonnull
|
||||
|
||||
@ArtifactProviderFor(GriffonView)
|
||||
class WizardView {
|
||||
@MVCMember @Nonnull
|
||||
FactoryBuilderSupport builder
|
||||
@MVCMember @Nonnull
|
||||
WizardModel model
|
||||
|
||||
def dialog
|
||||
def p
|
||||
|
||||
void initUI() {
|
||||
dialog = new JDialog(model.parent, "Setup Wizard", true)
|
||||
|
||||
p = builder.panel {
|
||||
borderLayout()
|
||||
panel (id : "cards-panel", constraints : BorderLayout.CENTER) {
|
||||
cardLayout()
|
||||
model.steps.each {
|
||||
it.buildUI(builder)
|
||||
}
|
||||
}
|
||||
panel (constraints : BorderLayout.SOUTH) {
|
||||
button(text : "Previous", enabled : bind {model.previousButtonEnabled}, previousAction)
|
||||
button(text : "Next", enabled : bind {model.nextButtonEnabled}, nextAction)
|
||||
button(text : "Finish", enabled : bind {model.finishButtonEnabled}, finishAction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateLayout() {
|
||||
String constraints = model.steps[model.currentStep].getConstraint()
|
||||
def cardsPanel = builder.getVariable("cards-panel")
|
||||
cardsPanel.getLayout().show(cardsPanel, constraints)
|
||||
}
|
||||
|
||||
void mvcGroupInit(Map<String,String> args) {
|
||||
dialog.getContentPane().add(p)
|
||||
dialog.pack()
|
||||
dialog.setLocationRelativeTo(model.parent)
|
||||
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE)
|
||||
dialog.addWindowListener( new WindowAdapter() {
|
||||
public void windowClosed(WindowEvent e) {
|
||||
mvcGroup.destroy()
|
||||
}
|
||||
})
|
||||
dialog.show()
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package com.muwire.gui.wizard
|
||||
|
||||
import javax.swing.JFileChooser
|
||||
|
||||
import com.muwire.core.MuWireSettings
|
||||
|
||||
class DirectoriesStep extends WizardStep {
|
||||
|
||||
def downloadLocationField
|
||||
def incompleteLocationField
|
||||
def downloadLocationButton
|
||||
def incompleteLocationButton
|
||||
|
||||
public DirectoriesStep(String constraint) {
|
||||
super("directories")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void buildUI(FactoryBuilderSupport builder) {
|
||||
File defaultDownloadLocation = new File(System.getProperty("user.home"), "MuWire Downloads")
|
||||
File defaultIncompleteLocation = new File(System.getProperty("user.home"), "MuWire Incompletes")
|
||||
|
||||
builder.panel(constraints : getConstraint()) {
|
||||
gridBagLayout()
|
||||
label(text : "Select directories for saving downloaded and incomplete files. They will be created if they do not already exist",
|
||||
constraints : gbc(gridx: 0, gridy: 0, gridwidth : 2))
|
||||
|
||||
label(text : "Directory for saving downloaded files", constraints : gbc(gridx:0, gridy: 1))
|
||||
downloadLocationField = textField(text : defaultDownloadLocation.getAbsolutePath(), constraints : gbc(gridx : 0, gridy : 2))
|
||||
downloadLocationButton = button(text : "Choose", constraints : gbc(gridx: 1, gridy: 2), actionPerformed : showDownloadChooser)
|
||||
label(text : "Directory for storing incomplete files", constraints : gbc(gridx:0, gridy: 3))
|
||||
incompleteLocationField = textField(text : defaultIncompleteLocation.getAbsolutePath(), constraints : gbc(gridx:0, gridy:4))
|
||||
incompleteLocationButton = button(text : "Choose", constraints : gbc(gridx: 1, gridy: 4), actionPerformed : showIncompleteChooser)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> validate() {
|
||||
// TODO Auto-generated method stub
|
||||
return null
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void apply(MuWireSettings muSettings, Properties i2pSettings) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
def showDownloadChooser = {
|
||||
String text = chooseFile("Select directory for downloaded files")
|
||||
if (text != null)
|
||||
downloadLocationField.text = text
|
||||
}
|
||||
|
||||
def showIncompleteChooser = {
|
||||
String text = chooseFile("Select directory for incomplete files")
|
||||
if (text != null)
|
||||
incompleteLocationField.text = text
|
||||
}
|
||||
|
||||
private String chooseFile(String title) {
|
||||
def chooser = new JFileChooser()
|
||||
chooser.setFileHidingEnabled(false)
|
||||
chooser.setDialogTitle(title)
|
||||
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)
|
||||
int rv = chooser.showOpenDialog(null)
|
||||
if (rv == JFileChooser.APPROVE_OPTION)
|
||||
return chooser.getSelectedFile().getAbsolutePath()
|
||||
else
|
||||
return null
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.muwire.gui.wizard
|
||||
|
||||
import com.muwire.core.Constants
|
||||
import com.muwire.core.MuWireSettings
|
||||
import com.muwire.core.util.DataUtil
|
||||
|
||||
class NicknameStep extends WizardStep {
|
||||
|
||||
volatile def nickField
|
||||
|
||||
public NicknameStep() {
|
||||
super("nickname")
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void buildUI(FactoryBuilderSupport builder) {
|
||||
builder.panel(constraints : getConstraint()) {
|
||||
label(text: "Select a nickname")
|
||||
nickField = textField(columns: 30)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> validate() {
|
||||
if (!DataUtil.isValidName(nickField.text))
|
||||
return ["Nickname cannot contain any of ${Constants.INVALID_NICKNAME_CHARS} and must be no longer than ${Constants.MAX_NICKNAME_LENGTH} characters. Choose another."]
|
||||
null
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void apply(MuWireSettings muSettings, Properties i2pSettings) {
|
||||
muSettings.nickname = nickField.text
|
||||
}
|
||||
}
|
22
gui/src/main/groovy/com/muwire/gui/wizard/WizardStep.groovy
Normal file
22
gui/src/main/groovy/com/muwire/gui/wizard/WizardStep.groovy
Normal file
@ -0,0 +1,22 @@
|
||||
package com.muwire.gui.wizard
|
||||
|
||||
import com.muwire.core.MuWireSettings
|
||||
|
||||
abstract class WizardStep {
|
||||
|
||||
final String constraint
|
||||
|
||||
protected WizardStep(String constraint) {
|
||||
this.constraint = constraint
|
||||
}
|
||||
|
||||
|
||||
protected abstract void buildUI(FactoryBuilderSupport builder)
|
||||
|
||||
/**
|
||||
* @return list of errors, null if validation is successful
|
||||
*/
|
||||
protected abstract List<String> validate()
|
||||
|
||||
protected abstract void apply(MuWireSettings muSettings, Properties i2pSettings)
|
||||
}
|
Reference in New Issue
Block a user