PrintStyle 25.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
/* Copyright 1997 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/***************************************************/
/* File   : PrintStyle.c                           */
/*                                                 */
/* Purpose: Change print style options with the    */
/*          PrintStyle dialogue.                   */
/*                                                 */
/*          This source is fairly closely tied to  */
/*          Print.c, as the Print Style dialogue   */
/*          is typically opened from the Print     */
/*          dialogue.                              */
/*                                                 */
/* Author : A.D.Hodgkinson                         */
/*                                                 */
/* History: 24-Aug-97: Created.                    */
/***************************************************/

#include <stdlib.h>
#include <string.h>

#include "swis.h"

#include "wimp.h"
#include "wimplib.h"
#include "event.h"

#include "toolbox.h"
#include "printdbox.h"
#include "window.h"

#include "svcprint.h"
#include "Global.h"
#include "Utils.h"

#include "Browser.h"
#include "Menus.h"
#include "Printing.h"

#include "PrintStyle.h"

/* Local structures and supporting definitions */

#define Background_Show_Type_None   0
#define Background_Show_Type_Tables 1
#define Background_Show_Type_All    2

/* Holds info on the Print Style dialogue's contents; small enough */
/* to hold as a static, as the code to dynamically allocate it     */
/* would occupy more room than the structure itself.               */

typedef struct printstyle_contents
{
  unsigned int underline_links      :1;
67
  unsigned int use_source_cols      :1;
68 69 70 71
  unsigned int show_foreground      :1;
  unsigned int show_background      :1;

  unsigned int background_show_type :2; /* 0 = none, 1 = in tables, 2 = all */
72
  unsigned int black_no_background  :1;
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
  unsigned int always_use_black     :1;

} printstyle_contents;

/* Local statics */

static printstyle_contents contents;         /* Remember the old dialogue contents so the Cancel button can work, and */
                                             /* other functions can inquire about the state of the contents without   */
                                             /* needing this end to start calling toolbox routines to find out.       */

static ObjectId            window_id    = 0; /* Remember the ID in case it needs closing 'out of the blue'. */
static ObjectId            ancestor_id  = 0; /* Remember then ancestor ID in case the ancestor closes. */

static int                 defaults_set = 0;

/* Static function prototypes */

static _kernel_oserror * printstyle_read_contents    (ObjectId dialogue, printstyle_contents * contents);
static _kernel_oserror * printstyle_set_contents     (ObjectId dialogue, printstyle_contents * contents);

static int               printstyle_cancel           (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle);
static int               printstyle_option_group_one (int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle);

/*************************************************/
/* printstyle_read_contents()                    */
/*                                               */
/* Reads the contents of the Print Style         */
/* dialogue into a printstyle_contents struct.   */
/*                                               */
/* Parameters: Object ID of the dialogue;        */
/*                                               */
/*             Pointer to the structure to write */
/*             to.                               */
/*************************************************/

static _kernel_oserror * printstyle_read_contents(ObjectId dialogue, printstyle_contents * contents)
{
110
  int state;
111 112 113

  /* Read the four basic display options */

114 115 116 117
  RetError(optionbutton_get_state(0, dialogue, PSUnderlineLinks,       &state)); contents->underline_links = !!state;
  RetError(optionbutton_get_state(0, dialogue, PSUseDocumentColours,   &state)); contents->use_source_cols = !!state;
  RetError(optionbutton_get_state(0, dialogue, PSShowForegroundImages, &state)); contents->show_foreground = !!state;
  RetError(optionbutton_get_state(0, dialogue, PSShowBackgroundImages, &state)); contents->show_background = !!state;
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137

  /* Read the background show type */

  RetError(radiobutton_get_state(0, dialogue, PSAllBackgrounds, NULL, &state));

  switch (state)
  {
    default:
    case PSNoBackgrounds:  contents->background_show_type = Background_Show_Type_None;
    break;

    case PSTablesOnly:     contents->background_show_type = Background_Show_Type_Tables;
    break;

    case PSAllBackgrounds: contents->background_show_type = Background_Show_Type_All;
    break;
  }

  /* Finally, read the 'print text in black' options */

138
  RetError(optionbutton_get_state(0, dialogue, PSBlackIfNoBackground,  &state));
139
  contents->black_no_background = !!state;
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163

  RetError(optionbutton_get_state(0, dialogue, PSAlwaysUseBlack, &state));
  contents->always_use_black = !!state;


  return NULL;
}

