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

pstable.C

// pstable.C
//
// This program is free software. See the file COPYING for details.
// Author: Mattias Engdegård, 1997-1999

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

#include <limits.h>

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),
         leftmostchanged(-1)
{
    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)));
}

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]);
}

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)
{
    Category *cat = procview->cats[col];
    return cat->alignment();
}

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

QString Pstable::tipText(int col)
{
    Category *cat = procview->cats[col];
    QString s(cat->help);
    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;
}

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

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

// Recompute table widths and determine the leftmost column whose width
// has changed
void Pstable::recompute_table_widths()
{
    leftmostchanged = INT_MAX;

    for(int col = 0; col < numCols(); col++)
      if(widthChanged(logCol(col)) && leftmostchanged > col)
          leftmostchanged = col;
    if(leftmostchanged < INT_MAX)
      updateTableSize();
    else
      leftmostchanged = -1;
}

// repaint cells that have been changed from previous generation
void Pstable::repaint_changed()
{
    int rows = numRows();
    int cols = numCols();
    int left = leftCell(), right = lastColVisible();
    int top = topCell(), bottom = lastRowVisible();
    if(right >= cols) right = cols - 1;
    if(bottom >= rows) bottom = rows - 1;
    int far_right = right;
    if(leftmostchanged != -1 && right >= leftmostchanged)
      right = leftmostchanged - 1;
    for(int c = right + 1; c <= far_right; c++)
      updateHeading(logCol(c));
    int oldrows = procview->old_procs.size();
    for(int r = top; r <= bottom; r++) {
      for(int c = left; c <= right; c++) {
          Category *cat = procview->cats[logCol(c)];
          Procinfo *p = procview->procs[r];
          if(r < oldrows) {
            Procinfo *oldp = procview->old_procs[r];
            if((!treeMode() || c != 0
                || (!linesEnabled() && p->level == oldp->level))
               && cat->compare(p, oldp) == 0
               && p->selected == oldp->selected)
                continue;     // cell is unchanged
          }
          updateCell(r, c);
      }     
      // update all cells that have moved or changed width
      for(int c = right + 1; c <= far_right; c++)
          updateCell(r, c);
    }
    if(leftmostchanged != -1)
      clearRight();
    if(oldrows > rows && top == 0 && bottom == rows - 1)
      clearBelow();
}

// 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);
}

void Pstable::setRows()
{
    setAutoUpdate(FALSE);
    setNumRows(procview->procs.size());
    setAutoUpdate(TRUE);
}

// slot: called when selection changes
void Pstable::selection_update(const Svec<int> *rows)
{
    for(int i = 0; i < rows->size(); i++) {
      int row = (*rows)[i];
      procview->procs[row]->selected = isSelected(row);
    }
    emit selection_changed();
}

// slot: called when a title is clicked
void Pstable::sortcol_change(int col)
{
    invalidateCache();
    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();
    topAndRepaint();
}

// 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);
    }
}

// Slot: called when a subtree is opened or closed
void Pstable::subtree_folded(int row)
{
    Procinfo *p = procview->procs[row];
    p->hidekids = !p->hidekids;
    if(p->hidekids)
      clear_subtree_selections(p);
    Procinfo *nextp = (row < numRows() - 1) ? procview->procs[row + 1] : 0;
    resetWidths();
    invalidateCache();
    procview->rebuild();
    setRows();
    transfer_selection();
    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
    repaintAll();
}

// slot: changes table mode
void Pstable::set_mode(bool treemode)
{
    invalidateCache();
    procview->treeview = treemode;
    procview->rebuild();
    setRows();
    transfer_selection();
    setTreeMode(treemode);
    repaintAll();
}

void Pstable::set_initial_mode(bool treemode)
{
    if(treemode != treeMode())
      setTreeMode(treemode);
}


Generated by  Doxygen 1.6.0   Back to index