2015-10-20 14:26:58 +00:00
package com.coder.client.gui.editor ;
2015-10-20 06:56:14 +00:00
2015-10-20 14:26:58 +00:00
import java.io.IOException ;
2015-10-20 06:56:14 +00:00
import java.net.URL ;
2015-11-17 16:16:29 +01:00
import java.util.ArrayList ;
2015-11-13 11:58:23 +01:00
import java.util.Enumeration ;
2015-11-17 16:16:29 +01:00
import java.util.Properties ;
2015-10-20 06:56:14 +00:00
import java.util.ResourceBundle ;
2015-11-13 11:58:23 +01:00
import java.util.logging.Level ;
2015-11-11 16:13:01 +01:00
import java.util.logging.Logger ;
2015-10-20 06:56:14 +00:00
import org.controlsfx.control.PropertySheet ;
import org.controlsfx.property.editor.PropertyEditor ;
2015-11-11 16:13:01 +01:00
import zutil.log.LogUtil ;
import com.coder.client.CoderClient ;
2015-11-17 15:48:04 +01:00
import com.coder.client.ProjectHandler ;
import com.coder.client.SessionHandler ;
2015-10-20 14:26:58 +00:00
import com.coder.client.gui.GuiWindow ;
2015-11-13 15:44:47 +01:00
import com.coder.client.project.OpenProjectEventHandler ;
2015-10-20 06:56:14 +00:00
import com.coder.client.property.CoderClientProperty ;
import com.coder.client.property.ComboBoxProperty ;
2015-11-16 15:16:41 +01:00
import com.coder.client.session.FileRspMsgListener ;
2015-11-11 16:13:01 +01:00
import com.coder.client.session.ProjectRspMsgListener ;
import com.coder.client.session.ProjectTypeRspMsgListener ;
2015-11-13 11:58:23 +01:00
import com.coder.server.message.CoderMessage ;
2015-11-16 15:16:41 +01:00
import com.coder.server.message.FileReqMsg ;
import com.coder.server.message.FileRspMsg ;
2015-11-13 13:25:36 +01:00
import com.coder.server.message.ProjectReqMsg ;
2015-11-11 16:13:01 +01:00
import com.coder.server.message.ProjectRspMsg ;
2015-11-13 11:58:23 +01:00
import com.coder.server.message.ProjectTypeReqMsg ;
2015-11-11 16:13:01 +01:00
import com.coder.server.message.ProjectTypeRspMsg ;
2015-10-20 06:56:14 +00:00
import javafx.beans.value.ChangeListener ;
import javafx.beans.value.ObservableValue ;
import javafx.event.ActionEvent ;
import javafx.fxml.FXML ;
import javafx.scene.control.Button ;
import javafx.scene.control.TextArea ;
import javafx.scene.control.TreeItem ;
import javafx.scene.control.TreeView ;
import javafx.util.Callback ;
2015-10-20 14:26:58 +00:00
public class EditorWindow extends GuiWindow {
2015-11-11 16:13:01 +01:00
public static final Logger logger = LogUtil . getLogger ( ) ;
private CoderClient client ;
2015-11-17 15:48:04 +01:00
private SessionHandler sessionHandler ;
private ProjectHandler projectHandler ;
2015-11-11 16:13:01 +01:00
2015-11-16 15:16:41 +01:00
@FXML private TreeView < FileTreeItem > fileTreeView ;
2015-10-20 06:56:14 +00:00
@FXML private TextArea editTextArea ;
@FXML private PropertySheet propertySheet ;
@FXML private Button compileButton ;
@FXML private Button runButton ;
2015-11-05 14:42:40 +01:00
@FXML private Button exitButton ;
@FXML private Button changeProjectButton ;
2015-10-20 06:56:14 +00:00
2015-11-13 11:58:23 +01:00
private String projectType = null ;
public EditorWindow ( final CoderClient client ) throws IOException {
2015-10-20 14:26:58 +00:00
super ( EditorWindow . class . getResource ( " EditorWindow.fxml " ) ) ;
2015-11-11 16:13:01 +01:00
this . client = client ;
2015-11-13 13:25:36 +01:00
2015-11-17 15:48:04 +01:00
this . sessionHandler = SessionHandler . getInstance ( ) ;
this . projectHandler = ProjectHandler . getInstance ( ) ;
sessionHandler . addMessageListener ( new ProjectRspMsgListener ( ) {
2015-11-11 16:13:01 +01:00
@Override
public void messageReceived ( final ProjectRspMsg msg ) {
2015-11-13 11:58:23 +01:00
try {
logger . fine ( " a ProjectRspMsg received " ) ;
if ( msg . error ! = null ) {
logger . severe ( " Server responded on the project request with the following error message: " + msg . error ) ;
2015-11-17 15:48:04 +01:00
projectHandler . setProject ( null ) ;
2015-11-13 11:58:23 +01:00
return ;
} else {
2015-11-17 15:48:04 +01:00
projectHandler . setProject ( msg . name ) ;
2015-11-13 11:58:23 +01:00
}
2015-11-17 16:16:29 +01:00
//load project to GUI
loadProject ( msg . name , msg . type , msg . description , msg . config , msg . fileList ) ;
2015-11-13 11:58:23 +01:00
} catch ( Exception e ) {
2015-11-13 15:44:47 +01:00
logger . log ( Level . SEVERE , " exception while load the project " , e ) ;
2015-11-17 15:48:04 +01:00
projectHandler . triggerOpenProjectFailureEvent ( " ERROR: failed to loading project " ) ;
2015-11-11 16:13:01 +01:00
}
2015-11-13 15:44:47 +01:00
client . showOnStage ( EditorWindow . this ) ;
2015-11-11 16:13:01 +01:00
}
} ) ;
2015-11-13 13:25:36 +01:00
2015-11-17 15:48:04 +01:00
sessionHandler . addMessageListener ( new ProjectTypeRspMsgListener ( ) {
2015-11-11 16:13:01 +01:00
@Override
public void messageReceived ( ProjectTypeRspMsg msg ) {
2015-11-13 11:58:23 +01:00
for ( String type : msg . keySet ( ) ) {
if ( type . equals ( projectType ) ) { //the current project type matches the project type in the message
//TODO: handle type specific configurations
}
}
2015-11-11 16:13:01 +01:00
}
} ) ;
2015-11-13 13:25:36 +01:00
2015-11-17 15:48:04 +01:00
sessionHandler . addMessageListener ( new FileRspMsgListener ( ) {
2015-11-16 15:16:41 +01:00
@Override
public void messageReceived ( FileRspMsg msg ) {
if ( msg . error ! = null | | msg . path = = null ) {
if ( msg . error ! = null ) {
logger . severe ( " recieved error message \" " + msg . error + " \" the FileRspMsg " ) ;
}
if ( msg . path = = null ) {
logger . severe ( " recieved a file with a null path " ) ;
setErrorMessage ( " ERROR: en error occured while loading a file " ) ;
} else {
setErrorMessage ( " ERROR: en error occured while loading the file: \" " + msg . path + " \" " ) ;
}
return ;
} else {
setErrorMessage ( " " ) ;
}
logger . fine ( " recieved file content for file: \" " + msg . path + " \" " ) ;
//TODO: load file content to text area
}
} ) ;
2015-11-17 15:48:04 +01:00
projectHandler . addprojectEventHandler ( new OpenProjectEventHandler ( ) {
2015-11-13 13:25:36 +01:00
@Override
public void openProject ( String projectName ) {
CoderMessage msg = new CoderMessage ( ) ;
msg . ProjectReq = new ProjectReqMsg ( ) ;
msg . ProjectReq . name = projectName ;
2015-11-17 15:48:04 +01:00
sessionHandler . sendMessage ( msg ) ;
2015-11-13 13:25:36 +01:00
}
} ) ;
2015-10-20 06:56:14 +00:00
}
@Override
public void initialize ( URL fxmlFileLocation , ResourceBundle resources ) {
2015-11-13 11:58:23 +01:00
setErrorMessage ( " " ) ;
2015-10-20 06:56:14 +00:00
setupPropertySheet ( ) ;
setupFileTreeView ( ) ;
2015-10-20 14:26:58 +00:00
}
@Override
2015-11-13 13:25:36 +01:00
public void willShow ( ) {
2015-11-11 16:13:01 +01:00
2015-10-20 06:56:14 +00:00
}
@FXML
2015-11-11 16:13:01 +01:00
protected void run ( ActionEvent event ) {
//TODO
2015-10-20 06:56:14 +00:00
}
@FXML
2015-11-11 16:13:01 +01:00
protected void compile ( ActionEvent event ) {
//TODO
2015-10-20 06:56:14 +00:00
}
2015-10-23 13:44:11 +00:00
@FXML
2015-11-11 16:13:01 +01:00
protected void changeProject ( ActionEvent event ) {
2015-11-17 15:48:04 +01:00
projectHandler . setProject ( null ) ;
projectHandler . triggerSelectProjectEvent ( ) ;
2015-10-23 13:44:11 +00:00
}
2015-11-05 14:42:40 +01:00
@FXML
2015-11-11 16:13:01 +01:00
protected void exit ( ActionEvent event ) {
client . exit ( ) ;
2015-11-05 14:42:40 +01:00
}
2015-11-13 11:58:23 +01:00
private void sendProjectTypeReqMsg ( String type ) {
CoderMessage msg = new CoderMessage ( ) ;
msg . ProjectTypeReq = new ProjectTypeReqMsg ( ) ;
msg . ProjectTypeReq . type = type ;
2015-11-17 15:48:04 +01:00
sessionHandler . sendMessage ( msg ) ;
2015-11-13 11:58:23 +01:00
}
2015-10-20 06:56:14 +00:00
private void setupFileTreeView ( ) {
2015-11-16 15:16:41 +01:00
fileTreeView . getSelectionModel ( ) . selectedItemProperty ( ) . addListener ( new ChangeListener < TreeItem < FileTreeItem > > ( ) {
2015-10-20 06:56:14 +00:00
@Override
2015-11-16 15:16:41 +01:00
public void changed ( ObservableValue < ? extends TreeItem < FileTreeItem > > item , TreeItem < FileTreeItem > oldValue , TreeItem < FileTreeItem > newValue ) {
2015-10-20 06:56:14 +00:00
if ( newValue ! = fileTreeView . getRoot ( ) ) {
2015-11-16 15:16:41 +01:00
FileTreeItem fileTreeItem = newValue . getValue ( ) ;
if ( fileTreeItem . isDirectory ( ) ) {
FileTreeDirectory directory = ( FileTreeDirectory ) fileTreeItem ;
logger . fine ( " directory " + directory . getName ( ) + " selected in the file tree " ) ;
System . out . println ( ) ;
} else {
FileTreeFile file = ( FileTreeFile ) fileTreeItem ;
logger . fine ( " file " + file . getName ( ) + " selected in the file tree. The file has the full path: \" " + file . getFullPath ( ) + " \" " ) ;
//sending file request message
CoderMessage msg = new CoderMessage ( ) ;
msg . FileReq = new FileReqMsg ( ) ;
msg . FileReq . path = file . getFullPath ( ) ;
2015-11-17 15:48:04 +01:00
sessionHandler . sendMessage ( msg ) ;
2015-11-16 15:16:41 +01:00
}
2015-10-20 06:56:14 +00:00
}
}
} ) ;
2015-11-16 15:16:41 +01:00
TreeItem < FileTreeItem > root = new TreeItem < FileTreeItem > ( new FileTreeDirectory ( " / " ) ) ;
2015-10-20 06:56:14 +00:00
root . setExpanded ( true ) ;
fileTreeView . setRoot ( root ) ;
}
private void setupPropertySheet ( ) {
//handle custom ProperySheet.Item's editor
propertySheet . setPropertyEditorFactory ( new Callback < PropertySheet . Item , PropertyEditor < ? > > ( ) {
@Override
public PropertyEditor < ? > call ( PropertySheet . Item param ) {
//only support internal types
if ( param instanceof CoderClientProperty ) {
return ( ( CoderClientProperty < ? > ) param ) . getEditor ( ) ;
}
//not a internal property type
return null ;
}
} ) ;
propertySheet . getItems ( ) . clear ( ) ;
2015-11-16 15:16:41 +01:00
/ * EXAMPLE CODE :
2015-10-20 06:56:14 +00:00
ArrayList < String > boards = new ArrayList < String > ( ) ;
boards . add ( " UNO " ) ;
boards . add ( " Mega " ) ;
ComboBoxProperty p1 = new ComboBoxProperty ( " Port " , null , boards ) ;
propertySheet . getItems ( ) . add ( p1 ) ;
CheckBoxProperty p2 = new CheckBoxProperty ( " Melt? " , false ) ;
propertySheet . getItems ( ) . add ( p2 ) ;
2015-11-16 15:16:41 +01:00
* /
2015-10-20 06:56:14 +00:00
}
2015-10-21 16:13:45 +00:00
@Override
2015-11-13 13:25:36 +01:00
public String getTitle ( ) {
2015-10-21 16:13:45 +00:00
return " Coder Client " ;
}
2015-11-11 16:13:01 +01:00
private void setErrorMessage ( String msg ) {
2015-10-23 13:44:11 +00:00
// TODO Auto-generated method stub
}
2015-11-11 16:13:01 +01:00
@Override
2015-11-13 13:25:36 +01:00
public String getDescriptiveName ( ) {
2015-11-11 16:13:01 +01:00
return " Editor Window " ;
}
2015-11-17 16:16:29 +01:00
private void loadProject ( final String projectName , final String projectType , final String projectDescription , final Properties projectConfig , ArrayList < String > projectFileList ) {
logger . info ( " loading project \" " + projectName + " \" " ) ;
client . showOnStage ( EditorWindow . this ) ; //TODO: show "loading project" popup instead
//handle name and description
fileTreeView . getRoot ( ) . setValue ( new FileTreeDirectory ( projectName ) ) ; //set file tree root name to the project name
//handle config
propertySheet . getItems ( ) . clear ( ) ;
if ( projectConfig ! = null ) { // projectConfig is an optional parameter
logger . fine ( " the project has a configuration - populating property sheet " ) ;
Enumeration < ? > propertyNames = projectConfig . propertyNames ( ) ;
while ( propertyNames . hasMoreElements ( ) ) { //populate propertySheet with all config elements
Object propertyNameObject = propertyNames . nextElement ( ) ;
if ( propertyNameObject instanceof String ) {
String propertyName = ( String ) propertyNameObject ;
String propertyValue = projectConfig . getProperty ( projectName ) ;
ComboBoxProperty comboProperty = new ComboBoxProperty ( propertyName , propertyValue , null ) ;
propertySheet . getItems ( ) . add ( comboProperty ) ;
}
}
//request alternative values for config of this project type
this . projectType = projectType ;
sendProjectTypeReqMsg ( projectType ) ;
} else {
logger . fine ( " the project has no configuration " ) ;
}
//handle file list
fileTreeView . getRoot ( ) . getChildren ( ) . clear ( ) ;
for ( String filePath : projectFileList ) {
String fullPath = filePath ;
logger . finer ( " adding file \" " + filePath + " \" to the file tree " ) ;
if ( filePath . endsWith ( " / " ) ) {
logger . warning ( " file: \" " + filePath + " \" in file list is a directory and not a file. Currently not supported. Ignoring entry " ) ;
continue ;
}
if ( filePath . startsWith ( " / " ) ) {
filePath = filePath . substring ( 1 , filePath . length ( ) ) ;
}
TreeItem < FileTreeItem > tmpParent = fileTreeView . getRoot ( ) ;
String [ ] filePathSpilt = filePath . split ( " / " ) ;
for ( int i = 0 ; i < filePathSpilt . length ; + + i ) {
if ( i < filePathSpilt . length - 1 ) {
String directoryName = filePathSpilt [ i ] ;
if ( ! tmpParent . getChildren ( ) . contains ( directoryName ) ) {
if ( tmpParent = = fileTreeView . getRoot ( ) ) {
logger . finer ( " adding directory \" " + directoryName + " \" to directory \" / \" " ) ;
} else {
logger . finer ( " adding directory \" " + directoryName + " \" to directory \" " + tmpParent + " \" " ) ;
}
TreeItem < FileTreeItem > tmpChild = new TreeItem < FileTreeItem > ( new FileTreeDirectory ( directoryName ) ) ;
tmpParent . getChildren ( ) . add ( tmpChild ) ;
tmpParent = tmpChild ;
} else {
int index = tmpParent . getChildren ( ) . indexOf ( directoryName ) ;
tmpParent = tmpParent . getChildren ( ) . get ( index ) ;
}
} else {
String fileName = filePathSpilt [ i ] ;
if ( ! tmpParent . getChildren ( ) . contains ( fileName ) ) {
if ( tmpParent = = fileTreeView . getRoot ( ) ) {
logger . finer ( " adding file \" " + fileName + " \" to directory \" / \" " ) ;
} else {
logger . finer ( " adding file \" " + fileName + " \" to directory \" " + tmpParent + " \" " ) ;
}
TreeItem < FileTreeItem > tmpChild = new TreeItem < FileTreeItem > ( new FileTreeFile ( fileName , fullPath ) ) ;
tmpParent . getChildren ( ) . add ( tmpChild ) ;
tmpParent = tmpChild ;
} else {
logger . warning ( " The project seems to contain two or more files with the same location and name. The file tree presented may be missing files. duplicates not allowed. " ) ;
}
}
}
}
}
2015-11-11 16:13:01 +01:00
2015-10-20 06:56:14 +00:00
}