function needs_save($cont = '', $posted_app = '', $posted_table = '', $edited_table = '')
 {
     if (!$posted_app && is_array($cont)) {
         if (isset($cont['yes'])) {
             $this->app = $cont['app'];
             $this->table = $cont['table'];
             $this->read($this->app, $this->data);
             $this->data[$this->table] = $cont['edited_table'];
             $this->changes = $cont['changes'];
             if ($cont['new_version']) {
                 $this->update($this->app, $this->data, $cont['new_version']);
             } else {
                 foreach ($this->data as $tname => $tinfo) {
                     $tables .= ($tables ? ',' : '') . "'{$tname}'";
                 }
                 $this->setup_version($this->app, '', $tables);
             }
             $msg .= $this->write($this->app, $this->data) ? lang('File writen') : lang('Error: writing file (no write-permission for the webserver) !!!');
         }
         $this->changes = array();
         // return to edit with everything set, so the user gets the table he asked for
         $this->edit(array('app' => $cont['new_app'], 'table_name' => $cont['app'] == $cont['new_app'] ? $cont['new_table'] : '', 'posted_app' => $cont['new_app']), $msg);
         return True;
     }
     $new_app = $this->app;
     // these are the ones, the users whiches to change too
     $new_table = $this->table;
     $this->app = $posted_app;
     $this->data = array();
     $this->read($posted_app, $this->data);
     if (isset($this->data[$posted_table]) && $this->tables_identical($this->data[$posted_table], $edited_table)) {
         if ($new_app != $this->app) {
             $this->app = $new_app;
             // if we change init the data empty
             $this->data = array();
         }
         return False;
         // continue edit
     }
     $content = array('app' => $posted_app, 'table' => $posted_table, 'version' => $this->setup_version($posted_app));
     $preserv = $content + array('new_app' => $new_app, 'new_table' => $new_table, 'edited_table' => $edited_table, 'changes' => $this->changes);
     $new_version = explode('.', $content['version']);
     $minor = count($new_version) - 1;
     $new_version[$minor] = sprintf('%03d', 1 + $new_version[$minor]);
     $content['new_version'] = implode('.', $new_version);
     $tmpl = new etemplate('etemplate.db-tools.ask_save');
     if (!file_exists(PHPGW_SERVER_ROOT . "/{$posted_app}/setup/tables_current.inc.php")) {
         $tmpl->disable_cells('version');
         $tmpl->disable_cells('new_version');
     }
     $tmpl->exec('etemplate.db_tools.needs_save', $content, array(), array(), $preserv);
     return True;
     // dont continue in edit
 }
 function pre_process($name, &$value, &$cell, &$readonlys, &$extension_data, &$tmpl)
 {
     $nm_global =& $GLOBALS['phpgw_info']['etemplate']['nextmatch'];
     //echo "<p>nextmatch_widget.pre_process(name='$name',type='$cell[type]'): value = "; _debug_array($value);
     //echo "<p>nextmatch_widget.pre_process(name='$name',type='$cell[type]'): nm_global = "; _debug_array($nm_global);
     $extension_data = array('type' => $cell['type']);
     switch ($cell['type']) {
         case 'nextmatch-sortheader':
             $cell['type'] = 'button';
             $cell['onchange'] = True;
             if (!$cell['help']) {
                 $cell['help'] = 'click to order after that criteria';
             }
             if ($this->last_part($name) == $nm_global['order']) {
                 $cell[1] = $cell;
                 $cell[1]['span'] .= ',activ_sortcolumn';
                 $cell[2] = $tmpl->empty_cell('image', $nm_global['sort'] != 'DESC' ? 'down' : 'up');
                 $cell['type'] = 'hbox';
                 $cell['size'] = '2,0,0';
                 $cell['name'] = $cell['label'] = '';
             } else {
                 $cell['span'] .= ',inactiv_sortcolumn';
             }
             return True;
         case 'nextmatch-filterheader':
             $cell['type'] = 'select';
             if (!$cell['size']) {
                 $cell['size'] = 'All';
             }
             if (!$cell['help']) {
                 $cell['help'] = 'select which values to show';
             }
             $cell['onchange'] = True;
             $extension_data['old_value'] = $value = $nm_global['col_filter'][$this->last_part($name)];
             return True;
     }
     list($app, $class, $method) = explode('.', $value['get_rows']);
     $obj = CreateObject($app . '.' . $class);
     if (!is_object($obj) || !method_exists($obj, $method)) {
         echo "<p>nextmatch_widget::pre_process({$name}): '{$value['get_rows']}' is no valid method !!!</p>\n";
         //return;
     } else {
         $total = $value['total'] = $obj->{$method}($value, $value['rows'], $readonlys['rows']);
     }
     if ($value['start'] > $total) {
         $value['start'] = 0;
         $total = $obj->{$method}($value, $value['rows'], $readonlys['rows']);
     }
     list($template, $options) = explode(',', $cell['size']);
     if ($template) {
         $value['template'] = $template;
     }
     if (!is_object($value['template'])) {
         $value['template'] = new etemplate($value['template'], $tmpl->as_array());
     }
     if ($total < 1) {
         $value['template']->data[0]['h2'] = ',1';
         // disable the data row
     }
     $max = $GLOBALS['phpgw_info']['user']['preferences']['common']['maxmatchs'];
     if ($total <= $max && $options && $value['search'] == '' && ($value['no_cat'] || !$value['cat_id']) && ($value['no_filter'] || !$value['filter'] || $value['filter'] == 'none') && ($value['no_filter2'] || !$value['filter2'] || $value['filter2'] == 'none')) {
         // disable whole nextmatch line if no scrolling necessary
         if ($value['header_left'] || $value['header_right']) {
             $nextmatch = new etemplate('etemplate.nextmatch_widget.header_only');
             $cell['size'] = $cell['name'];
             $cell['obj'] =& $nextmatch;
             $cell['name'] = $nextmatch->name;
         } else {
             $cell['size'] = $cell['name'] . '[rows]';
             $cell['obj'] =& $value['template'];
             $cell['name'] = $value['template']->name;
         }
     } else {
         $nextmatch = new etemplate('etemplate.nextmatch_widget');
         if ($value['no_cat']) {
             $nextmatch->disable_cells('cat_id');
         }
         if ($value['no_filter']) {
             $nextmatch->disable_cells('filter');
         }
         if ($value['no_filter2']) {
             $nextmatch->disable_cells('filter2');
         }
         $start = $value['start'];
         $end = $start + $max > $total ? $total : $start + $max;
         $value['range'] = $total ? 1 + $start . ' - ' . $end : '0';
         $nextmatch->set_cell_attribute('first', 'readonly', $start <= 0);
         $nextmatch->set_cell_attribute('left', 'readonly', $start <= 0);
         $nextmatch->set_cell_attribute('right', 'readonly', $start + $max >= $total);
         $nextmatch->set_cell_attribute('last', 'readonly', $start + $max >= $total);
         $cell['size'] = $cell['name'];
         $cell['obj'] =& $nextmatch;
         $cell['name'] = $nextmatch->name;
     }
     $cell['type'] = 'template';
     $cell['label'] = $cell['help'] = '';
     // save values in persistent extension_data to be able use it in post_process
     $extension_data += $value;
     foreach (array('sort', 'order', 'col_filter') as $n) {
         $nm_global[$n] = $value[$n];
     }
     $value['bottom'] = $value;
     // copy the values for the bottom-bar
     return False;
     // NO extra Label
 }