Logo Search packages:      
Sourcecode: qps version File versions  Download package

pstable.cpp

// pstable.cpp 
//
// This program is free software. See the file COPYING for details.
// Author: Mattias Engdeg´┐Żd, 1997-1999

// ** need new Design, tooo complex... should be  more easier !(by fasthyun@magicn.com) 

#include <qpixmap.h>
#include <qpainter.h>
#include <qapplication.h>
#include <qclipboard.h>
#include <limits.h>

#include "pstable.h"
#include "proc.h"
#include "global.h"

//next line added to solve this debian bug: 386273
#include "svec.cpp"


Pstable::Pstable(QWidget *parent)
      : HeadedTable(parent,
                  HTBL_ROW_SELECTION
                  | HTBL_ROW_DOUBLE_CLICK
                  | HTBL_ROW_CONTEXT_MENU
                  | HTBL_HEADING_TOOLTIPS
                  | HTBL_HEADING_CONTEXT_MENU
                  | HTBL_HEADING_CLICK
                  | HTBL_REORDER_COLS)
{
      connect(this, SIGNAL(selectionChanged(const Svec<int> *)),SLOT(selection_update(const Svec<int> *)));
      connect(this, SIGNAL(titleClicked(int)), SLOT(sortcol_change(int)));
      connect(this, SIGNAL(foldSubTree(int)), SLOT(subtree_folded(int)));
}

// who call this ? : from qps.cpp
void Pstable::setProcview(Procview *pv)
{
      procview = pv;
      set_sortcol();
}

QString Pstable::title(int col)
{
      return procview->cats[col]->name;
}

QString Pstable::text(int row, int col)
{
      return procview->cats[col]->string(procview->procs[row]);
}

//DRAFT 
char* Pstable::total_selectedRow(int col)
{
      static char buff[48];
      char mem_str[48];
      char *name;
      int   index;
      
      if(procview->cats.size()<=col or col<0 ) return 0;  // col == -1 
      index=procview->cats[col]->index;

      switch(index)
      {
            case F_SIZE:
                  name="total SIZE: ";
                  break;
            case F_RSS:
                  name="total RSS: ";
                  break;
            case F_TRS:
                  name="total Text: ";
                  break;
            case F_DRS:
                  name="total Data: ";
                  break;
            case F_STACK:
                  name="total STACK: ";
                  break;
            default:
                  return 0;
      }
      
      int total=0;
      int rows = procview->procs.size();
      for(int i = 0; i < rows; i++)
            if(procview->procs[i]->selected)
            {
                  switch(index)
                  {
                        case F_SIZE:
                              total+=procview->procs[i]->size;break;
                        case F_RSS:
                              total+=procview->procs[i]->resident;break;
                        case F_TRS:
                              total+=procview->procs[i]->trs;break;
                        case F_DRS:
                              total+=procview->procs[i]->drs;break;
                        case F_STACK:
                              total+=procview->procs[i]->stack;break;
                  }
            }

      mem_string(total,mem_str);
      strcpy(buff,name);
      strcat(buff,mem_str);
      //sprintf(buff,"total:%s",total);
      return buff;
}

int Pstable::colWidth(int col)
{
      // this is -1 for variable width fields, htable keeps track of it
      return procview->cats[col]->width();
}

int Pstable::alignment(int col)
{
      //printf("debug:alignment()\n");
      Category *cat = procview->cats[col];
      return cat->alignment();
}

//DEL
int Pstable::leftGap(int col)
{
      return 0;
//    return procview->cats[col]->gap();
}

QString Pstable::tipText(int col)
{
      Category *cat = procview->cats[col];
      QString s(cat->help);
      
      // trick 
      if(cat->index == F_STAT)
            s.append("\n(R =running, S =sleeping, T =stopped, Z=Zombie)");
      if(cat->index == F_PLCY)
            s.append("\n(TS =Time Sharing)");
            
      if(cat->index == F_RSS)
            //s.append("\nRSS = CODE + DATA + SHARE\n"
            //       "RSS = TRS  + DRS  + SHARE\n");
            ///s.append("\n(RSS = TRS + DRS)");

      if(cat == procview->sortcat)
            s.append(procview->reversed ? "\n(sorted backwards)" : "\n(sorted)");

      return s;
}

int Pstable::rowDepth(int row)
{
      return procview->procs[row]->level;
}

HeadedTable::NodeState Pstable::folded(int row)
{
      Procinfo *p = procview->procs[row];
      ///return (p->children && p->children->size() > 0)    ? (p->hidekids ? Closed : Open) : Leaf;
      return p->children->size() ? (p->hidekids ? Closed : Open) : Leaf;
}

int Pstable::parentRow(int row)
{
      return procview->parent_rows[row];
}

bool Pstable::lastChild(int row)
{
      return procview->procs[row]->lastchild;
}


// transfer selection from procview to pstable
// (no visible update is done)
void Pstable::transfer_selection()
{
      int rows = procview->procs.size();
      for(int i = 0; i < rows; i++)
            setSelected(i, procview->procs[i]->selected, FALSE);

}

