/* * mark.c: Option marking routines * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * * * See the AUTHORS file for a list of people who have hacked on * this code. * See the ChangeLog file for a list of changes. * * Contents: * * ppdConflicts() - Check to see if there are any conflicts. * ppd_find_choice() - Return a pointer to an option choice. * ppd_find_marked_choice() - Return the marked choice for the specified option. * ppd_find_option_by_keyword() - Return a pointer to the specified option. * ppd_check_option_is_marked() - Check to see if an option is marked... * ppd_mark_defaults() - Mark all default options in the PPD file. * ppd_mark_option() - Mark an option in a PPD file. * ppd_defaults() - Set the defaults for this group and all sub-groups * * * OLD Contents: * * ppdConflicts() - Check to see if there are any conflicts. * ppdFindChoice() - Return a pointer to an option choice. * ppdFindMarkedChoice() - Return the marked choice for the specified option. * ppdFindOption() - Return a pointer to the specified option. * ppdIsMarked() - Check to see if an option is marked... * ppdMarkDefaults() - Mark all default options in the PPD file. * ppdMarkOption() - Mark an option in a PPD file. * ppd_defaults() - Set the defaults for this group and all sub-groups. */ /* * Include necessary headers... */ #include "ppd.h" /* Do we need string.h? Is this a local or the standard string.h? -- MJF #include "string.h" */ /* * Local functions... */ static void ppd_defaults(PpdFile * ppd, PpdGroup * g); /* * 'ppd_get_num_conflicts()' - Check to see if there are any conflicts. */ int /* O - Number of conflicts found */ ppd_get_num_conflicts(PpdFile * ppd) { /* I - PPD to check */ int conflicts; /* Number of conflicts */ PpdConstraint *c; /* Current constraint */ PpdGroup *g; // *sg; /* Groups */ PpdOption *o1, *o2; /* Options */ PpdChoice *c1, *c2; /* Choices */ GSList *glist, *olist, *sglist, *clist, *chlist; if (ppd == NULL) return (0); /* * Clear all conflicts... */ conflicts = 0; /* iterate through all the groups in ppd, setting all their options to conflicted = FALSE do the same for the subgroups */ glist = ppd->groups; while (glist) { g = PPD_GROUP(glist->data); olist = g->options; while (olist) { o1 = PPD_OPTION(olist->data); o1->conflicted = FALSE; olist = g_slist_next(olist); } sglist = g->subgroups; while (sglist) { o1 = PPD_OPTION(sglist->data); o1->conflicted = FALSE; sglist = g_slist_next(sglist); } glist = g_slist_next(glist); } /* * Loop through all of the UI constraints and flag any options * that conflict... */ clist = ppd->consts; while (clist) { c = PPD_CONSTRAINT(clist->data); /* * Grab pointers to the first option... */ if ((c == NULL) || (c->option1 == NULL)) { clist = g_slist_next(clist); continue; } o1 = ppd_find_option_by_keyword(ppd, c->option1->str); if (o1 == NULL) { clist = g_slist_next(clist); continue; } else if (c->choice1 != NULL) { /* * This constraint maps to a specific choice. */ c1 = ppd_find_choice(o1, c->choice1->str); } else { /* * This constraint applies to any choice for this option. */ /* iterate through the choices in o1, stopping when a marked one is found. If one isn't found, c1 should come out of the loop == NULL */ chlist = o1->choices; while (chlist) { c1 = PPD_CHOICE(chlist->data); if (c1->marked) break; else c1 = NULL; chlist = g_slist_next(chlist); } if ((c1 != NULL) && (g_strcasecmp(c1->choice->str, "None") == 0)) c1 = NULL; } /* * Grab pointers to the second option... */ if (c->option2 == NULL) { clist = g_slist_next(clist); continue; } o2 = ppd_find_option_by_keyword(ppd, c->option2->str); if (o2 == NULL) { clist = g_slist_next(clist); continue; } else if (c->choice2 != NULL) { /* * This constraint maps to a specific choice. */ c2 = ppd_find_choice(o2, c->choice2->str); } else { /* * This constraint applies to any choice for this option. */ chlist = o2->choices; while (chlist) { c2 = PPD_CHOICE(chlist->data); if (c2->marked) break; else c2 = NULL; chlist = g_slist_next(chlist); } if ((c2 != NULL) && (g_strcasecmp(c2->choice->str, "None") == 0)) c2 = NULL; } /* * If both options are marked then there is a conflict... */ if ((c1 != NULL) && (c1->marked) && (c2 != NULL) && (c2->marked)) { conflicts++; o1->conflicted = TRUE; o2->conflicted = TRUE; } clist = g_slist_next(clist); } /* * Return the number of conflicts found... */ return (conflicts); } /* * 'ppd_find_choice()' - Return a pointer to an option choice. */ PpdChoice * /* O - Choice pointer or NULL */ ppd_find_choice(PpdOption * o, /* I - Pointer to option */ const char *choice) { /* I - Name of choice */ PpdChoice *c; /* Current choice */ GSList *list; /* List iteration variable */ if (o == NULL || choice == NULL) return (NULL); list = o->choices; while (list) { c = PPD_CHOICE(list->data); if (g_strcasecmp(c->choice->str, choice) == 0) return (c); list = g_slist_next(list); } /* we couldn't find a match */ return (NULL); } /* * 'ppd_find_marked_choice()' - Return the marked choice for the specified option. */ PpdChoice * /* O - Pointer to choice or NULL */ ppd_find_marked_choice(PpdFile * ppd, /* I - PPD file */ const char *option) { /* I - Keyword/option name */ PpdOption *o; /* Pointer to option */ PpdChoice *c; /* Pointer to choice */ GSList *list; if ((o = ppd_find_option_by_keyword(ppd, option)) == NULL) return (NULL); list = o->choices; while (list) { c = PPD_CHOICE(list->data); if (c->marked) return (c); list = g_slist_next(list); } return (NULL); } /* 'ppd_find_option_by_keyword()' - Return a pointer to the specified * option. O - Pointer to option or NULL I - PPD file data */ PpdOption *ppd_find_option_by_keyword(PpdFile * ppd, const char *option) { /* I - Option/Keyword name */ GSList *groupl; /* Group List iteration var */ if (ppd == NULL || option == NULL) return (NULL); /* iterate through the top level group list */ for (groupl = ppd->groups; groupl; groupl = g_slist_next(groupl)) { PpdGroup *g = PPD_GROUP(groupl->data); GSList *subgl; /* Subgroup List iteration var */ GSList *optl; /* Option List iteration var */ /* check the options of this group */ for (optl = g->options; optl; optl = g_slist_next(optl)) { PpdOption *o = PPD_OPTION(optl->data); /* Pointer to option */ if (o != NULL && g_strcasecmp(o->keyword->str, option) == 0) return (o); } /* iterate through the subgroups of this group, and check their options */ for (subgl = g->subgroups; subgl; subgl = g_slist_next(subgl)) { PpdGroup *sg = PPD_GROUP(subgl->data); for (optl = sg->options; optl; subgl = g_slist_next(sg)) { PpdOption *o = PPD_OPTION(optl->data); if (g_strcasecmp(o->keyword->str, option) == 0) return (o); } } } return (NULL); } /* 'ppd_check_option_is_marked()' - Check to see if an option is * marked... */ /* returns Non-zero if option is marked */ gboolean ppd_check_option_is_marked(PpdFile * ppd, const char *option, const char *choice) { PpdOption *o; /* Option pointer */ PpdChoice *c; /* Choice pointer */ return ppd == NULL || (o = ppd_find_option_by_keyword(ppd, option)) == NULL || (c = ppd_find_choice(o, choice)) == NULL ? FALSE : c->marked; } /* 'ppd_mark_defaults()' - Mark all default options in the PPD file. */ void ppd_mark_defaults(PpdFile * ppd) { /* I - PPD file record */ PpdGroup *g; /* Current group */ GSList *list; if (ppd == NULL) return; list = ppd->groups; while (list) { g = PPD_GROUP(list->data); ppd_defaults(ppd, g); list = g_slist_next(list); } } /* * 'ppd_mark_option()' - Mark an option in a PPD file. * * Notes: * * -1 is returned if the given option would conflict with any currently * selected option. */ int /* O - Number of conflicts */ ppd_mark_option(PpdFile * ppd, /* I - PPD file record */ const char *option, /* I - Keyword */ const char *choice) { /* I - Option name */ PpdOption *o; /* Option pointer */ PpdChoice *c; /* Choice pointer */ GSList *list; gboolean found = FALSE; PpdSize *size; if (ppd == NULL) return (0); if (g_strcasecmp(option, "PageSize") == 0 && g_strncasecmp(choice, "Custom.", 7) == 0) { /* * Handle variable page sizes... */ ppd_get_page_size(ppd, choice); choice = "Custom"; } if ((o = ppd_find_option_by_keyword(ppd, option)) == NULL) return (0); /* Cycle through the choices list, for each choice, if c->choice == choice then found = TRUE, break; */ list = o->choices; while (list) { c = PPD_CHOICE(list->data); if ((c != NULL) && (c->choice != NULL) && (g_strcasecmp(c->choice->str, choice) == 0)) { found = TRUE; break; } list = g_slist_next(list); } /* for (i = o->num_choices, c = o->choices; i > 0; i--, c++) if (strcasecmp(c->choice, choice) == 0) break; */ if (found) { /* * Option found; mark it and then handle unmarking any other options. */ c->marked = TRUE; /* * Unmark it as being emitted */ o->emitted = FALSE; if (o->ui != PPD_UI_PICKMANY) { /* Iterate through the option->choices list, looking for choices whose 'choice' field != choice, and mark them */ list = o->choices; while (list) { c = PPD_CHOICE(list->data); if ((c != NULL) && (c->choice != NULL) && (g_strcasecmp(c->choice->str, choice) != 0)) c->marked = FALSE; list = g_slist_next(list); } } if (g_strcasecmp(option, "PageSize") == 0 || g_strcasecmp(option, "PageRegion") == 0) { /* * Mark current page size... */ list = ppd->sizes; while (list) { size = PPD_SIZE(list->data); if ((size != NULL) && (size->name != NULL)) { if (g_strcasecmp(size->name->str, choice) == 0) size->marked = TRUE; else size->marked = FALSE; } list = g_slist_next(list); } /* for (i = 0; i < ppd->num_sizes; i++) ppd->sizes[i].marked = strcasecmp(ppd->sizes[i].name, choice) == 0; */ /* * Unmark the current PageSize or PageRegion setting, as appropriate... */ if (g_strcasecmp(option, "PageSize") == 0) { if ((o = ppd_find_option_by_keyword(ppd, "PageRegion")) != NULL) { list = o->choices; while (list) { c = PPD_CHOICE(list->data); c->marked = FALSE; list = g_slist_next(list); } // for (i = 0; i < o->num_choices; i++) // o->choices[i].marked = 0; } } else { if ((o = ppd_find_option_by_keyword(ppd, "PageSize")) != NULL) { list = o->choices; while (list) { c = PPD_CHOICE(list->data); c->marked = FALSE; list = g_slist_next(list); } // for (i = 0; i < o->num_choices; i++) // o->choices[i].marked = 0; } } } } return (ppd_get_num_conflicts(ppd)); } /* * 'ppd_defaults()' - Set the defaults for this group and all sub-groups. */ static void ppd_defaults(PpdFile * ppd, /* I - PPD file */ PpdGroup * g) { /* I - Group to default */ PpdOption *o; /* Current option */ PpdGroup *sg; /* Current sub-group */ GSList *list; /* List iteration variable */ if (g == NULL) return; /* go through every option in the group, if option->keyword != "PageRegion" then Mark the option */ list = g->options; while (list) { o = PPD_OPTION(list->data); if ((o->keyword != NULL) && (o->defchoice != NULL) && (g_strcasecmp(o->keyword->str, "PageRegion") != 0)) ppd_mark_option(ppd, o->keyword->str, o->defchoice->str); list = g_slist_next(list); } list = g->subgroups; while (list) { sg = PPD_GROUP(list->data); ppd_defaults(ppd, sg); list = g_slist_next(list); } } /* * End */