1<?php 2/** 3 * ODTTextOutlineStyle: class for ODT text outline styles. 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author LarsDW223 7 */ 8 9require_once DOKU_INC.'lib/plugins/odt/ODT/XMLUtil.php'; 10require_once DOKU_INC.'lib/plugins/odt/ODT/styles/ODTStyle.php'; 11require_once DOKU_INC.'lib/plugins/odt/ODT/styles/ODTTextStyle.php'; 12 13/** 14 * The ODTTextOutlineStyle class 15 */ 16class ODTTextOutlineStyle extends ODTStyle 17{ 18 static $outline_fields = array( 19 // Fields belonging to "text:outline-style" 20 'style-name' => array ('style:name', 'style', false), 21 22 // Fields belonging to "text:outline-level-style" 23 'level' => array ('text:level', 'level', true), 24 'text-style-name' => array ('text:style-name', 'level', true), 25 'num-format' => array ('style:num-format', 'level', true), 26 'num-letter-sync' => array ('style:num-letter-sync', 'level', true), 27 'num-prefix' => array ('style:num-prefix', 'level', true), 28 'num-suffix' => array ('style:num-suffix', 'level', true), 29 'display-levels' => array ('text:display-levels', 'level', true), 30 'start-value' => array ('text:start-value', 'level', true), 31 32 // Fields belonging to "style-list-level-properties" 33 'text-align' => array ('fo:text-align', 'level-list', true), 34 'text-space-before' => array ('text:space-before', 'level-list', true), 35 'text-min-label-width' => array ('text:min-label-width', 'level-list', true), 36 'text-min-label-distance' => array ('text:min-label-distance', 'level-list', true), 37 'font-name' => array ('style:font-name', 'level-list', true), 38 'width' => array ('fo:width', 'level-list', true), 39 'height' => array ('fo:height', 'level-list', true), 40 'vertical-rel' => array ('style:vertical-rel', 'level-list', true), 41 'vertical-pos' => array ('style:vertical-pos', 'level-list', true), 42 'list-level-position-and-space-mode' => array ('text:list-level-position-and-space-mode', 'level-list', true), 43 44 // Fields belonging to "style:list-level-label-alignment" 45 'label-followed-by' => array ('text:label-followed-by', 'level-label', true), 46 'list-tab-stop-position' => array ('text:list-tab-stop-position', 'level-label', true), 47 'text-indent' => array ('fo:text-indent', 'level-label', true), 48 'margin-left' => array ('fo:margin-left', 'level-label', true), 49 ); 50 protected $outline_level_styles = array(); 51 52 /** 53 * Get the element name for the ODT XML encoding of the style. 54 */ 55 public function getElementName() { 56 return 'text:outline-style'; 57 } 58 59 /** 60 * Set style properties by importing values from a properties array. 61 * Properties might be disabled by setting them in $disabled. 62 * The style must have been previously created. 63 * 64 * @param $properties Properties to be imported 65 * @param $disabled Properties to be ignored 66 */ 67 public function importProperties($properties, $disabled=array()) { 68 $this->importPropertiesInternal(ODTTextStyle::getTextProperties (), $properties, $disabled); 69 $this->importPropertiesInternal(self::$outline_fields, $properties, $disabled); 70 } 71 72 /** 73 * Check if a style is a common style. 74 * 75 * @return bool Is common style 76 */ 77 public function mustBeCommonStyle() { 78 return false; 79 } 80 81 /** 82 * Set a property. 83 * 84 * @param $property The name of the property to set 85 * @param $value New value to set 86 */ 87 public function setProperty($property, $value) { 88 $text_fields = ODTTextStyle::getTextProperties (); 89 if (array_key_exists ($property, $style_fields)) { 90 $this->setPropertyInternal 91 ($property, $text_fields [$property][0], $value, $text_fields [$property][1]); 92 return; 93 } 94 if (array_key_exists ($property, self::$outline_fields)) { 95 $this->setPropertyInternal 96 ($property, self::$outline_fields [$property][0], $value, self::$outline_fields [$property][1]); 97 return; 98 } 99 } 100 101 /** 102 * Create new style by importing ODT style definition. 103 * 104 * @param $xmlCode Style definition in ODT XML format 105 * @return ODTStyle New specific style 106 */ 107 static public function importODTStyle($xmlCode) { 108 $style = new ODTTextOutlineStyle(); 109 $attrs = 0; 110 111 $open = XMLUtil::getElementOpenTag('text:outline-style', $xmlCode); 112 if (!empty($open)) { 113 // This properties are stored in the properties of ODTStyle 114 $attrs += $style->importODTStyleInternal(self::$outline_fields, $open); 115 } 116 117 $pos = 0; 118 $end = 0; 119 $max = strlen ($xmlCode); 120 $level = XMLUtil::getElement('text:outline-level-style', substr($xmlCode, $pos), $end); 121 $pos += $end; 122 $text_fields = ODTTextStyle::getTextProperties (); 123 124 $check = 0; 125 while (isset($level)) 126 { 127 // We can have multiple level definitons with all the same properties. 128 // So we store this in our own array. The "text:level" is the array key. 129 if (!empty($level)) { 130 $properties = array(); 131 $attrs += $style->importODTStyleInternal($text_fields, $level, $properties); 132 $attrs += $style->importODTStyleInternal(self::$outline_fields, $level, $properties); 133 134 // Assign properties array to our level array 135 $level_number = $style->getPropertyInternal('level', $properties); 136 $style->outline_level_styles [$level_number] = $properties; 137 } 138 139 // Get XML code for next level. 140 $level = XMLUtil::getElement('text:outline-level-style', substr($xmlCode, $pos), $end); 141 $pos += $end; 142 if ($pos >= $max) { 143 break; 144 } 145 } 146 147 // If style has no meaningfull content then throw it away 148 if ( $attrs == 0 ) { 149 return NULL; 150 } 151 152 return $style; 153 } 154 155 /** 156 * Encode current style values in a string and return it. 157 * 158 * @return string ODT XML encoded style 159 */ 160 public function toString() { 161 $style = ''; 162 $levels = ''; 163 164 // The style properties are stored in the properties of ODTStyle 165 foreach ($this->properties as $property => $items) { 166 $style .= $items ['odt_property'].'="'.$items ['value'].'" '; 167 } 168 169 // The level properties are stored in our level properties 170 foreach ($this->outline_level_styles as $key => $properties) { 171 $level = ''; 172 $level_list = ''; 173 $level_label = ''; 174 $text = ''; 175 foreach ($properties as $property => $items) { 176 switch ($items ['section']) { 177 case 'level': 178 $level .= $items ['odt_property'].'="'.$items ['value'].'" '; 179 break; 180 case 'level-list': 181 $level_list .= $items ['odt_property'].'="'.$items ['value'].'" '; 182 break; 183 case 'level-label': 184 $level_label .= $items ['odt_property'].'="'.$items ['value'].'" '; 185 break; 186 case 'text': 187 $text .= $items ['odt_property'].'="'.$items ['value'].'" '; 188 break; 189 } 190 } 191 $levels .= ' <text:outline-level-style '.$level.">\n"; 192 if (!empty($level_list)) { 193 if (empty($level_label)) { 194 $levels .= ' <style:list-level-properties '.$level_list."/>\n"; 195 } else { 196 $levels .= ' <style:list-level-properties '.$level_list.">\n"; 197 $levels .= ' <style:list-level-label-alignment '.$level_label."/>\n"; 198 $levels .= " </style:list-level-properties>\n"; 199 } 200 } 201 if (!empty($text)) { 202 $levels .= ' <style:text-properties '.$text.'/>'; 203 } 204 $levels .= " </text:outline-level-style>\n"; 205 } 206 207 // Build style. 208 $element = $this->getElementName(); 209 $style = '<'.$element.' '.$style.">\n"; 210 if ( !empty($levels) ) { 211 $style .= $levels; 212 } 213 $style .= '</'.$element.">\n"; 214 return $style; 215 } 216 217 /** 218 * Get the value of a property for text outline level $level. 219 * 220 * @param $level The text outline level (usually 1 to 10) 221 * @param $property The property name 222 * @return string The current value of the property 223 */ 224 public function getPropertyFromLevel($level, $property) { 225 return $this->getPropertyInternal($property, $this->outline_level_styles [$level]); 226 } 227 228 /** 229 * Set a property. 230 * 231 * @param $property The name of the property to set 232 * @param $value New value to set 233 */ 234 public function setPropertyForLevel($level, $property, $value) { 235 if (array_key_exists ($property, self::$outline_fields)) { 236 $this->setPropertyInternal 237 ($property, self::$outline_fields [$property][0], $value, self::$outline_fields [$property][1], $this->outline_level_styles [$level]); 238 return; 239 } 240 } 241} 242 243