int
context_config_shuffle(struct pine *ps, CONF_S **cl)
{
    char      prompt[256];
    int	      n = 0, cmd, i1, i2, count = 0, insert_num, starting_varmem;
    int       news_problem = 0, deefault = 0;
    ESCKEY_S  ekey[3];
    CONTEXT_S *cur_ctxt, *other_ctxt;
    char     *tmp, **lval, **lval1, **lval2;
    struct variable *cur_var, *other_var;

    if(!((*cl)->d.c.ct && (*cl)->var))
      return(0);

    /* enable UP? */
    if((*cl)->d.c.ct->prev && !((*cl)->d.c.ct->prev->use & CNTXT_INHERIT)){
	/*
	 * Don't allow shuffling news collection up to become
	 * the primary collection. That would happen if prev is primary
	 * and this one is news.
	 */
	if((*cl)->d.c.ct->prev->use & CNTXT_SAVEDFLT &&
	   (*cl)->d.c.ct->use & CNTXT_NEWS)
	  news_problem++;
	else{
	    ekey[n].ch      = 'u';
	    ekey[n].rval    = 'u';
	    ekey[n].name    = "U";
	    ekey[n++].label = N_("Up");
	    deefault        = 'u';
	}
    }

    /* enable DOWN? */
    if((*cl)->d.c.ct->next && !((*cl)->d.c.ct->next->use & CNTXT_INHERIT)){
	/*
	 * Don't allow shuffling down past news collection if this
	 * is primary collection.
	 */
	if((*cl)->d.c.ct->use & CNTXT_SAVEDFLT &&
	   (*cl)->d.c.ct->next->use & CNTXT_NEWS)
	  news_problem++;
	else{
	    ekey[n].ch      = 'd';
	    ekey[n].rval    = 'd';
	    ekey[n].name    = "D";
	    ekey[n++].label = N_("Down");
	    if(!deefault)
	      deefault = 'd';
	}
    }

    if(n){
	ekey[n].ch = -1;
	snprintf(prompt, sizeof(prompt), _("Shuffle selected context %s%s%s? "),
		(ekey[0].ch == 'u') ?  _("UP") : "",
		(n > 1) ? " or " : "",
		(ekey[0].ch == 'd' || n > 1) ? _("DOWN") : "");
	prompt[sizeof(prompt)-1] = '\0';

	cmd = radio_buttons(prompt, -FOOTER_ROWS(ps), ekey,
			    deefault, 'x', NO_HELP, RB_NORM);
	switch(cmd){
	  case 'x':
	  default:
	    cmd_cancelled("Shuffle");
	    return(0);
	  
	  case 'u':
	  case 'd':
	    break;
	}

	/*
	 * This is complicated by the fact that there are two
	 * vars involved, the folder-collections and the news-collections.
	 * We may have to shuffle across collections.
	 */
	cur_ctxt = (*cl)->d.c.ct;
	if(cmd == 'd')
	  other_ctxt = (*cl)->d.c.ct->next;
	else if(cmd == 'u')
	  other_ctxt = (*cl)->d.c.ct->prev;
	
	cur_var = cur_ctxt->var.v;
	other_var = other_ctxt->var.v;

	/* swap elements of config var */
	if(cur_var == other_var){
	    i1 = cur_ctxt->var.i;
	    i2 = other_ctxt->var.i;
	    lval = LVAL(cur_var, ew);
	    if(lval){
		tmp = lval[i1];
		lval[i1] = lval[i2];
		lval[i2] = tmp;
	    }

	    starting_varmem = i2;
	}
	else{
	    /* swap into the other_var */
	    i1 = cur_ctxt->var.i;
	    i2 = other_ctxt->var.i;
	    lval1 = LVAL(cur_var, ew);
	    lval2 = LVAL(other_var, ew);
	    /* count */
	    for(count = 0; lval2 && lval2[count]; count++)
	      ;
	    if(cmd == 'd')
	      insert_num = count ? 1 : 0;
	    else{
		insert_num = count ? count - 1 : count;
	    }

	    starting_varmem = insert_num;
	    if(ccs_var_insert(ps,lval1[i1],other_var,lval2,insert_num)){
		if(!ccs_var_delete(ps, cur_ctxt)){
		    q_status_message(SM_ORDER|SM_DING, 3, 3,
				     _("Error deleting shuffled context"));
		    return(0);
		}
	    }
	    else{
		q_status_message(SM_ORDER, 3, 3,
				 _("Trouble shuffling, cancelled"));
		return(0);
	    }
	}

	(*cl)->d.c.cs->starting_var = other_var;
	(*cl)->d.c.cs->starting_varmem = starting_varmem;

	q_status_message(SM_ORDER, 0, 3, _("Collections shuffled"));
	return(15);
    }

    if(news_problem)
      /* TRANSLATORS: Sorry, can't move news group collections above email collections */
      q_status_message(SM_ORDER, 0, 3, _("Sorry, cannot Shuffle news to top"));
    else
      q_status_message(SM_ORDER, 0, 3, _("Sorry, nothing to Shuffle"));

    return(0);
}
Exemple #2
0
/*----------------------------------------------------------------------
   Function to control flag set/clearing

   Basically, turn the flags into a fake list of features...

   Returns 0 unless user has added a keyword, then 1.

 ----*/