/*************************************************/
/* printstyle_set_contents()                     */
/*                                               */
/* Sets the contents of the Print Style dialogue */
/* from a printstyle_contents structure.         */
/*                                               */
/* Parameters: Object ID of the dialogue;        */
/*                                               */
/*             Pointer to the structure to read  */
/*             from.                             */
/*************************************************/

static _kernel_oserror * printstyle_set_contents(ObjectId dialogue, printstyle_contents * contents)
{
  /* Set the four basic display options */

164
  RetError(optionbutton_set_state(0, dialogue, PSUnderlineLinks,       contents->underline_links));
165
  RetError(optionbutton_set_state(0, dialogue, PSUseDocumentColours,   contents->use_source_cols));
166 167
  RetError(optionbutton_set_state(0, dialogue, PSShowForegroundImages, contents->show_foreground));
  RetError(optionbutton_set_state(0, dialogue, PSShowBackgroundImages, contents->show_background));
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188

  /* Ensure the browser (if any) is up to date with this */

  printstyle_option_group_one(0, NULL, NULL, NULL);

  /* Set the background show type */

  switch (contents->background_show_type)
  {
    default:
    case Background_Show_Type_None:   RetError(radiobutton_set_state(0, dialogue, PSNoBackgrounds, 1));
    break;

    case Background_Show_Type_Tables: RetError(radiobutton_set_state(0, dialogue, PSTablesOnly, 1));
    break;

    case Background_Show_Type_All:    RetError(radiobutton_set_state(0, dialogue, PSAllBackgrounds, 1));
  }

  /* Finally, set the 'print text in black' options */

189
  RetError(optionbutton_set_state(0, dialogue, PSBlackIfNoBackground, contents->black_no_background));
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218

  return optionbutton_set_state(0, dialogue, PSAlwaysUseBlack, contents->always_use_black);
}

/*************************************************/
/* printstyle_set_defaults()                     */
/*                                               */
/* Fills in the local printstyle_contents        */
/* structure with the default values to put in   */
/* a Print Style dialogue, if they have not      */
/* already been filled in.                       */
/*                                               */
/* If the dialogue is open, the contents are     */
/* updated.                                      */
/*                                               */
/* Returns:    1 if the structure was filled in, */
/*             else 0.                           */
/*************************************************/

int printstyle_set_defaults(void)
{
  if (!defaults_set)
  {
    /* Read the defaults from the Choices file */

    if      (!strcmp(lookup_choice("PrintBack:tables", 0, 0),"none"))  contents.background_show_type = Background_Show_Type_None;
    else if (!strcmp(lookup_choice("PrintBack:tables", 0, 0),"all"))   contents.background_show_type = Background_Show_Type_All;
    else                                                               contents.background_show_type = Background_Show_Type_Tables;

219 220 221
    if      (!strcmp(lookup_choice("PrintBlack:bg", 0, 0), "always"))  contents.always_use_black = 1, contents.black_no_background = 0;
    else if (!strcmp(lookup_choice("PrintBlack:bg", 0, 0), "never"))   contents.always_use_black = 0, contents.black_no_background = 0;
    else                                                               contents.always_use_black = 0, contents.black_no_background = 1;
222 223 224 225 226 227 228 229 230 231 232 233 234 235

    defaults_set = 1;

    if (window_id) printstyle_set_contents(window_id, &contents);

    return 1;
  }

  return 0;
}

/*************************************************/
/* printstyle_to_be_shown()                      */
/*                                               */
236
/* Called when the EPSToBeShown event is         */
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
/* generated, typically when the Print Style     */
/* dialogue is about to be shown. Registers      */
/* event handlers for the dialogue, reads and    */
/* sets options in it, etc.                      */
/*                                               */
/* Parameters are as standard for a Toolbox      */
/* event hander, though only the self_id and     */
/* ancestor_id fields of the ID block are of     */
/* interest.                                     */
/*************************************************/

