// $Id$ #include "ktablistbox.h" #include #include #include #include #include #include #include #define INIT_MAX_ITEMS 16 #include "ktablistbox.moc" //============================================================================= // // C L A S S KTabListBoxItem // //============================================================================= KTabListBoxItem :: KTabListBoxItem (int aColumns) { columns = aColumns; txt = new QString[columns]; mark = -2; } KTabListBoxItem :: ~KTabListBoxItem () { if (txt) delete[] txt; txt = NULL; } void KTabListBoxItem :: setForeground (const QColor& fg) { fgColor = fg; } void KTabListBoxItem :: setMarked (int m) { mark = m; } KTabListBoxItem& KTabListBoxItem :: operator= (const KTabListBoxItem& from) { int i; for (i=0; ifontMetrics(); QPixmap* pix; switch (colType) { case KTabListBox::PixmapColumn: if (string) pix = parent->dict().find(string); else pix = NULL; if (pix) { paint->drawPixmap (0, 0, *pix); break; } /*else output as string*/ case KTabListBox::TextColumn: paint->drawText (3, fm->ascent() + (fm->leading()), (const char*)string); break; } } //----------------------------------------------------------------------------- void KTabListBoxColumn :: paint (QPainter* paint) { const QFontMetrics* fm = &paint->fontMetrics(); paint->drawText (3, fm->ascent() + (fm->leading()), (const char*)name()); } //============================================================================= // // C L A S S KTabListBox // //============================================================================= KTabListBox :: KTabListBox (QWidget *parent, const char *name, int columns, WFlags f): KTabListBoxInherited (parent, name, f), lbox(this) { const QFontMetrics* fm = &fontMetrics(); QString f; initMetaObject(); f = kapp->kdedir(); f.detach(); f += "/lib/pics/khtmlw_dnd.xpm"; dndDefaultPixmap.load(f.data()); maxItems = 0; current = -1; colList = NULL; itemList = NULL; sepChar = '\t'; labelHeight = fm->height() + 4; if (columns > 0) lbox.setNumCols(columns); lbox.setGeometry(0, labelHeight, width(), height()-labelHeight); } //----------------------------------------------------------------------------- KTabListBox :: ~KTabListBox () { if (colList) delete[] colList; if (itemList) delete[] itemList; colList = NULL; itemList = NULL; } //----------------------------------------------------------------------------- void KTabListBox :: setNumRows (int aRows) { lbox.setNumRows(aRows); } //----------------------------------------------------------------------------- void KTabListBox :: setNumCols (int aCols) { maxItems = 0; if (colList) delete[] colList; if (itemList) delete[] itemList; colList = NULL; itemList = NULL; if (aCols < 0) aCols = 0; lbox.setNumCols(aCols); if (aCols <= 0) return; colList = new KTabListBoxColumn[aCols](this); itemList = new KTabListBoxItem[INIT_MAX_ITEMS](aCols); maxItems = INIT_MAX_ITEMS; } //----------------------------------------------------------------------------- void KTabListBox :: setColumn (int col, const char* aName, int aWidth, ColumnType aType) { if (col<0 || col>=numCols()) return; colList[col].setWidth(aWidth); colList[col].setName(aName); colList[col].setType(aType); update(); } //----------------------------------------------------------------------------- void KTabListBox :: setCurrentItem (int idx, int colId) { int i; if (idx>=numRows()) return; unmarkAll(); if (idx != current) { i = current; current = idx; updateItem(i,FALSE); } if (current >= 0) { markItem(idx); emit highlighted(current, colId); } } //----------------------------------------------------------------------------- void KTabListBox :: markItem (int idx, int colId) { if (itemList[idx].marked()==colId) return; itemList[idx].setMarked(colId); updateItem(idx,FALSE); } //----------------------------------------------------------------------------- void KTabListBox :: unmarkItem (int idx) { int mark; mark = itemList[idx].marked(); itemList[idx].setMarked(-2); if (mark>=-1) updateItem(idx); } //----------------------------------------------------------------------------- void KTabListBox :: unmarkAll (void) { int i; for (i=numRows()-1; i>=0; i--) unmarkItem(i); } //----------------------------------------------------------------------------- void KTabListBox :: insertItem (const char* aStr, int row) { int i; if (row < 0) row = numRows(); if (row >= maxItems) resizeList(); for (i=numRows()-1; i>=row; i--) itemList[i+1] = itemList[i]; if (current >= row) current++; setNumRows (numRows()+1); changeItem (aStr, row); if (needsUpdate(row)) lbox.repaint(); } //----------------------------------------------------------------------------- void KTabListBox :: changeItem (const char* aStr, int row) { char* str; char sepStr[2]; char* pos; int i; KTabListBoxItem* item; if (row < 0 || row >= numRows()) return; str = new char[strlen(aStr)+2]; strcpy (str, aStr); sepStr[0] = sepChar; sepStr[1] = '\0'; item = &itemList[row]; pos = strtok (str, sepStr); for (i=0; pos && *pos && isetText (i, pos); pos = strtok (NULL, sepStr); } item->setForeground (black); if (needsUpdate(row)) lbox.repaint(); delete str; } //----------------------------------------------------------------------------- void KTabListBox :: changeItem (const char* aStr, int row, int col) { if (row < 0 || row >= numRows()) return; if (col < 0 || col >= numCols()) return; itemList[row].setText (col, aStr); if (needsUpdate(row)) lbox.repaint(); } //----------------------------------------------------------------------------- void KTabListBox :: changeItemColor (const QColor& newColor, int row) { if (row >= numRows()) return; if (row < 0) row = numRows()-1; itemList[row].setForeground (newColor); if (needsUpdate(row)) lbox.repaint(); } //----------------------------------------------------------------------------- void KTabListBox :: removeItem (int row) { int i, nr; if (row < 0 || row >= numRows()) return; if (current > row) current--; nr = numRows()-1; for (i=row; i=0; i--) lbox.updateCell (row, i, erase); } //----------------------------------------------------------------------------- void KTabListBox :: clear (void) { int i; for (i=numRows()-1; i>=0; i--) itemList[i].setMarked(-2); setNumRows(0); lbox.setTopLeftCell(0,0); current = -1; } //----------------------------------------------------------------------------- void KTabListBox :: setSeparator (char sep) { sepChar = sep; } //----------------------------------------------------------------------------- void KTabListBox :: resizeList (int newNumItems) { KTabListBoxItem* newItemList; int i, ih; if (newNumItems < 0) newNumItems = (maxItems << 1); if (newNumItems < INIT_MAX_ITEMS) newNumItems = INIT_MAX_ITEMS; newItemList = new KTabListBoxItem[newNumItems](numCols()); ih = newNumItems=0; i--) { newItemList[i] = itemList[i]; } delete[] itemList; itemList = newItemList; maxItems = newNumItems; setNumRows(ih); } //----------------------------------------------------------------------------- void KTabListBox :: resizeEvent (QResizeEvent* e) { KTabListBoxInherited::resizeEvent(e); lbox.setGeometry (0, labelHeight, e->size().width(), e->size().height()-labelHeight); lbox.reconnectSBSignals(); repaint(); } //----------------------------------------------------------------------------- void KTabListBox :: paintEvent (QPaintEvent* e) { int i, ih, x, w; QPainter paint; QWMatrix matrix; QRect clipR; QColorGroup colGrp; ih = numCols(); x = -lbox.xOffset(); matrix.translate (x, 0); //if (!isUpdatesEnabled()) return; paint.begin(this); for (i=0; i= 0) { clipR.setRect (x, 0, w, labelHeight); paint.setWorldMatrix (matrix, FALSE); paint.setClipRect (clipR); colList[i].paint (&paint); qDrawShadePanel (&paint, 0, 0, w, labelHeight, KTabListBoxInherited::colorGroup()); } matrix.translate (w, 0); x += w; } paint.end(); } //----------------------------------------------------------------------------- bool KTabListBox :: startDrag (int aCol, int aRow, const QPoint& p) { int dx = -(dndDefaultPixmap.width() >> 1); int dy = -(dndDefaultPixmap.height() >> 1); KDNDIcon* icon = new KDNDIcon(dndDefaultPixmap, p.x()+dx, p.y()+dy); int size, type; char* data; if (!prepareForDrag(aCol,aRow, &data, &size, &type)) return FALSE; KTabListBoxInherited::startDrag(icon, data, size, type, dx, dy); return TRUE; } //----------------------------------------------------------------------------- bool KTabListBox :: prepareForDrag (int aCol, int aRow, char** data, int* size, int* type) { return FALSE; } //----------------------------------------------------------------------------- void KTabListBox :: horSbValue (int val) { update(); } //----------------------------------------------------------------------------- void KTabListBox :: horSbSlidingDone () { printf ("sliding done\n"); } //============================================================================= // // C L A S S KTabListBoxTable // //============================================================================= QPoint KTabListBoxTable::dragStartPos; int KTabListBoxTable::dragCol = -1; int KTabListBoxTable::dragRow = -1; int KTabListBoxTable::selIdx = -1; KTabListBoxTable :: KTabListBoxTable (KTabListBox *parent): KTabListBoxTableInherited (parent) { QFontMetrics fm = fontMetrics(); initMetaObject(); dragging = FALSE; setTableFlags (Tbl_autoVScrollBar|Tbl_autoHScrollBar|Tbl_smoothVScrolling| Tbl_clipCellPainting); switch (style()) { case MotifStyle: case WindowsStyle: setBackgroundColor (colorGroup().base()); setFrameStyle( QFrame::WinPanel | QFrame::Sunken ); break; default: setLineWidth (1); setFrameStyle (QFrame::Panel|QFrame::Plain); } setCellWidth (0); setCellHeight (fm.lineSpacing() + 1); setNumRows (0); setFocusPolicy (StrongFocus); } //----------------------------------------------------------------------------- KTabListBoxTable :: ~KTabListBoxTable() { } //----------------------------------------------------------------------------- void KTabListBoxTable :: paintCell (QPainter* p, int row, int col) { QColor bg; QColorGroup g = colorGroup(); KTabListBox* owner = (KTabListBox*)parentWidget(); KTabListBoxItem* item = owner->getItem(row); if (!item) return; if (item->marked()==-1) { bg = g.background(); p->fillRect (0, 0, cellWidth(col), cellHeight(row), bg); } p->setPen (item->foreground()); p->setBackgroundColor (g.base()); owner->colList[col].paintCell (p, item->text(col)); } //----------------------------------------------------------------------------- int KTabListBoxTable :: cellWidth (int col) { KTabListBox* owner = (KTabListBox*)parentWidget(); return (owner->colList ? owner->colList[col].width() : 0); } //----------------------------------------------------------------------------- void KTabListBoxTable :: mouseDoubleClickEvent (QMouseEvent* e) { KTabListBox* owner = (KTabListBox*)parentWidget(); int idx, colnr; //mouseReleaseEvent(event); idx = owner->currentItem(); colnr = findCol(e->pos().x()); if (idx >= 0) emit owner->selected(idx,colnr); } //----------------------------------------------------------------------------- void KTabListBoxTable :: doItemSelection (QMouseEvent* e, int idx) { KTabListBox* owner = (KTabListBox*)parentWidget(); int i, di; owner->unmarkAll(); if ((e->state()&ShiftButton)!=0 && owner->currentItem()>=0) { i = owner->currentItem(); di = (i>idx ? -1 : 1); while (1) { owner->markItem(i); if (i == idx) break; i += di; } } else owner->setCurrentItem(idx); } //----------------------------------------------------------------------------- void KTabListBoxTable :: mousePressEvent (QMouseEvent* e) { KTabListBox* owner = (KTabListBox*)parentWidget(); int idx; // arm for possible dragging dragStartPos = e->pos(); dragCol = findCol(e->pos().x()); dragRow = findRow(e->pos().y()); // handle item highlighting idx = findRow(e->pos().y()); if (idx >= 0 && owner->getItem(idx)->marked() < -1) { doItemSelection(e, idx); selIdx = idx; } else selIdx = -1; } //----------------------------------------------------------------------------- void KTabListBoxTable :: mouseReleaseEvent (QMouseEvent* e) { KTabListBox* owner = (KTabListBox*)parentWidget(); int idx; if (dragging) { owner->mouseReleaseEvent(e); dragRow = dragCol = -1; dragging = FALSE; } else { idx = findRow(e->pos().y()); if (idx >= 0 && selIdx < 0) doItemSelection(e, idx); } } //----------------------------------------------------------------------------- void KTabListBoxTable :: mouseMoveEvent (QMouseEvent* e) { KTabListBox* owner = (KTabListBox*)parentWidget(); if (dragging) { owner->mouseMoveEvent(e); return; } if ((e->state() & (RightButton|LeftButton|MidButton)) != 0) { if (dragRow >= 0 && dragCol >= 0 && (abs(e->pos().x()-dragStartPos.x()) >= 5 || abs(e->pos().y()-dragStartPos.y()) >= 5)) { // we have a liftoff ! dragging = owner->startDrag(dragCol, dragRow, mapToGlobal(e->pos())); return; } } } //----------------------------------------------------------------------------- void KTabListBoxTable :: reconnectSBSignals (void) { QWidget* hsb = (QWidget*)horizontalScrollBar(); KTabListBox* owner = (KTabListBox*)parentWidget(); if (!hsb) return; connect(hsb, SIGNAL(valueChanged(int)), owner, SLOT(horSbValue(int))); connect(hsb, SIGNAL(sliderReleased()), owner, SLOT(horSbSlidingDone())); }