int
flag_maintenance_screen(struct pine *ps, struct flag_screen *flags)
{
    int		  i, lv, lc, maxwidth, offset, need, rv = 0;
    char	  tmp[1200], **p, *spacer;
    CONF_S	 *ctmpa, *first_line;
    struct	  flag_table  *fp;
    OPT_SCREEN_S  screen;

try_again:
    maxwidth = MAX(MIN((ps->ttyo ? ps->ttyo->screen_cols : 80), 150), 30);
    first_line = NULL;
    ctmpa = NULL;

    for(p = flags->explanation; p && *p; p++) {
        new_confline(&ctmpa);
        ctmpa->keymenu   = &flag_keymenu;
        ctmpa->help      = NO_HELP;
        ctmpa->tool      = flag_checkbox_tool;
        ctmpa->flags    |= CF_NOSELECT;
        ctmpa->valoffset = 0;
        ctmpa->value     = cpystr(_(*p));
    }

    /* Now wire flags checkboxes together */
    for(lv = 0, lc = 0, fp = (flags->flag_table ? *flags->flag_table : NULL);
            fp && fp->name; fp++) {	/* longest name */
        if(fp->flag != F_COMMENT) {
            if(lv < (i = utf8_width(_(fp->name))))
                lv = i;
            if(fp->comment && lc < (i = utf8_width(fp->comment)))
                lc = i;
        }
    }

    lv = MIN(lv,100);
    lc = MIN(lc,100);
    if(lc > 0)
        spacer = "    ";
    else
        spacer = "";

    offset = 6;
    if((need = offset + 5 + lv + strlen(spacer) + lc) > maxwidth) {
        offset -= (need - maxwidth);
        offset = MAX(0,offset);
        if((need = offset + 5 + lv + strlen(spacer) + lc) > maxwidth) {
            spacer = " ";
            if((need = offset + 5 + lv + strlen(spacer) + lc) > maxwidth) {
                lc -= (need - maxwidth);
                lc = MAX(0,lc);
                if(lc == 0)
                    spacer = "";
            }
        }
    }

    new_confline(&ctmpa);
    ctmpa->keymenu   = &flag_keymenu;
    ctmpa->help      = NO_HELP;
    ctmpa->tool      = flag_checkbox_tool;
    ctmpa->flags    |= CF_NOSELECT;
    ctmpa->valoffset = 0;
    ctmpa->value     = cpystr("");

    new_confline(&ctmpa);
    ctmpa->keymenu   = &flag_keymenu;
    ctmpa->help      = NO_HELP;
    ctmpa->tool      = flag_checkbox_tool;
    ctmpa->flags    |= CF_NOSELECT;
    ctmpa->valoffset = 0;
    utf8_snprintf(tmp, sizeof(tmp), "%*.*w  %s", offset+3, offset+3, _("Set"), _("Flag/Keyword Name"));
    tmp[sizeof(tmp)-1] = '\0';
    ctmpa->value = cpystr(tmp);

    new_confline(&ctmpa);
    ctmpa->keymenu   = &flag_keymenu;
    ctmpa->help      = NO_HELP;
    ctmpa->tool      = flag_checkbox_tool;
    ctmpa->flags    |= CF_NOSELECT;
    ctmpa->valoffset = 0;
    snprintf(tmp, sizeof(tmp), "%*.*s---  %.*s",
             offset, offset, "",
             lv+lc+strlen(spacer), repeat_char(lv+lc+strlen(spacer), '-'));
    tmp[sizeof(tmp)-1] = '\0';
    ctmpa->value = cpystr(tmp);

    for(fp = (flags->flag_table ? *flags->flag_table : NULL);
            fp && fp->name; fp++) {	/* build the list */
        new_confline(&ctmpa);
        if(!first_line && (fp->flag != F_COMMENT))
            first_line = ctmpa;

        ctmpa->keymenu   = &flag_keymenu;
        ctmpa->tool      = flag_checkbox_tool;
        ctmpa->valoffset = offset;

        if(fp->flag == F_COMMENT) {
            ctmpa->help   = NO_HELP;
            ctmpa->flags |= CF_NOSELECT;
            ctmpa->value  = cpystr(fp->name);
        }
        else {
            ctmpa->help		  = fp->help;
            ctmpa->d.f.ftbl	  = flags->flag_table;
            ctmpa->d.f.fp	  = fp;

            utf8_snprintf(tmp, sizeof(tmp), "[%c]  %-*.*w%s%-*.*w",
                          (fp->set == 0) ? ' ' : (fp->set == 1) ? 'X' : '?',
                          lv, lv, _(fp->name),
                          spacer, lc, lc, fp->comment ? fp->comment : "");
            ctmpa->value = cpystr(tmp);
        }
    }

    memset(&screen, 0, sizeof(screen));
    /*
     * TRANSLATORS: FLAG MAINTENANCE is a screen title.
     * Print something1 using something2.  configuration is something1
     */
    if(conf_scroll_screen(ps, &screen, first_line,
                          _("FLAG MAINTENANCE"),
                          _("configuration"), 0) == FLAG_ADD_RETURN) {
        int flags, r;
        char keyword[500];
        char nickname[500];
        char prompt[500];
        char *error = NULL;
        KEYWORD_S *kw;
        HelpType help;

        /*
         * User is asking to add a new keyword. We will add it to the
         * mailbox if necessary and add it to the keywords list from
         * Setup/Config. Then we will modify the flag_table and present
         * the flag modification screen again.
         */

        ps->mangled_screen = 1;
        keyword[0] = '\0';
        flags = OE_APPEND_CURRENT;
        help = NO_HELP;

        do {
            if(error) {
                q_status_message(SM_ORDER, 3, 4, error);
                fs_give((void **) &error);
            }

            strncpy(prompt, _("Keyword to be added : "), sizeof(prompt)-1);
            prompt[sizeof(prompt)-1] = '\0';
            r = optionally_enter(keyword, -FOOTER_ROWS(ps_global), 0,
                                 sizeof(keyword), prompt, NULL, help, &flags);

            if(r == 3)
                help = help == NO_HELP ? h_type_keyword : NO_HELP;
            else if(r == 1) {
                cmd_cancelled("Add Keyword");
                goto try_again;
            }

            removing_leading_and_trailing_white_space(keyword);

        } while(r == 3 || keyword_check(keyword, &error));

        for(kw = ps->keywords; kw; kw = kw->next) {
            if(kw->kw && !strucmp(kw->kw, keyword)) {
                q_status_message(SM_ORDER, 3, 4, _("Keyword already configured, changing nickname"));
                break;
            }
        }

        snprintf(prompt, sizeof(prompt), _("Optional nickname for \"%s\" : "), keyword);

        nickname[0] = '\0';
        help = NO_HELP;

        do {
            r = optionally_enter(nickname, -FOOTER_ROWS(ps_global), 0,
                                 sizeof(nickname), prompt, NULL, help, &flags);

            if(r == 3)
                help = help == NO_HELP ? h_type_keyword_nickname : NO_HELP;
            else if(r == 1) {
                cmd_cancelled("Add Keyword");
                goto try_again;
            }

            removing_leading_and_trailing_white_space(nickname);

        } while(r == 3);

        if(keyword[0]) {
            char ***alval;
            int offset = -1;
            struct variable *var;

            var = &ps_global->vars[V_KEYWORDS];
            alval = ALVAL(var, Main);

            for(kw = ps->keywords; kw; kw = kw->next) {
                offset++;
                if(kw->kw && !strucmp(kw->kw, keyword)) {
                    /* looks like it should already exist at offset */
                    break;
                }
            }

            if(!kw)
                offset = -1;

            if(offset >= 0 && (*alval) && (*alval)[offset]) {
                fs_give((void **) &(*alval)[offset]);
                (*alval)[offset] = put_pair(nickname, keyword);
            }
            else if(!*alval) {
                offset = 0;
                *alval = (char **) fs_get(2*sizeof(char *));
                (*alval)[offset] = put_pair(nickname, keyword);
                (*alval)[offset+1] = NULL;
            }
            else {
                for(offset=0; (*alval)[offset]; offset++);
                ;

                fs_resize((void **) alval, (offset + 2) * sizeof(char *));
                (*alval)[offset] = put_pair(nickname, keyword);
                (*alval)[offset+1] = NULL;
            }

            set_current_val(var, TRUE, FALSE);
            if(ps_global->prc)
                ps_global->prc->outstanding_pinerc_changes = 1;

            if(ps_global->keywords)
                free_keyword_list(&ps_global->keywords);

            if(var->current_val.l && var->current_val.l[0])
                ps_global->keywords = init_keyword_list(var->current_val.l);

            clear_index_cache(ps_global->mail_stream, 0);

            rv = 1;
        }
    }

    ps->mangled_screen = 1;

    return(rv);
}