Logo Search packages:      
Sourcecode: qps version File versions

htable.h

// htable.h                   emacs, this is written in -*-c++-*-
//
// This program is free software. See the file COPYING for details.
// Author: Mattias Engdegård, 1997-1999

// This file defines the HeadedTable class.
// A HeadedTable is a QTableView with one line of headers over each column.

#ifndef HTABLE_H
#define HTABLE_H

#include "qttableview.h"
#include <qscrollbar.h>
#include <qtooltip.h>
#include <qintdict.h>
#include <qbitarray.h>
#include <qpixmap.h>
#include "svec.h"

class HeadedTable;

class HeadingTip : public QToolTip
{
public:
    HeadingTip(QWidget *parent);

    friend class TableHead;

protected:
    void maybeTip(const QPoint &pos);
};

class TableHead : public QtTableView
{
    Q_OBJECT
public:
    TableHead(HeadedTable *parent = 0);

    void tip(const QPoint &pos);

protected slots:
    void scrollSideways(int);

protected:
    virtual void paintCell(QPainter *p, int row, int col);
    virtual int cellWidth(int col);
    virtual void mousePressEvent(QMouseEvent *e);
    virtual void mouseReleaseEvent(QMouseEvent *e);
    virtual void mouseMoveEvent(QMouseEvent *e);

    void drawSunken(int col);
    void paintHeading(int x, int col);

    static const int drag_threshold = 10; // movement before title drag starts

    HeadedTable *htable;
    QFont titlefont;
    QFontMetrics fm;
    int cellheight;
    HeadingTip *htip;
    QPoint press;
    bool left_pressed;
    int click_col;            // physical column clicked in
    bool dragging;
    int drag_pos;       // previous dragging position
    int drag_offset;

    friend class HeadedTable;
};

class TableBody : public QtTableView
{
    Q_OBJECT
public:
    TableBody(HeadedTable *parent = 0);

    void TableBody::drawGhostCol(int x, int w);

protected slots:
    // for keyboard accelerators
    void scrollUp();
    void scrollDown();
    void scrollLeft();
    void scrollRight();
    void pageUp();
    void pageDown();
    void jumpTop();
    void jumpBottom();
    void centerVertically(int row);
    void showRange(int from, int to);

protected:
    virtual void paintCell(QPainter *p, int row, int col);
    virtual int cellWidth(int col);
    void mousePressEvent(QMouseEvent *e);
    void mouseDoubleClickEvent(QMouseEvent *e);
    void mouseMoveEvent(QMouseEvent *e);
    void mouseReleaseEvent(QMouseEvent *);
    void timerEvent(QTimerEvent *);
    virtual void setFont(const QFont &);

    void updateRow(int row);
    void dragSelectTo(int row);
    QColor getXorColor();

    HeadedTable *htable;
    int cellheight;
    int zerowidth;            // width of the digit 0
    int first_drag_row;       // row where drag started
    int prev_drag_row;        // row where drag was at last event
    bool autoscrolling;       // true if we are autoscrolling right now
    enum { UP, DOWN } scrolldir;
    static const int scroll_delay = 10; // time delay when autoscrolling, in ms
    bool gadget_click;        // whether mouse press was on folding gadget
    QColor background;
    QFontMetrics fm;

    friend class HeadedTable;
};

// table options (bits to be ORed together)

#define HTBL_ROW_SELECTION 1  // rows are selectable
#define HTBL_ROW_DOUBLE_CLICK 2     // rows can be double-clicked
#define HTBL_ROW_CONTEXT_MENU 4     // right button menu on rows
#define HTBL_HEADING_TOOLTIPS 8     // tooltips on headings
#define HTBL_HEADING_CONTEXT_MENU 16 // right button menu on headings
#define HTBL_HEADING_CLICK 32 // able to click on heading (change sort order)
#define HTBL_REORDER_COLS 64  // able to reorder columns

class HeadedTable : public QWidget
{
    Q_OBJECT
public:
    HeadedTable(QWidget *parent, int opts);
    ~HeadedTable();

    enum NodeState { Leaf, Open, Closed };

