1 module unde.file_manager.events; 2 3 import unde.global_state; 4 import unde.clickable; 5 import unde.lib; 6 import unde.file_manager.remove_paths; 7 import unde.file_manager.copy_paths; 8 import unde.file_manager.move_paths; 9 import unde.command_line.events; 10 import unde.viewers.image_viewer.events; 11 import unde.viewers.text_viewer.events; 12 import unde.keybar.settings; 13 import unde.keybar.lib; 14 import unde.marks; 15 import unde.tick; 16 import unde.scan; 17 import unde.path_mnt; 18 import unde.slash; 19 import unde.translations.lib; 20 21 import berkeleydb.all; 22 import derelict.sdl2.sdl; 23 24 import std.utf; 25 import std.stdio; 26 import std..string; 27 import std.conv; 28 import std.format; 29 import std.datetime; 30 import std.functional; 31 32 import std.file; 33 34 void nothing(GlobalState gs) 35 { 36 } 37 38 void quit(GlobalState gs) 39 { 40 gs.finish=true; 41 } 42 43 void restart(GlobalState gs) 44 { 45 gs.finish=true; 46 gs.restart=true; 47 } 48 49 void mark(GlobalState gs) 50 { 51 gs.mark=true; 52 } 53 54 void unmark(GlobalState gs) 55 { 56 gs.unmark=true; 57 } 58 59 void gomark(GlobalState gs) 60 { 61 gs.gomark=true; 62 } 63 64 void cancel_mark(GlobalState gs) 65 { 66 gs.mark=false; 67 gs.unmark=false; 68 gs.gomark=false; 69 } 70 71 void 72 rescan(GlobalState gs) 73 { 74 rescan_path(gs, PathMnt(gs.lsblk, gs.full_current_path)); 75 } 76 77 void 78 deselect_all(GlobalState gs) 79 { 80 gs.selection_hash = null; 81 calculate_selection_sub(gs); 82 gs.dirty = true; 83 } 84 85 void clear_messages(GlobalState gs) 86 { 87 gs.msg_stamp = Clock.currTime().toUnixTime() - 10; 88 gs.dirty = true; 89 } 90 91 auto get_copy_or_move(GlobalState gs, string copy_or_move) 92 { 93 return (GlobalState gs) 94 { 95 int copy_or_move_to_the_same_directory = 0; 96 int copy_or_move_to_subdirectory = 0; 97 foreach (selection; gs.selection_hash.byKey()) 98 { 99 string parent = 100 getParent(selection); 101 if (parent == "") parent = SL; 102 if (parent == gs.full_current_path) 103 copy_or_move_to_the_same_directory++; 104 105 if ( gs.full_current_path.startsWith(selection) ) 106 copy_or_move_to_subdirectory++; 107 } 108 109 if (copy_or_move_to_the_same_directory && 110 gs.selection_hash.length > 1) 111 { 112 string msg; 113 if (copy_or_move == "copy") 114 msg = format(_("Copy to the same directory works only for exactly 1 selection")); 115 else 116 msg = format(_("Rename (move to the same directory) works only for exactly 1 selection")); 117 gs.messages ~= ConsoleMessage( 118 SDL_Color(0xFF, 0xFF, 0xFF, 0xFF), 119 msg, 120 SDL_GetTicks() ); 121 writeln(msg); 122 } 123 else if (copy_or_move_to_subdirectory) 124 { 125 string msg; 126 if (copy_or_move == "copy") 127 msg = format(_("Can't copy to a subdirectory")); 128 else 129 msg = format(_("Can't move to a subdirectory")); 130 gs.messages ~= ConsoleMessage( 131 SDL_Color(0xFF, 0x00, 0x00, 0xFF), 132 msg, 133 SDL_GetTicks() ); 134 writeln(msg); 135 } 136 else 137 { 138 if (copy_or_move_to_the_same_directory && 139 gs.selection_hash.length == 1) 140 { 141 gs.shift_copy_or_move = gs.shift; 142 string path = gs.selection_hash.keys[0]; 143 gs.animation_info[path] = 144 AnimationInfo(); 145 gs.animation_info[path].parent = 146 gs.full_current_path; 147 if (copy_or_move == "copy") 148 gs.animation_info[path].type = 149 NameType.Copy; 150 else 151 gs.animation_info[path].type = 152 NameType.Move; 153 154 gs.keybar.input_mode = true; 155 setup_keybar(gs); 156 gs.redraw_fast = true; 157 change_current_dir(gs, 158 (ref RectSize rectsize) 159 { 160 if (rectsize.show_info != 161 InfoType.CreateDirectory && 162 rectsize.show_info != InfoType.Copy && 163 rectsize.show_info != InfoType.Move) 164 { 165 rectsize.show_info = InfoType.Copy; 166 string name = 167 path[path.lastIndexOf(SL)+1..$]; 168 if (copy_or_move == "copy") 169 gs.enter_names[gs.current_path] = 170 EnterName(NameType.Copy, name, 171 cast(int)name.length); 172 else 173 gs.enter_names[gs.current_path] = 174 EnterName(NameType.Move, name, 175 cast(int)name.length); 176 } 177 } ); 178 } 179 else 180 { 181 // copy_or_move_paths algorithm wants SL at the end 182 string path = gs.full_current_path ~ SL; 183 if (copy_or_move == "copy") 184 copy_paths(gs, gs.selection_hash.keys, path, gs.shift); 185 else 186 move_paths(gs, gs.selection_hash.keys, path, gs.shift); 187 gs.dirty = true; 188 } 189 } 190 }; 191 } 192 193 void start_create_directory(GlobalState gs) 194 { 195 gs.keybar.input_mode = true; 196 setup_keybar(gs); 197 gs.redraw_fast = true; 198 change_current_dir(gs, 199 (ref RectSize rectsize) 200 { 201 if (rectsize.show_info != InfoType.CreateDirectory && 202 rectsize.show_info != InfoType.Copy && 203 rectsize.show_info != InfoType.Move) 204 { 205 rectsize.show_info = InfoType.CreateDirectory; 206 gs.enter_names[gs.current_path] = 207 EnterName(NameType.CreateDirectory, "", 0); 208 } 209 } ); 210 } 211 212 void remove_selection(GlobalState gs) 213 { 214 bool not_fit_on_screen = false; 215 foreach(path, ref rect; gs.selection_hash) 216 { 217 SDL_Rect sdl_rect = rect.to_screen(gs.screen); 218 219 if (sdl_rect.x < 0 || sdl_rect.y < 0 || 220 (sdl_rect.x+sdl_rect.w) > gs.screen.w || 221 (sdl_rect.y+sdl_rect.h) > gs.screen.h) 222 { 223 not_fit_on_screen = true; 224 break; 225 } 226 } 227 228 if (not_fit_on_screen) 229 { 230 string msg = format(_("Go (up) to directory which fully covers selection to confirm removing %d items"), 231 gs.selection_hash.length); 232 gs.messages ~= ConsoleMessage( 233 SDL_Color(0xFF, 0xFF, 0xFF, 0xFF), 234 msg, 235 SDL_GetTicks() ); 236 writeln(msg); 237 } 238 else 239 { 240 remove_paths(gs, gs.selection_hash.keys); 241 } 242 } 243 244 void change_sorting(GlobalState gs) 245 { 246 change_current_dir(gs, 247 (ref RectSize rectsize) 248 { 249 rectsize.sort = cast(SortType)( (rectsize.sort+1)%(SortType.max+1) ); 250 } ); 251 } 252 253 void filemanager_left(GlobalState gs) 254 { 255 with(gs.enter_names[gs.current_path]) 256 { 257 if (pos > 0) 258 pos -= name.strideBack(pos); 259 } 260 gs.dirty = true; 261 } 262 263 void filemanager_right(GlobalState gs) 264 { 265 with(gs.enter_names[gs.current_path]) 266 { 267 if (pos < name.length) 268 pos += name.stride(pos); 269 } 270 gs.dirty = true; 271 } 272 273 void filemanager_enter(GlobalState gs) 274 { 275 with(gs.enter_names[gs.current_path]) 276 { 277 if (name != "") 278 { 279 final switch (type) 280 { 281 case NameType.CreateDirectory: 282 try{ 283 string path = gs.full_current_path ~ SL ~ 284 name; 285 mkdir(path); 286 gs.animation_info[path] = 287 AnimationInfo(); 288 gs.animation_info[path].parent = 289 gs.full_current_path; 290 gs.animation_info[path].type = 291 NameType.CreateDirectory; 292 gs.dirty = true; 293 } 294 catch (FileException exp) 295 { 296 string msg = format("Failed Create Directory: %s", exp.msg); 297 gs.messages ~= ConsoleMessage( 298 SDL_Color(0xFF, 0x00, 0x00, 0xFF), 299 msg, 300 SDL_GetTicks() 301 ); 302 writeln(msg); 303 } 304 break; 305 306 case NameType.Copy: 307 goto case; 308 case NameType.Move: 309 string path = gs.full_current_path ~ SL ~ 310 name; 311 string[] selection = gs.selection_hash.keys; 312 try 313 { 314 auto de = DirEntry(selection[0]); 315 if (!de.isSymlink() && de.isDir()) 316 { 317 selection[0] ~= SL;//It is the single entry 318 } 319 } 320 catch(Exception e) 321 { 322 // Ignore errors 323 } 324 325 if (type == NameType.Copy) 326 { 327 copy_paths(gs, selection.idup(), path, gs.shift_copy_or_move); 328 } 329 else 330 { 331 move_paths(gs, selection.idup(), path, gs.shift_copy_or_move); 332 } 333 gs.animation_info[path] = 334 AnimationInfo(); 335 gs.animation_info[path].parent = 336 gs.full_current_path; 337 gs.animation_info[path].type = 338 type; 339 gs.animation_info[path].stage = 340 1; 341 gs.dirty = true; 342 break; 343 } 344 } 345 filemanager_escape(gs); 346 } 347 } 348 349 void filemanager_escape(GlobalState gs) 350 { 351 gs.keybar.input_mode = false; 352 353 gs.redraw_fast = false; 354 change_current_dir(gs, 355 (ref RectSize rectsize) 356 { 357 rectsize.show_info = InfoType.None; 358 gs.enter_names.remove(gs.current_path); 359 } ); 360 361 gs.last_escape = SDL_GetTicks(); 362 } 363 364 void filemanager_backscape(GlobalState gs) 365 { 366 RectSize rectsize = getRectSize(gs); 367 with(gs.enter_names[gs.current_path]) 368 { 369 if ( (rectsize.show_info == InfoType.CreateDirectory || 370 rectsize.show_info == InfoType.Copy || 371 rectsize.show_info == InfoType.Move) && 372 name > "" && pos > 0 ) 373 { 374 int sb = name.strideBack(pos); 375 name = (name[0..pos-sb] ~ name[pos..$]).idup(); 376 pos -= sb; 377 gs.dirty = true; 378 } 379 } 380 } 381 382 auto get_mark(string mark) 383 { 384 return (GlobalState gs) 385 { 386 unde.marks.mark(gs, mark); 387 gs.mark = false; 388 }; 389 } 390 391 auto get_unmark(string mark) 392 { 393 return (GlobalState gs) 394 { 395 unde.marks.unmark(gs, mark); 396 gs.unmark = false; 397 }; 398 } 399 400 auto get_gomark(string mark) 401 { 402 return (GlobalState gs) 403 { 404 unde.marks.go_mark(gs, mark); 405 gs.gomark = false; 406 }; 407 } 408 409 void process_event(GlobalState gs, ref SDL_Event event) 410 { 411 switch( event.type ) 412 { 413 case SDL_TEXTINPUT: 414 RectSize rectsize = getRectSize(gs); 415 if (rectsize.show_info == InfoType.CreateDirectory || 416 rectsize.show_info == InfoType.Copy || 417 rectsize.show_info == InfoType.Move) 418 { 419 with(gs.enter_names[gs.current_path]) 420 { 421 char[] input = fromStringz(cast(char*)event.text.text); 422 name = 423 (name[0..pos] ~ 424 input ~ 425 name[pos..$]).idup(); 426 pos += input.length; 427 gs.dirty = true; 428 } 429 } 430 break; 431 432 case SDL_MOUSEMOTION: 433 if (gs.mouse_buttons & unDE_MouseButtons.Left && 434 event.motion.x < gs.screen.w) 435 { 436 gs.screen.x -= cast(double)(event.motion.xrel)*gs.screen.scale; 437 gs.screen.y -= cast(double)(event.motion.yrel)*gs.screen.scale; 438 } 439 440 gs.mousex = event.motion.x * gs.screen.scale + gs.screen.x; 441 gs.mousey = event.motion.y * gs.screen.scale + gs.screen.y; 442 gs.mouse_screen_x = event.motion.x; 443 gs.mouse_screen_y = event.motion.y; 444 gs.moved_while_click++; 445 446 if (gs.mouse_buttons & unDE_MouseButtons.Right) 447 { 448 process_click(gs.right_clickable_list, gs.mouse_screen_x, gs.mouse_screen_y, 1); 449 } 450 break; 451 452 case SDL_MOUSEBUTTONDOWN: 453 switch (event.button.button) 454 { 455 case SDL_BUTTON_LEFT: 456 gs.mouse_buttons |= unDE_MouseButtons.Left; 457 gs.moved_while_click = 0; 458 break; 459 case SDL_BUTTON_MIDDLE: 460 gs.mouse_buttons |= unDE_MouseButtons.Middle; 461 break; 462 case SDL_BUTTON_RIGHT: 463 gs.mouse_buttons |= unDE_MouseButtons.Right; 464 process_click(gs.right_clickable_list, gs.mouse_screen_x, gs.mouse_screen_y, 0); 465 break; 466 default: 467 break; 468 } 469 break; 470 471 case SDL_MOUSEBUTTONUP: 472 switch (event.button.button) 473 { 474 case SDL_BUTTON_LEFT: 475 gs.mouse_buttons &= ~unDE_MouseButtons.Left; 476 if (!gs.moved_while_click) 477 { 478 if (SDL_GetTicks() - gs.last_left_click < DOUBLE_DELAY) 479 { 480 process_click(gs.double_clickable_list, gs.mouse_screen_x, gs.mouse_screen_y); 481 } 482 else 483 { 484 process_click(gs.clickable_list, gs.mouse_screen_x, gs.mouse_screen_y); 485 } 486 gs.last_left_click = SDL_GetTicks(); 487 } 488 break; 489 case SDL_BUTTON_MIDDLE: 490 gs.mouse_buttons &= ~unDE_MouseButtons.Middle; 491 process_click(gs.middle_clickable_list, gs.mouse_screen_x, gs.mouse_screen_y, 2); 492 break; 493 case SDL_BUTTON_RIGHT: 494 gs.mouse_buttons &= ~unDE_MouseButtons.Right; 495 if (SDL_GetTicks() - gs.last_right_click < DOUBLE_DELAY) 496 { 497 process_click(gs.double_right_clickable_list, gs.mouse_screen_x, gs.mouse_screen_y); 498 } 499 process_click(gs.right_clickable_list, gs.mouse_screen_x, gs.mouse_screen_y, 2); 500 gs.last_right_click = SDL_GetTicks(); 501 break; 502 default: 503 break; 504 } 505 break; 506 507 case SDL_MOUSEWHEEL: 508 while (event.wheel.y > 0) 509 { 510 gs.screen.scale /= 1.0905; 511 event.wheel.y--; 512 } 513 while (event.wheel.y < 0) 514 { 515 gs.screen.scale *= 1.0905; 516 event.wheel.y++; 517 } 518 gs.screen.x = gs.mousex - gs.mouse_screen_x*gs.screen.scale; 519 gs.screen.y = gs.mousey - gs.mouse_screen_y*gs.screen.scale; 520 //writeln("scale=", gs.screen.scale); 521 break; 522 523 case SDL_JOYAXISMOTION: 524 /* Do something with event.jaxis */ 525 break; 526 527 case SDL_JOYBALLMOTION: 528 /* Do something with event.jball */ 529 break; 530 531 case SDL_JOYHATMOTION: 532 /* Do something with event.jhat */ 533 break; 534 535 case SDL_JOYBUTTONDOWN: 536 /* Do something with event.jbutton */ 537 break; 538 539 case SDL_JOYBUTTONUP: 540 /* Do something event.jbutton */ 541 break; 542 543 case SDL_QUIT: 544 /* Do something event.quit */ 545 gs.finish=true; 546 break; 547 548 case SDL_SYSWMEVENT: 549 /* Do something with event.syswm */ 550 break; 551 552 case SDL_WINDOWEVENT: 553 /*if (event.window.event == SDL_WINDOWEVENT_RESIZED) 554 diz_setvideomode(event.window.data1, event.window.data2, 555 dizvideomode.flags & SDL_WINDOW_FULLSCREEN_DESKTOP);*/ 556 break; 557 default: 558 writeln("Ignored event: "~to!string(event.type)); 559 break; 560 } 561 } 562 563 bool setup_keybar_mark(GlobalState gs) 564 { 565 if (gs.mark || gs.unmark || gs.gomark) 566 { 567 gs.keybar.handlers.clear(); 568 gs.keybar.handlers_down.clear(); 569 gs.keybar.handlers_double.clear(); 570 571 gs.keybar.handlers[SDL_SCANCODE_ESCAPE] = KeyHandler(toDelegate(&cancel_mark), "Cancel", "Esc"); 572 for (ssize_t i = 0; i < 3; i++) 573 { 574 for (ssize_t pos = 0; pos < (*gs.keybar.letters)[i].length; pos++) 575 { 576 string mark = (*gs.keybar.letters)[i][pos]; 577 if ( mark.length == 1 && 578 (mark[0] >= '0' && 579 mark[0] <= '9' || 580 mark[0] >= 'A' && 581 mark[0] <= 'Z') ) 582 { 583 if (gs.mark) 584 { 585 gs.keybar.handlers[(*gs.keybar.scans_cur)[i][pos]] = 586 KeyHandler(get_mark(mark), "Mark "~mark, mark); 587 } 588 else if (gs.unmark && check_mark(gs, mark)) 589 { 590 gs.keybar.handlers[(*gs.keybar.scans_cur)[i][pos]] = 591 KeyHandler(get_unmark(mark), "Unmark "~mark, mark); 592 } 593 else if (gs.gomark && 594 (mark[0] >= '0' && mark[0] <= '9' || 595 check_mark(gs, mark))) 596 { 597 gs.keybar.handlers[(*gs.keybar.scans_cur)[i][pos]] = 598 KeyHandler(get_gomark(mark), "Go to Mark "~mark, mark); 599 } 600 } 601 } 602 } 603 604 if (!gs.shift) 605 { 606 gs.keybar.handlers_down[SDL_SCANCODE_LSHIFT] = KeyHandler(toDelegate(¬hing), "Global Mark", "Shift"); 607 gs.keybar.handlers_down[SDL_SCANCODE_RSHIFT] = KeyHandler(toDelegate(¬hing), "", ""); 608 } 609 return true; 610 } 611 else return false; 612 } 613 614 void setup_keybar(GlobalState gs) 615 { 616 foreach (uipage; gs.uipages) 617 { 618 if (uipage.show) 619 { 620 uipage.set_keybar(gs); 621 return; 622 } 623 } 624 625 final switch (gs.state) 626 { 627 case State.FileManager: 628 if (setup_keybar_mark(gs)) 629 { 630 } 631 else if (gs.command_line.enter) 632 { 633 if (gs.ctrl) 634 { 635 setup_keybar_command_line_ctrl(gs); 636 } 637 else 638 { 639 setup_keybar_command_line_default(gs); 640 } 641 } 642 else if (gs.command_line.terminal) 643 { 644 if (gs.command_line.command_in_focus_id > 0) 645 { 646 setup_keybar_terminal_command_focus_in(gs); 647 } 648 else 649 { 650 if (gs.ctrl) 651 { 652 setup_keybar_terminal_ctrl(gs); 653 } 654 else 655 { 656 setup_keybar_terminal(gs); 657 } 658 } 659 } 660 else if (gs.current_path in gs.enter_names) 661 { 662 gs.keybar.input_mode = true; 663 gs.keybar.handlers.clear(); 664 gs.keybar.handlers_down.clear(); 665 gs.keybar.handlers_double.clear(); 666 gs.keybar.handlers_down[SDL_SCANCODE_LEFT] = KeyHandler(toDelegate(&filemanager_left), "Left", "←"); 667 gs.keybar.handlers_down[SDL_SCANCODE_RIGHT] = KeyHandler(toDelegate(&filemanager_right), "Right", "→"); 668 gs.keybar.handlers[SDL_SCANCODE_RETURN] = KeyHandler(toDelegate(&filemanager_enter), "Finish Enter", "Enter"); 669 gs.keybar.handlers[SDL_SCANCODE_ESCAPE] = KeyHandler(toDelegate(&filemanager_escape), "Cancel", "Esc"); 670 gs.keybar.handlers_down[SDL_SCANCODE_BACKSPACE] = KeyHandler(toDelegate(&filemanager_backscape), "Backspace", "<--"); 671 672 } 673 else 674 { 675 gs.keybar.input_mode = false; 676 if (gs.ctrl) 677 setup_keybar_filemanager_ctrl(gs); 678 else if (gs.shift) 679 setup_keybar_filemanager_shift(gs); 680 else 681 setup_keybar_filemanager_default(gs); 682 } 683 break; 684 685 case State.ImageViewer: 686 if (setup_keybar_mark(gs)) 687 { 688 } 689 else if (gs.shift) 690 setup_keybar_imageviewer_shift(gs); 691 else 692 setup_keybar_imageviewer_default(gs); 693 break; 694 695 case State.TextViewer: 696 if (setup_keybar_mark(gs)) 697 { 698 } 699 else if (gs.shift) 700 setup_keybar_textviewer_shift(gs); 701 else 702 setup_keybar_textviewer_default(gs); 703 break; 704 } 705 } 706 707 void 708 setup_keybar_filemanager_default(GlobalState gs) 709 { 710 gs.keybar.handlers.clear(); 711 gs.keybar.handlers_down.clear(); 712 gs.keybar.handlers_double.clear(); 713 714 gs.keybar.handlers[SDL_SCANCODE_Q] = KeyHandler(toDelegate(&quit), _("Quit"), "exit.png"); 715 gs.keybar.handlers[SDL_SCANCODE_PRINTSCREEN] = KeyHandler(toDelegate(&make_screenshot), _("Make screenshot"), "Prt Sc"); 716 gs.keybar.handlers[SDL_SCANCODE_M] = KeyHandler(toDelegate(&mark), _("Make Mark"), "mark.png"); 717 gs.keybar.handlers[SDL_SCANCODE_APOSTROPHE] = KeyHandler(toDelegate(&gomark), _("Go To Mark"), "gomark.png"); 718 gs.keybar.handlers[SDL_SCANCODE_R] = KeyHandler(toDelegate(&rescan), _("Rescan directory"), "rescan.png"); 719 gs.keybar.handlers[SDL_SCANCODE_A] = KeyHandler(toDelegate(&deselect_all), _("Clear selection"), "deselect.png"); 720 gs.keybar.handlers_down[SDL_SCANCODE_LSHIFT] = KeyHandler(toDelegate(&setup_keybar_filemanager_shift), "", "Shift"); 721 gs.keybar.handlers_down[SDL_SCANCODE_RSHIFT] = KeyHandler(toDelegate(&setup_keybar_filemanager_shift), "", ""); 722 gs.keybar.handlers_down[SDL_SCANCODE_LCTRL] = KeyHandler(toDelegate(&setup_keybar_filemanager_ctrl), "", "Ctrl"); 723 gs.keybar.handlers_down[SDL_SCANCODE_RCTRL] = KeyHandler(toDelegate(&setup_keybar_filemanager_ctrl), "", ""); 724 gs.keybar.handlers_double[SDL_SCANCODE_ESCAPE] = KeyHandler(toDelegate(&clear_messages), _("Clear error messages in directories"), "clear_errors.png"); 725 gs.keybar.handlers[SDL_SCANCODE_C] = KeyHandler(get_copy_or_move(gs, "copy"), _("Copy selection to current directory"), "copy.png"); 726 gs.keybar.handlers[SDL_SCANCODE_V] = KeyHandler(get_copy_or_move(gs, "move"), _("Move selection to current directory"), "move.png"); 727 gs.keybar.handlers[SDL_SCANCODE_D] = KeyHandler(toDelegate(&start_create_directory), _("Create Directory"), "create_directory.png"); 728 gs.keybar.handlers[SDL_SCANCODE_E] = KeyHandler(toDelegate(&remove_selection), _("Remove Selection"), "remove.png"); 729 gs.keybar.handlers[SDL_SCANCODE_S] = KeyHandler(toDelegate(&change_sorting), _("Change Sort Order"), "sort.png"); 730 gs.keybar.handlers_double[SDL_SCANCODE_RETURN] = KeyHandler(toDelegate(&turn_on_terminal), _("Open Terminal"), "terminal.png"); 731 } 732 733 void 734 setup_keybar_filemanager_ctrl(GlobalState gs) 735 { 736 gs.keybar.handlers.clear(); 737 gs.keybar.handlers_down.clear(); 738 gs.keybar.handlers_double.clear(); 739 740 gs.keybar.handlers[SDL_SCANCODE_Q] = KeyHandler(toDelegate(&restart), _("Restart"), "exit.png"); 741 gs.keybar.handlers[SDL_SCANCODE_SEMICOLON] = KeyHandler(toDelegate(&turn_on_command_line), _("Command line"), "command_line.png"); 742 gs.keybar.handlers[SDL_SCANCODE_L] = KeyHandler(toDelegate(&turn_on_keybar_settings), _("Keyboard layouts settings"), "keybar"); 743 gs.keybar.handlers[SDL_SCANCODE_LCTRL] = KeyHandler(toDelegate(&setup_keybar_filemanager_default), "", "Ctrl"); 744 gs.keybar.handlers[SDL_SCANCODE_RCTRL] = KeyHandler(toDelegate(&setup_keybar_filemanager_default), "", ""); 745 } 746 747 void 748 setup_keybar_filemanager_shift(GlobalState gs) 749 { 750 gs.keybar.handlers.clear(); 751 gs.keybar.handlers_down.clear(); 752 gs.keybar.handlers_double.clear(); 753 754 gs.keybar.handlers[SDL_SCANCODE_M] = KeyHandler(toDelegate(&unmark), _("Delete Mark"), "unmark.png"); 755 gs.keybar.handlers[SDL_SCANCODE_C] = KeyHandler(get_copy_or_move(gs, "copy"), _("Copy selection to current directory with deleting not exists files in the source directory"), "copy.png"); 756 gs.keybar.handlers[SDL_SCANCODE_V] = KeyHandler(get_copy_or_move(gs, "move"), _("Move selection to current directory with deleting not exists files in the source directory"), "move.png"); 757 gs.keybar.handlers[SDL_SCANCODE_LSHIFT] = KeyHandler(toDelegate(&setup_keybar_filemanager_default), "", "Shift"); 758 gs.keybar.handlers[SDL_SCANCODE_RSHIFT] = KeyHandler(toDelegate(&setup_keybar_filemanager_default), "", ""); 759 }