|  | @@ -411,20 +411,129 @@ void Director::menu_choice(void) {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | +/**
 | 
	
		
			
				|  |  | + * @brief Setup Config Input
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * @return DispatchInput*
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +InputDispatch *Director::init_config_input(void) {
 | 
	
		
			
				|  |  | +  InputDispatch *id;
 | 
	
		
			
				|  |  | +  if (config_input) {
 | 
	
		
			
				|  |  | +    // Yes, it has been setup before.
 | 
	
		
			
				|  |  | +    id = dynamic_cast<InputDispatch *>(&(*config_input));
 | 
	
		
			
				|  |  | +    id->prompt = "Config => ";
 | 
	
		
			
				|  |  | +    id->max_length = 3;
 | 
	
		
			
				|  |  | +    config_item.clear();
 | 
	
		
			
				|  |  | +    return id;
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    // set it up
 | 
	
		
			
				|  |  | +    config_input = std::make_shared<InputDispatch>(*this);
 | 
	
		
			
				|  |  | +    id = static_cast<InputDispatch *>(&(*config_input));
 | 
	
		
			
				|  |  | +    id->prompt = "Config => ";
 | 
	
		
			
				|  |  | +    id->max_length = 3;
 | 
	
		
			
				|  |  | +    id->setNotify([this]() { this->config_have_input(); });
 | 
	
		
			
				|  |  | +    config_item.clear();
 | 
	
		
			
				|  |  | +    return id;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void Director::config_edit(void) {
 | 
	
		
			
				|  |  |    // display current config
 | 
	
		
			
				|  |  | -  to_client("Configuration:\n\r");
 | 
	
		
			
				|  |  | +  std::string menu_box_color = "\x1b[1;33;44m";
 | 
	
		
			
				|  |  | +  std::string menu_text_color = "\x1b[1;37;44m";
 | 
	
		
			
				|  |  | +  auto abox = Boxes::alert("   Configuration:   ", menu_box_color,
 | 
	
		
			
				|  |  | +                           menu_text_color, 20, 1, true);
 | 
	
		
			
				|  |  | +  for (auto line : abox) {
 | 
	
		
			
				|  |  | +    to_client(line);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  // to_client("Configuration:\n\r");
 | 
	
		
			
				|  |  |    int item = 1;
 | 
	
		
			
				|  |  |    for (auto const &cfg : galaxy.config) {
 | 
	
		
			
				|  |  | -    std::string output = str(boost::format("%1$2d %2$20s:%3$s\n\r") % item %
 | 
	
		
			
				|  |  | +    std::string output = str(boost::format("%1$2d %2$20s: %3$s\n\r") % item %
 | 
	
		
			
				|  |  |                               cfg.first % cfg.second);
 | 
	
		
			
				|  |  |      to_client(output);
 | 
	
		
			
				|  |  |      ++item;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | +  to_client("Enter number to edit.\n\r");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // setup call to config_input:
 | 
	
		
			
				|  |  | +  InputDispatch *id = init_config_input();
 | 
	
		
			
				|  |  | +  chain = config_input;
 | 
	
		
			
				|  |  | +  id->activate();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |    // to return to the menu:
 | 
	
		
			
				|  |  | -  MenuDispatch *md = dynamic_cast<MenuDispatch *>(&(*chain));  
 | 
	
		
			
				|  |  | -  md->activate();
 | 
	
		
			
				|  |  | +  // MenuDispatch *md = dynamic_cast<MenuDispatch *>(&(*chain));
 | 
	
		
			
				|  |  | +  // md->activate();
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +void Director::config_have_input(void) {
 | 
	
		
			
				|  |  | +  InputDispatch *id = dynamic_cast<InputDispatch *>(&(*config_input));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (config_item.empty()) {
 | 
	
		
			
				|  |  | +    // This is a config menu selection
 | 
	
		
			
				|  |  | +    if (id->input.empty()) {
 | 
	
		
			
				|  |  | +      // We're done here.  Return to menu.
 | 
	
		
			
				|  |  | +      chain = main_menu;
 | 
	
		
			
				|  |  | +      MenuDispatch *md = dynamic_cast<MenuDispatch *>(&(*chain));
 | 
	
		
			
				|  |  | +      md->activate();
 | 
	
		
			
				|  |  | +      // destroy the input?
 | 
	
		
			
				|  |  | +      config_input.reset();
 | 
	
		
			
				|  |  | +      return;
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +      int item;
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        item = stoi(id->input);
 | 
	
		
			
				|  |  | +      } catch (const std::invalid_argument &e) {
 | 
	
		
			
				|  |  | +        BUGZ_LOG(fatal) << e.what();
 | 
	
		
			
				|  |  | +        item = 0;
 | 
	
		
			
				|  |  | +      } catch (const std::out_of_range &e) {
 | 
	
		
			
				|  |  | +        BUGZ_LOG(fatal) << e.what();
 | 
	
		
			
				|  |  | +        item = 0;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      if ((item < 1) || (item > (int)galaxy.config.size())) {
 | 
	
		
			
				|  |  | +        // selection out of range - redisplay config menu
 | 
	
		
			
				|  |  | +        config_edit();
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        int pos = 1;
 | 
	
		
			
				|  |  | +        const YAML::Node &config = galaxy.config;
 | 
	
		
			
				|  |  | +        for (auto const &c : config) {
 | 
	
		
			
				|  |  | +          if (pos == item) {
 | 
	
		
			
				|  |  | +            // got it!
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            config_item = c.first.as<std::string>();
 | 
	
		
			
				|  |  | +            std::string output =
 | 
	
		
			
				|  |  | +                str(boost::format("%1% : %2%\n\r") % config_item %
 | 
	
		
			
				|  |  | +                    galaxy.meta["help"][config_item]);
 | 
	
		
			
				|  |  | +            to_client(output);
 | 
	
		
			
				|  |  | +            id->max_length = 30;
 | 
	
		
			
				|  |  | +            id->prompt = "Change to => ";
 | 
	
		
			
				|  |  | +            id->activate();
 | 
	
		
			
				|  |  | +            return;
 | 
	
		
			
				|  |  | +          };
 | 
	
		
			
				|  |  | +          ++pos;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        to_client("What?  I didn't find that item?\n\r");
 | 
	
		
			
				|  |  | +        config_edit();
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  } else {
 | 
	
		
			
				|  |  | +    // This is a config item edit
 | 
	
		
			
				|  |  | +    if (id->input.empty()) {
 | 
	
		
			
				|  |  | +      to_client("No change.\n\r");
 | 
	
		
			
				|  |  | +      config_item.clear();
 | 
	
		
			
				|  |  | +      config_edit();
 | 
	
		
			
				|  |  | +      return;
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +      BUGZ_LOG(fatal) << "Config EDIT: " << config_item << " = " << id->input;
 | 
	
		
			
				|  |  | +      galaxy.config[config_item] = id->input;
 | 
	
		
			
				|  |  | +      config_item.clear();
 | 
	
		
			
				|  |  | +      config_edit();
 | 
	
		
			
				|  |  | +      return;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void Director::have_input(void) {
 |