    void setSortedCol(int col);
    int sortedCol() { return sorted_col; };
    void setNumRows(int rows);
    int numRows() { return nrows; };
    void setNumCols(int cols);
    int numCols() { return ncols; };
    int physCol(int logcol) { return physcols[logcol]; };
    int logCol(int physcol) { return logcols[physcol]; };
    void setPhysCols(Svec<int> *phys);
    void setSelected(int row, bool sel, bool update = TRUE);
    int numSelected() { return nselected; };
    void clearAllSelections();
    void selectOnly(int row);
    bool isSelected(int row) { return selected.testBit(row); };
    void deleteCol(int col, bool update = TRUE);
    void addCol(int col, bool update = TRUE);
    void updateTableSize();
    void updateColWidths();
    void repaintBody() { body->repaint(); };
    void repaintHead() { head->repaint(); };
    void repaintAll();
    void topAndRepaint();
    int leftCell() { return body->leftCell(); };
    int lastColVisible() { return body->lastColVisible(); };
    int topCell() { return body->topCell(); };
    int lastRowVisible() { return body->lastRowVisible(); };
    void updateCell(int row, int col, bool erase=TRUE)
      { body->updateCell(row, col, erase); };
    void updateHeading(int col) { head->updateCell(0, physcols[col]); };
    int bodyTextWidth(const char *s);
    int headTextWidth(const char *s);
    void clearRight();
    void clearBelow();
    void setAutoUpdate(bool update)
      { head->setAutoUpdate(update); body->setAutoUpdate(update); };
    bool widthChanged(int col);
    int actualColWidth(int col);
    void setBodyFont(QFont f) { body->setFont(f); };
    void centerVertically(int row) { body->centerVertically(row); };
    void showRange(int from, int to) { body->showRange(from, to); };
    void resetWidths();
    void resetWidth(int col) { widths[col] = -1; };
    void setSelectionColors(QColor fg, QColor bg);
    void invalidateCache();
    void selectionNotify();
    void moveCol(int col, int place);
    bool locked();
    void repaintColumns(int col0, int col1 = -1);
    void setTreeMode(bool tm);
    bool treeMode() { return treemode; };
    void enableFolding(bool enable);
    bool foldingEnabled() { return folding; };
    void enableLines(bool enable);
    bool linesEnabled() { return lines; };

signals:
    void titleClicked(int col);
    void selectionChanged(const Svec<int> *rows);
    void doubleClicked(int row);
    void rightClickedRow(QPoint where);
    void rightClickedHeading(QPoint where, int col);
    void foldSubTree(int row);
    void colMoved(int col, int place);

protected:
    // These must be implemented in subclasses
    virtual QString title(int col) = 0;
    virtual QString text(int row, int col) = 0;
    // colWidth returns width in digit units; negative means variable width.
    virtual int colWidth(int col) = 0;
    virtual int alignment(int col) = 0;
    virtual int leftGap(int col) = 0;

    // may be reimplemented (default exists)
    virtual QString tipText(int col);
    virtual void drawCellContents(int row, int col, int w, int h,
                          QPainter *painter);
    virtual int rowDepth(int row);
    virtual NodeState folded(int row);
    virtual int parentRow(int row);
    virtual bool lastChild(int row);

    void resizeEvent(QResizeEvent *);
    QString cachedText(int row, int col);
    int bodyCellHeight() { return body->cellheight; };

private:
    // to make signals originate from the right object
    void emit_click_signal(int col);
    void emit_double_click_signal(int row);
    void emit_right_click_signal(QPoint where);
    void emit_right_click_heading_signal(QPoint where, int col);
    void emit_fold(int row);

    int computedWidth(int col);
    int colOffset(int col);
    void updateCols(int deltacols, int place, bool update);

    void make_gadgets();

    int sorted_col;           // logical column to emphasize
    int options;
    int nrows;
    int ncols;

    QBitArray selected;
    int nselected;
    Svec<int> affected_rows;  // rows whose selection state has changed

    Svec<int> widths;         // row widths, indexed by logical columns
                        // -1 if width not known yet

    // column reorder tables
    Svec<int> logcols;        // logical column numbers, indexed by physical
    Svec<int> physcols;       // physical column numbers, indexed by logical

    TableHead *head;
    TableBody *body;

    QColor sel_fg, sel_bg;

    // text cache is in logical columns (reorder causes no flush)
    QIntDict<QString> text_cache; // indexed by (row << 16) + col

    bool treemode;
    bool folding;       // true if folding gadgets are used
    bool lines;               // true if tree lines are drawn
    int treestep;       // indentation for each tree level
    int gadget_space;         // horizontal space for show/hide tree gadget
    QPixmap closed_pm, open_pm;

    friend class TableHead;
    friend class TableBody;
};

inline bool HeadedTable::locked()
{
    return head->dragging;
}

#endif      // HTABLE_H




Generated by  Doxygen 1.6.0   Back to index