[ Index ] |
|
Code source de b2evolution 2.1.0-beta |
1 <?php 2 /** 3 * This file implements the Widget class. 4 * 5 * This file is part of the evoCore framework - {@link http://evocore.net/} 6 * See also {@link http://sourceforge.net/projects/evocms/}. 7 * 8 * @copyright (c)2003-2007 by Francois PLANQUE - {@link http://fplanque.net/} 9 * Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}. 10 * 11 * {@internal License choice 12 * - If you have received this file as part of a package, please find the license.txt file in 13 * the same folder or the closest folder above for complete license terms. 14 * - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/) 15 * then you must choose one of the following licenses before using the file: 16 * - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php 17 * - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php 18 * }} 19 * 20 * {@internal Open Source relicensing agreement: 21 * Daniel HAHLER grants Francois PLANQUE the right to license 22 * Daniel HAHLER's contributions to this file and the b2evolution project 23 * under any OSI approved OSS license (http://www.opensource.org/licenses/). 24 * }} 25 * 26 * @package evocore 27 * 28 * {@internal Below is a list of authors who have contributed to design/coding of this file: }} 29 * @author fplanque: Francois PLANQUE 30 * @author blueyed: Daniel HAHLER 31 * 32 * @version $Id: _uiwidget.class.php,v 1.5 2007/09/26 21:53:23 fplanque Exp $ 33 */ 34 if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' ); 35 36 37 /** 38 * Widget class which provides an interface to widget methods for other classes. 39 * 40 * It provides a method {@link replace_vars()} that can be used to replace object properties in given strings. 41 * You can also register global action icons. 42 * 43 * @package evocore 44 * @abstract 45 */ 46 class Widget 47 { 48 /** 49 * Display parameters. 50 * Example params would be 'block_start' and 'block_end'. 51 * Params may contain special variables that will be replaced by replace_vars() 52 * Different types of Widgets will expect different parameters. 53 * @var array 54 */ 55 var $params = NULL; 56 57 /** 58 * Title of the widget (to be displayed) 59 */ 60 var $title; 61 62 /** 63 * List of registered global action icons that get substituted through '$global_icons$'. 64 * @see global_icon() 65 */ 66 var $global_icons = array(); 67 68 69 /** 70 * Constructor 71 * 72 * @param string template name to get from $AdminUI 73 */ 74 function Widget( $ui_template = NULL ) 75 { 76 global $AdminUI; 77 78 if( !empty( $ui_template ) ) 79 { // Get template params from Admin Skin: 80 $this->params = $AdminUI->get_template( $ui_template ); 81 } 82 } 83 84 85 /** 86 * Registers a global action icon 87 * 88 * @param string TITLE text (IMG and A link) 89 * @param string icon code for {@link get_icon()} 90 * @param string URL to link to 91 * @param integer 1-5: weight of the icon. the icon will be displayed only if its weight is >= than the user setting threshold 92 * @param integer 1-5: weight of the word. the word will be displayed only if its weight is >= than the user setting threshold 93 * @param array Additional attributes to the A tag. See {@link action_icon()}. 94 */ 95 function global_icon( $title, $icon, $url, $word = '', $icon_weight = 3, $word_weight = 2, $link_attribs = array( 'class'=>'action_icon' ) ) 96 { 97 $this->global_icons[] = array( 98 'title' => $title, 99 'icon' => $icon, 100 'url' => $url, 101 'word' => $word, 102 'icon_weight' => $icon_weight, 103 'word_weight' => $word_weight, 104 'link_attribs' => $link_attribs ); 105 } 106 107 108 /** 109 * Display a template param without replacing variables 110 */ 111 function disp_template_raw( $param_name ) 112 { 113 echo $this->params[ $param_name ]; 114 } 115 116 117 /** 118 * Display a template param with its variables replaced 119 */ 120 function disp_template_replaced( $param_name ) 121 { 122 echo $this->replace_vars( $this->params[ $param_name ] ); 123 } 124 125 126 /** 127 * Replaces $vars$ with appropriate values. 128 * 129 * You can give an alternative string to display, if the substituted variable 130 * is empty, like: 131 * <code>$vars "Display if empty"$</code> 132 * 133 * @param string template 134 * @param array optional params that are put into {@link $this->params} 135 * to be accessible by derived replace_callback() methods 136 * @return string The substituted string 137 */ 138 function replace_vars( $template, $params = NULL ) 139 { 140 if( !is_null( $params ) ) 141 { 142 $this->params = $params; 143 } 144 145 return preg_replace_callback( 146 '~\$([a-z_]+)(?:\s+"([^"]*)")?\$~', # pattern 147 array( $this, 'replace_callback_wrapper' ), # callback 148 $template ); 149 } 150 151 152 /** 153 * This is an additional wrapper to {@link replace_vars()} that allows to react 154 * on the return value of it. 155 * 156 * Used by replace_callback() 157 * 158 * @param array {@link preg_match() preg match} 159 * @return string 160 */ 161 function replace_callback_wrapper( $match ) 162 { 163 // Replace the variable with its content (which will be computed on the fly) 164 $r = $this->replace_callback( $match ); 165 166 if( empty($r) ) 167 { // Empty result 168 if( !empty($match[2]) ) 169 { 170 return $match[2]; // "display if empty" 171 } 172 173 // return $match[1]; 174 } 175 return $r; 176 } 177 178 179 /** 180 * Callback function used to replace only necessary values in template. 181 * 182 * This gets used by {@link replace_vars()} to replace $vars$. 183 * 184 * @param array {@link preg_match() preg match}. Index 1 is the template variable. 185 * @return string to be substituted 186 */ 187 function replace_callback( $matches ) 188 { 189 //echo $matches[1]; 190 switch( $matches[1] ) 191 { 192 case 'global_icons' : 193 // Icons for the whole result set: 194 return $this->gen_global_icons(); 195 196 case 'title': 197 // Results title: 198 return $this->title; 199 200 default: 201 return $matches[1]; 202 } 203 } 204 205 206 /** 207 * Generate img tags for registered icons, through {@link global_icon()}. 208 * 209 * This is used by the default callback to replace '$global_icons$'. 210 */ 211 function gen_global_icons() 212 { 213 $r = ''; 214 215 foreach( $this->global_icons as $icon_params ) 216 { 217 $r .= action_icon( $icon_params['title'], $icon_params['icon'], $icon_params['url'], $icon_params['word'], 218 $icon_params['icon_weight'], $icon_params['word_weight'], $icon_params['link_attribs'] ); 219 } 220 221 return $r; 222 } 223 224 } 225 226 227 /** 228 * Class Table 229 * @todo dh> shouldn't this be in a separate file? 230 * @package evocore 231 */ 232 class Table extends Widget 233 { 234 /** 235 * Total number of pages 236 */ 237 var $total_pages = 1; 238 239 /** 240 * Number of cols. 241 */ 242 var $nb_cols; 243 244 /** 245 * Number of lines already displayed 246 */ 247 var $displayed_lines_count; 248 249 /** 250 * Number of cols already displayed (in current line) 251 */ 252 var $displayed_cols_count; 253 254 /** 255 * @var array 256 */ 257 var $fadeout_array; 258 259 var $fadeout_count = 0; 260 261 /** 262 * @var boolean 263 */ 264 var $is_fadeout_line; 265 266 var $no_results_text; 267 268 269 /** 270 * Constructor 271 * 272 * @param string template name to get from $AdminUI 273 */ 274 function Table( $ui_template = NULL ) 275 { 276 parent::Widget( $ui_template ); 277 278 $this->no_results_text = T_('No results.'); 279 } 280 281 282 /** 283 * Initialize things in order to be ready for displaying. 284 * 285 * Lazy fills $this->params 286 * 287 * @param array ***please document*** 288 * @param array Fadeout settings array( 'key column' => array of values ) or 'session' 289 */ 290 function display_init( $display_params = NULL, $fadeout = NULL ) 291 { 292 global $AdminUI, $Session, $Debuglog; 293 294 if( empty( $this->params ) && isset( $AdminUI ) ) 295 { // Use default params from Admin Skin: 296 $this->params = $AdminUI->get_template( 'Results' ); 297 } 298 299 // Make sure we have display parameters: 300 if( !is_null($display_params) ) 301 { // Use passed params: 302 //$this->params = & $display_params; 303 if( !empty( $this->params ) ) 304 { 305 $this->params = array_merge( $this->params, $display_params ); 306 } 307 else 308 { 309 $this->params = & $display_params; 310 } 311 } 312 313 314 if( $fadeout == 'session' ) 315 { // Get fadeout_array from session: 316 if( ($this->fadeout_array = $Session->get('fadeout_array')) && is_array( $this->fadeout_array ) ) 317 { 318 $Debuglog->add( 'Got fadeout_array from session data.', 'session' ); 319 $Session->delete( 'fadeout_array' ); 320 } 321 else 322 { 323 $this->fadeout_array = NULL; 324 } 325 } 326 else 327 { 328 $this->fadeout_array = $fadeout; 329 } 330 331 if( !empty( $this->fadeout_array ) ) 332 { // Initialize fadeout javascript: 333 global $rsc_url; 334 echo '<script type="text/javascript" src="'.$rsc_url.'js/fadeout.js"></script>'; 335 echo '<script type="text/javascript">addEvent( window, "load", Fat.fade_all, false);</script>'; 336 } 337 338 339 } 340 341 342 /** 343 * Display list/table start. 344 * 345 * Typically outputs UL or TABLE tags. 346 */ 347 function display_list_start() 348 { 349 if( $this->total_pages == 0 ) 350 { // There are no results! Nothing to display! 351 echo $this->replace_vars( $this->params['no_results_start'] ); 352 echo $this->no_results_text; 353 echo $this->replace_vars( $this->params['no_results_end'] ); 354 } 355 else 356 { // We have rows to display: 357 echo $this->params['list_start']; 358 } 359 } 360 361 362 /** 363 * Display list/table end. 364 * 365 * Typically outputs </ul> or </table> 366 */ 367 function display_list_end() 368 { 369 if( $this->total_pages == 0 ) 370 { // There are no results! Nothing to display! 371 } 372 else 373 { // We have rows to display: 374 echo $this->params['list_end']; 375 } 376 } 377 378 379 /** 380 * Display list/table head. 381 * 382 * This includes list head/title and column headers. 383 * EXPERIMENTAL: also dispays <tfoot> 384 * 385 * @access protected 386 */ 387 function display_head() 388 { 389 echo $this->params['head_start']; 390 391 392 // DISPLAY TITLE: 393 if( isset($this->title) ) 394 { // A title has been defined for this result set: 395 echo $this->replace_vars( $this->params['head_title'] ); 396 } 397 398 // DISPLAY COLUMN HEADERS: 399 $this->display_col_headers(); 400 401 402 echo $this->params['head_end']; 403 404 405 // Experimental: 406 echo $this->params['tfoot_start']; 407 echo $this->params['tfoot_end']; 408 } 409 410 411 /** 412 * Display column headers 413 */ 414 function display_col_headers() 415 { 416 if( isset( $this->cols ) ) 417 { 418 419 if( !isset($this->nb_cols) ) 420 { // Needed for sort strings: 421 $this->nb_cols = count($this->cols); 422 } 423 424 425 $th_group_activated = false; 426 427 // Loop on all columns to see if we have th_group columns: 428 foreach( $this->cols as $col ) 429 { 430 if( isset( $col['th_group'] ) ) 431 { // We have a th_group column, so break: 432 $th_group_activated = true; 433 break; 434 } 435 } 436 437 $current_th_group_colspan = 1; 438 $current_th_colspan = 1; 439 $current_th_group_title = NULL; 440 $current_th_title = NULL; 441 $header_cells = array(); 442 443 // Loop on all columns to get an array of header cells description 444 // Each header cell will have a colspan and rowspan value 445 // The line 0 is reserved for th_group 446 // The line 1 is reserved for th 447 foreach( $this->cols as $key=>$col ) 448 { 449 //_______________________________ TH GROUP __________________________________ 450 451 if( isset( $col['th_group'] ) ) 452 { // The column has a th_group 453 if( is_null( $current_th_group_title ) || $col['th_group'] != $current_th_group_title ) 454 { // It's the begining of a th_group colspan (line0): 455 456 //Initialize current th_group colspan to 1 (line0): 457 $current_th_group_colspan = 1; 458 459 // Set colspan and rowspan colum for line0 to 1: 460 $header_cells[0][$key]['colspan'] = 1; 461 $header_cells[0][$key]['rowspan'] = 1; 462 } 463 else 464 { // The column is part of a th group colspan 465 // Update the first th group colspan cell 466 $header_cells[0][$key-$current_th_group_colspan]['colspan']++; 467 468 // Set the colspan column to 0 to not display it 469 $header_cells[0][$key]['colspan'] = 0; 470 $header_cells[0][$key]['rowspan'] = 0; 471 472 //Update current th_group colspan to 1 (line0): 473 $current_th_group_colspan++; 474 } 475 476 // Update current th group title: 477 $current_th_group_title = $col['th_group']; 478 } 479 480 //___________________________________ TH ___________________________________ 481 482 if( is_null( $current_th_title ) || $col['th'] != $current_th_title ) 483 { // It's the begining of a th colspan (line1) 484 485 //Initialize current th colspan to 1 (line1): 486 $current_th_colspan = 1; 487 488 // Update current th title: 489 $current_th_title = $col['th']; 490 491 if( $th_group_activated && !isset( $col['th_group'] ) ) 492 { // We have to lines and the column has no th_group, so it will be a "rowspan2" 493 494 // Set the cell colspan and rowspan values for the line0: 495 $header_cells[0][$key]['colspan'] = 1; 496 $header_cells[0][$key]['rowspan'] = 2; 497 498 // Set the cell colspan and rowspan values for the line1, to do not display it: 499 $header_cells[1][$key]['colspan'] = 0; 500 $header_cells[1][$key]['rowspan'] = 0; 501 } 502 else 503 { // The cell has no rowspan 504 $header_cells[1][$key]['colspan'] = 1; 505 $header_cells[1][$key]['rowspan'] = 1; 506 } 507 } 508 else 509 { // The column is part of a th colspan 510 if( $th_group_activated && !isset( $col['th_group'] ) ) 511 { // We have to lines and the column has no th_group, the colspan is "a rowspan 2" 512 513 // Update the first th cell colspan in line0 514 $header_cells[0][$key-$current_th_colspan]['colspan']++; 515 516 // Set the cell colspan to 0 in line0 to not display it: 517 $header_cells[0][$key]['colspan'] = 0; 518 $header_cells[0][$key]['rowspan'] = 0; 519 } 520 else 521 { // Update the first th colspan cell in line1 522 $header_cells[1][$key-$current_th_colspan]['colspan']++; 523 } 524 525 // Set the cell colspan to 0 in line1 to do not display it: 526 $header_cells[1][$key]['colspan'] = 0; 527 $header_cells[1][$key]['rowspan'] = 0; 528 529 $current_th_colspan++; 530 } 531 } 532 533 // ________________________________________________________________________________ 534 535 if( !$th_group_activated ) 536 { // We have only the "th" line to display 537 $start = 1; 538 } 539 else 540 { // We have the "th_group" and the "th" lines to display 541 $start = 0; 542 } 543 544 //__________________________________________________________________________________ 545 546 // Loop on all headers lines: 547 for( $i = $start; $i <2 ; $i++ ) 548 { 549 echo $this->params['line_start_head']; 550 // Loop on all headers lines cells to display them: 551 foreach( $header_cells[$i] as $key=>$cell ) 552 { 553 if( $cell['colspan'] ) 554 { // We have to dispaly cell: 555 if( $i == 0 && $cell['rowspan'] != 2 ) 556 { // The cell is a th_group 557 $th_title = $this->cols[$key]['th_group']; 558 $col_order = isset( $this->cols[$key]['order_group'] ); 559 } 560 else 561 { // The cell is a th 562 $th_title = $this->cols[$key]['th'] ; 563 $col_order = isset( $this->cols[$key]['order'] ) || isset( $this->cols[$key]['order_objects_callback'] ) || isset( $this->cols[$key]['order_rows_callback'] ); 564 } 565 566 567 if( isset( $this->cols[$key]['th_class'] ) ) 568 { // We have a class for the th column 569 $class = $this->cols[$key]['th_class']; 570 } 571 else 572 { // We have no class for the th column 573 $class = ''; 574 } 575 576 if( $key == 0 && isset($this->params['colhead_start_first']) ) 577 { // Display first column start: 578 $output = $this->params['colhead_start_first']; 579 580 // Add the total column class in the grp col start first param class: 581 $output = str_replace( '$class$', $class, $output ); 582 } 583 elseif( ( $key + $cell['colspan'] ) == (count( $this->cols) ) && isset($this->params['colhead_start_last']) ) 584 { // Last column can get special formatting: 585 $output = $this->params['colhead_start_last']; 586 587 // Add the total column class in the grp col start end param class: 588 $output = str_replace( '$class$', $class, $output ); 589 } 590 else 591 { // Display regular colmun start: 592 $output = $this->params['colhead_start']; 593 594 // Replace the "class_attrib" in the grp col start param by the td column class 595 $output = str_replace( '$class_attrib$', 'class="'.$class.'"', $output ); 596 } 597 598 599 // Set colspan and rowspan values for the cell: 600 $output = preg_replace( '#(<)([^>]*)>$#', '$1$2 colspan="'.$cell['colspan'].'" rowspan="'.$cell['rowspan'].'">' , $output ); 601 602 echo $output; 603 604 if( $col_order ) 605 { // The column can be ordered: 606 $col_sort_values = $this->get_col_sort_values( $key ); 607 608 609 // Determine CLASS SUFFIX depending on wether the current column is currently sorted or not: 610 if( !empty($col_sort_values['current_order']) ) 611 { // We are currently sorting on the current column: 612 $class_suffix = '_current'; 613 } 614 else 615 { // We are not sorting on the current column: 616 $class_suffix = '_sort_link'; 617 } 618 619 // Display title depending on sort type/mode: 620 if( $this->params['sort_type'] == 'single' ) 621 { // single column sort type: 622 623 // Title with toggle: 624 echo '<a href="'.$col_sort_values['order_toggle'].'"' 625 .' title="'.T_('Change Order').'"' 626 .' class="single'.$class_suffix.'"' 627 .'>'.$th_title.'</a>'; 628 629 // Icon for ascending sort: 630 echo '<a href="'.$col_sort_values['order_asc'].'"' 631 .' title="'.T_('Ascending order').'"' 632 .'>'.$this->params['sort_asc_'.($col_sort_values['current_order'] == 'ASC' ? 'on' : 'off')].'</a>'; 633 634 // Icon for descending sort: 635 echo '<a href="'.$col_sort_values['order_desc'].'"' 636 .' title="'.T_('Descending order').'"' 637 .'>'.$this->params['sort_desc_'.($col_sort_values['current_order'] == 'DESC' ? 'on' : 'off')].'</a>'; 638 639 } 640 else 641 { // basic sort type (toggle single column): 642 643 if( $col_sort_values['current_order'] == 'ASC' ) 644 { // the sorting is ascending and made on the current column 645 $sort_icon = $this->params['basic_sort_asc']; 646 } 647 elseif( $col_sort_values['current_order'] == 'DESC' ) 648 { // the sorting is descending and made on the current column 649 $sort_icon = $this->params['basic_sort_desc']; 650 } 651 else 652 { // the sorting is not made on the current column 653 $sort_icon = $this->params['basic_sort_off']; 654 } 655 656 // Toggle Icon + Title 657 echo '<a href="'.$col_sort_values['order_toggle'].'"' 658 .' title="'.T_('Change Order').'"' 659 .' class="basic'.$class_suffix.'"' 660 .'>'.$sort_icon.' '.$th_title.'</a>'; 661 662 } 663 664 } 665 elseif( $th_title ) 666 { // the column can't be ordered, but we still have a header defined: 667 echo '<span>'.$th_title.'</span>'; 668 } 669 // </td> 670 echo $this->params['colhead_end']; 671 } 672 } 673 // </tr> 674 echo $this->params['line_end']; 675 } 676 } // this->cols not set 677 } 678 679 680 /** 681 * 682 */ 683 function display_body_start() 684 { 685 echo $this->params['body_start']; 686 687 $this->displayed_lines_count = 0; 688 689 } 690 691 692 /** 693 * 694 */ 695 function display_body_end() 696 { 697 echo $this->params['body_end']; 698 } 699 700 701 /** 702 * 703 */ 704 function display_line_start( $is_last = false, $is_fadeout_line = false ) 705 { 706 if( $this->displayed_lines_count % 2 ) 707 { // Odd line: 708 if( $is_last ) 709 echo $this->params['line_start_odd_last']; 710 else 711 echo $this->params['line_start_odd']; 712 } 713 else 714 { // Even line: 715 if( $is_last ) 716 echo $this->params['line_start_last']; 717 else 718 echo $this->params['line_start']; 719 } 720 721 $this->displayed_cols_count = 0; 722 723 $this->is_fadeout_line = $is_fadeout_line; 724 } 725 726 727 /** 728 * 729 */ 730 function display_line_end() 731 { 732 echo $this->params['line_end']; 733 734 $this->displayed_lines_count ++; 735 } 736 737 738 /** 739 * 740 */ 741 function display_col_start() 742 { 743 // Get colum definitions for current column: 744 $col = $this->cols[$this->displayed_cols_count]; 745 746 if( isset( $col['td_class'] ) ) 747 { // We have a class for the total column 748 $class = $col['td_class']; 749 } 750 else 751 { // We have no class for the total column 752 $class = ''; 753 } 754 755 /** 756 * Update class and add a fadeout ID for fadeout list results 757 */ 758 if( $this->is_fadeout_line ) 759 { 760 // echo ' fadeout '.$this->fadeout_count; 761 $class .= ' fadeout-ffff00" id="fadeout-'.$this->fadeout_count; 762 $this->fadeout_count++; 763 } 764 765 if( ($this->displayed_cols_count == 0) && isset($this->params['col_start_first']) ) 766 { // Display first column column start: 767 $output = $this->params['col_start_first']; 768 // Add the total column class in the col start first param class: 769 $output = str_replace( '$class$', $class, $output ); 770 } 771 elseif( ( $this->displayed_cols_count == count($this->cols)-1) && isset($this->params['col_start_last']) ) 772 { // Last column can get special formatting: 773 $output = $this->params['col_start_last']; 774 // Add the total column class in the col start end param class: 775 $output = str_replace( '$class$', $class, $output ); 776 } 777 else 778 { // Display regular colmun start: 779 $output = $this->params['col_start']; 780 // Replace the "class_attrib" in the total col start param by the td column class 781 $output = str_replace( '$class_attrib$', 'class="'.$class.'"', $output ); 782 } 783 784 echo $output; 785 } 786 787 788 /** 789 * 790 */ 791 function display_col_end() 792 { 793 echo $this->params['col_end']; 794 795 $this->displayed_cols_count ++; 796 } 797 798 799 /** 800 * Widget callback for template vars. 801 * 802 * This allows to replace template vars, see {@link Widget::replace_callback()}. 803 * 804 * @return string 805 */ 806 function replace_callback( $matches ) 807 { 808 // echo '['.$matches[1].']'; 809 switch( $matches[1] ) 810 { 811 case 'nb_cols' : 812 // Number of columns in result: 813 if( !isset($this->nb_cols) ) 814 { 815 $this->nb_cols = count($this->cols); 816 } 817 return $this->nb_cols; 818 819 default : 820 return parent::replace_callback( $matches ); 821 } 822 } 823 824 } 825 826 /* 827 * $Log: _uiwidget.class.php,v $ 828 * Revision 1.5 2007/09/26 21:53:23 fplanque 829 * file manager / file linking enhancements 830 * 831 * Revision 1.4 2007/09/04 13:23:18 fplanque 832 * Fixed display for category screen. 833 * 834 * Revision 1.3 2007/09/03 18:32:50 fplanque 835 * enhanced dashboard / comment moderation 836 * 837 * Revision 1.2 2007/07/24 23:29:26 blueyed 838 * todo 839 * 840 * Revision 1.1 2007/06/25 10:59:01 fplanque 841 * MODULES (refactored MVC) 842 * 843 * Revision 1.16 2007/04/26 00:11:08 fplanque 844 * (c) 2007 845 * 846 * Revision 1.15 2007/01/14 22:06:48 fplanque 847 * support for customized 'no results' messages 848 * 849 * Revision 1.14 2007/01/11 21:06:05 fplanque 850 * bugfix 851 * 852 * Revision 1.13 2007/01/11 02:25:06 fplanque 853 * refactoring of Table displays 854 * body / line / col / fadeout 855 * 856 * Revision 1.12 2007/01/09 00:49:04 blueyed 857 * todo 858 * 859 * Revision 1.11 2007/01/08 23:44:19 fplanque 860 * inserted Table widget 861 * WARNING: this has nothing to do with ComponentWidgets... 862 * (except that I'm gonna need the Table Widget when handling the ComponentWidgets :> 863 * 864 * Revision 1.10 2006/11/26 01:42:10 fplanque 865 * doc 866 * 867 */ 868 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Thu Nov 29 23:58:50 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |