/PyRTF/PropertySets.py

https://github.com/kaiquewdev/pyrtf
Python | 488 lines | 372 code | 96 blank | 20 comment | 37 complexity | fc6f24045dda910d807d25b830418709 MD5 | raw file
  1. """
  2. PropertySets group common attributes together, each property set is used to control a specific part of the rendering.
  3. PropertySets can be used in different elements of the document.
  4. For example the FramePropertySet is used in paragraphs, tables, cells, etc.
  5. The TextPropertySet can be used for text or in a Paragraph Style.
  6. """
  7. from types import StringType
  8. from copy import deepcopy
  9. #
  10. # We need some basic Type like fonts, colours and paper definitions
  11. #
  12. def MakeAttributeName( value ) :
  13. assert value and type( value ) is StringType
  14. value = value.replace( ' ', '' )
  15. return value
  16. class AttributedList( list ) :
  17. def __init__( self, accepted_type=None ) :
  18. super( AttributedList, self ).__init__()
  19. self.AcceptedType = accepted_type
  20. self._append = super( AttributedList, self ).append
  21. def append( self, *values ) :
  22. for value in values :
  23. if self.AcceptedType : assert isinstance( value, self.AcceptedType )
  24. self._append( value )
  25. name = getattr( value, 'Name', None )
  26. if name :
  27. name = MakeAttributeName( value.Name )
  28. setattr( self, name, value )
  29. def __deepcopy__( self, memo ) :
  30. result = self.__class__()
  31. result.append( *self[:] )
  32. return result
  33. class Colour :
  34. def __init__( self, name, red, green, blue ) :
  35. self.SetName ( name )
  36. self.SetRed ( red )
  37. self.SetGreen( green )
  38. self.SetBlue ( blue )
  39. def SetName( self, value ) :
  40. self.Name = value
  41. return self
  42. def SetRed( self, value ) :
  43. self.Red = value
  44. return self
  45. def SetGreen( self, value ) :
  46. self.Green = value
  47. return self
  48. def SetBlue( self, value ) :
  49. self.Blue = value
  50. return self
  51. class Colours( AttributedList ) :
  52. def __init__( self ) :
  53. super( Colours, self ).__init__( Colour )
  54. class Font :
  55. def __init__( self, name, family, character_set = 0, pitch = None, panose = None, alternate = None ) :
  56. self.SetName ( name )
  57. self.SetFamily ( family )
  58. self.SetCharacterSet( character_set )
  59. self.SetPitch ( pitch )
  60. self.SetPanose ( panose )
  61. self.SetAlternate ( alternate )
  62. def SetName( self, value ) :
  63. self.Name = value
  64. return self
  65. def SetFamily( self, value ) :
  66. self.Family = value
  67. return self
  68. def SetCharacterSet( self, value ) :
  69. self.CharacterSet = value
  70. return self
  71. def SetPitch( self, value ) :
  72. self.Pitch = value
  73. return self
  74. def SetPanose( self, value ) :
  75. self.Panose = value
  76. return self
  77. def SetAlternate( self, value ) :
  78. self.Alternate = value
  79. return self
  80. class Fonts( AttributedList ) :
  81. def __init__( self ) :
  82. super( Fonts, self ).__init__( Font )
  83. class Paper :
  84. def __init__( self, name, code, description, width, height ) :
  85. self.SetName ( name )
  86. self.SetCode ( code )
  87. self.SetDescription( description )
  88. self.SetWidth ( width )
  89. self.SetHeight ( height )
  90. def SetName( self, value ) :
  91. self.Name = value
  92. return self
  93. def SetCode( self, value ) :
  94. self.Code = value
  95. return self
  96. def SetDescription( self, value ) :
  97. self.Description = value
  98. return self
  99. def SetWidth( self, value ) :
  100. self.Width = value
  101. return self
  102. def SetHeight( self, value ) :
  103. self.Height = value
  104. return self
  105. class Papers( AttributedList ) :
  106. def __init__( self ) :
  107. super( Papers, self ).__init__( Paper )
  108. #
  109. # Then we have property sets which represent different aspects of Styles
  110. #
  111. class MarginsPropertySet :
  112. def __init__( self, top=None, left=None, bottom=None, right=None ) :
  113. self.SetTop ( top )
  114. self.SetLeft ( left )
  115. self.SetBottom( bottom )
  116. self.SetRight ( right )
  117. def SetTop( self, value ) :
  118. self.Top = value
  119. return self
  120. def SetLeft( self, value ) :
  121. self.Left = value
  122. return self
  123. def SetBottom( self, value ) :
  124. self.Bottom = value
  125. return self
  126. def SetRight( self, value ) :
  127. self.Right = value
  128. return self
  129. class ShadingPropertySet :
  130. HORIZONTAL = 1
  131. VERTICAL = 2
  132. FORWARD_DIAGONAL = 3
  133. BACKWARD_DIAGONAL = 4
  134. VERTICAL_CROSS = 5
  135. DIAGONAL_CROSS = 6
  136. DARK_HORIZONTAL = 7
  137. DARK_VERTICAL = 8
  138. DARK_FORWARD_DIAGONAL = 9
  139. DARK_BACKWARD_DIAGONAL = 10
  140. DARK_VERTICAL_CROSS = 11
  141. DARK_DIAGONAL_CROSS = 12
  142. PATTERNS = [ HORIZONTAL,
  143. VERTICAL,
  144. FORWARD_DIAGONAL,
  145. BACKWARD_DIAGONAL,
  146. VERTICAL_CROSS,
  147. DIAGONAL_CROSS,
  148. DARK_HORIZONTAL,
  149. DARK_VERTICAL,
  150. DARK_FORWARD_DIAGONAL,
  151. DARK_BACKWARD_DIAGONAL,
  152. DARK_VERTICAL_CROSS,
  153. DARK_DIAGONAL_CROSS ]
  154. def __init__( self, shading=None, pattern=None, foreground=None, background=None ) :
  155. self.SetShading ( shading )
  156. self.SetForeground( foreground )
  157. self.SetBackground( background )
  158. self.SetPattern ( pattern )
  159. def __deepcopy__( self, memo ) :
  160. return ShadingPropertySet( self.Shading,
  161. self.Foreground,
  162. self.Background,
  163. self.Pattern )
  164. def SetShading( self, value ) :
  165. self.Shading = value
  166. return self
  167. def SetPattern( self, value ) :
  168. assert value is None or value in self.PATTERNS
  169. self.Pattern = value
  170. return self
  171. def SetForeground( self, value ) :
  172. assert not value or isinstance( value, Colour )
  173. self.Foreground = value
  174. return self
  175. def SetBackground( self, value ) :
  176. assert not value or isinstance( value, Colour )
  177. self.Background = value
  178. return self
  179. class BorderPropertySet :
  180. SINGLE = 1
  181. DOUBLE = 2
  182. SHADOWED = 3
  183. DOUBLED = 4
  184. DOTTED = 5
  185. DASHED = 6
  186. HAIRLINE = 7
  187. STYLES = [ SINGLE, DOUBLE, SHADOWED, DOUBLED, DOTTED, DASHED, HAIRLINE ]
  188. def __init__( self, width=None, style=None, colour=None, spacing=None ) :
  189. self.SetWidth ( width )
  190. self.SetStyle ( style or self.SINGLE )
  191. self.SetColour ( colour )
  192. self.SetSpacing( spacing )
  193. def SetWidth( self, value ) :
  194. self.Width = value
  195. return self
  196. def SetStyle( self, value ) :
  197. assert value is None or value in self.STYLES
  198. self.Style = value
  199. return self
  200. def SetColour( self, value ) :
  201. assert value is None or isinstance( value, Colour )
  202. self.Colour = value
  203. return self
  204. def SetSpacing( self, value ) :
  205. self.Spacing = value
  206. return self
  207. class FramePropertySet :
  208. def __init__( self, top=None, left=None, bottom=None, right=None ) :
  209. self.SetTop ( top )
  210. self.SetLeft ( left )
  211. self.SetBottom( bottom )
  212. self.SetRight ( right )
  213. def SetTop( self, value ) :
  214. assert value is None or isinstance( value, BorderPropertySet )
  215. self.Top = value
  216. return self
  217. def SetLeft( self, value ) :
  218. assert value is None or isinstance( value, BorderPropertySet )
  219. self.Left = value
  220. return self
  221. def SetBottom( self, value ) :
  222. assert value is None or isinstance( value, BorderPropertySet )
  223. self.Bottom = value
  224. return self
  225. def SetRight( self, value ) :
  226. assert value is None or isinstance( value, BorderPropertySet )
  227. self.Right = value
  228. return self
  229. class TabPropertySet :
  230. DEFAULT_WIDTH = 720
  231. LEFT = 1
  232. RIGHT = 2
  233. CENTER = 3
  234. DECIMAL = 4
  235. ALIGNMENT = [ LEFT, RIGHT, CENTER, DECIMAL ]
  236. DOTS = 1
  237. HYPHENS = 2
  238. UNDERLINE = 3
  239. THICK_LINE = 4
  240. EQUAL_SIGN = 5
  241. LEADERS = [ DOTS, HYPHENS, UNDERLINE, THICK_LINE, EQUAL_SIGN ]
  242. def __init__( self, width=None, alignment=None, leader=None ) :
  243. self.SetWidth ( width )
  244. self.SetAlignment( alignment or self.LEFT )
  245. self.SetLeader ( leader )
  246. def SetWidth( self, value ) :
  247. self.Width = value
  248. return self
  249. def SetAlignment( self, value ) :
  250. assert value in self.ALIGNMENT
  251. self.Alignment = value
  252. return self
  253. def SetLeader( self, value ) :
  254. assert not value or value in self.LEADERS
  255. self.Leader = value
  256. return self
  257. class TextPropertySet :
  258. def __init__( self, font=None, size=None, bold=None, italic=None, underline=None, colour=None, frame=None, expansion=None ) :
  259. self.SetFont ( font )
  260. self.SetSize ( size )
  261. self.SetBold ( bold or False )
  262. self.SetItalic ( italic or False )
  263. self.SetUnderline ( underline or False )
  264. self.SetColour( colour )
  265. self.SetFrame ( frame )
  266. self.SetStrikeThrough ( False )
  267. self.SetDottedUnderline( False )
  268. self.SetDoubleUnderline( False )
  269. self.SetWordUnderline ( False )
  270. self.SetExpansion ( expansion )
  271. def Copy( self ) :
  272. return deepcopy( self )
  273. def __deepcopy__( self, memo ) :
  274. # the font must remain a reference to the same font that we are looking at
  275. # so we want to stop the recursiveness at this point and return an object
  276. # with the right references.
  277. result = TextPropertySet( self.Font,
  278. self.Size,
  279. self.Bold,
  280. self.Italic,
  281. self.Underline,
  282. self.Colour,
  283. deepcopy( self.Frame, memo ) )
  284. result.SetStrikeThrough( self.StrikeThrough )
  285. return result
  286. def SetFont( self, value ) :
  287. assert not value or isinstance( value, Font )
  288. self.Font = value
  289. return self
  290. def SetSize( self, value ) :
  291. self.Size = value
  292. return self
  293. def SetBold( self, value ) :
  294. self.Bold = False
  295. if value : self.Bold = True
  296. return self
  297. def SetItalic( self, value ) :
  298. self.Italic = False
  299. if value : self.Italic = True
  300. return self
  301. def SetUnderline( self, value ) :
  302. self.Underline = False
  303. if value : self.Underline = True
  304. return self
  305. def SetColour( self, value ) :
  306. assert value is None or isinstance( value, Colour )
  307. self.Colour = value
  308. return self
  309. def SetFrame( self, value ) :
  310. assert value is None or isinstance( value, BorderPropertySet )
  311. self.Frame = value
  312. return self
  313. def SetStrikeThrough( self, value ) :
  314. self.StrikeThrough = False
  315. if value : self.StrikeThrough = True
  316. return self
  317. def SetDottedUnderline( self, value ) :
  318. self.DottedUnderline = False
  319. if value : self.DottedUnderline = True
  320. return self
  321. def SetDoubleUnderline( self, value ) :
  322. self.DoubleUnderline = False
  323. if value : self.DoubleUnderline = True
  324. return self
  325. def SetWordUnderline( self, value ) :
  326. self.WordUnderline = False
  327. if value : self.WordUnderline = True
  328. return self
  329. def SetExpansion( self, value ) :
  330. self.Expansion = value
  331. return self
  332. class ParagraphPropertySet :
  333. LEFT = 1
  334. RIGHT = 2
  335. CENTER = 3
  336. JUSTIFY = 4
  337. DISTRIBUTE = 5
  338. ALIGNMENT = [ LEFT, RIGHT, CENTER, JUSTIFY, DISTRIBUTE ]
  339. def __init__( self, alignment=None, space_before=None, space_after=None, tabs=None, first_line_indent=None, left_indent=None, right_indent=None, page_break_before=None ) :
  340. self.SetAlignment ( alignment or self.LEFT )
  341. self.SetSpaceBefore( space_before )
  342. self.SetSpaceAfter ( space_after )
  343. self.Tabs = []
  344. if tabs : apply( self.SetTabs, tabs )
  345. self.SetFirstLineIndent( first_line_indent or None )
  346. self.SetLeftIndent ( left_indent or None )
  347. self.SetRightIndent ( right_indent or None )
  348. self.SetPageBreakBefore( page_break_before )
  349. self.SetSpaceBetweenLines( None )
  350. def Copy( self ) :
  351. return deepcopy( self )
  352. def SetAlignment( self, value ) :
  353. assert not value or value in self.ALIGNMENT
  354. self.Alignment = value or self.LEFT
  355. return self
  356. def SetSpaceBefore( self, value ) :
  357. self.SpaceBefore = value
  358. return self
  359. def SetSpaceAfter( self, value ) :
  360. self.SpaceAfter = value
  361. return self
  362. def SetTabs( self, *params ) :
  363. self.Tabs = params
  364. return self
  365. def SetFirstLineIndent( self, value ) :
  366. self.FirstLineIndent = value
  367. return self
  368. def SetLeftIndent( self, value ) :
  369. self.LeftIndent = value
  370. return self
  371. def SetRightIndent( self, value ) :
  372. self.RightIndent = value
  373. return self
  374. def SetSpaceBetweenLines( self, value ) :
  375. self.SpaceBetweenLines = value
  376. return self
  377. def SetPageBreakBefore( self, value ) :
  378. self.PageBreakBefore = False
  379. if value : self.PageBreakBefore = True
  380. return self
  381. # Some short cuts to make the code a bit easier to read
  382. MarginsPS = MarginsPropertySet
  383. ShadingPS = ShadingPropertySet
  384. BorderPS = BorderPropertySet
  385. FramePS = FramePropertySet
  386. TabPS = TabPropertySet
  387. TextPS = TextPropertySet
  388. ParagraphPS = ParagraphPropertySet