int printstyle_to_be_shown(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle)
{
  browser_data * ancestor = NULL;

  /* If the stored dialogue ID is non-zero on entry, the dialogue */
  /* was reopened without closing - so get rid of the various     */
  /* event handlers before we reregister them.                    */

  if (window_id) printstyle_close(0, 0);

  /* Right, record the ID as given in the ID block */

  window_id = idb->self_id;

  /* Sigh. Blimmin' Toolbox. The Setup button in the Print */
  /* dialogue, when used to open Print Style, does not     */
  /* transmit the ancestor ID information - aargh!         */
  /*                                                       */
  /* This appears to be because the underlying window ID   */
  /* is given as this object's parent, rather than the     */
  /* print dialogue, and it doesn't have an ancestor (bug, */
  /* I'd say). Maybe because it's an alternative window,   */
  /* rather than a standard print dialogue? In any case,   */
  /* we must assume that the setup window did come from    */
  /* the print dialogue (and not, say, the choices) if     */
  /* there's no ancestor window, and ask the print         */
  /* routines what window it was for.                      */

  ancestor_id = idb->ancestor_id;

  if (ancestor_id)
  {
    ChkError(toolbox_get_ancestor(0, ancestor_id, &ancestor_id, NULL));
  }
  else
  {
    print_return_dialogue_info(NULL, NULL, &ancestor_id, &ancestor);
  }

  /* Attach event handlers - OK and Cancel functions */

  ChkError(event_register_toolbox_handler(idb->self_id, EPSOK,     printstyle_ok,     NULL));
  ChkError(event_register_toolbox_handler(idb->self_id, EPSCancel, printstyle_cancel, NULL));

  /* If defaults have never been set before, set them now */

  printstyle_set_defaults();

  /* Set up the basic display options to match the ancestor browser, */
  /* if there is one. Do this before registering handlers for the    */
  /* basic display options.                                          */

  if (ancestor)
  {
302 303 304 305
    contents.underline_links = ancestor->underline_links;
    contents.use_source_cols = ancestor->use_source_cols;
    contents.show_foreground = ancestor->show_foreground;
    contents.show_background = ancestor->show_background;
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417

    ChkError(printstyle_set_contents(idb->self_id, &contents));
  }

  /* Changing basic display type options (so that the browser window */
  /* can be updated to reflect the new settings)                     */

  ChkError(event_register_toolbox_handler(idb->self_id,
                                          EPSOG1,
                                          printstyle_option_group_one,
                                          NULL));

  /* Finished */

  return 1;
}

/*************************************************/
/* printstyle_ok()                               */
/*                                               */
/* Handles clicks on the 'OK' (or 'Use', etc.)   */
/* button in the Print Style dialogue.           */
/*                                               */
/* Parameters are as standard for a Toolbox      */
/* event handler (though none are actually       */
/* used).                                        */
/*************************************************/

int printstyle_ok(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle)
{
  if (!window_id) return 0;

  /* As with the Print dialogue, because this routine takes no */
  /* direct action, other functions are called independently   */
  /* and must act on the 'contents' printstyle_contents struct */
  /* - we can't use a local one here to allow Adjust-clicks.   */

  ChkError(printstyle_read_contents(window_id, &contents));
  ChkError(printstyle_close(0, 0));

  /* No other actual direct action to take; that's done by the Print dialogue */

  return 1;
}

/*************************************************/
/* printstyle_cancel()                           */
/*                                               */
/* Handles clicks on the 'Cancel' button in the  */
/* Print Style dialogue.                         */
/*                                               */
/* Parameters are as standard for a Toolbox      */
/* event handler.                                */
/*************************************************/

static int printstyle_cancel(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle)
{
  WimpGetPointerInfoBlock info;

  /* Restore the old contents */

  ChkError(printstyle_set_contents(window_id, &contents));

  /* If Select was pressed, the dialogue should close. */
  /* (No button => Escape was pressed).                */

  ChkError(wimp_get_pointer_info(&info));

  if ((info.button_state & Wimp_MouseButtonSelect) || !info.button_state)
  {
    ChkError(printstyle_close(0, 0));
  }

  return 1;
}

/*************************************************/
/* printstyle_close()                            */
/*                                               */
/* If the Print Style dialogue is opened, this   */
/* will close it, deregistering any associated   */
/* event handlers.                               */
/*                                               */
/* Parameters: An object ID, or 0. If not zero,  */
/*             the ID must match the ancestor    */
/*             recorded when the dialogue was    */
/*             opened or no action is taken;     */
/*                                               */
/*             0 to close the dialogue, 1 to do  */
/*             everything except that.           */
/*************************************************/