// slot: called when selection changes
//    called by 
//          1.void HeadedTable::selectionNotify()
void Pstable::selection_update(const Svec<int> *rows)
{
      //printf("debug:selection_update()\n")
      for(int i = 0; i < rows->size(); i++) {
            int row = (*rows)[i];
            procview->procs[row]->selected = isSelected(row);
      }
      
      qps->update_menu_selection_status();
      if(numSelected() > 0 && qps->pids_to_selection) {
            // set the X11 selection to "PID1 PID2 PID3 ..."
            QString s, num;
            int n = numRows();
            for(int i = 0; i < n; i++) {
                  if(isSelected(i)) {
                        num.setNum(procview->procs[i]->pid);
                        s.append(num);
                        if(i < n - 1)
                              s.append(" ");
                  }
            }

            // important: this mustn't be called non-interactively since Qt uses
            // the selection time of the last mouse or keyboard event
            QApplication::clipboard()->setText(s);
      }

}

// slot: called when a title is clicked
void Pstable::sortcol_change(int col)
{
      if(col == sortedCol()) {
            procview->reversed = !procview->reversed;
            if(!procview->treeview) {
                  // just reverse the lines
                  int n = procview->procs.size();
                  for(int i = 0; i < n / 2; i++) {
                        Procinfo *p = procview->procs[i];
                        procview->procs[i] = procview->procs[n - 1 - i];
                        procview->procs[n - 1 - i] = p;
                  }
            } else
                  procview->rebuild();
      } else {
            procview->reversed = FALSE;
            procview->sortcat = procview->cats[col];
            setSortedCol(col);
            procview->rebuild();
      }
      transfer_selection();
      refresh();
      //    topAndRepaint();
}

// dont work !! BUG !!!
// set sorted column of table to procview->sortcol
void Pstable::set_sortcol()
{
      for(int i = 0; i < procview->cats.size(); i++)
      {
            if(procview->cats[i] == procview->sortcat) {
                  setSortedCol(i); 
                  return;
            }
      }
      setSortedCol(-1);
}

// When a subtree is folded away, selections inside it disappear to prevent
// unexpected behaviour
static void clear_subtree_selections(Procinfo *p)
{
      for(int i = 0; i < p->children->size(); i++) {
            Procinfo *c = (*p->children)[i];
            c->selected = FALSE;
            if(c->children)
                  clear_subtree_selections(c);
      }
}

// NEED Check !!
// Slot: called when a subtree is opened or closed
// row = row number of sheet
void Pstable::subtree_folded(int row)
{
                              
      Procinfo *p = procview->procs[row];
      p->hidekids = !p->hidekids;
      
      if(p->hidekids)   
            clear_subtree_selections(p);  // *** important 

      // NEED updateColWidth()!!
      //HeadedTable::updateCell(row,0,true); // redraw triangle 
    //printf("row=%d\n",row);
      refresh();
      return ;    
      // ???
      Procinfo *nextp = (row < numRows() - 1) ? procview->procs[row + 1] : 0;
      if(!p->hidekids) {
            // Show as much as possible of the opened subtree
            int r = row + 1;
            while(r < numRows() && procview->procs[r] != nextp)
                  r++;
            setAutoUpdate(FALSE);
            showRange(row, r - 1);
            setAutoUpdate(TRUE);
      }
      // ???
      // This is a stopgap solution; it would be better to have htable
      // take care of the hiding of subtrees and repaint only the rows under
      // the line hidden
      
}

// slot: changes table mode
// called by 
//    1.void Qps::set_table_mode(bool treemode)
void Pstable::set_mode(bool treemode)
{
      procview->treeview = treemode;
      setTreeMode(treemode);   
}

//    1.void Pstable::moveCol(int col, int place) 
void Pstable::update_customfield()
{
      int i;
      int place;
      // copy ...

      for(i=0;i<procview->cats.size();i++)
            procview->custom_fields[i]=procview->cats[i]->index;

      procview->custom_fields[i]=F_END; 
      procview->viewfields=Procview::CUSTOM;
}


// Description : FIELD movement by mouse drag 
//                       To place From col
void Pstable::moveCol(int col, int place) 
{
      int i;
      // "COMMAND" field should be the first field in TreeMode!
      if( treeMode()==true )  
      {
            if(place==0)      return;
            if(procview->cats[col]->index==F_COMM) place=0; // *** important  , RIGHT SOLUTION !!
      }
      // "COMMAND_LINE" field should be the last field 
      if(procview->cats[place]->index==F_CMDLINE) return; // important !
      if(procview->cats[col]->index==F_CMDLINE)
            place=procview->cats.size() - 1;
      

      Category *cat = procview->cats[col];
      procview->cats.insert(place,cat); //first  insert 
      if(place<col) col++;
      procview->cats.remove(col);    //second  remove idx

      // recompute_table_widths();  // need check 
      refresh();
      update_customfield();
}


// DRAFT CODE:
// 1.procview->refresh: proc.refresh, rebuild
// 2.resetwidth
// 3.repaint

// called by 
//    1.void Qps::timer_refresh()
//
void Pstable::refresh()
{
      //void HeadedTable::updateCols(int deltacols, int place, bool update)
    //printf("Pstable:refresh()\n");
      procview->refresh(); 
      
      setAutoUpdate(FALSE);
      setNumRows(procview->procs.size()); //1.
      setNumCols(procview->cats.size());  //2. resetWidths() 
      setAutoUpdate(TRUE);
      
      transfer_selection();              // 3. procs => htable
      repaint_changed();  ///repaintAll();
}



Generated by  Doxygen 1.6.0   Back to index