1#Copyright ReportLab Europe Ltd. 2000-2017 2#see license.txt for license details 3#history https://hg.reportlab.com/hg-public/reportlab/log/tip/docs/userguide/ch3_pdffeatures.py 4from tools.docco.rl_doc_utils import * 5 6heading1("Exposing PDF Special Capabilities") 7disc("""PDF provides a number of features to make electronic 8 document viewing more efficient and comfortable, and 9 our library exposes a number of these.""") 10 11heading2("Forms") 12disc("""The Form feature lets you create a block of graphics and text 13 once near the start of a PDF file, and then simply refer to it on 14 subsequent pages. If you are dealing with a run of 5000 repetitive 15 business forms - for example, one-page invoices or payslips - you 16 only need to store the backdrop once and simply draw the changing 17 text on each page. Used correctly, forms can dramatically cut 18 file size and production time, and apparently even speed things 19 up on the printer. 20 """) 21disc("""Forms do not need to refer to a whole page; anything which 22 might be repeated often should be placed in a form.""") 23disc("""The example below shows the basic sequence used. A real 24 program would probably define the forms up front and refer to 25 them from another location.""") 26 27 28eg(examples.testforms) 29 30heading2("Links and Destinations") 31disc("""PDF supports internal hyperlinks. There is a very wide 32 range of link types, destination types and events which 33 can be triggered by a click. At the moment we just 34 support the basic ability to jump from one part of a document 35 to another, and to control the zoom level of the window after 36 the jump. The bookmarkPage method defines a destination that 37 is the endpoint of a jump.""") 38#todo("code example here...") 39 40eg(""" 41 canvas.bookmarkPage(name, 42 fit="Fit", 43 left=None, 44 top=None, 45 bottom=None, 46 right=None, 47 zoom=None 48 ) 49""") 50disc(""" 51By default the $bookmarkPage$ method defines the page itself as the 52destination. After jumping to an endpoint defined by bookmarkPage, 53the PDF browser will display the whole page, scaling it to fit the 54screen:""") 55 56eg("""canvas.bookmarkPage(name)""") 57 58disc("""The $bookmarkPage$ method can be instructed to display the 59page in a number of different ways by providing a $fit$ 60parameter.""") 61 62eg("") 63 64t = Table([ 65 ['fit','Parameters Required','Meaning'], 66 ['Fit',None,'Entire page fits in window (the default)'], 67 ['FitH','top','Top coord at top of window, width scaled to fit'], 68 ['FitV','left','Left coord at left of window, height scaled to fit'], 69 ['FitR','left bottom right top','Scale window to fit the specified rectangle'], 70 ['XYZ','left top zoom','Fine grained control. If you omit a parameter\nthe PDF browser interprets it as "leave as is"'] 71 ]) 72t.setStyle(TableStyle([ 73 ('FONT',(0,0),(-1,1),'Times-Bold',10,12), 74 ('VALIGN',(0,0),(-1,-1),'MIDDLE'), 75 ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black), 76 ('BOX', (0,0), (-1,-1), 0.25, colors.black), 77 ])) 78 79getStory().append(t) 80caption("""Table <seq template="%(Chapter)s-%(Table+)s"/> - Required attributes for different fit types""") 81 82disc(""" 83Note : $fit$ settings are case-sensitive so $fit="FIT"$ is invalid 84""") 85 86 87disc(""" 88Sometimes you want the destination of a jump to be some part of a page. 89The $FitR$ fit allows you to identify a particular rectangle, scaling 90the area to fit the entire page. 91""") 92 93disc(""" 94To set the display to a particular x and y coordinate of the page and to 95control the zoom directly use fit="XYZ". 96""") 97 98eg(""" 99canvas.bookmarkPage('my_bookmark',fit="XYZ",left=0,top=200) 100""") 101 102 103 104disc(""" 105This destination is at the leftmost of the page with the top of the screen 106at position 200. Because $zoom$ was not set the zoom remains at whatever the 107user had it set to. 108""") 109 110eg(""" 111canvas.bookmarkPage('my_bookmark',fit="XYZ",left=0,top=200,zoom=2) 112""") 113 114disc("""This time zoom is set to expand the page 2X its normal size.""") 115 116disc(""" 117Note : Both $XYZ$ and $FitR$ fit types require that their positional parameters 118($top, bottom, left, right$) be specified in terms of the default user space. 119They ignore any geometric transform in effect in the canvas graphic state. 120""") 121 122 123 124pencilnote() 125 126disc(""" 127<i>Note:</i> Two previous bookmark methods are supported but deprecated now 128that bookmarkPage is so general. These are $bookmarkHorizontalAbsolute$ 129and $bookmarkHorizontal$. 130""") 131 132heading3("Defining internal links") 133eg(""" 134 canvas.linkAbsolute(contents, destinationname, Rect=None, addtopage=1, name=None, 135 thickness=0, color=None, dashArray=None, **kw) 136 """) 137 138disc(""" 139 The $linkAbsolute$ method defines a starting point for a jump. When the user 140 is browsing the generated document using a dynamic viewer (such as Acrobat Reader) 141 when the mouse is clicked when the pointer is within the rectangle specified 142 by $Rect$ the viewer will jump to the endpoint associated with $destinationname$. 143 As in the case with $bookmarkHorizontalAbsolute$ the rectangle $Rect$ must be 144 specified in terms of the default user space. The $contents$ parameter specifies 145 a chunk of text which displays in the viewer if the user left-clicks on the region. 146""") 147 148disc(""" 149The rectangle $Rect$ must be specified in terms of a tuple ^(x1,y1,x2,y2)^ identifying 150the lower left and upper right points of the rectangle in default user space. 151""") 152 153disc(""" 154For example the code 155""") 156 157eg(""" 158 canvas.bookmarkPage("Meaning_of_life") 159""") 160 161disc(""" 162defines a location as the whole of the current page with the identifier 163$Meaning_of_life$. To create a rectangular link to it while drawing a possibly 164different page, we would use this code: 165""") 166 167eg(""" 168 canvas.linkAbsolute("Find the Meaning of Life", "Meaning_of_life", 169 (inch, inch, 6*inch, 2*inch)) 170""") 171 172disc(""" 173By default during interactive viewing a rectangle appears around the 174link. Use the keyword argument $Border='[0 0 0]'$ to 175suppress the visible rectangle around the during viewing link. 176For example 177""") 178 179eg(""" 180 canvas.linkAbsolute("Meaning of Life", "Meaning_of_life", 181 (inch, inch, 6*inch, 2*inch), Border='[0 0 0]') 182""") 183 184disc("""The $thickness$, $color$ and $dashArray$ arguments may be used alternately 185to specify a border if no Border argument is specified. 186If Border is specified it must be either a string representation of a PDF 187array or a $PDFArray$ (see the pdfdoc module). The $color$ argument (which should be a $Color$ instance) is equivalent to a keyword argument $C$ which should resolve to a PDF color definition (Normally a three entry PDF array). 188""") 189disc("""The $canvas.linkRect$ method is similar in intent to the $linkAbsolute$ method, but has an extra argument $relative=1$ so is intended to obey the local userspace transformation.""") 190 191heading2("Outline Trees") 192disc("""Acrobat Reader has a navigation page which can hold a 193 document outline; it should normally be visible when you 194 open this guide. We provide some simple methods to add 195 outline entries. Typically, a program to make a document 196 (such as this user guide) will call the method 197 $canvas.addOutlineEntry(^self, title, key, level=0, 198 closed=None^)$ as it reaches each heading in the document. 199 """) 200 201disc("""^title^ is the caption which will be displayed in 202 the left pane. The ^key^ must be a string which is 203 unique within the document and which names a bookmark, 204 as with the hyperlinks. The ^level^ is zero - the 205 uppermost level - unless otherwise specified, and 206 it is an error to go down more than one level at a time 207 (for example to follow a level 0 heading by a level 2 208 heading). Finally, the ^closed^ argument specifies 209 whether the node in the outline pane is closed 210 or opened by default.""") 211 212disc("""The snippet below is taken from the document template 213 that formats this user guide. A central processor looks 214 at each paragraph in turn, and makes a new outline entry 215 when a new chapter occurs, taking the chapter heading text 216 as the caption text. The key is obtained from the 217 chapter number (not shown here), so Chapter 2 has the 218 key 'ch2'. The bookmark to which the 219 outline entry points aims at the whole page, but it could 220 as easily have been an individual paragraph. 221 """) 222 223eg(""" 224#abridged code from our document template 225if paragraph.style == 'Heading1': 226 self.chapter = paragraph.getPlainText() 227 key = 'ch%d' % self.chapterNo 228 self.canv.bookmarkPage(key) 229 self.canv.addOutlineEntry(paragraph.getPlainText(), 230 key, 0, 0) 231 """) 232 233heading2("Page Transition Effects") 234 235 236eg(""" 237 canvas.setPageTransition(self, effectname=None, duration=1, 238 direction=0,dimension='H',motion='I') 239 """) 240 241disc(""" 242The $setPageTransition$ method specifies how one page will be replaced with 243the next. By setting the page transition effect to "dissolve" for example 244the current page will appear to melt away when it is replaced by the next 245page during interactive viewing. These effects are useful in spicing up 246slide presentations, among other places. 247Please see the reference manual for more detail on how to use this method. 248""") 249 250heading2("Internal File Annotations") 251 252eg(""" 253 canvas.setAuthor(name) 254 canvas.setTitle(title) 255 canvas.setSubject(subj) 256 """) 257 258disc(""" 259These methods have no automatically seen visible effect on the document. 260They add internal annotations to the document. These annotations can be 261viewed using the "Document Info" menu item of the browser and they also can 262be used as a simple standard way of providing basic information about the 263document to archiving software which need not parse the entire 264file. To find the annotations view the $*.pdf$ output file using a standard 265text editor (such as $notepad$ on MS/Windows or $vi$ or $emacs$ on unix) and look 266for the string $/Author$ in the file contents. 267""") 268 269eg(examples.testannotations) 270 271disc(""" 272If you want the subject, title, and author to automatically display 273in the document when viewed and printed you must paint them onto the 274document like any other text. 275""") 276 277illust(examples.annotations, "Setting document internal annotations") 278 279heading2("Encryption") 280 281heading3("About encrypting PDF files") 282 283disc(""" 284Adobe's PDF standard allows you to do three related things to a PDF file when you encrypt it: 285""") 286bullet("""Apply password protection to it, so a user must supply a valid password before being able to read it, 287""") 288bullet("""Encrypt the contents of the file to make it useless until it is decrypted, and 289""") 290bullet("""Control whether the user can print, copy and paste or modify the document while viewing it. 291""") 292 293disc(""" 294The PDF security handler allows two different passwords to be specified for a document: 295""") 296 297bullet("""The 'owner' password (aka the 'security password' or 'master password') 298""") 299 300bullet("""The 'user' password (aka the 'open password') 301""") 302 303disc(""" 304When a user supplies either one of these passwords, the PDF file will be opened, decrypted and displayed on 305screen. 306""") 307 308disc(""" 309If the owner password is supplied, then the file is opened with full control - you can do anything to it, 310including changing the security settings and passwords, or re-encrypting it with a new password. 311""") 312 313disc(""" 314 If the user password was the one that was supplied, you open it up in a more restricted mode. The restrictions were put in 315place when the file was encrypted, and will either allow or deny the user permission to do the following: 316""") 317 318bullet(""" 319Modifying the document's contents 320""") 321 322bullet(""" 323Copying text and graphics from the document 324""") 325 326bullet(""" 327Adding or modifying text annotations and interactive form fields 328""") 329 330bullet(""" 331Printing the document 332""") 333 334disc(""" 335Note that all password protected PDF files are encrypted, but not all encrypted PDFs are password protected. If 336a document's user password is an empty string, there will be no prompt for the password when the file is 337opened. If you only secure a document with the owner password, there will also not be a prompt for the 338password when you open the file. If the owner and user passwords are set to the same string when encrypting 339the PDF file, the document will always open with the user access privileges. This means that it is possible to 340create a file which, for example, is impossible for anyone to print out, even the person who created it. 341""") 342 343t = Table([ 344 ['Owner Password \nset?','User Password \nset?','Result'], 345 ['Y','-','No password required when opening file. \nRestrictions apply to everyone.'], 346 ['-','Y','User password required when opening file. \nRestrictions apply to everyone.'], 347 ['Y','Y','A password required when opening file. \nRestrictions apply only if user password supplied.'], 348 ],[90, 90, 260]) 349 350t.setStyle(TableStyle([ 351 ('FONT',(0,0),(-1,0),'Times-Bold',10,12), 352 ('VALIGN',(0,0),(-1,-1),'MIDDLE'), 353 ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black), 354 ('BOX', (0,0), (-1,-1), 0.25, colors.black), 355 ])) 356 357getStory().append(t) 358 359disc(""" 360When a PDF file is encrypted, encryption is applied to all the strings and streams in the file. This prevents 361people who don't have the password from simply removing the password from the PDF file to gain access to it - 362it renders the file useless unless you actually have the password. 363""") 364disc(""" 365PDF's standard encryption methods use the 366MD5 message digest algorithm (as described in RFC 1321, The MD5 Message-Digest Algorithm) and an 367encryption algorithm known as RC4. RC4 is a symmetric stream cipher - the same algorithm is used both for 368encryption and decryption, and the algorithm does not change the length of the data. 369""") 370 371heading3("How To Use Encryption") 372 373disc(""" 374 Documents can be encrypted by passing an argument to the canvas object. 375 """) 376 377disc(""" 378 If the argument is a string object, it is used as the User password to the PDF. 379 """) 380 381disc(""" 382 The argument can also be an instance of the class $reportlab.lib.pdfencrypt.StandardEncryption$, 383 which allows more finegrained control over encryption settings. 384 """) 385 386disc(""" 387 The $StandardEncryption$ constructor takes the following arguments: 388 """) 389 390eg(""" 391 def __init__(self, userPassword, 392 ownerPassword=None, 393 canPrint=1, 394 canModify=1, 395 canCopy=1, 396 canAnnotate=1, 397 strength=40): 398 """) 399 400disc(""" 401 The $userPassword$ and $ownerPassword$ parameters set the relevant password on the encrypted PDF. 402 """) 403 404disc(""" 405 The boolean flags $canPrint$, $canModify$, $canCopy$, $canAnnotate$ determine wether a user can 406 perform the corresponding actions on the PDF when only a user password has been supplied. 407 """) 408disc(""" 409 If the user supplies the owner password while opening the PDF, all actions can be performed regardless 410 of the flags. 411 """) 412 413heading3("Example") 414 415disc(""" 416 To create a document named hello.pdf with a user password of 'rptlab' on which printing is not allowed, 417 use the following code: 418 """) 419 420eg(""" 421from reportlab.pdfgen import canvas 422from reportlab.lib import pdfencrypt 423 424enc=pdfencrypt.StandardEncryption("rptlab",canPrint=0) 425 426def hello(c): 427 c.drawString(100,100,"Hello World") 428c = canvas.Canvas("hello.pdf",encrypt=enc) 429hello(c) 430c.showPage() 431c.save() 432 433""") 434 435heading2("Interactive Forms") 436heading3("Overview of Interactive Forms") 437 438disc("""The PDF standard allows for various kinds of interactive elements, 439the ReportLab toolkit currently supports only a fraction of the possibilities and should be considered a work in progress. 440At present we allow choices with 441<i>checkbox</i>, <i>radio</i>, <i>choice</i> & <i>listbox</i> widgets; text values can be entered with a 442<i>textfield</i> widget. All the widgets are created by calling methods on the <i>canvas.acroform</i> property.""" 443) 444heading3("Example") 445disc("This shows the basic mechanism of creating an interactive element on the current page.") 446eg(""" 447 canvas.acroform.checkbox( 448 name='CB0', 449 tooltip='Field CB0', 450 checked=True, 451 x=72,y=72+4*36, 452 buttonStyle='diamond', 453 borderStyle='bevelled', 454 borderWidth=2, 455 borderColor=red, 456 fillColor=green, 457 textColor=blue, 458 forceBorder=True) 459""") 460alStyle=TableStyle([ 461 ('SPAN',(0,0),(-1,0)), 462 ('FONT',(0,0),(-1,0),'Helvetica-Bold',10,12), 463 ('FONT',(0,1),(-1,1),'Helvetica-BoldOblique',8,9.6), 464 ('FONT',(0,2),(0,-1),'Helvetica-Bold',7,8.4), 465 ('FONT',(1,2),(1,-1),'Helvetica',7,8.4), 466 ('FONT',(2,2),(2,-1),'Helvetica-Oblique',7,8.4), 467 ('ALIGN',(0,0),(-1,0),'CENTER'), 468 ('ALIGN',(1,1),(1,1),'CENTER'), 469 ('INNERGRID', (0,0), (-1,-1), 0.25, colors.black), 470 ('BOX', (0,0), (-1,-1), 0.25, colors.black), 471 ]) 472 473disc("""<b>NB</b> note that the <i>acroform</i> canvas property is created automatically on demand and that there is only one form allowd in a document.""") 474heading3("Checkbox Usage") 475disc("""The <i>canvas.acroform.checkbox</i> method creates a <i>checkbox</i> widget on the current page. The value of the checkbox is either <b>YES</b> or <b>OFF</b>. 476The arguments are""") 477t = Table([ 478 ['canvas.acroform.checkbox parameters','',''], 479 ['Parameter','Meaning','Default'], 480 ["name","the parameter's name","None"], 481 ["x","the horizontal position on the page (absolute coordinates)","0"], 482 ["y","the vertical position on the page (absolute coordinates)","0"], 483 ["size","The outline dimensions size x size","20"], 484 ["checked","if True the checkbox is initially checked","False"], 485 ["buttonStyle","the checkbox style (see below)","'check'"], 486 ["shape","The outline of the widget (see below)","'square'"], 487 ["fillColor","colour to be used to fill the widget","None"], 488 ["textColor","the colour of the symbol or text","None"], 489 ["borderWidth","as it says","1"], 490 ["borderColor","the widget's border colour","None"], 491 ["borderStyle","The border style name","'solid'"], 492 ["tooltip","The text to display when hovering over the widget","None"], 493 ["annotationFlags","blank separated string of annotation flags","'print'"], 494 ["fieldFlags","Blank separated field flags (see below)","'required'"], 495 ["forceBorder","when true a border force a border to be drawn","False"], 496 ["relative","if true obey the current canvas transform","False"], 497 ["dashLen ","the dashline to be used if the borderStyle=='dashed'","3"], 498 ],[90, 260, 90],style=alStyle,repeatRows=2) 499getStory().append(t) 500 501heading3("Radio Usage") 502disc("""The <i>canvas.acroform.radio</i> method creates a <i>radio</i> widget on the current page. The value of the radio is the value of the radio group's 503selected value or <b>OFF</b> if none are selected. 504The arguments are""") 505t = Table([ 506 ['canvas.acroform.radio parameters','',''], 507 ['Parameter','Meaning','Default'], 508 ["name","the radio's group (ie parameter) name","None"], 509 ["value","the radio's group name","None"], 510 ["x","the horizontal position on the page (absolute coordinates)","0"], 511 ["y","the vertical position on the page (absolute coordinates)","0"], 512 ["size","The outline dimensions size x size","20"], 513 ["selected","if True this radio is the selected one in its group","False"], 514 ["buttonStyle","the checkbox style (see below)","'check'"], 515 ["shape","The outline of the widget (see below)","'square'"], 516 ["fillColor","colour to be used to fill the widget","None"], 517 ["textColor","the colour of the symbol or text","None"], 518 ["borderWidth","as it says","1"], 519 ["borderColor","the widget's border colour","None"], 520 ["borderStyle","The border style name","'solid'"], 521 ["tooltip","The text to display when hovering over the widget","None"], 522 ["annotationFlags","blank separated string of annotation flags","'print'"], 523 ["fieldFlags","Blank separated field flags (see below)","'noToggleToOff required radio'"], 524 ["forceBorder","when true a border force a border to be drawn","False"], 525 ["relative","if true obey the current canvas transform","False"], 526 ["dashLen ","the dashline to be used if the borderStyle=='dashed'","3"], 527 ],[90, 260, 90],style=alStyle,repeatRows=2) 528getStory().append(t) 529heading3("Listbox Usage") 530disc("""The <i>canvas.acroform.listbox</i> method creates a <i>listbox</i> widget on the current page. The listbox contains a 531list of options one or more of which (depending on fieldFlags) may be selected. 532""") 533t = Table([ 534 ['canvas.acroform.listbox parameters','',''], 535 ['Parameter','Meaning','Default'], 536 ["name","the radio's group (ie parameter) name","None"], 537 ["options","List or tuple of avaiable options","[]"], 538 ["value","Singleton or list of strings of selected options","[]"], 539 ["x","the horizontal position on the page (absolute coordinates)","0"], 540 ["y","the vertical position on the page (absolute coordinates)","0"], 541 ["width","The widget width","120"], 542 ["height","The widget height","36"], 543 ["fontName","The name of the type 1 font to be used","'Helvetica'"], 544 ["fontSize","The size of font to be used","12"], 545 ["fillColor","colour to be used to fill the widget","None"], 546 ["textColor","the colour of the symbol or text","None"], 547 ["borderWidth","as it says","1"], 548 ["borderColor","the widget's border colour","None"], 549 ["borderStyle","The border style name","'solid'"], 550 ["tooltip","The text to display when hovering over the widget","None"], 551 ["annotationFlags","blank separated string of annotation flags","'print'"], 552 ["fieldFlags","Blank separated field flags (see below)","''"], 553 ["forceBorder","when true a border force a border to be drawn","False"], 554 ["relative","if true obey the current canvas transform","False"], 555 ["dashLen ","the dashline to be used if the borderStyle=='dashed'","3"], 556 ],[90, 260, 90],style=alStyle,repeatRows=2) 557getStory().append(t) 558heading3("Choice Usage") 559disc("""The <i>canvas.acroform.choice</i> method creates a <i>dropdown</i> widget on the current page. The dropdown contains a 560list of options one or more of which (depending on fieldFlags) may be selected. If you add <i>edit</i> to the <i>fieldFlags</i> 561then the result may be edited. 562""") 563t = Table([ 564 ['canvas.acroform.choice parameters','',''], 565 ['Parameter','Meaning','Default'], 566 ["name","the radio's group (ie parameter) name","None"], 567 ["options","List or tuple of avaiable options","[]"], 568 ["value","Singleton or list of strings of selected options","[]"], 569 ["x","the horizontal position on the page (absolute coordinates)","0"], 570 ["y","the vertical position on the page (absolute coordinates)","0"], 571 ["width","The widget width","120"], 572 ["height","The widget height","36"], 573 ["fontName","The name of the type 1 font to be used","'Helvetica'"], 574 ["fontSize","The size of font to be used","12"], 575 ["fillColor","colour to be used to fill the widget","None"], 576 ["textColor","the colour of the symbol or text","None"], 577 ["borderWidth","as it says","1"], 578 ["borderColor","the widget's border colour","None"], 579 ["borderStyle","The border style name","'solid'"], 580 ["tooltip","The text to display when hovering over the widget","None"], 581 ["annotationFlags","blank separated string of annotation flags","'print'"], 582 ["fieldFlags","Blank separated field flags (see below)","'combo'"], 583 ["forceBorder","when true a border force a border to be drawn","False"], 584 ["relative","if true obey the current canvas transform","False"], 585 ["dashLen ","the dashline to be used if the borderStyle=='dashed'","3"], 586 ["maxlen ","None or maximum length of the widget value","None"], 587 ],[90, 260, 90],style=alStyle,repeatRows=2) 588getStory().append(t) 589 590heading3("Textfield Usage") 591disc("""The <i>canvas.acroform.textfield</i> method creates a <i>textfield</i> entry widget on the current page. The textfield may be edited 592to change tha value of the widget 593""") 594t = Table([ 595 ['canvas.acroform.textfield parameters','',''], 596 ['Parameter','Meaning','Default'], 597 ["name","the radio's group (ie parameter) name","None"], 598 ["value","Value of the text field","''"], 599 ["maxlen ","None or maximum length of the widget value","100"], 600 ["x","the horizontal position on the page (absolute coordinates)","0"], 601 ["y","the vertical position on the page (absolute coordinates)","0"], 602 ["width","The widget width","120"], 603 ["height","The widget height","36"], 604 ["fontName","The name of the type 1 font to be used","'Helvetica'"], 605 ["fontSize","The size of font to be used","12"], 606 ["fillColor","colour to be used to fill the widget","None"], 607 ["textColor","the colour of the symbol or text","None"], 608 ["borderWidth","as it says","1"], 609 ["borderColor","the widget's border colour","None"], 610 ["borderStyle","The border style name","'solid'"], 611 ["tooltip","The text to display when hovering over the widget","None"], 612 ["annotationFlags","blank separated string of annotation flags","'print'"], 613 ["fieldFlags","Blank separated field flags (see below)","''"], 614 ["forceBorder","when true a border force a border to be drawn","False"], 615 ["relative","if true obey the current canvas transform","False"], 616 ["dashLen ","the dashline to be used if the borderStyle=='dashed'","3"], 617 ],[90, 260, 90],style=alStyle,repeatRows=2) 618getStory().append(t) 619 620heading3("Button styles") 621disc("""The button style argument indicates what style of symbol should appear in the button when it is selected. There are several choices""") 622eg(""" check 623 cross 624 circle 625 star 626 diamond 627""") 628disc("""note that the document renderer can make some of these symbols wrong for their intended application. Acrobat reader 629prefers to use its own rendering on top of what the specification says should be shown (especially when the forms hihlighting features are used""") 630 631heading3("Widget shape") 632disc("""The shape argument describes how the outline of the checkbox or radio widget should appear you can use""") 633eg(""" circle 634 square 635""") 636 637disc("""The renderer may make its own decisions about how the widget should look; so Acrobat Reader prefers circular outlines for radios.""") 638 639heading3("Border style") 640disc("""The borderStyle argument changes the 3D appearance of the widget on the page alternatives are""") 641eg(""" solid 642 dashed 643 inset 644 bevelled 645 underlined 646 """) 647heading3("fieldFlags Argument") 648disc("""The fieldFlags arguments can be an integer or a string containing blank separate tokens the values are shown in the table below. For 649more information consult the PDF specification.""") 650t = Table([ 651 ['Field Flag Tokens and values','',''], 652 ['Token','Meaning','Value'], 653 ["readOnly","The widget is read only","1<<0"], 654 ["required","the widget is required","1<<1"], 655 ["noExport","don't export the widget value","1<<2"], 656 ["noToggleToOff","radios one only must be on","1<<14"], 657 ["radio","added by the radio method","1<<15"], 658 ["pushButton","if the button is a push button","1<<16"], 659 ["radiosInUnison","radios with the same value toggle together","1<<25"], 660 ["multiline","for multiline text widget","1<<12"], 661 ["password","password textfield","1<<13"], 662 ["fileSelect","file selection widget","1<<20"], #1.4 663 ["doNotSpellCheck","as it says","1<<22"], #1.4 664 ["doNotScroll","text fields do not scroll","1<<23"], #1.4 665 ["comb","make a comb style text based on the maxlen value","1<<24"], #1.5 666 ["richText","if rich text is used","1<<25"], #1.5 667 ["combo","for choice fields","1<<17"], 668 ["edit","if the choice is editable","1<<18"], 669 ["sort","if the values should be sorted","1<<19"], 670 ["multiSelect","if the choice allows multi-select","1<<21"], #1.4 671 ["commitOnSelChange","not used by reportlab","1<<26"], #1.5 672 ],[90, 260, 90],style=alStyle,repeatRows=2) 673getStory().append(t) 674heading3("annotationFlags Argument") 675disc("""PDF widgets are annotations and have annotation properties these are shown in the table below""") 676t = Table([ 677 ['Annotation Flag Tokens and values','',''], 678 ['Token','Meaning','Value'], 679 ["invisible","The widget is not shown","1<<0"], 680 ["hidden","The widget is hidden","1<<1"], 681 ["print","The widget will print","1<<2"], 682 ["nozoom","The annotation will notscale with the rendered page","1<<3"], 683 ["norotate","The widget won't rotate with the page","1<<4"], 684 ["noview","Don't render the widget","1<<5"], 685 ["readonly","Widget cannot be interacted with","1<<6"], 686 ["locked","The widget cannot be changed","1<<7"], #1.4 687 ["togglenoview","Teh widget may be viewed after some events","1<<8"], #1.9 688 ["lockedcontents","The contents of the widget are fixed","1<<9"], #1.7 689 ],[90, 260, 90],style=alStyle) 690getStory().append(t) 691