_kernel_oserror * printstyle_close(ObjectId ancestor, int do_not_close)
{
  _kernel_oserror * e = NULL;

  if (ancestor && ancestor != ancestor_id) return NULL;

  if (window_id)
  {
    /* Deregister associated event handlers */

    e = event_deregister_toolbox_handlers_for_object(window_id);
    if (e) goto printstyle_close_exit;

    /* Restore the old contents */

    e = printstyle_set_contents(window_id, &contents);
    if (e) goto printstyle_close_exit;

    /* Close the dialogue */

418 419 420 421 422 423 424 425 426 427 428
    if (!do_not_close)
    {
      /* Restore input focus to the Print dialogue, */
      /* if the Print Style dialogue still has it.  */

      utils_restore_caret(window_id);

      /* Now hide the Print Style dialogue */

      e = toolbox_hide_object(0, window_id);
    }
429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
  }

printstyle_close_exit:

  window_id = ancestor_id = 0;
  return e;
}

/*************************************************/
/* printstyle_option_group_one()                 */
/*                                               */
/* Handles clicks on the group of four option    */
/* buttons controlling basic page display.       */
/*                                               */
/* Parameters are as standard for a Toolbox      */
/* event handler (though none are used!).        */
/*************************************************/

static int printstyle_option_group_one(int eventcode, ToolboxEvent * event, IdBlock * idb, void * handle)
{
  browser_data * b;
  int            ul, dc, sf, sb;

  /* What browser is the Print dialogue for, if any? */

  print_return_dialogue_info(NULL, NULL, NULL, &b);

  if (b)
  {
    /* Read the option states */

460 461 462 463
    ChkError(optionbutton_get_state(0, window_id, PSUnderlineLinks,       &ul));
    ChkError(optionbutton_get_state(0, window_id, PSUseDocumentColours,   &dc));
    ChkError(optionbutton_get_state(0, window_id, PSShowForegroundImages, &sf));
    ChkError(optionbutton_get_state(0, window_id, PSShowBackgroundImages, &sb));
464 465 466

    /* Update the browser to reflect the changes */

467
    ChkError(browser_set_look(b, window_id, ul, dc, sf, sb));
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
  }

  return 1;
}

/*************************************************/
/* printstyle_set_look()                         */
/*                                               */
/* If the Print Style dialogue is open for the   */
/* given browser, update option group one with   */
/* the values specified.                         */
/*                                               */
/* If the object changing the look is not the    */
/* Print Style window itself, the changes are    */
/* stored inside the local printstyle_contents   */
/* struct; Cancel will thus not restore them.    */
/* This is because it is assumed that if another */
/* object sets the look (e.g. via. the           */
/* browser_set_look function), this is meant to  */
/* be a change controlled by that object, and it */
/* shouldn't be cancelled if the Print or Print  */
/* Style dialogues go.                           */
/*                                               */
/* Parameters: Object ID of the object that is   */
/*             changing the look of the browser, */
/*             e.g. a menu or even the Print     */
/*             Style dialogue itself, or 0 to    */
/*             have the same effect as the Print */
/*             Style dialogue object ID (see     */
/*             comments above);                  */
/*                                               */
/*             Object ID of the browser that the */
/*             Print Style dialogue should be    */
/*             open for;                         */
/*                                               */
/*             1 to underline links, 0 not to,   */
/*             -1 to not change this state;      */
/*                                               */
/*             1 to use document colours, 0 to   */
/*             use defaults, -1 to not change    */
/*             this state;                       */
/*                                               */
/*             1 to show images, 0 not to (any   */
/*             pending image fetches are started */
/*             up again if 1 is given), or -1 to */
/*             not change this state;            */
/*                                               */
/*             1 to display plain backgrounds, 0 */
/*             to allow background images (and   */
/*             here too, any pending image       */
/*             fetches for background images are */
/*             restarted if 0 is given), or -1   */
/*             to not change this state.         */
/*************************************************/

523 524
_kernel_oserror * printstyle_set_look(ObjectId source, ObjectId browser, int underline_links,
                                      int use_source_cols, int show_foreground, int show_background)
525
{
526
  int state;
527 528 529 530 531

  if (ancestor_id == browser)
  {
    /* Not much to say here - just go through each option in turn */

532
    if (underline_links >= 0)
533 534 535 536 537 538 539
    {
      /* Get the option state */

      RetError(optionbutton_get_state(0, window_id, PSUnderlineLinks, &state));

      /* If the requested state is different, set the new state */

540
      if (state != underline_links) RetError(optionbutton_set_state(0, window_id, PSUnderlineLinks, underline_links));
541 542 543 544

      /* If we've been given a source ID and it isn't the Print Style   */
      /* dialogue itself, set the new value so Cancel won't destroy it. */

545
      if (source && source != window_id) contents.underline_links = underline_links;
546 547
    }

548
    if (use_source_cols >= 0)
549
    {
550
      RetError(optionbutton_get_state(0, window_id, PSUseDocumentColours, &state));
551

552
      if (state != use_source_cols) RetError(optionbutton_set_state(0, window_id, PSUseDocumentColours, use_source_cols));
553

554
      if (source && source != window_id) contents.use_source_cols = use_source_cols;
555 556
    }

557
    if (show_foreground >= 0)
558
    {
559
      RetError(optionbutton_get_state(0, window_id, PSShowForegroundImages, &state));
560

561
      if (state != show_foreground) RetError(optionbutton_set_state(0, window_id, PSShowForegroundImages, show_foreground));
562

563
      if (source && source != window_id) contents.show_foreground = show_foreground;
564 565
    }

566
    if (show_background >= 0)
567
    {
568
      RetError(optionbutton_get_state(0, window_id, PSShowBackgroundImages, &state));
569

570
      if (state == show_background) RetError(optionbutton_set_state(0, window_id, PSShowBackgroundImages, show_background));
571

572
      if (source && source != window_id) contents.show_background = show_background;
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
    }
  }

  return NULL;
}

/*************************************************/
/* printstyle_show_none()                        */
/*                                               */
/* Ask if no backgrounds should be plotted.      */
/*                                               */
/* Returns:    1 if the Print Style dialogue     */
/*             specified no backgrounds, else    */
/*             0.                                */
/*************************************************/

int printstyle_show_none(void)
{
  return (contents.background_show_type == Background_Show_Type_None);
}

/*************************************************/
/* printstyle_show_in_tables_only()              */
/*                                               */
/* Ask if backgrounds should be plotted in       */
/* tables only.                                  */
/*                                               */
/* Returns:    1 if the Print Style dialogue     */
/*             specified backgrounds in tables   */
/*             only, else 0.                     */
/*************************************************/

int printstyle_show_in_tables_only(void)
{
  return (contents.background_show_type == Background_Show_Type_Tables);
}

/*************************************************/
/* printstyle_show_all()                         */
/*                                               */
/* Ask if all backgrounds should be plotted.     */
/*                                               */
/* Returns:    1 if the Print Style dialogue     */
/*             specified all backgrounds, else   */
/*             0.                                */
/*************************************************/

int printstyle_show_all(void)
{
  return (contents.background_show_type == Background_Show_Type_All);
}

/*************************************************/
626
/* printstyle_black_no_background()              */
627 628 629 630 631 632 633 634
/*                                               */
/* Ask if all body text should be plotted in     */
/* black.                                        */
/*                                               */
/* Returns:    1 if the Print Style dialogue     */
/*             specified black body text else 0. */
/*************************************************/

635
int printstyle_black_no_background(void)
636
{
637
  return contents.black_no_background;
638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685

  return 0;
}

/*************************************************/
/* printstyle_always_use_black()                 */
/*                                               */
/* Ask if all table text should be plotted in    */
/* black.                                        */
/*                                               */
/* Returns:    1 if the Print Style dialogue     */
/*             specified black table text, else  */
/*             0.                                */
/*************************************************/

int printstyle_always_use_black(void)
{
  return contents.always_use_black;

  return 0;
}

/*************************************************/
/* printstyle_return_dialogue_info()             */
/*                                               */
/* Returns information on the Print Style        */
/* dialogue, and its ancestor.                   */
/*                                               */
/* Parameters: Pointer to an ObjectId, in which  */
/*             the ID of the dialogue is placed; */
/*                                               */
/*             Pointer to an ObjectId, in which  */
/*             the ID of the ancestor window is  */
/*             placed.                           */
/*                                               */
/* Returns:    See parameters list, and note     */
/*             that the returned values will be  */
/*             0, and 0 if the Print Style       */
/*             dialogue is closed.               */
/*                                               */
/* Assumes:    Either pointer may be NULL.       */
/*************************************************/

void printstyle_return_dialogue_info(ObjectId * window, ObjectId * ancestor)
{
  if (window)   *window   = window_id;
  if (ancestor) *ancestor = ancestor_id;
}