mcabber/mcabber/screen.c
changeset 2304 fa8365fb6ac2
parent 2292 f181418db215
child 2305 5b1a63dc2b1a
equal deleted inserted replaced
2303:4f3821bda633 2304:fa8365fb6ac2
    92 #endif
    92 #endif
    93 
    93 
    94 #if defined(WITH_ENCHANT) || defined(WITH_ASPELL)
    94 #if defined(WITH_ENCHANT) || defined(WITH_ASPELL)
    95 static void spellcheck(char *, char *);
    95 static void spellcheck(char *, char *);
    96 #endif
    96 #endif
       
    97 
       
    98 static void open_chat_window(void);
       
    99 static void clear_inputline(void);
    97 
   100 
    98 static GHashTable *winbufhash;
   101 static GHashTable *winbufhash;
    99 
   102 
   100 typedef struct {
   103 typedef struct {
   101   GList    *hbuf;
   104   GList    *hbuf;
  4173 #endif
  4176 #endif
  4174 
  4177 
  4175 static inline void refresh_inputline(void)
  4178 static inline void refresh_inputline(void)
  4176 {
  4179 {
  4177 #if defined(WITH_ENCHANT) || defined(WITH_ASPELL)
  4180 #if defined(WITH_ENCHANT) || defined(WITH_ASPELL)
  4178   if (settings_opt_get_int("spell_enable")) {
  4181   if (settings_opt_get_int("spell_enable") &&
       
  4182       (chatmode || !settings_opt_get_int("vi_mode"))) {
  4179     memset(maskLine, 0, INPUTLINE_LENGTH+1);
  4183     memset(maskLine, 0, INPUTLINE_LENGTH+1);
  4180     spellcheck(inputLine, maskLine);
  4184     spellcheck(inputLine, maskLine);
  4181   }
  4185   }
  4182   print_checked_line();
  4186   print_checked_line();
  4183   wclrtoeol(inputWnd);
  4187   wclrtoeol(inputWnd);
  4424     scr_LogPrint(LPRINT_NORMAL,
  4428     scr_LogPrint(LPRINT_NORMAL,
  4425                  "WARNING: Compiled without full UTF-8 support!");
  4429                  "WARNING: Compiled without full UTF-8 support!");
  4426 #endif
  4430 #endif
  4427 }
  4431 }
  4428 
  4432 
       
  4433 static void scr_process_vi_arrow_key(int key)
       
  4434 {
       
  4435   const char *l;
       
  4436   char mask[INPUTLINE_LENGTH+1] = "/roster search ";
       
  4437   size_t cmd_len = strlen(mask);
       
  4438   size_t str_len = strlen(inputLine) - 1;
       
  4439 
       
  4440   switch (inputLine[0]) {
       
  4441     case ':':
       
  4442         inputLine[0] = '/';
       
  4443         if (key == KEY_UP)
       
  4444           l = scr_cmdhisto_prev(inputLine, ptr_inputline - inputLine);
       
  4445         else
       
  4446           l = scr_cmdhisto_next(inputLine, ptr_inputline - inputLine);
       
  4447         if (l)
       
  4448           strcpy(inputLine, l);
       
  4449         inputLine[0] = ':';
       
  4450         break;
       
  4451     case '/':
       
  4452         if (cmd_len + str_len > INPUTLINE_LENGTH)
       
  4453           return;
       
  4454 
       
  4455         memcpy(mask + cmd_len, inputLine + 1, str_len + 1);
       
  4456         if (key == KEY_UP)
       
  4457           l = scr_cmdhisto_prev(mask, ptr_inputline - inputLine + cmd_len - 1);
       
  4458         else
       
  4459           l = scr_cmdhisto_next(mask, ptr_inputline - inputLine + cmd_len - 1);
       
  4460         if (l)
       
  4461           strcpy(inputLine + 1, l + cmd_len);
       
  4462         break;
       
  4463     default:
       
  4464         if (key == KEY_UP)
       
  4465           process_command(mkcmdstr("roster up"), TRUE);
       
  4466         else
       
  4467           process_command(mkcmdstr("roster down"), TRUE);
       
  4468         break;
       
  4469   }
       
  4470 }
       
  4471 
  4429 //  scr_process_key(key)
  4472 //  scr_process_key(key)
  4430 // Handle the pressed key, in the command line (bottom).
  4473 // Handle the pressed key, in the command line (bottom).
  4431 void scr_process_key(keycode kcode)
  4474 void scr_process_key(keycode kcode)
  4432 {
  4475 {
  4433   int key = kcode.value;
  4476   int key = kcode.value;
  4434   int display_char = FALSE;
  4477   int display_char = FALSE;
       
  4478   int vi_completion = FALSE;
       
  4479   static int ex_or_search_mode = FALSE;
  4435 
  4480 
  4436   lock_chatstate = FALSE;
  4481   lock_chatstate = FALSE;
  4437 
  4482 
  4438   switch (kcode.mcode) {
  4483   switch (kcode.mcode) {
  4439     case 0:
  4484     case 0:
  4444         break;
  4489         break;
  4445     case MKEY_META:
  4490     case MKEY_META:
  4446     default:
  4491     default:
  4447         bindcommand(kcode);
  4492         bindcommand(kcode);
  4448         key = ERR; // Do not process any further
  4493         key = ERR; // Do not process any further
       
  4494   }
       
  4495 
       
  4496   if (settings_opt_get_int("vi_mode") && !chatmode) {
       
  4497     int got_cmd_prefix = FALSE;
       
  4498     int unrecognized = FALSE;
       
  4499     static char search_cmd[INPUTLINE_LENGTH+1] = "/roster search ";
       
  4500 
       
  4501     if (key == KEY_UP || key == KEY_DOWN) {
       
  4502       scr_process_vi_arrow_key(key);
       
  4503       key = ERR;    // Do not process any further
       
  4504     } else if (ex_or_search_mode) {
       
  4505       switch (key) {
       
  4506         case 27:    // Escape
       
  4507             clear_inputline();
       
  4508             ex_or_search_mode = FALSE;
       
  4509             break;
       
  4510         case 9:     // Tab
       
  4511         case 353:   // Shift-Tab
       
  4512             if (inputLine[0] == ':') {
       
  4513               inputLine[0] = '/';
       
  4514               vi_completion = TRUE;
       
  4515             }
       
  4516             break;
       
  4517         case 13:    // Enter
       
  4518         case 343:   // Enter on Maemo
       
  4519             switch (inputLine[0]) {
       
  4520               case ':':
       
  4521                   {
       
  4522                     char *p = strchr(inputLine, 0);
       
  4523 
       
  4524                     while (*--p == ' ' && p > inputLine)
       
  4525                       *p = 0;
       
  4526                   }
       
  4527                   if (!strcmp(inputLine, ":x") ||
       
  4528                       !strcmp(inputLine, ":q") ||
       
  4529                       !strcmp(inputLine, ":wq"))
       
  4530                     strcpy(inputLine, ":quit");
       
  4531                   if (isdigit((int)(unsigned char)inputLine[1]) &&
       
  4532                       strlen(inputLine) <= 9) {
       
  4533                     process_command(mkcmdstr("roster top"), TRUE);
       
  4534                     memcpy(inputLine + 13, inputLine + 1, 10);
       
  4535                     memcpy(inputLine + 1, "roster down ", 12);
       
  4536                   }
       
  4537                   inputLine[0] = '/';
       
  4538                   process_command(inputLine, TRUE);
       
  4539                   scr_cmdhisto_addline(inputLine);
       
  4540                   break;
       
  4541               case '/':
       
  4542                   {
       
  4543                     size_t cmd_len = sizeof("/roster search ") - 1;
       
  4544                     size_t str_len = strlen(inputLine) - 1;
       
  4545 
       
  4546                     if (cmd_len + str_len > INPUTLINE_LENGTH)
       
  4547                       return;
       
  4548 
       
  4549                     memcpy(search_cmd + cmd_len, inputLine + 1,
       
  4550                            str_len + 1);
       
  4551                   }
       
  4552                   process_command(search_cmd, TRUE);
       
  4553                   scr_cmdhisto_addline(search_cmd);
       
  4554                   break;
       
  4555             }
       
  4556             ex_or_search_mode = FALSE;
       
  4557             break;
       
  4558       }
       
  4559     } else if (key >= '0' && key <= '9') {
       
  4560       got_cmd_prefix = TRUE;
       
  4561     } else {
       
  4562       switch (key) {
       
  4563         case '/':
       
  4564         case ':':
       
  4565             ex_or_search_mode = TRUE;
       
  4566             break;
       
  4567         case ' ':
       
  4568             process_command(mkcmdstr("group toggle"), TRUE);
       
  4569             break;
       
  4570         case '!':
       
  4571             {
       
  4572               const char *bjid = buddy_getjid(BUDDATA(current_buddy));
       
  4573 
       
  4574               if (bjid) {
       
  4575                 guint type = buddy_gettype(BUDDATA(current_buddy));
       
  4576                 guint prio = buddy_getuiprio(BUDDATA(current_buddy));
       
  4577 
       
  4578                 if (type & ROSTER_TYPE_ROOM &&
       
  4579                     prio < ROSTER_UI_PRIO_MUC_HL_MESSAGE) {
       
  4580                   roster_setuiprio(bjid, FALSE,
       
  4581                                    ROSTER_UI_PRIO_MUC_HL_MESSAGE, prio_set);
       
  4582                   roster_msg_setflag(bjid, FALSE, TRUE);
       
  4583                 } else if (type & ROSTER_TYPE_USER &&
       
  4584                            prio < ROSTER_UI_PRIO_ATTENTION_MESSAGE) {
       
  4585                   roster_setuiprio(bjid, FALSE,
       
  4586                                    ROSTER_UI_PRIO_ATTENTION_MESSAGE, prio_set);
       
  4587                   roster_msg_setflag(bjid, FALSE, TRUE);
       
  4588                 } else {
       
  4589                   roster_msg_setflag(bjid, FALSE, FALSE);
       
  4590                 }
       
  4591                 scr_update_roster();
       
  4592               }
       
  4593             }
       
  4594             break;
       
  4595         case '#':
       
  4596             {
       
  4597               const char *bjid = buddy_getjid(BUDDATA(current_buddy));
       
  4598 
       
  4599               if (bjid) {
       
  4600                 unsigned short bflags = buddy_getflags(BUDDATA(current_buddy));
       
  4601 
       
  4602                 if (bflags & ROSTER_FLAG_MSG)
       
  4603                   roster_msg_setflag(bjid, FALSE, FALSE);
       
  4604                 else
       
  4605                   roster_msg_setflag(bjid, FALSE, TRUE);
       
  4606 
       
  4607                 scr_update_roster();
       
  4608               }
       
  4609             }
       
  4610             break;
       
  4611         case '\'':
       
  4612             if (inputLine[0] == '\'')
       
  4613               process_command(mkcmdstr("roster alternate"), TRUE);
       
  4614             else
       
  4615               got_cmd_prefix = TRUE;
       
  4616             break;
       
  4617         case 'A':
       
  4618             process_command(mkcmdstr("roster unread_first"), TRUE);
       
  4619             break;
       
  4620         case 'a':
       
  4621             process_command(mkcmdstr("roster unread_next"), TRUE);
       
  4622             break;
       
  4623         case 'F':
       
  4624             process_command(mkcmdstr("roster group_prev"), TRUE);
       
  4625             break;
       
  4626         case 'f':
       
  4627             process_command(mkcmdstr("roster group_next"), TRUE);
       
  4628             break;
       
  4629         case 'G':
       
  4630             process_command(mkcmdstr("roster bottom"), TRUE);
       
  4631             break;
       
  4632         case 'g':
       
  4633             if (inputLine[0] == 'g')
       
  4634               process_command(mkcmdstr("roster top"), TRUE);
       
  4635             else {
       
  4636               clear_inputline();
       
  4637               got_cmd_prefix = TRUE;
       
  4638             }
       
  4639             break;
       
  4640         case 'i':
       
  4641             open_chat_window();
       
  4642             break;
       
  4643         case 'j':
       
  4644             if (isdigit((int)(unsigned char)inputLine[0]) &&
       
  4645                 strlen(inputLine) <= 9) {
       
  4646               char down_cmd[32] = "/roster down ";
       
  4647 
       
  4648               strcat(down_cmd, inputLine);
       
  4649               process_command(down_cmd, TRUE);
       
  4650             } else
       
  4651               process_command(mkcmdstr("roster down"), TRUE);
       
  4652             break;
       
  4653         case 'k':
       
  4654             if (isdigit((int)(unsigned char)inputLine[0]) &&
       
  4655                 strlen(inputLine) <= 9) {
       
  4656               char up_cmd[32] = "/roster up ";
       
  4657 
       
  4658               strcat(up_cmd, inputLine);
       
  4659               process_command(up_cmd, TRUE);
       
  4660             } else
       
  4661               process_command(mkcmdstr("roster up "), TRUE);
       
  4662             break;
       
  4663         case 'M':
       
  4664             if (inputLine[0] == 'z') {
       
  4665               GSList *groups = compl_list(ROSTER_TYPE_GROUP);
       
  4666               GSList *g;
       
  4667 
       
  4668               for (g = groups; g; g = g_slist_next(g)) {
       
  4669                 char fold_cmd[128] = "/group fold ";
       
  4670                 size_t cmd_len = strlen(fold_cmd);
       
  4671                 size_t grp_len = strlen(g->data);
       
  4672 
       
  4673                 if (cmd_len + grp_len + 1 > sizeof(fold_cmd))
       
  4674                   continue;
       
  4675                 memcpy(fold_cmd + cmd_len, g->data, grp_len + 1);
       
  4676                 process_command(fold_cmd, TRUE);
       
  4677                 g_free(g->data);
       
  4678               }
       
  4679               g_slist_free(groups);
       
  4680             } else
       
  4681               unrecognized = TRUE;
       
  4682             break;
       
  4683         case 'n':
       
  4684             process_command(search_cmd, TRUE);
       
  4685             break;
       
  4686         case 'O':
       
  4687             process_command(mkcmdstr("roster unread_first"), TRUE);
       
  4688             open_chat_window();
       
  4689             break;
       
  4690         case 'o':
       
  4691             process_command(mkcmdstr("roster unread_next"), TRUE);
       
  4692             open_chat_window();
       
  4693             break;
       
  4694         case 'R':
       
  4695             if (inputLine[0] == 'z') {
       
  4696               GSList *groups = compl_list(ROSTER_TYPE_GROUP);
       
  4697               GSList *g;
       
  4698 
       
  4699               for (g = groups; g; g = g_slist_next(g)) {
       
  4700                 char fold_cmd[128] = "/group unfold ";
       
  4701                 size_t cmd_len = strlen(fold_cmd);
       
  4702                 size_t grp_len = strlen(g->data);
       
  4703 
       
  4704                 if (cmd_len + grp_len + 1 > sizeof(fold_cmd))
       
  4705                   continue;
       
  4706                 memcpy(fold_cmd + cmd_len, g->data, grp_len + 1);
       
  4707                 process_command(fold_cmd, TRUE);
       
  4708                 g_free(g->data);
       
  4709               }
       
  4710               g_slist_free(groups);
       
  4711             } else
       
  4712               unrecognized = TRUE;
       
  4713             break;
       
  4714         case 'Z':
       
  4715             if (inputLine[0] == 'Z')
       
  4716               process_command(mkcmdstr("quit"), TRUE);
       
  4717             else {
       
  4718               clear_inputline();
       
  4719               got_cmd_prefix = TRUE;
       
  4720             }
       
  4721             break;
       
  4722         case 'z':
       
  4723             clear_inputline();
       
  4724             got_cmd_prefix = TRUE;
       
  4725             break;
       
  4726         case 13:    // Enter
       
  4727         case 343:   // Enter on Maemo
       
  4728             break;
       
  4729         default:
       
  4730             unrecognized = TRUE;
       
  4731             break;
       
  4732       }
       
  4733       cmdhisto_cur = NULL;
       
  4734     }
       
  4735     if (!ex_or_search_mode && !got_cmd_prefix) {
       
  4736       clear_inputline();
       
  4737       if (!unrecognized)
       
  4738         key = ERR;  // Do not process any further
       
  4739     }
       
  4740     lock_chatstate = TRUE;
  4449   }
  4741   }
  4450 
  4742 
  4451   if (kcode.utf8) {
  4743   if (kcode.utf8) {
  4452     if (key != ERR && !kcode.mcode)
  4744     if (key != ERR && !kcode.mcode)
  4453       display_char = TRUE;
  4745       display_char = TRUE;
  4511     }
  4803     }
  4512   }
  4804   }
  4513 
  4805 
  4514   if (completion_started && key != 9 && key != 353 && key != KEY_RESIZE)
  4806   if (completion_started && key != 9 && key != 353 && key != KEY_RESIZE)
  4515     scr_end_current_completion();
  4807     scr_end_current_completion();
       
  4808   else if (vi_completion)
       
  4809     inputLine[0] = ':';
  4516   refresh_inputline();
  4810   refresh_inputline();
       
  4811 
       
  4812   if (ex_or_search_mode && inputLine[0] != ':' && inputLine[0] != '/')
       
  4813     ex_or_search_mode = FALSE;
  4517 
  4814 
  4518   if (!lock_chatstate) {
  4815   if (!lock_chatstate) {
  4519     // Set chat state to composing (1) if the user is currently composing,
  4816     // Set chat state to composing (1) if the user is currently composing,
  4520     // i.e. not an empty line and not a command line.
  4817     // i.e. not an empty line and not a command line.
  4521     if (inputLine[0] == 0 || inputLine[0] == COMMAND_CHAR)
  4818     if (inputLine[0] == 0 || inputLine[0] == COMMAND_CHAR)
  4691       memset(&checked[start - line_start], SPELLBADCHAR, line - start);
  4988       memset(&checked[start - line_start], SPELLBADCHAR, line - start);
  4692   }
  4989   }
  4693 }
  4990 }
  4694 #endif
  4991 #endif
  4695 
  4992 
       
  4993 static void open_chat_window(void)
       
  4994 {
       
  4995   last_activity_buddy = current_buddy;
       
  4996   scr_check_auto_away(TRUE);
       
  4997   scr_set_chatmode(TRUE);
       
  4998   scr_show_buddy_window();
       
  4999 }
       
  5000 
       
  5001 static void clear_inputline(void)
       
  5002 {
       
  5003   ptr_inputline = inputLine;
       
  5004   *ptr_inputline = 0;
       
  5005   inputline_offset = 0;
       
  5006 }
       
  5007 
  4696 /* vim: set et cindent cinoptions=>2\:2(0 ts=2 sw=2:  For Vim users... */
  5008 /* vim: set et cindent cinoptions=>2\:2(0 ts=2 sw=2:  For Vim users... */