/* This file is part of the KDE libraries
Copyright (C) 1997 The KDE Team
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/* Written by Stefan Taferner <taferner@kde.org>
* Alessandro Russo <axela@bigfoot.com>
* A multi column listbox. Requires the Qt widget set.
*/
#ifndef KTabListBox_h
#define KTabListBox_h
#undef del_item
#include <qdict.h>
#include <qtableview.h>
#include <qcolor.h>
#include <qpixmap.h>
#include <drag.h>
#include <stdlib.h>
#define MAX_SEP_CHARS 16
class KTabListBoxColumn;
class KTabListBoxTable;
class KTabListBoxItem;
class KTabListBox;
class KNumCheckButton;
typedef QDict<QPixmap> KTabListBoxDict;
//-----------------------------------------------------
/**
* Provides a different type of Check button.
*
*/
class KNumCheckButton : public QWidget
{
Q_OBJECT
public:
KNumCheckButton( QWidget *_parent = 0L, const char *name = 0L );
~KNumCheckButton() {};
void setText( const char * );
signals:
void selected();
void deselected();
/** leftbutton=true if is a leftbutton, =false if is a rightbutton
* centerbutton doubleclick events aren't emitted.
*/
void doubleclick(bool leftbutton);
protected:
virtual void leaveEvent( QEvent *_ev );
virtual void enterEvent( QEvent *_ev );
virtual void mousePressEvent( QMouseEvent * );
virtual void mouseDoubleClickEvent( QMouseEvent * );
virtual void paintEvent( QPaintEvent *event);
private:
bool raised;
QString btext;
};
//--------------------------------------------------
#define KTabListBoxTableInherited QTableView
class KTabListBoxTable: public QTableView
{
Q_OBJECT
friend KTabListBox;
public:
KTabListBoxTable(KTabListBox *owner=0);
virtual ~KTabListBoxTable();
void enableKey();
int findRealCol(int x);
protected:
virtual void focusInEvent(QFocusEvent*);
virtual void focusOutEvent(QFocusEvent*);
virtual void mouseDoubleClickEvent (QMouseEvent*);
virtual void mousePressEvent (QMouseEvent*);
virtual void mouseReleaseEvent (QMouseEvent*);
virtual void mouseMoveEvent (QMouseEvent*);
virtual void doItemSelection (QMouseEvent*, int idx);
virtual void paintCell (QPainter*, int row, int col);
virtual int cellWidth (int col);
void reconnectSBSignals (void);
QPoint dragStartPos;
int dragCol, dragRow;
int selIdx;
bool dragging;
};
//--------------------------------------------------
#define KTabListBoxInherited KDNDWidget
/** A multi column listbox
* Features:
* - User resizeable columns.
* - The order of columns can be changed with drag&drop. (Alex)
* - 3 modes: Standard, SimpleOrder, ComplexOrder. (Alex)
* ToDo:
* - Configurable vertical column divisor lines.
* - Save all setting to config file.
* - fix flickering into column headers.
*/
class KTabListBox : public KDNDWidget
{
Q_OBJECT
friend KTabListBoxTable;
friend KTabListBoxColumn;
public:
enum ColumnType { TextColumn, PixmapColumn, MixedColumn };
enum OrderMode { Ascending, Descending };
enum OrderType { NoOrder, SimpleOrder, ComplexOrder };
KTabListBox (QWidget *parent=0, const char *name=0,
int columns=1, WFlags f=0);
virtual ~KTabListBox();
/** This enable the key-bindings (and set StrongFocus!)
* if you don't want StrongFocus you can implement your own keyPressEvent
* and send an event to KTabListBox from there... */
void enableKey(void) { lbox.enableKey(); }
/** Returns the number of rows */
uint count (void) const { return numRows(); };
/** Insert a line before given index, using the separator character to separate the fields. If no index is given the line is appended at the end. Returns index of inserted item. */
virtual void insertItem (const char* string, int itemIndex=-1);
/** Append a QStrList */
void appendStrList( QStrList const *strLst );
/** Same as insertItem, but always appends the new item. */
void appendItem (const char* string) { insertItem(string); }
/** Change contents of a line using the separator character to separate the fields. */
virtual void changeItem (const char* string, int itemIndex);
/** Change part of the contents of a line. */
virtual void changeItemPart (const char* string, int itemIndex, int column);
/** Change color of line. Changes last inserted item when itemIndex==-1 */
virtual void changeItemColor (const QColor& color, int itemIndex=-1);
/** Get number of pixels one tab character stands for. Default: 10 */
int tabWidth(void) const { return tabPixels; }
/** Set number of pixels one tab character stands for. Default: 10 */
virtual void setTabWidth(int);
/** Returns contents of given row/column. If col is not set the
contents of the whole row is returned, seperated with the current
seperation character. In this case the string returned is a
temporary string that will change on the next text() call on any
KTabListBox object. */
const QString& text(int idx, int col=-1) const;
/** Remove one item from the list. */
virtual void removeItem (int itemIndex);
/** Remove contents of listbox */
virtual void clear (void);
/** Return index of current item */
int currentItem (void) const { return current; }
/** Set the current (selected) column. colId is the value that
is transfered with the selected() signal that is emited. */
virtual void setCurrentItem (int idx, int colId=-1);
/** Unmark all items */
virtual void unmarkAll (void);
/** Mark/unmark item with index idx. */
virtual void markItem (int idx, int colId=-1);
virtual void unmarkItem (int idx);
/** Returns TRUE if item with given index is marked. */
virtual bool isMarked (int idx) const;
/** Find item at given screen y position. */
int findItem (int yPos) const { return (itemShowList[lbox.findRow(yPos)]); }
/** Returns first item that is currently displayed in the widget. */
int topItem (void) const { return (itemShowList[lbox.topCell()]); }
/** Change first displayed item by repositioning the visible part
of the list. */
void setTopItem (int idx) { lbox.setTopCell(itemPosList(idx)); }
/** Set number of columns. Warning: this *deletes* the contents
of the listbox. */
virtual void setNumCols (int);
/** Set number of rows in the listbox. The contents stays as it is. */
virtual void setNumRows (int);
/** See the docs for the QTableView class. */
int numRows (void) const { return lbox.numRows(); }
/** See the docs for the QTableView class. */
int numCols (void) const { return lbox.numCols(); }
/** See the docs for the QTableView class. */
int cellWidth (int col) { return lbox.cellWidth(col); }
/** See the docs for the QTableView class. */
int totalWidth (void) { return lbox.totalWidth(); }
/** See the docs for the QTableView class. */
int cellHeight (int row) { return lbox.cellHeight(row); }
/** See the docs for the QTableView class. */
int totalHeight (void) { return lbox.totalHeight(); }
/** See the docs for the QTableView class. */
int topCell (void) const { return itemShowList[lbox.topCell()]; }
/** See the docs for the QTableView class. */
int leftCell (void) const { return colShowList[lbox.leftCell()]; }
/** See the docs for the QTableView class. */
int lastColVisible (void) const { return colShowList[lbox.lastColVisible()]; }
/** See the docs for the QTableView class. */
int lastRowVisible (void) const { return itemShowList[lbox.lastRowVisible()]; }
/** See the docs for the QTableView class. */
bool autoUpdate (void) const { return lbox.autoUpdate(); }
/** See the docs for the QTableView class. */
void setAutoUpdate (bool upd) { lbox.setAutoUpdate(upd); }
/** See the docs for the QTableView class. */
void clearTableFlags(uint f=~0) { lbox.clearTableFlags(f); }
/** See the docs for the QTableView class. */
uint tableFlags(void) { return lbox.tableFlags(); }
/** See the docs for the QTableView class. */
bool testTableFlags(uint f) { return lbox.testTableFlags(f); }
/** See the docs for the QTableView class. */
void setTableFlags(uint f) { lbox.setTableFlags(f); }
/** See the docs for the QTableView class. */
int findCol(int x) { return lbox.findRealCol(x); }
/** See the docs for the QTableView class. */
int findRow(int y) { return itemShowList[lbox.findRow(y)]; }
/** See the docs for the QTableView class. */
bool colXPos(int col, int* x) { return lbox.colXPos(colPosList(col),x); }
/** See the docs for the QTableView class. */
bool rowYPos(int row, int* y) { return lbox.rowYPos(itemPosList(row),y); }
/** This call the 'compar' functions if they were been defined in
* setColumn or else use strcmp. (i.e. if you want a case-insensitive sort
* put strcasecmp in setColumn call).
* That compar function must take as arguments two char *, and must return
* an integer less than, equal to, or greater than zero if the first
* argument is considered to be respectively less than, equal to,
* or greater than the second. */
virtual void reorderRows();
/** Set column caption, width, type,order-type and order-mode */
virtual void setColumn (int col, const char* caption,
int width=0, ColumnType type=TextColumn,
OrderType ordt=NoOrder,
OrderMode omode=Descending,
bool verticalLine=false,
int (*compar)(const char *, const char *)=0L);
/** Set column width. */
virtual void setColumnWidth (int col, int width=0);
/** Get column width. */
int columnWidth (int col) { return lbox.cellWidth(col); }
/** Set default width of all columns. */
virtual void setDefaultColumnWidth(int width0, ...);
/** change the Ascending/Descending mode of column col.*/
void changeMode(int col);
/** Clear all number-check-buttons (ComplexOrder only) */
void clearAllNum();
/** Set separator character, e.g. '\t'. */
virtual void setSeparator (char sep) { sepChar = sep; }
/** Return separator character. */
virtual char separator (void) const { return sepChar; }
/** For convenient access to the dictionary of pictures that this listbox understands. */
KTabListBoxDict& dict (void) { return pixDict; }
void repaint (void);
/** Indicates that a drag has started with given item. Returns TRUE if we are dragging, FALSE if drag-start failed. */
bool startDrag(int col, int row, const QPoint& mousePos);
QPixmap& dndPixmap(void) { return dndDefaultPixmap; }
/** Read the config file entries in the group with the name of the listbox and set the default column widths and those. */
virtual void readConfig(void);
/** Write the config file entries in the group with the name of the listbox*/
virtual void writeConfig(void);
/** Return the actual position of the colum in the table.*/
int colPosList(int num);
/** Return the actual positon of the row number num.*/
int itemPosList(int num);
/** Get/set font of the table. font() and setFont() apply to the
caption only. */
const QFont& tableFont(void) const { return lbox.font(); }
void setTableFont(const QFont& fnt) { lbox.setFont(fnt); }
signals:
/** emited when the current item changes (either via setCurrentItem() or via mouse single-click). */
void highlighted (int Index, int column);
/** emitted when the user double-clicks into a line. */
void selected (int Index, int column);
/** emitted when the user presses the right mouse button over a line. */
void popupMenu (int Index, int column);
/** emitted when the user presses the middle mouse button over a line. */
void midClick (int Index, int column);
/** emitted when the user clicks on a column header. */
void headerClicked (int column);
protected slots:
void horSbValue(int val);
void horSbSlidingDone();
protected:
/** Used to create new column objects. Overwrite this method
* in a subclass to have your own column objects (e.g. with custom
* data in it). You will then also need customData()/setCustomData()
* methods in here that access the elememts in itemList[]. */
virtual KTabListBoxColumn* newKTabListBoxColumn(void);
bool itemVisible (int idx) { return lbox.rowIsVisible(idx); }
void updateItem (int idx, bool clear = TRUE);
bool needsUpdate (int id);
/// Internal method called by keyPressEvent.
void setCItem (int idx);
/// Adjust the number in the number check boxes.
void adjustNumber(int num);
// This should really go into kdecore and should be used by all
// apps that have long scrollable widgets.
void flushKeys();
/// For internal use.
bool recursiveSort(int level,int n,KTabListBoxColumn **c,int *iCol);
KTabListBoxItem* getItem (int idx);
const KTabListBoxItem* getItem (int idx) const;
virtual void keyPressEvent(QKeyEvent*);
virtual void resizeEvent (QResizeEvent*);
virtual void paintEvent (QPaintEvent*);
virtual void mouseMoveEvent(QMouseEvent*);
virtual void mousePressEvent(QMouseEvent*);
virtual void mouseReleaseEvent(QMouseEvent*);
/** Resize item array. Per default enlarge it to double size. */
virtual void resizeList (int newNumItems=-1);
/** Called to set drag data, size, and type. If this method returns FALSE then no drag occurs. */
virtual bool prepareForDrag (int col, int row, char** data, int* size,
int* type);
/** Internal method that handles resizing of columns with the mouse. */
virtual void doMouseResizeCol(QMouseEvent*);
/** Internal method that handles moving of columns with the mouse. */
virtual void doMouseMoveCol(QMouseEvent*);
// This array contain the list of columns as they are inserted.
KTabListBoxColumn** colList;
// This array contain the column numbers as they are shown.
int *colShowList;
// This array contain the row numbers as they are shown.
int *itemShowList;
KTabListBoxItem** itemList;
int maxItems, numColumns;
int current;
char sepChar;
KTabListBoxDict pixDict;
KTabListBoxTable lbox;
int labelHeight;
QPixmap dndDefaultPixmap;
QPixmap upPix,downPix;
QPixmap disabledUpPix,disabledDownPix;
int columnPadding;
QColor highlightColor;
int tabPixels;
bool mResizeCol;
bool stopOrdering;
bool needsSort;
/// contain the number of the last column where the user clicked on checkbutton.
int lastSelectedColumn;
int nMarked; //number of marked rows.
int mSortCol; // selected column for sorting order or -1
int mMouseCol; // column where the mouse action started
// (resize, click, reorder)
int mMouseColLeft; // left offset of mouse column
int mLastX; // Used for drawing the XORed rect in column-drag.
int mMouseColWidth; // width of mouse column
QPoint mMouseStart;
bool mMouseAction;
bool mMouseDragColumn; // true when dragging the header of a column.
private:
// Disabled copy constructor and operator=
KTabListBox (const KTabListBox &) {}
KTabListBox& operator= (const KTabListBox&) { return *this; }
};
//--------------------------------------------------
class KTabListBoxItem
{
public:
KTabListBoxItem(int numColumns=1);
virtual ~KTabListBoxItem();
virtual const QString& text(int column) const { return txt[column]; }
void setText (int column, const char *text) { txt[column] = text; }
virtual void setForeground (const QColor& fg ) { fgColor = fg; }
const QColor& foreground (void) { return fgColor; }
KTabListBoxItem& operator= (const KTabListBoxItem&);
int marked (void) const { return mark; }
bool isMarked (void) const { return (mark >= -1); }
virtual void setMarked (int m) { mark = m; }
private:
QString* txt;
int columns;
QColor fgColor;
int mark;
friend class KTabListBox;
};
typedef KTabListBoxItem* KTabListBoxItemPtr;
//--------------------------------------------------
class KTabListBoxColumn: public QObject
{
Q_OBJECT
public:
KTabListBoxColumn (KTabListBox* parent, int w=0);
virtual ~KTabListBoxColumn();
int width (void) const { return iwidth; }
virtual void setWidth (int w) { iwidth = w; }
int defaultWidth (void) const { return idefwidth; }
virtual void setDefaultWidth (int w) { idefwidth = w; }
virtual void setType (KTabListBox::ColumnType lbt) { colType = lbt; }
KTabListBox::ColumnType type (void) const { return colType; }
/// @return true if need repaint.
virtual bool changeMode (void);
virtual void setNumber(int num);
int number (void) const { return inumber;}
void hideCheckButton(void) { if(mbut) mbut->hide(); }
virtual void setOrder (KTabListBox::OrderType type,
KTabListBox::OrderMode mode);
KTabListBox::OrderType orderType (void) const {return ordtype;}
KTabListBox::OrderMode orderMode (void) const {return ordmode;}
virtual void paintCell (QPainter*, int row, const QString& string,
bool marked);
virtual void paint (QPainter*);
protected slots:
virtual void setButton();
virtual void resetButton();
virtual void clearAll(bool leftbutton);
protected:
int iwidth, idefwidth, inumber;
KTabListBox::OrderMode ordmode;
KTabListBox::OrderType ordtype;
KTabListBox::ColumnType colType;
KTabListBox* parent;
KNumCheckButton *mbut;
public:
int (*columnSort)(const char *, const char *);
bool vline; // if true print a vertical line to the end of column.
};
typedef KTabListBoxColumn* KTabListBoxColumnPtr;
inline KTabListBoxItem* KTabListBox :: getItem (int idx)
{
return ((idx>=0 && idx<maxItems) ? itemList[idx] : (KTabListBoxItem*)0L);
}
inline const KTabListBoxItem* KTabListBox :: getItem (int idx) const
{
return ((idx>=0 && idx<maxItems) ? itemList[idx] : (KTabListBoxItem*)0L);
}
#endif /*KTabListBox_h*/
Documentation generated by tasin@cd1 on Die Nov 30 17:32:00 CET 1999