📄 ktreelist.cpp
字号:
/* qktstreelist.cpp-------------------------------------------------------------------$Id: ktreelist.cpp,v 1.1 2003/09/08 19:42:12 jasonk Exp $ KTreeList class implementationCopyright (C) 1996 Keith Brown and KtSoftThis program is free software; you can redistribute it and/or modifyit under the terms of the GNU Library General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNULibrary General Public License for more details. You should have received acopy of the GNU Library General Public License along with this program; ifnot, write to the Free Software Foundation, Inc, 675 Mass Ave, Cambridge, MA 02139, USA. -------------------------------------------------------------------*/#include <ktreelist.h>#include "ktreelist.h"#ifdef HAVE_CONFIG_H#include <config.h>#endif/* -------------------------------------------------------------------KTreeListItem -------------------------------------------------------------------*/// constructorKTreeListItem::KTreeListItem(const char *theText, const QPixmap* thePixmap): branch(0), indent(22), // seems to be a good default value numChildren(0), doExpandButton(TRUE), expanded(FALSE), doTree(TRUE), doText(TRUE), child(0), parent(0), sibling(0){ if(theText) text = theText; if(thePixmap) pixmap = *thePixmap;}// destructorKTreeListItem::~KTreeListItem(){ // anything need to be done here?}// adds child to internal list and fixes pointers, branch and child countvoid KTreeListItem::appendChild(KTreeListItem *newChild){ newChild->setParent(this); newChild->setBranch(branch + 1); if(!getChild()) setChild(newChild); else { KTreeListItem *lastChild = getChild(); while(lastChild->hasSibling()) lastChild = lastChild->getSibling(); lastChild->setSibling(newChild); } numChildren++;}// returns the bounding rectangle of the item content (not including indent// and branches) for hit testingQRect KTreeListItem::boundingRect(const QFontMetrics& fm) const{ int rectX = 3 + indent + branch * indent; int rectY = 1; int rectW = itemWidth(fm) - rectX; int rectH = itemHeight(fm) - 2; return QRect(rectX, rectY, rectW, rectH);}// returns the child item at the specified indexKTreeListItem *KTreeListItem::childAt(int index){ if(!hasChild()) return 0; int counter = 0; KTreeListItem *item = getChild(); while(counter != index && item) { item = item->getSibling(); counter++; } return item;}// returns the number of children this item hasuint KTreeListItem::childCount() const{ return numChildren;}// returns the index of the given child item in this item's branchint KTreeListItem::childIndex(KTreeListItem *theChild){ int counter = 0; KTreeListItem *item = getChild(); while(item && item != theChild) { item = item->getSibling(); counter++; } if(item) return counter; return -1;}// indicates wheter expand button will be displayedbool KTreeListItem::drawExpandButton() const{ return doExpandButton;}// indicates whether item text will be displayedbool KTreeListItem::drawText() const{ return doText;}// indicates whether tree branches will be drawnbool KTreeListItem::drawTree() const{ return doTree;}// indicates whether mouse press is in expand buttoninline bool KTreeListItem::expandButtonClicked(const QPoint& coord) const{ return expandButton.contains(coord);}// returns the branch level of this itemint KTreeListItem::getBranch() const{ return branch;}// returns a pointer to first child itemKTreeListItem *KTreeListItem::getChild(){ return child;}// returns the indent spacing of this itemint KTreeListItem::getIndent() const{ return indent;}// returns the parent of this itemKTreeListItem *KTreeListItem::getParent(){ return parent;}// returns reference to the item pixmapconst QPixmap *KTreeListItem::getPixmap() const{ return &pixmap;}// returns the sibling below this itemKTreeListItem *KTreeListItem::getSibling(){ return sibling;}// returns a pointer to the item textconst char *KTreeListItem::getText() const{ return text; // implicit cast to char *!}// indicates whether this item has any childrenbool KTreeListItem::hasChild() const{ return child != 0;}// indicates whether this item has a parentbool KTreeListItem::hasParent() const{ return parent != 0;}// indicates whether this item has a sibling below itbool KTreeListItem::hasSibling() const{ return sibling != 0;}// returns the the height of the cellint KTreeListItem::height(const KTreeList *theOwner) const{ return itemHeight(theOwner->fontMetrics());}// inserts child item at specified index in branch and fixes// pointers, branch and child countvoid KTreeListItem::insertChild(int index, KTreeListItem *newChild){ if(index == -1) { appendChild(newChild); return; } newChild->setParent(this); newChild->setBranch(branch + 1); if(index == 0) { newChild->setSibling(getChild()); setChild(newChild); } else { int counter = 1; KTreeListItem *prevItem = getChild(); KTreeListItem *nextItem = prevItem->getSibling(); while(counter != index && nextItem) { prevItem = nextItem; nextItem = prevItem->getSibling(); counter++; } prevItem->setSibling(newChild); newChild->setSibling(nextItem); } numChildren++;}// indicates whether this item is displayed expanded // NOTE: a TRUE response does not necessarily indicate the item // has any childrenbool KTreeListItem::isExpanded() const{ return expanded;}// paint this item, including tree branches and expand buttonvoid KTreeListItem::paint(QPainter *p, const QColorGroup& cg, bool highlighted){ p->save(); p->setPen(cg.text()); p->setBackgroundColor(cg.base()); // precalculate positions int cellHeight = itemHeight(p->fontMetrics()); int pixmapX = 3 + indent + branch * indent; int pixmapY = (cellHeight - pixmap.height()) / 2; int parentLeaderX = pixmapX - (indent / 2); int itemLeaderX = pixmapX - 1; int cellCenterY = cellHeight / 2; int cellBottomY = cellHeight - 1; if(doTree) { // if this is not the first item in the tree // draw the line up towards parent or sibling if(!(parent->getBranch() == -1 && parent->getChild() == this)) p->drawLine(parentLeaderX, 0, parentLeaderX, cellCenterY); // draw the line down towards sibling if(sibling) p->drawLine(parentLeaderX, cellCenterY, parentLeaderX, cellBottomY); // if this item has children or siblings in the tree or is a child of // an item other than the root item then // draw the little line from the item out to the left if(sibling || (child && doExpandButton) || (parent && (branch > 0 || (branch == 0 && parent->getChild() != this)))) p->drawLine(parentLeaderX, cellCenterY, itemLeaderX, cellCenterY); // if there are siblings of ancestors below, draw our portion of // the branches that extend through this cell KTreeListItem *prevRoot = parent; for(int i = 1; i <= branch; i++) { if(prevRoot->hasSibling()) { int sibLeaderX = parentLeaderX - i * indent; p->drawLine(sibLeaderX, 0, sibLeaderX, cellBottomY); } prevRoot = prevRoot->getParent(); } } // if this item has at least one child and expand button drawing is enabled, // set the rect for the expand button for later mouse press bounds checking, // and draw the button if(doExpandButton && child) { expandButton.setRect(parentLeaderX - 4, cellCenterY - 4, 9, 9); p->setBrush( cg.base () ); p->drawRect(expandButton); if(expanded) p->drawLine(parentLeaderX - 2, cellCenterY, parentLeaderX + 2, cellCenterY); else { p->drawLine(parentLeaderX - 2, cellCenterY, parentLeaderX + 2, cellCenterY); p->drawLine(parentLeaderX, cellCenterY - 2, parentLeaderX, cellCenterY + 2); } p->setBrush(NoBrush); } // now draw the item pixmap and text, if applicable p->drawPixmap(pixmapX, pixmapY, pixmap); if(doText) { int textX = pixmapX + pixmap.width() + 4; int textY = cellHeight - ((cellHeight - p->fontMetrics().ascent() - p->fontMetrics().leading()) / 2); if(highlighted) { if(QApplication::style() == WindowsStyle) { p->setPen(white); p->setBackgroundColor(QApplication::winStyleHighlightColor()); } else { p->setPen(cg.base()); p->setBackgroundColor(cg.text()); } } else { p->setPen(cg.text()); p->setBackgroundColor(cg.base()); } p->drawText(textX, textY, text); } p->restore();}// removes the given child from the branchvoid KTreeListItem::removeChild(KTreeListItem *theChild){ KTreeListItem *prevItem = 0; KTreeListItem *toRemove = getChild(); while(toRemove && toRemove != theChild) { prevItem = toRemove; toRemove = toRemove->getSibling(); } if(toRemove) { if(!prevItem) setChild(toRemove->getSibling()); else prevItem->setSibling(toRemove->getSibling()); numChildren--; }}// sets the branch level of this itemvoid KTreeListItem::setBranch(int level){ branch = level;}// sets child pointer to the given itemvoid KTreeListItem::setChild(KTreeListItem *newChild){ child = newChild;}// sets the draw expand button flag of this itemvoid KTreeListItem::setDrawExpandButton(bool doit){ doExpandButton = doit;}// sets the draw text flag of this itemvoid KTreeListItem::setDrawText(bool doit){ doText = doit;}// sets the draw tree branch flag of this itemvoid KTreeListItem::setDrawTree(bool doit){ doTree = doit;}// sets the expanded flag of this itemvoid KTreeListItem::setExpanded(bool is){ expanded = is;}// sets the indent spacing of this itemvoid KTreeListItem::setIndent(int value){ indent = value;}// sets the parent to the given itemvoid KTreeListItem::setParent(KTreeListItem *newParent){ parent = newParent;}// sets the item pixmap to the given pixmapvoid KTreeListItem::setPixmap(const QPixmap *pm){ pixmap = *pm;}// sets the item's sibling to the given itemvoid KTreeListItem::setSibling(KTreeListItem *newSibling){ sibling = newSibling;}// sets the item text to the given stringvoid KTreeListItem::setText(const char *t){ text = t;}// returns the bounding rect of the item text in cell coordinates// couldn't get QFontMetrics::boundingRect() to work right// so I made my ownQRect KTreeListItem::textBoundingRect(const QFontMetrics& fm) const{ int cellHeight = itemHeight(fm); int rectX = 3 + indent + branch * indent + pixmap.width() + 3; int rectY = (cellHeight - fm.ascent() - fm.leading()) / 2 + 2; int rectW = fm.width(text) + 1; int rectH = fm.ascent() + fm.leading(); return QRect(rectX, rectY, rectW, rectH);}QRect KTreeListItem::itemBoundingRect(const QFontMetrics& fm) const{ int rectX = indent + branch * indent + 2; int rectY = 4; int rectW = fm.width(text) + pixmap.width() + 6; int rectH = ((pixmap.height() > fm.lineSpacing()) ? pixmap.height() : fm.lineSpacing()) + 2; return QRect(rectX, rectY, rectW, rectH);}// returns the cell's widthint KTreeListItem::width(const KTreeList *theOwner) const{ return itemWidth(theOwner->fontMetrics());}// returns the maximum height of text and pixmap including margins// or -1 if item is empty -- SHOULD NEVER BE -1!int KTreeListItem::itemHeight(const QFontMetrics& fm) const{ int maxHeight = pixmap.height(); int textHeight = fm.ascent() + fm.leading(); maxHeight = textHeight > maxHeight ? textHeight : maxHeight; return maxHeight == 0 ? -1 : maxHeight + 8;}// returns the total width of text and pixmap, including margins, spacing// and indent, or -1 if empty -- SHOULD NEVER BE -1!int KTreeListItem::itemWidth(const QFontMetrics& fm) const{ int maxWidth = pixmap.width(); maxWidth += (4 + fm.width(text)); return maxWidth == 0 ? -1 : indent + maxWidth + indent * branch + 6;}// returns the bounding rect of the item text in cell relative// coordinates/*-------------------------------------------------------------------KTreeList -------------------------------------------------------------------*/// constructorKTreeList::KTreeList(QWidget *parent, const char *name, WFlags f): QTableView(parent, name, f), clearing(FALSE), current(-1),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -