00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "global.hpp"
00016
00017 #define GETTEXT_DOMAIN "wesnoth-lib"
00018
00019 #include "config.hpp"
00020 #include "construct_dialog.hpp"
00021 #include "display.hpp"
00022 #include "events.hpp"
00023 #include "hotkeys.hpp"
00024 #include "game_config.hpp"
00025 #include "game_errors.hpp"
00026 #include "gettext.hpp"
00027 #include "filesystem.hpp"
00028 #include "log.hpp"
00029 #include "menu_events.hpp"
00030 #include "preferences_display.hpp"
00031 #include "show_dialog.hpp"
00032 #include "util.hpp"
00033 #include "video.hpp"
00034 #include "wesconfig.h"
00035 #include "wml_separators.hpp"
00036 #include "SDL.h"
00037
00038 #include <algorithm>
00039 #include <cstdlib>
00040 #include <map>
00041
00042 #define ERR_G LOG_STREAM(err, general)
00043 #define LOG_G LOG_STREAM(info, general)
00044 #define DBG_G LOG_STREAM(debug, general)
00045 #define ERR_CONFIG LOG_STREAM(err, config)
00046
00047 namespace {
00048
00049 const struct {
00050 hotkey::HOTKEY_COMMAND id;
00051 const char* command;
00052 const char* description;
00053 bool hidden;
00054 } hotkey_list_[] = {
00055 { hotkey::HOTKEY_CYCLE_UNITS, "cycle", N_("Next Unit"), false },
00056 { hotkey::HOTKEY_CYCLE_BACK_UNITS, "cycleback", N_("Previous Unit"), false },
00057 { hotkey::HOTKEY_UNIT_HOLD_POSITION, "holdposition", N_("Hold Position"), false},
00058 { hotkey::HOTKEY_END_UNIT_TURN, "endunitturn", N_("End Unit Turn"), false },
00059 { hotkey::HOTKEY_LEADER, "leader", N_("Leader"), false },
00060 { hotkey::HOTKEY_UNDO, "undo", N_("Undo"), false },
00061 { hotkey::HOTKEY_REDO, "redo", N_("Redo"), false },
00062 { hotkey::HOTKEY_ZOOM_IN, "zoomin", N_("Zoom In"), false },
00063 { hotkey::HOTKEY_ZOOM_OUT, "zoomout", N_("Zoom Out"), false },
00064 { hotkey::HOTKEY_ZOOM_DEFAULT, "zoomdefault", N_("Default Zoom"), false },
00065 { hotkey::HOTKEY_FULLSCREEN, "fullscreen", N_("Toggle Full Screen"), false },
00066 { hotkey::HOTKEY_SCREENSHOT, "screenshot", N_("Screenshot"), false },
00067 { hotkey::HOTKEY_MAP_SCREENSHOT, "mapscreenshot", N_("Map Screenshot"), false },
00068 { hotkey::HOTKEY_ACCELERATED, "accelerated", N_("Accelerated"), false },
00069 { hotkey::HOTKEY_UNIT_DESCRIPTION, "describeunit", N_("Unit Description"), false },
00070 { hotkey::HOTKEY_RENAME_UNIT, "renameunit", N_("Rename Unit"), false },
00071 { hotkey::HOTKEY_SAVE_GAME, "save", N_("Save Game"), false },
00072 { hotkey::HOTKEY_SAVE_REPLAY, "savereplay", N_("Save Replay"), false },
00073 { hotkey::HOTKEY_SAVE_MAP, "savemap", N_("Save The Map"), false },
00074 { hotkey::HOTKEY_LOAD_GAME, "load", N_("Load Game"), false },
00075 { hotkey::HOTKEY_RECRUIT, "recruit", N_("Recruit"), false },
00076 { hotkey::HOTKEY_REPEAT_RECRUIT, "repeatrecruit", N_("Repeat Recruit"), false },
00077 { hotkey::HOTKEY_RECALL, "recall", N_("Recall"), false },
00078 { hotkey::HOTKEY_ENDTURN, "endturn", N_("End Turn"), false },
00079 { hotkey::HOTKEY_TOGGLE_GRID, "togglegrid", N_("Toggle Grid"), false },
00080 { hotkey::HOTKEY_MOUSE_SCROLL, "mousescroll", N_("Mouse Scrolling"), false },
00081 { hotkey::HOTKEY_STATUS_TABLE, "statustable", N_("Status Table"), false },
00082 { hotkey::HOTKEY_MUTE, "mute", N_("Mute"), false },
00083 { hotkey::HOTKEY_SPEAK, "speak", N_("Speak"), false },
00084 { hotkey::HOTKEY_CREATE_UNIT, "createunit", N_("Create Unit (Debug!)"), false },
00085 { hotkey::HOTKEY_CHANGE_UNIT_SIDE, "changeside", N_("Change Unit Side (Debug!)"), false },
00086 { hotkey::HOTKEY_PREFERENCES, "preferences", N_("Preferences"), false },
00087 { hotkey::HOTKEY_OBJECTIVES, "objectives", N_("Scenario Objectives"), false },
00088 { hotkey::HOTKEY_UNIT_LIST, "unitlist", N_("Unit List"), false },
00089 { hotkey::HOTKEY_STATISTICS, "statistics", N_("Statistics"), false },
00090 { hotkey::HOTKEY_QUIT_GAME, "quit", N_("Quit Game"), false },
00091 { hotkey::HOTKEY_LABEL_TEAM_TERRAIN, "labelteamterrain", N_("Set Team Label"), false },
00092 { hotkey::HOTKEY_LABEL_TERRAIN, "labelterrain", N_("Set Label"), false },
00093 { hotkey::HOTKEY_CLEAR_LABELS, "clearlabels", N_("Clear Labels"), false },
00094 { hotkey::HOTKEY_SHOW_ENEMY_MOVES, "showenemymoves", N_("Show Enemy Moves"), false },
00095 { hotkey::HOTKEY_BEST_ENEMY_MOVES, "bestenemymoves", N_("Best Possible Enemy Moves"), false },
00096 { hotkey::HOTKEY_PLAY_REPLAY, "playreplay", N_("Play"), false },
00097 { hotkey::HOTKEY_RESET_REPLAY, "resetreplay", N_("Reset"), false },
00098 { hotkey::HOTKEY_STOP_REPLAY, "stopreplay", N_("Stop"), false },
00099 { hotkey::HOTKEY_REPLAY_NEXT_TURN, "replaynextturn", N_("Next Turn"), false },
00100 { hotkey::HOTKEY_REPLAY_NEXT_SIDE, "replaynextside", N_("Next Side"), false },
00101 { hotkey::HOTKEY_REPLAY_SHOW_EVERYTHING, "replayshoweverything",
00102 N_("Full map"), false },
00103 { hotkey::HOTKEY_REPLAY_SHOW_EACH, "replayshoweach",
00104 N_("Each team"), false },
00105 { hotkey::HOTKEY_REPLAY_SHOW_TEAM1, "replayshowteam1",
00106 N_("Team 1"), false },
00107 { hotkey::HOTKEY_REPLAY_SKIP_ANIMATION, "replayskipanimation", N_("Skip animation"), false },
00108
00109 { hotkey::HOTKEY_EDIT_SET_TERRAIN, "editsetterrain", N_("Set Terrain"),true },
00110 { hotkey::HOTKEY_EDIT_QUIT, "editquit", N_("Quit Editor"),true },
00111 { hotkey::HOTKEY_EDIT_NEW_MAP, "editnewmap", N_("New Map"),true },
00112 { hotkey::HOTKEY_EDIT_LOAD_MAP, "editloadmap", N_("Load Map"),true },
00113 { hotkey::HOTKEY_EDIT_SAVE_MAP, "editsavemap", N_("Save Map"),true },
00114 { hotkey::HOTKEY_EDIT_SAVE_AS, "editsaveas", N_("Save As"),true },
00115 { hotkey::HOTKEY_EDIT_SET_START_POS, "editsetstartpos", N_("Set Player's keep"),true },
00116 { hotkey::HOTKEY_EDIT_FLOOD_FILL, "editfloodfill", N_("Flood Fill"),true },
00117 { hotkey::HOTKEY_EDIT_FILL_SELECTION, "editfillselection", N_("Fill Selection"),true },
00118 { hotkey::HOTKEY_EDIT_ROTATE_SELECTION, "editrotateselection", N_("Rotate Selection"),true },
00119 { hotkey::HOTKEY_EDIT_CUT, "editcut", N_("Cut"),true },
00120 { hotkey::HOTKEY_EDIT_COPY, "editcopy", N_("Copy"),true },
00121 { hotkey::HOTKEY_EDIT_PASTE, "editpaste", N_("Paste"),true },
00122 { hotkey::HOTKEY_EDIT_REVERT, "editrevert", N_("Revert from Disk"),true },
00123 { hotkey::HOTKEY_EDIT_RESIZE, "editresize", N_("Resize Map"),true },
00124 { hotkey::HOTKEY_EDIT_FLIP, "editflip", N_("Flip Map"),true },
00125 { hotkey::HOTKEY_EDIT_SELECT_ALL, "editselectall", N_("Select All"),true },
00126 { hotkey::HOTKEY_EDIT_DRAW, "editdraw", N_("Draw Terrain"),true },
00127 { hotkey::HOTKEY_EDIT_REFRESH, "editrefresh", N_("Refresh Image Cache"), true },
00128 { hotkey::HOTKEY_EDIT_AUTO_UPDATE, "editautoupdate", N_("Delay transition updates"), true },
00129 { hotkey::HOTKEY_EDIT_UPDATE, "editupdate", N_("Update transitions"), true },
00130
00131 { hotkey::HOTKEY_DELAY_SHROUD, "delayshroud", N_("Delay Shroud Updates"), false },
00132 { hotkey::HOTKEY_UPDATE_SHROUD, "updateshroud", N_("Update Shroud Now"), false },
00133 { hotkey::HOTKEY_CONTINUE_MOVE, "continue", N_("Continue Move"), false },
00134 { hotkey::HOTKEY_SEARCH, "search", N_("Find Label or Unit"), false },
00135 { hotkey::HOTKEY_SPEAK_ALLY, "speaktoally", N_("Speak to Ally"), false },
00136 { hotkey::HOTKEY_SPEAK_ALL, "speaktoall", N_("Speak to All"), false },
00137 { hotkey::HOTKEY_HELP, "help", N_("Help"), false },
00138 { hotkey::HOTKEY_CHAT_LOG, "chatlog", N_("View Chat Log"), false },
00139 { hotkey::HOTKEY_LANGUAGE, "changelanguage", N_("Change the language"), true },
00140
00141 { hotkey::HOTKEY_USER_CMD, "command", N_("Enter user command"), false },
00142 { hotkey::HOTKEY_CUSTOM_CMD, "customcommand", N_("Custom command"), false },
00143 { hotkey::HOTKEY_AI_FORMULA, "aiformula", N_("Run AI formula"), false },
00144 { hotkey::HOTKEY_CLEAR_MSG, "clearmessages", N_("Clear messages"), false },
00145 #ifdef USRCMD2
00146 { hotkey::HOTKEY_USER_CMD_2, "usercommand#2", N_("User-Command#2"), false },
00147 { hotkey::HOTKEY_USER_CMD_3, "usercommand#3", N_("User-Command#3"), false },
00148 #endif
00149 { hotkey::HOTKEY_NULL, NULL, NULL, true }
00150 };
00151
00152 std::vector<hotkey::hotkey_item> hotkeys_;
00153 hotkey::hotkey_item null_hotkey_;
00154
00155 }
00156
00157 namespace hotkey {
00158
00159 static void key_event_execute(display& disp, const SDL_KeyboardEvent& event, command_executor* executor);
00160
00161 const std::string CLEARED_TEXT = "__none__";
00162
00163 hotkey_item::hotkey_item(HOTKEY_COMMAND id,
00164 const std::string& command, const std::string& description, bool hidden) :
00165 id_(id),
00166 command_(command),
00167 description_(description),
00168 type_(UNBOUND),
00169 character_(0),
00170 ctrl_(false),
00171 alt_(false),
00172 cmd_(false),
00173 keycode_(0),
00174 shift_(false),
00175 hidden_(hidden)
00176 {
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186 void hotkey_item::load_from_config(const config& cfg)
00187 {
00188 const std::string& key = cfg["key"];
00189
00190 alt_ = utils::string_bool(cfg["alt"]);
00191 cmd_ = utils::string_bool(cfg["cmd"]);
00192 ctrl_ = utils::string_bool(cfg["ctrl"]);
00193 shift_ = utils::string_bool(cfg["shift"]);
00194
00195 if (!key.empty()) {
00196
00197
00198 if (key == CLEARED_TEXT)
00199 {
00200 type_ = hotkey_item::CLEARED;
00201 }
00202 else if (key.size() > 1) {
00203 type_ = BY_KEYCODE;
00204
00205 keycode_ = sdl_keysym_from_name(key);
00206 if (keycode_ == SDLK_UNKNOWN) {
00207 if (tolower(key[0]) != 'f') {
00208 ERR_CONFIG << "hotkey key '" << key << "' invalid\n";
00209 } else {
00210 int num = lexical_cast_default<int>
00211 (std::string(key.begin()+1, key.end()), 1);
00212 keycode_ = num + SDLK_F1 - 1;
00213 }
00214 }
00215 } else if (key == " " || shift_
00216 #ifdef __APPLE__
00217 || alt_
00218 #endif
00219 ) {
00220
00221
00222
00223
00224
00225
00226 type_ = BY_KEYCODE;
00227 keycode_ = key[0];
00228 } else {
00229 type_ = BY_CHARACTER;
00230 character_ = key[0];
00231 }
00232 }
00233 }
00234
00235 std::string hotkey_item::get_name() const
00236 {
00237 std::stringstream str;
00238 if (type_ == BY_CHARACTER) {
00239 if (alt_)
00240 str << "alt+";
00241 if (cmd_)
00242 str << "cmd+";
00243 if (ctrl_)
00244 str << "ctrl+";
00245 str << static_cast<char>(character_);
00246 } else if (type_ == BY_KEYCODE) {
00247 if (alt_)
00248 str << "alt+";
00249 if (ctrl_)
00250 str << "ctrl+";
00251 if (shift_)
00252 str << "shift+";
00253 if (cmd_)
00254 str << "cmd+";
00255 str << SDL_GetKeyName(SDLKey(keycode_));
00256 }
00257 return str.str();
00258 }
00259
00260 void hotkey_item::set_description(const std::string& description)
00261 {
00262 description_ = description;
00263 }
00264 void hotkey_item::clear_hotkey()
00265 {
00266 type_ = CLEARED;
00267 }
00268
00269 void hotkey_item::set_key(int character, int keycode, bool shift, bool ctrl, bool alt, bool cmd)
00270 {
00271 const std::string keyname = SDL_GetKeyName(SDLKey(keycode));
00272
00273 LOG_G << "setting hotkey: char=" << lexical_cast<std::string>(character)
00274 << " keycode=" << lexical_cast<std::string>(keycode) << " "
00275 << (shift ? "shift," : "")
00276 << (ctrl ? "ctrl," : "")
00277 << (alt ? "alt," : "")
00278 << (cmd ? "cmd," : "")
00279 << "\n";
00280
00281
00282 if (character < 64 && ctrl) {
00283 if (shift)
00284 character += 64;
00285 else
00286 character += 96;
00287 LOG_G << "Mapped to character " << lexical_cast<std::string>(character) << "\n";
00288 }
00289
00290
00291 if (cmd && character > 96 && character < 123 && shift)
00292 character -= 32;
00293
00294
00295 if (isprint(character) && !isspace(character)) {
00296 type_ = BY_CHARACTER;
00297 character_ = character;
00298 ctrl_ = ctrl;
00299 alt_ = alt;
00300 cmd_ = cmd;
00301 LOG_G << "type = BY_CHARACTER\n";
00302 } else {
00303 type_ = BY_KEYCODE;
00304 keycode_ = keycode;
00305 shift_ = shift;
00306 ctrl_ = ctrl;
00307 alt_ = alt;
00308 cmd_ = cmd;
00309 LOG_G << "type = BY_KEYCODE\n";
00310 }
00311 }
00312
00313 manager::manager()
00314 {
00315 for (int i = 0; hotkey_list_[i].command; ++i) {
00316 hotkeys_.push_back(hotkey_item(hotkey_list_[i].id, hotkey_list_[i].command,
00317 "", hotkey_list_[i].hidden));
00318 }
00319 }
00320
00321
00322 manager::~manager()
00323 {
00324 hotkeys_.clear();
00325 }
00326
00327 void load_descriptions()
00328 {
00329 for (size_t i = 0; hotkey_list_[i].command; ++i) {
00330 if (i >= hotkeys_.size()) {
00331 ERR_G << "Hotkey list too short: " << hotkeys_.size() << "\n";
00332 }
00333 hotkeys_[i].set_description(dsgettext(PACKAGE "-lib", hotkey_list_[i].description));
00334 }
00335 }
00336
00337 void load_hotkeys(const config& cfg)
00338 {
00339 const config::child_list& children = cfg.get_children("hotkey");
00340 for(config::child_list::const_iterator i = children.begin(); i != children.end(); ++i) {
00341 hotkey_item& h = get_hotkey((**i)["command"]);
00342
00343 if(h.get_id() != HOTKEY_NULL) {
00344 h.load_from_config(**i);
00345 }
00346 }
00347 }
00348
00349 void save_hotkeys(config& cfg)
00350 {
00351 cfg.clear_children("hotkey");
00352
00353 for(std::vector<hotkey_item>::iterator i = hotkeys_.begin(); i != hotkeys_.end(); ++i) {
00354 if (i->hidden() || i->get_type() == hotkey_item::UNBOUND)
00355 continue;
00356
00357 config& item = cfg.add_child("hotkey");
00358 item["command"] = i->get_command();
00359
00360 if (i->get_type() == hotkey_item::CLEARED)
00361 {
00362 item["key"] = CLEARED_TEXT;
00363 continue;
00364 }
00365
00366 if (i->get_type() == hotkey_item::BY_KEYCODE) {
00367 item["key"] = SDL_GetKeyName(SDLKey(i->get_keycode()));
00368 item["shift"] = i->get_shift() ? "yes" : "no";
00369 } else if (i->get_type() == hotkey_item::BY_CHARACTER) {
00370 item["key"] = std::string(1, static_cast<char>(i->get_character()));
00371 }
00372 item["alt"] = i->get_alt() ? "yes" : "no";
00373 item["ctrl"] = i->get_ctrl() ? "yes" : "no";
00374 item["cmd"] = i->get_cmd() ? "yes" : "no";
00375 }
00376 }
00377
00378 hotkey_item& get_hotkey(HOTKEY_COMMAND id)
00379 {
00380 std::vector<hotkey_item>::iterator itor;
00381
00382 for (itor = hotkeys_.begin(); itor != hotkeys_.end(); ++itor) {
00383 if (itor->get_id() == id)
00384 break;
00385 }
00386
00387 if (itor == hotkeys_.end())
00388 return null_hotkey_;
00389
00390 return *itor;
00391 }
00392
00393 hotkey_item& get_hotkey(const std::string& command)
00394 {
00395 std::vector<hotkey_item>::iterator itor;
00396
00397 for (itor = hotkeys_.begin(); itor != hotkeys_.end(); ++itor) {
00398 if (itor->get_command() == command)
00399 break;
00400 }
00401
00402 if (itor == hotkeys_.end())
00403 return null_hotkey_;
00404
00405 return *itor;
00406 }
00407
00408 hotkey_item& get_hotkey(int character, int keycode, bool shift, bool ctrl, bool alt, bool cmd)
00409 {
00410 std::vector<hotkey_item>::iterator itor;
00411
00412 DBG_G << "getting hotkey: char=" << lexical_cast<std::string>(character)
00413 << " keycode=" << lexical_cast<std::string>(keycode) << " "
00414 << (shift ? "shift," : "")
00415 << (ctrl ? "ctrl," : "")
00416 << (alt ? "alt," : "")
00417 << (cmd ? "cmd," : "")
00418 << "\n";
00419
00420
00421 if (character < 64 && ctrl) {
00422 if (shift)
00423 character += 64;
00424 else
00425 character += 96;
00426 DBG_G << "Mapped to character " << lexical_cast<std::string>(character) << "\n";
00427 }
00428
00429
00430 if (cmd && character > 96 && character < 123 && shift)
00431 character -= 32;
00432
00433 for (itor = hotkeys_.begin(); itor != hotkeys_.end(); ++itor) {
00434 if (itor->get_type() == hotkey_item::BY_CHARACTER) {
00435 if (character == itor->get_character()) {
00436 if (ctrl == itor->get_ctrl()
00437 && alt == itor->get_alt()
00438 && cmd == itor->get_cmd()) {
00439 DBG_G << "Could match by character..." << "yes\n";
00440 break;
00441 }
00442 DBG_G << "Could match by character..." << "but modifiers different\n";
00443 }
00444 } else if (itor->get_type() == hotkey_item::BY_KEYCODE) {
00445 if (keycode == itor->get_keycode()) {
00446 if (shift == itor->get_shift()
00447 && ctrl == itor->get_ctrl()
00448 && alt == itor->get_alt()
00449 && cmd == itor->get_cmd()) {
00450 DBG_G << "Could match by keycode..." << "yes\n";
00451 break;
00452 }
00453 DBG_G << "Could match by keycode..." << "but modifiers different\n";
00454 }
00455 }
00456 }
00457
00458 if (itor == hotkeys_.end())
00459 return null_hotkey_;
00460
00461 return *itor;
00462 }
00463
00464 hotkey_item& get_hotkey(const SDL_KeyboardEvent& event)
00465 {
00466 return get_hotkey(event.keysym.unicode, event.keysym.sym,
00467 (event.keysym.mod & KMOD_SHIFT) != 0,
00468 (event.keysym.mod & KMOD_CTRL) != 0,
00469 (event.keysym.mod & KMOD_ALT) != 0,
00470 (event.keysym.mod & KMOD_LMETA) != 0
00471 #ifdef __APPLE__
00472 || (event.keysym.mod & KMOD_RMETA) != 0
00473 #endif
00474 );
00475 }
00476
00477 static void _get_visible_hotkey_itor(int index, std::vector<hotkey_item>::iterator& itor)
00478 {
00479 int counter = 0;
00480 for (itor = hotkeys_.begin(); itor != hotkeys_.end(); ++itor) {
00481 if (itor->hidden())
00482 continue;
00483
00484 if (index == counter)
00485 break;
00486
00487 counter++;
00488 }
00489 }
00490
00491 hotkey_item& get_visible_hotkey(int index)
00492 {
00493
00494 std::vector<hotkey_item>::iterator itor;
00495 _get_visible_hotkey_itor(index, itor);
00496 if (itor == hotkeys_.end())
00497 return null_hotkey_;
00498
00499 return *itor;
00500 }
00501
00502 std::vector<hotkey_item>& get_hotkeys()
00503 {
00504 return hotkeys_;
00505 }
00506
00507 basic_handler::basic_handler(display* disp, command_executor* exec) : disp_(disp), exec_(exec) {}
00508
00509 void basic_handler::handle_event(const SDL_Event& event)
00510 {
00511 if(event.type == SDL_KEYDOWN && disp_ != NULL) {
00512
00513
00514
00515 if(!gui::in_dialog()) {
00516 key_event(*disp_,event.key,exec_);
00517 } else if(exec_ != NULL) {
00518 key_event_execute(*disp_,event.key,exec_);
00519 }
00520 }
00521 }
00522
00523
00524 void key_event(display& disp, const SDL_KeyboardEvent& event, command_executor* executor)
00525 {
00526 if(event.keysym.sym == SDLK_ESCAPE && disp.in_game()) {
00527 ERR_G << "escape pressed..showing quit\n";
00528 const int res = gui::dialog(disp,_("Quit"),_("Do you really want to quit?"),gui::YES_NO).show();
00529 if(res == 0) {
00530 throw end_level_exception(QUIT);
00531 } else {
00532 return;
00533 }
00534 }
00535
00536 key_event_execute(disp,event,executor);
00537 }
00538
00539 void key_event_execute(display& disp, const SDL_KeyboardEvent& event, command_executor* executor)
00540 {
00541 const hotkey_item* hk = &get_hotkey(event);
00542
00543 #if 0
00544
00545 if(hk->null()) {
00546
00547 hk = &get_hotkey(event, true);
00548 }
00549 #endif
00550
00551 if(hk->null())
00552 return;
00553
00554 execute_command(disp,hk->get_id(),executor);
00555 }
00556
00557 bool command_executor::execute_command(HOTKEY_COMMAND command, int )
00558 {
00559 switch(command) {
00560 case HOTKEY_CYCLE_UNITS:
00561 cycle_units();
00562 break;
00563 case HOTKEY_CYCLE_BACK_UNITS:
00564 cycle_back_units();
00565 break;
00566 case HOTKEY_ENDTURN:
00567 end_turn();
00568 break;
00569 case HOTKEY_UNIT_HOLD_POSITION:
00570 unit_hold_position();
00571 break;
00572 case HOTKEY_END_UNIT_TURN:
00573 end_unit_turn();
00574 break;
00575 case HOTKEY_LEADER:
00576 goto_leader();
00577 break;
00578 case HOTKEY_UNDO:
00579 undo();
00580 break;
00581 case HOTKEY_REDO:
00582 redo();
00583 break;
00584 case HOTKEY_UNIT_DESCRIPTION:
00585 unit_description();
00586 break;
00587 case HOTKEY_RENAME_UNIT:
00588 rename_unit();
00589 break;
00590 case HOTKEY_SAVE_GAME:
00591 save_game();
00592 break;
00593 case HOTKEY_SAVE_REPLAY:
00594 save_replay();
00595 break;
00596 case HOTKEY_SAVE_MAP:
00597 save_map();
00598 break;
00599 case HOTKEY_LOAD_GAME:
00600 load_game();
00601 break;
00602 case HOTKEY_TOGGLE_GRID:
00603 toggle_grid();
00604 break;
00605 case HOTKEY_STATUS_TABLE:
00606 status_table();
00607 break;
00608 case HOTKEY_RECALL:
00609 recall();
00610 break;
00611 case HOTKEY_RECRUIT:
00612 recruit();
00613 break;
00614 case hotkey::HOTKEY_REPEAT_RECRUIT:
00615 repeat_recruit();
00616 break;
00617 case HOTKEY_SPEAK:
00618 speak();
00619 break;
00620 case HOTKEY_SPEAK_ALLY:
00621 whisper();
00622 break;
00623 case HOTKEY_SPEAK_ALL:
00624 shout();
00625 break;
00626 case HOTKEY_CREATE_UNIT:
00627 create_unit();
00628 break;
00629 case HOTKEY_CHANGE_UNIT_SIDE:
00630 change_unit_side();
00631 break;
00632 case HOTKEY_PREFERENCES:
00633 preferences();
00634 break;
00635 case HOTKEY_OBJECTIVES:
00636 objectives();
00637 break;
00638 case HOTKEY_UNIT_LIST:
00639 unit_list();
00640 break;
00641 case HOTKEY_STATISTICS:
00642 show_statistics();
00643 break;
00644 case HOTKEY_LABEL_TEAM_TERRAIN:
00645 label_terrain(true);
00646 break;
00647 case HOTKEY_LABEL_TERRAIN:
00648 label_terrain(false);
00649 break;
00650 case HOTKEY_CLEAR_LABELS:
00651 clear_labels();
00652 break;
00653 case HOTKEY_SHOW_ENEMY_MOVES:
00654 show_enemy_moves(false);
00655 break;
00656 case HOTKEY_BEST_ENEMY_MOVES:
00657 show_enemy_moves(true);
00658 break;
00659 case HOTKEY_DELAY_SHROUD:
00660 toggle_shroud_updates();
00661 break;
00662 case HOTKEY_UPDATE_SHROUD:
00663 update_shroud_now();
00664 break;
00665 case HOTKEY_CONTINUE_MOVE:
00666 continue_move();
00667 break;
00668 case HOTKEY_SEARCH:
00669 search();
00670 break;
00671 case HOTKEY_HELP:
00672 show_help();
00673 break;
00674 case HOTKEY_CHAT_LOG:
00675 show_chat_log();
00676 break;
00677 case HOTKEY_USER_CMD:
00678 user_command();
00679 break;
00680 case HOTKEY_CUSTOM_CMD:
00681 custom_command();
00682 break;
00683
00684 case HOTKEY_AI_FORMULA:
00685 std::cerr <<" run ai formula\n";
00686 ai_formula();
00687 break;
00688 case HOTKEY_CLEAR_MSG:
00689 clear_messages();
00690 break;
00691 #ifdef USRCMD2
00692 case HOTKEY_USER_CMD_2:
00693
00694 user_command_2();
00695 break;
00696 case HOTKEY_USER_CMD_3:
00697 user_command_3();
00698 break;
00699 #endif
00700
00701 case HOTKEY_EDIT_SET_TERRAIN:
00702 edit_set_terrain();
00703 break;
00704 case HOTKEY_EDIT_QUIT:
00705 edit_quit();
00706 break;
00707 case HOTKEY_EDIT_NEW_MAP:
00708 edit_new_map();
00709 break;
00710 case HOTKEY_EDIT_LOAD_MAP:
00711 edit_load_map();
00712 break;
00713 case HOTKEY_EDIT_SAVE_MAP:
00714 edit_save_map();
00715 break;
00716 case HOTKEY_EDIT_SAVE_AS:
00717 edit_save_as();
00718 break;
00719 case HOTKEY_EDIT_SET_START_POS:
00720 edit_set_start_pos();
00721 break;
00722 case HOTKEY_EDIT_FLOOD_FILL:
00723 edit_flood_fill();
00724 break;
00725 case HOTKEY_EDIT_FILL_SELECTION:
00726 edit_fill_selection();
00727 break;
00728 case HOTKEY_EDIT_ROTATE_SELECTION:
00729 edit_rotate_selection();
00730 break;
00731 case HOTKEY_EDIT_CUT:
00732 edit_cut();
00733 break;
00734 case HOTKEY_EDIT_PASTE:
00735 edit_paste();
00736 break;
00737 case HOTKEY_EDIT_COPY:
00738 edit_copy();
00739 break;
00740 case HOTKEY_EDIT_REVERT:
00741 edit_revert();
00742 break;
00743 case HOTKEY_EDIT_RESIZE:
00744 edit_resize();
00745 break;
00746 case HOTKEY_EDIT_FLIP:
00747 edit_flip();
00748 break;
00749 case HOTKEY_EDIT_SELECT_ALL:
00750 edit_select_all();
00751 break;
00752 case HOTKEY_EDIT_DRAW:
00753 edit_draw();
00754 break;
00755 case HOTKEY_EDIT_REFRESH:
00756 edit_refresh();
00757 break;
00758 case HOTKEY_EDIT_UPDATE:
00759 edit_update();
00760 break;
00761 case HOTKEY_EDIT_AUTO_UPDATE:
00762 edit_auto_update();
00763 break;
00764
00765 case HOTKEY_LANGUAGE:
00766 change_language();
00767 break;
00768 case HOTKEY_PLAY_REPLAY:
00769 play_replay();
00770 break;
00771 case HOTKEY_RESET_REPLAY:
00772 reset_replay();
00773 break;
00774 case HOTKEY_STOP_REPLAY:
00775 stop_replay();
00776 break;
00777 case HOTKEY_REPLAY_NEXT_TURN:
00778 replay_next_turn();
00779 break;
00780 case HOTKEY_REPLAY_NEXT_SIDE:
00781 replay_next_side();
00782 break;
00783 case HOTKEY_REPLAY_SHOW_EVERYTHING:
00784 replay_show_everything();
00785 break;
00786 case HOTKEY_REPLAY_SHOW_EACH:
00787 replay_show_each();
00788 break;
00789 case HOTKEY_REPLAY_SHOW_TEAM1:
00790 replay_show_team1();
00791 break;
00792 case HOTKEY_REPLAY_SKIP_ANIMATION:
00793 replay_skip_animation();
00794 break;
00795 default:
00796 return false;
00797 }
00798 return true;
00799 }
00800
00801 void execute_command(display& disp, HOTKEY_COMMAND command, command_executor* executor, int index)
00802 {
00803 const int zoom_amount = 4;
00804 bool map_screenshot = false;
00805
00806 if(executor != NULL) {
00807 if(!executor->can_execute_command(command, index) || executor->execute_command(command, index))
00808 return;
00809 }
00810 switch(command) {
00811 case HOTKEY_ZOOM_IN:
00812 disp.set_zoom(zoom_amount);
00813 break;
00814 case HOTKEY_ZOOM_OUT:
00815 disp.set_zoom(-zoom_amount);
00816 break;
00817 case HOTKEY_ZOOM_DEFAULT:
00818 disp.set_default_zoom();
00819 break;
00820 case HOTKEY_FULLSCREEN:
00821 preferences::set_fullscreen(!preferences::fullscreen());
00822 break;
00823 case HOTKEY_MAP_SCREENSHOT:
00824 if (!disp.in_game() && !disp.in_editor())
00825 break;
00826 map_screenshot = true;
00827 case HOTKEY_SCREENSHOT: {
00828 std::string name = map_screenshot ? _("Map-Screenshot") : _("Screenshot");
00829 std::string filename = get_screenshot_dir() + "/" + name + "_";
00830 filename = get_next_filename(filename, ".bmp");
00831 int size = disp.screenshot(filename, map_screenshot);
00832 if (size > 0) {
00833 std::stringstream res;
00834 res << filename << " ( " << size/1000000 <<" "<< (size/1000)%1000 << " KB )";
00835 gui::dialog(disp,_("Screenshot done"),res.str(),gui::MESSAGE).show();
00836 } else
00837 gui::dialog(disp,_("Screenshot failed"),"",gui::MESSAGE).show();
00838 break;
00839 }
00840 case HOTKEY_MOUSE_SCROLL:
00841 preferences::enable_mouse_scroll(!preferences::mouse_scroll_enabled());
00842 break;
00843 case HOTKEY_ACCELERATED:
00844 preferences::set_turbo(!preferences::turbo());
00845 break;
00846 case HOTKEY_MUTE:
00847 {
00848
00849 static struct before_muted_s
00850 {
00851 bool playing_sound,playing_music;
00852 before_muted_s() : playing_sound(false),playing_music(false){}
00853 } before_muted;
00854 if (preferences::music_on() || preferences::sound_on())
00855 {
00856
00857 before_muted.playing_sound = preferences::sound_on();
00858 before_muted.playing_music = preferences::music_on();
00859 preferences::set_sound(false);
00860 preferences::set_music(false);
00861 }
00862 else
00863 {
00864
00865 preferences::set_sound(before_muted.playing_sound);
00866 preferences::set_music(before_muted.playing_music);
00867 }
00868 }
00869 break;
00870 case HOTKEY_QUIT_GAME: {
00871 if(disp.in_game()) {
00872 DBG_G << "is in game -- showing quit message\n";
00873 const int res = gui::dialog(disp,_("Quit"),_("Do you really want to quit?"),gui::YES_NO).show();
00874 if(res == 0) {
00875 throw end_level_exception(QUIT);
00876 }
00877 }
00878
00879 break;
00880 }
00881 default:
00882 DBG_G << "command_executor: unknown command number " << command << ", ignoring.\n";
00883 break;
00884 }
00885 }
00886
00887 void command_executor::show_menu(const std::vector<std::string>& items_arg, int xloc, int yloc, bool context_menu, display& gui)
00888 {
00889 std::vector<std::string> items = items_arg;
00890 if (can_execute_command(hotkey::get_hotkey(items.front()).get_id(), 0)){
00891
00892 if(!context_menu && items.size() == 1 && items_arg.size() == 1) {
00893 hotkey::execute_command(gui,hotkey::get_hotkey(items.front()).get_id(),this);
00894 return;
00895 }
00896
00897 std::vector<std::string> menu = get_menu_images(items);
00898
00899 int res = 0;
00900 {
00901 gui::dialog mmenu = gui::dialog(gui,"","",
00902 gui::MESSAGE, gui::dialog::hotkeys_style);
00903 mmenu.set_menu(menu);
00904 res = mmenu.show(xloc, yloc);
00905 }
00906 if (res < 0 || size_t(res) >= items.size())
00907 return;
00908
00909 const hotkey::HOTKEY_COMMAND cmd = hotkey::get_hotkey(items[res]).get_id();
00910 hotkey::execute_command(gui,cmd,this,res);
00911 }
00912 }
00913
00914 std::string command_executor::get_menu_image(hotkey::HOTKEY_COMMAND command, int index) const {
00915 switch(get_action_state(command)) {
00916 case ACTION_ON: return game_config::checked_menu_image;
00917 case ACTION_OFF: return game_config::unchecked_menu_image;
00918 default: return get_action_image(command, index);
00919 }
00920 }
00921
00922 std::vector<std::string> command_executor::get_menu_images(const std::vector<std::string>& items){
00923 std::vector<std::string> result;
00924 bool has_image = false;
00925
00926 for(size_t i = 0; i < items.size(); ++i) {
00927 std::string const& item = items[i];
00928 const hotkey::hotkey_item hk = hotkey::get_hotkey(item);
00929
00930 std::stringstream str;
00931
00932 std::string img(get_menu_image(hk.get_id(), i));
00933 if(img.empty() == false) {
00934 has_image = true;
00935 str << IMAGE_PREFIX << img << COLUMN_SEPARATOR;
00936 }
00937
00938 if (hk.get_id() == hotkey::HOTKEY_NULL) {
00939 str << item.substr(0, item.find_last_not_of(' ') + 1) << COLUMN_SEPARATOR;
00940 } else {
00941 str << hk.get_description() << COLUMN_SEPARATOR << hk.get_name();
00942 }
00943
00944 result.push_back(str.str());
00945 }
00946
00947 if(has_image)
00948 for(std::vector<std::string>::iterator i = result.begin(); i != result.end(); ++i)
00949 if(*(i->begin()) != IMAGE_PREFIX)
00950 i->insert(i->begin(), COLUMN_SEPARATOR);
00951 return result;
00952 }
00953
00954 }