Skip to content
Snippets Groups Projects
Commit e72dc975 authored by Francois Henrotte's avatar Francois Henrotte
Browse files

socket listener for onelab-python

parent be0380ba
No related branches found
No related tags found
No related merge requests found
...@@ -52,20 +52,24 @@ typedef unsigned long intptr_t; ...@@ -52,20 +52,24 @@ typedef unsigned long intptr_t;
class onelabGmshServer : public GmshServer{ class onelabGmshServer : public GmshServer{
private: private:
bool _disconnected, _listen;
onelab::localNetworkClient *_client; onelab::localNetworkClient *_client;
public: public:
onelabGmshServer(onelab::localNetworkClient *client) onelabGmshServer(onelab::localNetworkClient *client, bool listen)
: GmshServer(), _client(client) {} : GmshServer(), _client(client) {
_disconnected = false;
_listen = listen;
}
~onelabGmshServer(){} ~onelabGmshServer(){}
int NonBlockingSystemCall(const char *str){ return SystemCall(str); } int NonBlockingSystemCall(const char *str){ return SystemCall(str); }
int NonBlockingWait(int socket, double waitint, double timeout) int NonBlockingWait(int socket, double waitint, double timeout)
{ {
double start = GetTimeInSeconds(); double start = GetTimeInSeconds();
printf("nb wait %s %s\n",_client->getName().c_str(), _client->getExecutable().c_str());
while(1){ while(1){
if(timeout > 0 && GetTimeInSeconds() - start > timeout) if(timeout > 0 && GetTimeInSeconds() - start > timeout)
return 2; // timeout return 2; // timeout
if(_client->getPid() < 0 || (_client->getExecutable().empty() && if (_disconnected || (_client->getExecutable().empty()&& !_listen))
!CTX::instance()->solver.listen))
return 1; // process has been killed or we stopped listening return 1; // process has been killed or we stopped listening
// check if there is data (call select with a zero timeout to // check if there is data (call select with a zero timeout to
// return immediately, i.e., do polling) // return immediately, i.e., do polling)
...@@ -86,9 +90,10 @@ class onelabGmshServer : public GmshServer{ ...@@ -86,9 +90,10 @@ class onelabGmshServer : public GmshServer{
else if(ret > 0){ else if(ret > 0){
return 0; // data is there! return 0; // data is there!
} }
else{ else{ // ret < 0
// an error happened // an error happened
_client->setPid(-1); _client->setPid(-1);
_disconnected = true;
_client->setGmshServer(0); _client->setGmshServer(0);
return 1; return 1;
} }
...@@ -96,13 +101,239 @@ class onelabGmshServer : public GmshServer{ ...@@ -96,13 +101,239 @@ class onelabGmshServer : public GmshServer{
} }
}; };
class socketListener {
std::map<GmshServer*, onelab::localNetworkClient*> _clients;
public:
void addClient(onelab::localNetworkClient* client, GmshServer *server)
{
_clients[server] = client;
}
int NonBlockingWait(double waitint, double timeout)
{
double start = GetTimeInSeconds();
while(1){
if(timeout > 0 && GetTimeInSeconds() - start > timeout)
return 2; // timeout
/*if(_client->getPid() < 0 || (_client->getExecutable().empty() &&
!CTX::instance()->solver.listen))
return 1; // process has been killed or we stopped listening*/
// check if there is data (call select with a zero timeout to
// return immediately, i.e., do polling)
bool somethingHappend = false;
for (std::map<GmshServer *, onelab::localNetworkClient*>::iterator it = _clients.begin(); it != _clients.end(); ) {
GmshServer *server = it->first;
std::map<GmshServer *, onelab::localNetworkClient*>::iterator next = it;
next++;
if(server->Select(0, 0)){
receiveMessage(server);
somethingHappend = true;
}
it = next;
}
if(! somethingHappend){ // nothing available
// if asked, refresh the onelab GUI
std::vector<onelab::string> ps;
onelab::server::instance()->get(ps, "Gmsh/Action");
if(ps.size() && ps[0].getValue() == "refresh"){
ps[0].setVisible(false);
ps[0].setValue("");
onelab::server::instance()->set(ps[0]);
if(FlGui::available()) onelab_cb(0, (void*)"refresh");
}
// wait at most waitint seconds and respond to FLTK events
if(FlGui::available()) FlGui::instance()->wait(waitint);
}
return _clients.empty();
}
}
void receiveMessage(GmshServer *server)
{
onelab::localNetworkClient *client = _clients[server];
int type, length, swap;
if(!server->ReceiveHeader(&type, &length, &swap)){
Msg::Error("Did not receive message header: stopping server");
return;
}
std::string message(length, ' ');
if(!server->ReceiveMessage(length, &message[0])){
Msg::Error("Did not receive message body: stopping server");
return;
}
//printf("%i %s\n", type, message.c_str());
double timer = GetTimeInSeconds();
switch (type) {
case GmshSocket::GMSH_START:
//_pid = atoi(message.c_str());
//_gmshServer = server;
break;
case GmshSocket::GMSH_STOP:
server->Shutdown();
client->setPid(-1);
client->setGmshServer(0);
_clients.erase(server);
delete server;
break;
case GmshSocket::GMSH_PARAMETER:
{
std::string version, type, name;
onelab::parameter::getInfoFromChar(message, version, type, name);
if(onelab::parameter::version() != version){
Msg::Error("OneLab version mismatch (server: %s / client: %s)",
onelab::parameter::version().c_str(), version.c_str());
}
else if(type == "number"){
onelab::number p; p.fromChar(message); client->set(p);
if(p.getName() == client->getName() + "/Progress")
if(FlGui::available())
FlGui::instance()->setProgress(p.getLabel().c_str(), p.getValue(),
p.getMin(), p.getMax());
}
else if(type == "string"){
onelab::string p; p.fromChar(message); client->set(p);
}
else if(type == "region"){
onelab::region p; p.fromChar(message); client->set(p);
}
else if(type == "function"){
onelab::function p; p.fromChar(message); client->set(p);
}
else
Msg::Error("Unknown OneLab parameter type: %s", type.c_str());
}
break;
case GmshSocket::GMSH_PARAMETER_QUERY:
{
std::string version, type, name, reply;
onelab::parameter::getInfoFromChar(message, version, type, name);
if(onelab::parameter::version() != version){
Msg::Error("OneLab version mismatch (server: %s / client: %s)",
onelab::parameter::version().c_str(), version.c_str());
}
else if(type == "number"){
std::vector<onelab::number> par; client->get(par, name);
if(par.size() == 1) reply = par[0].toChar();
}
else if(type == "string"){
std::vector<onelab::string> par; client->get(par, name);
if(par.size() == 1) reply = par[0].toChar();
}
else if(type == "region"){
std::vector<onelab::region> par; client->get(par, name);
if(par.size() == 1) reply = par[0].toChar();
}
else if(type == "function"){
std::vector<onelab::function> par; client->get(par, name);
if(par.size() == 1) reply = par[0].toChar();
}
else
Msg::Error("Unknown OneLab parameter type in query: %s", type.c_str());
if(reply.size()){
server->SendMessage(GmshSocket::GMSH_PARAMETER, reply.size(), &reply[0]);
}
else{
// FIXME: introduce GMSH_PARAMETER_NOT_FOUND message to handle this
// (need to change onelab.h accordingly)
reply = "OneLab parameter '" + name + "' not found";
server->SendMessage(GmshSocket::GMSH_INFO, reply.size(), &reply[0]);
}
}
break;
case GmshSocket::GMSH_PARAM_QUERY_ALL:
break;
case GmshSocket::GMSH_PROGRESS:
Msg::StatusBar(false, "%s %s", client->getName().c_str(), message.c_str());
break;
case GmshSocket::GMSH_INFO:
Msg::Direct("Info : %s - %s", client->getName().c_str(), message.c_str());
break;
case GmshSocket::GMSH_WARNING:
Msg::Warning("%s - %s", client->getName().c_str(), message.c_str());
break;
case GmshSocket::GMSH_ERROR:
Msg::Error("%s - %s", client->getName().c_str(), message.c_str());
break;
case GmshSocket::GMSH_MERGE_FILE:
if(CTX::instance()->solver.autoMergeFile){
unsigned int n = PView::list.size();
MergePostProcessingFile(message, CTX::instance()->solver.autoShowLastStep,
CTX::instance()->solver.autoHideNewViews, true);
drawContext::global()->draw();
if(FlGui::available() && n != PView::list.size()){
FlGui::instance()->rebuildTree();
FlGui::instance()->openModule("Post-processing");
}
}
break;
case GmshSocket::GMSH_PARSE_STRING:
ParseString(message);
drawContext::global()->draw();
break;
case GmshSocket::GMSH_SPEED_TEST:
Msg::Info("got %d Mb message in %g seconds",
length / 1024 / 1024, GetTimeInSeconds() - timer);
break;
/*case GmshSocket::GMSH_VERTEX_ARRAY:
{
int n = PView::list.size();
PView::fillVertexArray(server, length, &message[0], swap);
if(FlGui::available())
FlGui::instance()->updateViews(n != (int)PView::list.size());
drawContext::global()->draw();
}
break;*/
default:
Msg::Warning("Received unknown message type (%d)", type);
break;
case GmshSocket::GMSH_CONNECT:
{
const std::string subClientName = message;
onelab::localNetworkClient *subClient = dynamic_cast<onelab::localNetworkClient*> (onelab::server::instance()->findClient(subClientName)->second);
if (! subClient) {
subClient = new onelab::localNetworkClient(subClientName, "");
}
//if (onelab::server::instance()->getChanged(subClientName)) {
std::string sockname;
std::ostringstream tmp;
if(!strstr(CTX::instance()->solver.socketName.c_str(), ":")){
// Unix socket
tmp << CTX::instance()->homeDir << CTX::instance()->solver.socketName << subClient->getId();
sockname = FixWindowsPath(tmp.str());
}
else{
// TCP/IP socket
if(CTX::instance()->solver.socketName.size() &&
CTX::instance()->solver.socketName[0] == ':')
tmp << GetHostName(); // prepend hostname if only the port number is given
tmp << CTX::instance()->solver.socketName << subClient->getId();
sockname = tmp.str();
}
server->SendString(GmshSocket::GMSH_CONNECT, sockname.c_str());
GmshServer *subServer = new onelabGmshServer(subClient, true);
subServer->Start("", sockname.c_str(), CTX::instance()->solver.timeout);
addClient(subClient, subServer);
/*}
else {
server->SendString(GmshSocket::GMSH_CONNECT, "");
}*/
}
}
}
};
bool onelab::localNetworkClient::run() bool onelab::localNetworkClient::run()
{ {
if (getExecutable().empty())
return false;
printf("Onelab local client :: run on '%s'\n", getName().c_str());
new_connection: new_connection:
_pid = 0; _pid = 0;
_gmshServer = 0; _gmshServer = 0;
onelabGmshServer *server = new onelabGmshServer(this); onelabGmshServer *server = new onelabGmshServer(this, CTX::instance()->solver.listen);
std::string sockname; std::string sockname;
std::ostringstream tmp; std::ostringstream tmp;
...@@ -132,6 +363,7 @@ bool onelab::localNetworkClient::run() ...@@ -132,6 +363,7 @@ bool onelab::localNetworkClient::run()
} }
int sock; int sock;
printf("TRY\n");
try{ try{
sock = server->Start(command.c_str(), sockname.c_str(), sock = server->Start(command.c_str(), sockname.c_str(),
CTX::instance()->solver.timeout); CTX::instance()->solver.timeout);
...@@ -140,6 +372,7 @@ bool onelab::localNetworkClient::run() ...@@ -140,6 +372,7 @@ bool onelab::localNetworkClient::run()
Msg::Error("%s (on socket '%s')", err, sockname.c_str()); Msg::Error("%s (on socket '%s')", err, sockname.c_str());
sock = -1; sock = -1;
} }
printf("END TRY\n");
if(sock < 0){ if(sock < 0){
server->Shutdown(); server->Shutdown();
...@@ -148,203 +381,30 @@ bool onelab::localNetworkClient::run() ...@@ -148,203 +381,30 @@ bool onelab::localNetworkClient::run()
} }
Msg::StatusBar(true, "Running '%s'...", _name.c_str()); Msg::StatusBar(true, "Running '%s'...", _name.c_str());
socketListener *listener = new socketListener();
listener->addClient(this, server);
while(1) { while(1) {
if(_pid < 0 || (command.empty() && !CTX::instance()->solver.listen)) if(_pid < 0 || (command.empty() && !CTX::instance()->solver.listen))
break; break;
int stop = server->NonBlockingWait(sock, 0.001, 0.); int stop = listener->NonBlockingWait(0.001, 0.);
if(stop || _pid < 0 || (command.empty() && !CTX::instance()->solver.listen)) if(stop || _pid < 0 || (command.empty() && !CTX::instance()->solver.listen))
break; break;
double timer = GetTimeInSeconds();
int type, length, swap;
if(!server->ReceiveHeader(&type, &length, &swap)){
Msg::Error("Did not receive message header: stopping server");
break;
}
std::string message(length, ' ');
if(!server->ReceiveMessage(length, &message[0])){
Msg::Error("Did not receive message body: stopping server");
break;
}
switch (type) {
case GmshSocket::GMSH_START:
_pid = atoi(message.c_str());
_gmshServer = server;
break;
case GmshSocket::GMSH_STOP:
_pid = -1;
_gmshServer = 0;
break;
case GmshSocket::GMSH_PARAMETER:
{
std::string version, type, name;
onelab::parameter::getInfoFromChar(message, version, type, name);
if(onelab::parameter::version() != version){
Msg::Error("OneLab version mismatch (server: %s / client: %s)",
onelab::parameter::version().c_str(), version.c_str());
}
else if(type == "number"){
onelab::number p; p.fromChar(message); set(p);
if(p.getName() == getName() + "/Progress")
if(FlGui::available())
FlGui::instance()->setProgress(p.getLabel().c_str(), p.getValue(),
p.getMin(), p.getMax());
}
else if(type == "string"){
onelab::string p; p.fromChar(message); set(p);
}
else if(type == "region"){
onelab::region p; p.fromChar(message); set(p);
}
else if(type == "function"){
onelab::function p; p.fromChar(message); set(p);
}
else
Msg::Error("Unknown OneLab parameter type: %s", type.c_str());
}
break;
case GmshSocket::GMSH_PARAMETER_QUERY:
{
std::string version, type, name, reply;
onelab::parameter::getInfoFromChar(message, version, type, name);
if(onelab::parameter::version() != version){
Msg::Error("OneLab version mismatch (server: %s / client: %s)",
onelab::parameter::version().c_str(), version.c_str());
}
else if(type == "number"){
std::vector<onelab::number> par; get(par, name);
if(par.size() == 1) reply = par[0].toChar();
}
else if(type == "string"){
std::vector<onelab::string> par; get(par, name);
if(par.size() == 1) reply = par[0].toChar();
}
else if(type == "region"){
std::vector<onelab::region> par; get(par, name);
if(par.size() == 1) reply = par[0].toChar();
}
else if(type == "function"){
std::vector<onelab::function> par; get(par, name);
if(par.size() == 1) reply = par[0].toChar();
}
else
Msg::Error("Unknown OneLab parameter type in query: %s", type.c_str());
if(reply.size()){
server->SendMessage(GmshSocket::GMSH_PARAMETER, reply.size(), &reply[0]);
}
else{
// FIXME: introduce GMSH_PARAMETER_NOT_FOUND message to handle this
// (need to change onelab.h accordingly)
reply = "OneLab parameter '" + name + "' not found";
server->SendMessage(GmshSocket::GMSH_INFO, reply.size(), &reply[0]);
}
}
break;
case GmshSocket::GMSH_PARAM_QUERY_ALL:
{
std::string version, type, name, reply;
std::vector<std::string> replies;
onelab::parameter::getInfoFromChar(message, version, type, name);
if(onelab::parameter::version() != version){
Msg::Error("OneLab version mismatch (server: %s / client: %s)",
onelab::parameter::version().c_str(), version.c_str());
}
else if(type == "number"){
std::vector<onelab::number> numbers; get(numbers);
for(std::vector<onelab::number>::iterator it = numbers.begin();
it != numbers.end(); it++) replies.push_back((*it).toChar());
}
else if(type == "string"){
std::vector<onelab::string> strings; get(strings);
for(std::vector<onelab::string>::iterator it = strings.begin();
it != strings.end(); it++) replies.push_back((*it).toChar());
}
else if(type == "region"){
std::vector<onelab::region> regions; get(regions);
for(std::vector<onelab::region>::iterator it = regions.begin();
it != regions.end(); it++) replies.push_back((*it).toChar());
}
else if(type == "function"){
std::vector<onelab::function> functions; get(functions);
for(std::vector<onelab::function>::iterator it = functions.begin();
it != functions.end(); it++) replies.push_back((*it).toChar());
}
else
Msg::Error("Unknown OneLab parameter type in query: %s", type.c_str());
for(unsigned int i = 0; i < replies.size(); i++)
server->SendMessage
(GmshSocket::GMSH_PARAM_QUERY_ALL, replies[i].size(), &replies[i][0]);
reply = "Sent all OneLab " + type + "s";
server->SendMessage(GmshSocket::GMSH_PARAM_QUERY_END, reply.size(), &reply[0]);
}
break;
case GmshSocket::GMSH_PROGRESS:
Msg::StatusBar(false, "%s %s", _name.c_str(), message.c_str());
break;
case GmshSocket::GMSH_INFO:
Msg::Direct("Info : %s - %s", _name.c_str(), message.c_str());
break;
case GmshSocket::GMSH_WARNING:
Msg::Warning("%s - %s", _name.c_str(), message.c_str());
break;
case GmshSocket::GMSH_ERROR:
Msg::Error("%s - %s", _name.c_str(), message.c_str());
break;
case GmshSocket::GMSH_MERGE_FILE:
if(CTX::instance()->solver.autoMergeFile){
unsigned int n = PView::list.size();
MergePostProcessingFile(message, CTX::instance()->solver.autoShowLastStep,
CTX::instance()->solver.autoHideNewViews, true);
drawContext::global()->draw();
if(FlGui::available() && n != PView::list.size()){
FlGui::instance()->rebuildTree();
FlGui::instance()->openModule("Post-processing");
}
}
break;
case GmshSocket::GMSH_PARSE_STRING:
ParseString(message);
drawContext::global()->draw();
break;
case GmshSocket::GMSH_SPEED_TEST:
Msg::Info("got %d Mb message in %g seconds",
length / 1024 / 1024, GetTimeInSeconds() - timer);
break;
case GmshSocket::GMSH_VERTEX_ARRAY:
{
int n = PView::list.size();
PView::fillVertexArray(this, length, &message[0], swap);
if(FlGui::available())
FlGui::instance()->updateViews(n != (int)PView::list.size());
drawContext::global()->draw();
}
break;
default:
Msg::Warning("Received unknown message type (%d)", type);
break;
}
} }
_gmshServer = 0;
server->Shutdown();
delete server;
_gmshServer = 0;
delete listener;
Msg::StatusBar(true, "Done running '%s'", _name.c_str()); Msg::StatusBar(true, "Done running '%s'", _name.c_str());
if(command.empty()){ if(command.empty()){
Msg::Info("Client disconnected: starting new connection"); Msg::Info("Client disconnected: starting new connection");
goto new_connection; goto new_connection;
} }
return true; return true;
} }
...@@ -474,7 +534,6 @@ static void loadDb(const std::string &name) ...@@ -474,7 +534,6 @@ static void loadDb(const std::string &name)
void onelab_cb(Fl_Widget *w, void *data) void onelab_cb(Fl_Widget *w, void *data)
{ {
if(!data) return; if(!data) return;
std::string action((const char*)data); std::string action((const char*)data);
if(action == "refresh"){ if(action == "refresh"){
...@@ -553,8 +612,6 @@ void onelab_cb(Fl_Widget *w, void *data) ...@@ -553,8 +612,6 @@ void onelab_cb(Fl_Widget *w, void *data)
return; return;
} }
Msg::ResetErrorCounter();
FlGui::instance()->onelab->setButtonMode("", "stop"); FlGui::instance()->onelab->setButtonMode("", "stop");
if(action == "compute") initializeLoops(); if(action == "compute") initializeLoops();
...@@ -582,6 +639,7 @@ void onelab_cb(Fl_Widget *w, void *data) ...@@ -582,6 +639,7 @@ void onelab_cb(Fl_Widget *w, void *data)
OpenProject(GModel::current()->getFileName()); OpenProject(GModel::current()->getFileName());
drawContext::global()->draw(); drawContext::global()->draw();
} }
Msg::ResetErrorCounter();
#endif #endif
} }
else{ else{
...@@ -923,7 +981,7 @@ void onelabGroup::_addMenu(const std::string &path, Fl_Callback *callback, void ...@@ -923,7 +981,7 @@ void onelabGroup::_addMenu(const std::string &path, Fl_Callback *callback, void
void onelabGroup::_addViewMenu(int num) void onelabGroup::_addViewMenu(int num)
{ {
std::ostringstream path; std::ostringstream path;
path << "0Modules/Post-processing/View" << num; path << "0Gmsh modules/Post-processing/View" << num;
Fl_Tree_Item *n = _tree->add(path.str().c_str()); Fl_Tree_Item *n = _tree->add(path.str().c_str());
int ww = _baseWidth - (n->depth() + 1) * _indent; int ww = _baseWidth - (n->depth() + 1) * _indent;
_tree->begin(); _tree->begin();
...@@ -936,7 +994,7 @@ void onelabGroup::_addViewMenu(int num) ...@@ -936,7 +994,7 @@ void onelabGroup::_addViewMenu(int num)
viewButton *onelabGroup::getViewButton(int num) viewButton *onelabGroup::getViewButton(int num)
{ {
char tmp[256]; char tmp[256];
sprintf(tmp, "0Modules/Post-processing/View%d", num); sprintf(tmp, "0Gmsh modules/Post-processing/View%d", num);
Fl_Tree_Item *n = _tree->find_item(tmp); Fl_Tree_Item *n = _tree->find_item(tmp);
if(n) return (viewButton*)n->widget(); if(n) return (viewButton*)n->widget();
return 0; return 0;
...@@ -1085,8 +1143,7 @@ Fl_Widget *onelabGroup::_addParameterWidget(onelab::number &p, Fl_Tree_Item *n, ...@@ -1085,8 +1143,7 @@ Fl_Widget *onelabGroup::_addParameterWidget(onelab::number &p, Fl_Tree_Item *n,
} }
// general number input // general number input
inputRange *but = new inputRange(1, 1, ww, 1, onelab::parameter::maxNumber(), inputRange *but = new inputRange(1, 1, ww, 1, onelab::parameter::maxNumber());
p.getAttribute("ReadOnlyRange") == "1");
but->value(p.getValue()); but->value(p.getValue());
but->minimum(p.getMin()); but->minimum(p.getMin());
but->maximum(p.getMax()); but->maximum(p.getMax());
...@@ -1116,21 +1173,6 @@ static void onelab_string_button_cb(Fl_Widget *w, void *data) ...@@ -1116,21 +1173,6 @@ static void onelab_string_button_cb(Fl_Widget *w, void *data)
} }
} }
static void onelab_string_input_cb(Fl_Widget *w, void *data)
{
if(!data) return;
std::string name = FlGui::instance()->onelab->getPath((Fl_Tree_Item*)data);
std::vector<onelab::string> strings;
onelab::server::instance()->get(strings, name);
if(strings.size()){
Fl_Input *o = (Fl_Input*)w;
onelab::string old = strings[0];
strings[0].setValue(o->value());
onelab::server::instance()->set(strings[0]);
autoCheck(old, strings[0]);
}
}
static void onelab_string_input_choice_cb(Fl_Widget *w, void *data) static void onelab_string_input_choice_cb(Fl_Widget *w, void *data)
{ {
if(!data) return; if(!data) return;
...@@ -1141,17 +1183,6 @@ static void onelab_string_input_choice_cb(Fl_Widget *w, void *data) ...@@ -1141,17 +1183,6 @@ static void onelab_string_input_choice_cb(Fl_Widget *w, void *data)
Fl_Input_Choice *o = (Fl_Input_Choice*)w; Fl_Input_Choice *o = (Fl_Input_Choice*)w;
onelab::string old = strings[0]; onelab::string old = strings[0];
strings[0].setValue(o->value()); strings[0].setValue(o->value());
std::string choices;
for(int i = 0; i < o->menubutton()->menu()->size(); i++){
if(o->menubutton()->menu()[i].flags & FL_MENU_TOGGLE){
if(o->menubutton()->menu()[i].flags & FL_MENU_VALUE)
choices += "1";
else
choices += "0";
}
}
if(choices.size())
strings[0].setAttribute("MultipleSelection", choices);
onelab::server::instance()->set(strings[0]); onelab::server::instance()->set(strings[0]);
autoCheck(old, strings[0]); autoCheck(old, strings[0]);
} }
...@@ -1182,22 +1213,6 @@ static void onelab_input_choice_file_merge_cb(Fl_Widget *w, void *data) ...@@ -1182,22 +1213,6 @@ static void onelab_input_choice_file_merge_cb(Fl_Widget *w, void *data)
drawContext::global()->draw(); drawContext::global()->draw();
} }
static void multiple_selection_menu_cb(Fl_Widget *w, void *data)
{
Fl_Menu_Button *menu = (Fl_Menu_Button*)w;
std::string val;
for (int i = 0; i < menu->size() - 1; i++) {
const Fl_Menu_Item &item = menu->menu()[i];
if(item.value() && item.label()){
if(val.size()) val += ", ";
val += item.label();
}
}
Fl_Input_Choice *but = (Fl_Input_Choice*)data;
but->value(val.c_str());
but->do_callback();
}
Fl_Widget *onelabGroup::_addParameterWidget(onelab::string &p, Fl_Tree_Item *n, Fl_Widget *onelabGroup::_addParameterWidget(onelab::string &p, Fl_Tree_Item *n,
bool highlight, Fl_Color c) bool highlight, Fl_Color c)
{ {
...@@ -1227,32 +1242,15 @@ Fl_Widget *onelabGroup::_addParameterWidget(onelab::string &p, Fl_Tree_Item *n, ...@@ -1227,32 +1242,15 @@ Fl_Widget *onelabGroup::_addParameterWidget(onelab::string &p, Fl_Tree_Item *n,
return but; return but;
} }
// simple string (no menu)
if(p.getChoices().empty() && p.getKind() != "file"){
Fl_Input *but = new Fl_Input(1, 1, ww, 1);
but->value(p.getValue().c_str());
but->callback(onelab_string_input_cb, (void*)n);
but->when(FL_WHEN_ENTER_KEY);
but->align(FL_ALIGN_RIGHT);
if(highlight) but->color(c);
return but;
}
// general string input // general string input
Fl_Input_Choice *but = new Fl_Input_Choice(1, 1, ww, 1); Fl_Input_Choice *but = new Fl_Input_Choice(1, 1, ww, 1);
std::string multipleSelection = p.getAttribute("MultipleSelection");
if(multipleSelection.size())
but->menubutton()->callback(multiple_selection_menu_cb, but);
std::vector<Fl_Menu_Item> menu; std::vector<Fl_Menu_Item> menu;
for(unsigned int j = 0; j < p.getChoices().size(); j++){ for(unsigned int j = 0; j < p.getChoices().size(); j++){
char *str = strdup(p.getChoices()[j].c_str()); char *str = strdup(p.getChoices()[j].c_str());
_treeStrings.push_back(str); _treeStrings.push_back(str);
bool divider = (p.getKind() == "file" && bool divider = (p.getKind() == "file" &&
j == p.getChoices().size() - 1); j == p.getChoices().size() - 1);
int choice = multipleSelection.size() ? FL_MENU_TOGGLE : 0; Fl_Menu_Item it = {str, 0, 0, 0, divider ? FL_MENU_DIVIDER : 0};
if(multipleSelection.size() > j && multipleSelection[j] == '1')
choice |= FL_MENU_VALUE;
Fl_Menu_Item it = {str, 0, 0, 0, divider ? FL_MENU_DIVIDER : choice};
menu.push_back(it); menu.push_back(it);
} }
if(p.getKind() == "file"){ if(p.getKind() == "file"){
...@@ -1428,6 +1426,7 @@ void onelabGroup::openTreeItem(const std::string &name) ...@@ -1428,6 +1426,7 @@ void onelabGroup::openTreeItem(const std::string &name)
void onelabGroup::checkForErrors(const std::string &client) void onelabGroup::checkForErrors(const std::string &client)
{ {
if(Msg::GetErrorCount() > 0 && !CTX::instance()->expertMode){ if(Msg::GetErrorCount() > 0 && !CTX::instance()->expertMode){
Msg::ResetErrorCounter();
std::string msg std::string msg
(client + " reported an error: do you really want to continue?\n\n" (client + " reported an error: do you really want to continue?\n\n"
"(To disable this warning in the future, select `Enable expert mode'\n" "(To disable this warning in the future, select `Enable expert mode'\n"
...@@ -1629,6 +1628,8 @@ void onelabGroup::removeSolver(const std::string &name) ...@@ -1629,6 +1628,8 @@ void onelabGroup::removeSolver(const std::string &name)
void solver_cb(Fl_Widget *w, void *data) void solver_cb(Fl_Widget *w, void *data)
{ {
Msg::ResetErrorCounter();
int num = (intptr_t)data; int num = (intptr_t)data;
if(num >= 0){ if(num >= 0){
std::string name = opt_solver_name(num, GMSH_GET, ""); std::string name = opt_solver_name(num, GMSH_GET, "");
...@@ -1715,6 +1716,7 @@ void flgui_wait_cb(double time) ...@@ -1715,6 +1716,7 @@ void flgui_wait_cb(double time)
int metamodel_cb(const std::string &name, const std::string &action) int metamodel_cb(const std::string &name, const std::string &action)
{ {
#if defined(HAVE_ONELAB_METAMODEL) #if defined(HAVE_ONELAB_METAMODEL)
Msg::ResetErrorCounter();
if(FlGui::instance()->onelab->isBusy()) if(FlGui::instance()->onelab->isBusy())
FlGui::instance()->onelab->show(); FlGui::instance()->onelab->show();
else{ else{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment