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

listview.cpp

/*
      Description: qgit revision list view

      Author: Marco Costalba (C) 2005-2006

      Copyright: See COPYING file that comes with this distribution

*/
#include <qlistview.h>
#include <qpainter.h>
#include <qbitmap.h>
#include <qapplication.h>
#include <qstatusbar.h>
#include <qheader.h>
#include <qpopupmenu.h>
#include <qdragobject.h>
#include "common.h"
#include "domain.h"
#include "git.h"
#include "mainimpl.h"
#include "listview.h"

using namespace QGit;

ListView::ListView(Domain* dm, Git* g, QListView* l, FileHistory* f) :
                   QObject(dm), d(dm), git(g), lv(l), fh(f) {

      st = &(d->st);
      processedRevs = 0;
      diffTarget = NULL;
      filterNextContextMenuRequest = false;
      setupListView();

      lv->setAcceptDrops(fh == NULL);
      lv->viewport()->setAcceptDrops(fh == NULL);
      lv->viewport()->installEventFilter(this); // filter out some right clicks

      if (testFlag(REL_DATE_F))
            lv->setColumnText(TIME_COL, "Last Change");
      else
            lv->setColumnText(TIME_COL, "Author Date");

      connect(lv, SIGNAL(currentChanged(QListViewItem*)),
              this, SLOT(on_currentChanged(QListViewItem*)));

      connect(lv, SIGNAL(contentsMoving(int,int) ),
              this, SLOT(on_contentsMoving(int,int)));

      connect(lv, SIGNAL(mouseButtonPressed(int,QListViewItem*,const QPoint&,int)),
              this, SLOT(on_mouseButtonPressed(int,QListViewItem*,const QPoint&,int)));

      connect(lv, SIGNAL(clicked(QListViewItem*)),
              this, SLOT(on_clicked(QListViewItem*)));

      connect(lv, SIGNAL(onItem(QListViewItem*)),
              this, SLOT(on_onItem(QListViewItem*)));

      connect(lv, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&,int)),
              this, SLOT(on_contextMenuRequested(QListViewItem*)));
}

ListView::~ListView() {

      git->cancelDataLoading(fh); // blocking
}

void ListView::setupListView() {

      lv->setItemMargin(0);
      lv->setSorting(-1);

      int adj = (fh) ? 0 : -1;

      lv->setColumnWidthMode(GRAPH_COL, QListView::Manual);
      lv->setColumnWidthMode(COMMIT_COL, QListView::Manual);
      lv->setColumnWidthMode(LOG_COL + adj, QListView::Manual);
      lv->setColumnWidthMode(AUTH_COL + adj, QListView::Manual);
      lv->hideColumn(COMMIT_COL);

      lv->setColumnWidth(GRAPH_COL, DEF_GRAPH_COL_WIDTH);
      lv->setColumnWidth(LOG_COL + adj, DEF_LOG_COL_WIDTH);
      lv->setColumnWidth(AUTH_COL + adj, DEF_AUTH_COL_WIDTH);
      lv->setColumnWidth(TIME_COL + adj, DEF_TIME_COL_WIDTH);

      if (fh == NULL) {
            lv->setColumnWidthMode(DUMMY_COL, QListView::Manual);
            lv->hideColumn(DUMMY_COL);
      }
      lv->setFont(lv->font()); // use main list as reference
}

void ListView::repaintAll(QFont& f) {

      QListViewItemIterator it(lv);
      while (it.current()) {
            it.current()->setPixmap(GRAPH_COL, NULL);
            ++it;
      }
      lv->setFont(f);
      lv->ensureItemVisible(lv->currentItem());
}

void ListView::clear() {

      git->cancelDataLoading(fh);
      lv->clear();
      processedRevs = 0;
      diffTarget = NULL; // avoid a dangling pointer
}

void ListView::updateIdValues() {

      if (fh == NULL)
            return;

      int id = (int)lv->childCount();
      QListViewItem* item = lv->firstChild();
      while (item) {
            item->setText(ANN_ID_COL, QString::number(id) + "  ");
            --id;
            item = item->itemBelow();
      }
}

void ListView::getSelectedItems(QStringList& selectedItems) {

      selectedItems.clear();
      QListViewItem* item = lv->firstChild();
      while (item != 0) {
            if (item->isSelected())
                  selectedItems.append(item->text(COMMIT_COL));
            item = item->itemBelow();
      }
}

const QString ListView::getSha(int id) {

      if (fh == NULL)
            return "";

      // check to early skip common case of list mouse browsing
      QListViewItem* item = lv->currentItem();
      if (item && item->text(ANN_ID_COL).toInt() == id)
            return item->text(COMMIT_COL);

      item = lv->firstChild();
      while (item) {
            if (item->text(ANN_ID_COL).toInt() == id)
                  return item->text(COMMIT_COL);

            item = item->itemBelow();
      }
      return "";
}

void ListView::setHighlight(SCRef diffToSha) {

      if (diffTarget && diffTarget->text(COMMIT_COL) == diffToSha)
            return;

      // remove highlight on any previous target
      if (diffTarget) {
            diffTarget->setDiffTarget(false);
            diffTarget = NULL;
      }
      if (diffToSha.isEmpty())
            return;

      QListViewItem* item = lv->findItem(diffToSha, COMMIT_COL);
      diffTarget = static_cast<ListViewItem*>(item);
      if (diffTarget && (diffTarget->text(COMMIT_COL) != ZERO_SHA))
            diffTarget->setDiffTarget(true); // do highlight
}

bool ListView::update() {

      QListViewItem* newItem = NULL;
      QListViewItem* item = lv->currentItem();
      SCRef curSha = (item) ? item->text(COMMIT_COL) : "";
      bool shaChanged = (st->sha() != curSha);

      if (shaChanged) {
            // setCurrentItem() does not clear previous
            // selections in a multi selection QListView
            lv->clearSelection();

            newItem = lv->findItem(st->sha(), COMMIT_COL);
            if (!newItem)
                  return false; // do not change anything in this case
      }
      if (fh == NULL)
            setHighlight(st->diffToSha());

      if (shaChanged) {
            lv->setCurrentItem(newItem); // calls on_currentChanged()
            lv->setSelected(newItem, st->selectItem());
            lv->ensureItemVisible(newItem);
      } else
            lv->setSelected(item, st->selectItem()); // just a refresh

      return true;
}

// ************************************ SLOTS ********************************

void ListView::on_newRevsAdded(const FileHistory* f, const QValueVector<QString>& shaVec) {

      if (f != fh)
            return;

      bool evenLine = !(lv->childCount() % 2);

      if (lv->childCount() == 0)
            lastItem = NULL;

      for (uint i = processedRevs; i < shaVec.count(); i++) {
            lastItem = new ListViewItem(lv, lastItem, git, shaVec[i], d->m()->pixmaps,
                                        evenLine, d->m()->secs, fh);
            evenLine = !evenLine;
      }
      processedRevs = shaVec.count();
}

void ListView::on_currentChanged(QListViewItem* item) {

      if (!item)
            return;

      SCRef selRev(item->text(COMMIT_COL));
      if (st->sha() != selRev) { // to avoid looping
            st->setSha(selRev);
            st->setSelectItem(true);
            UPDATE_DOMAIN(d);
      }
}

void ListView::on_mouseButtonPressed(int b, QListViewItem* item, const QPoint&, int) {

      if (item && b == Qt::LeftButton)
            d->setReadyToDrag(true);
}

void ListView::on_clicked(QListViewItem*) {

      d->setReadyToDrag(false); // in case of just click without moving
}

void ListView::on_onItem(QListViewItem*) {

      if (d->isReadyToDrag()) {
            if (!d->setDragging(true))
                  return;

            QStringList dragRevs;
            getSelectedItems(dragRevs);
            if (!dragRevs.contains(ZERO_SHA)) {

                  const QString host(QString::fromLatin1("@") + d->m()->curDir);
                  QStringList::iterator it(dragRevs.begin());
                  for ( ; it != dragRevs.end(); ++it)
                        (*it).append(host);

                  QDragObject* drObj = new QTextDrag(dragRevs.join("\n"), lv);
                  drObj->dragCopy(); // do NOT delete drObj. Blocking until drop event
            }
            d->setDragging(false);
      }
}

void ListView::on_contextMenuRequested(QListViewItem* item) {

      if (!item)
            return;

      if (filterNextContextMenuRequest) {
            // event filter does not work on them
            filterNextContextMenuRequest = false;
            return;
      }
      emit contextMenu(item->text(COMMIT_COL), POPUP_LIST_EV);
}

void ListView::on_contentsMoving(int, int newY) {
// in case of very big archives pixmap memory can became huge.
// so we free pixmap memory for not visible items, avoiding
// traversing the list and using only the fast iterator
// itemBelow() and NOT the slower itemAbove()

      int ph = d->m()->ph;
      int h = lv->visibleHeight();
      if (lv->childCount() < h / ph + 10)
            return;

      int curY, dummy;
      lv->viewportToContents(0, 0, dummy, curY);
      int delta = newY - curY;
      QListViewItem* it;
      if (delta > 0)
            it = lv->itemAt(QPoint(0, 0));
      else {
            it = lv->itemAt(QPoint(0, h + delta));
            delta = -delta;
            if (it)
                  it = it->itemBelow();
      }
      if (!it)
            return;

      int cnt = 0;
      delta /= ph;
      while (cnt++ < delta) {
            it->setPixmap(GRAPH_COL, NULL); // free pixmap memory
            it = it->itemBelow();
            if (!it)
                  break;
      }
}

bool ListView::eventFilter(QObject* obj, QEvent* ev) {
// we need an event filter for:
//  - filter out some right click mouse events
//  - intercept drop events sent to listview

      if (obj == lv->viewport() && ev->type() == QEvent::MouseButtonPress) {
            QMouseEvent* e = static_cast<QMouseEvent*>(ev);
            if (e->button() == Qt::RightButton)
                  return filterRightButtonPressed(e);
      }
      if (obj == lv->viewport() && ev->type() == QEvent::Drop) {
            QDropEvent* e = static_cast<QDropEvent*>(ev);
            return filterDropEvent(e);
      }
      return QObject::eventFilter(obj, ev);
}

bool ListView::filterRightButtonPressed(QMouseEvent* e) {

      ListViewItem* item = static_cast<ListViewItem*>(lv->itemAt(e->pos()));
      if (item == NULL)
            return false;

      if (e->state() == Qt::ControlButton) { // check for 'diff to' function

            SCRef diffToSha(item->text(COMMIT_COL));

            if (diffToSha != ZERO_SHA && st->sha() != ZERO_SHA) {

                  if (diffToSha != st->diffToSha())
                        st->setDiffToSha(diffToSha);
                  else
                        st->setDiffToSha(""); // restore std view

                  UPDATE_DOMAIN(d);
                  filterNextContextMenuRequest = true;
                  return true; // filter event out
            }
      }
      // check for 'childs & parents' function, i.e. if mouse is on the graph
      int col = lv->header()->sectionAt(e->pos().x());
      if (col == GRAPH_COL) {
            QStringList parents, childs;
            if (getLaneParentsChilds(item, e->pos().x(), parents, childs))
                  emit lanesContextMenuRequested(parents, childs);
            return true; // filter event out
      }
      return false;
}

bool ListView::getLaneParentsChilds(ListViewItem* item, int x, SList p, SList c) {

      uint lane = x / d->m()->pw;
      int t = item->getLaneType(lane);
      if (t == EMPTY || t == -1)
            return false;

      // first find the parents
      p.clear();
      SCRef sha(item->text(COMMIT_COL));
      bool freeLane = isFreeLane(t);
      if (!freeLane)
            p = git->revLookup(sha)->parents(); // cannot be NULL pointer
      else {
            SCRef par(git->getLaneParent(sha, lane));
            if (par.isEmpty()) {
                  qDebug("ASSERT getLaneParentsChilds: parent not found");
                  return false;
            }
            p.append(par);
      }
      // then find childs
      SCRef root(freeLane ? p.first() : sha);
      c = git->getChilds(root);
      return true;
}

bool ListView::filterDropEvent(QDropEvent* e) {

      QString text;
      if (QTextDrag::decode(e, text)) {

            const QStringList& remoteRevs(QStringList::split('\n', text));
            SCRef remoteRepo(remoteRevs[0].section('@', 1));
            SCRef sha(remoteRevs[0].section('@', 0, 0));

            if (sha.length() == 40 && !remoteRepo.isEmpty())
                  emit droppedRevisions(sha, remoteRevs, remoteRepo);
      }
      return true; // filter out
}

// ****************************** ListViewItem *****************************

ListViewItem::ListViewItem(QListView* p, ListViewItem* a, Git* g, SCRef sha,
      const QPtrVector<QPixmap>& pm, bool e, unsigned long t, FileHistory* f) :
      QListViewItem(p, a), pms(pm) {

      git = g;
      isEvenLine = e;
      secs = t;
      fh = f;
      populated = isDiffTarget = isHighlighted = false;
      setText(COMMIT_COL, sha); // item key, must be set from beginning
}

int ListViewItem::getLaneType(uint pos) const {

      const Rev* r = git->revLookup(text(COMMIT_COL), fh); // cannot be NULL
      return (pos < r->lanes.count() ? r->lanes[pos] : -1);
}

void ListViewItem::setDiffTarget(bool b) {

      isDiffTarget = b;
      repaint();
}

void ListViewItem::paintCell(QPainter* p, const QColorGroup& cg,
                             int column, int width, int alignment) {
      QColorGroup _cg(cg);
      const Rev& c = *git->revLookup(text(COMMIT_COL), fh);

      // lazy setup, only when visible
      if (!populated)
            setupData(c);

      // pixmap graph, separated from setupData to allow deleting
      if (!pixmap(GRAPH_COL)) {
            QPixmap* pm = getGraph(c);
            setPixmap(GRAPH_COL, *pm);
            delete pm;
      }
      // adjust for annotation id column presence
      int mycolumn = (fh) ? column : column + 1;

      // alternate background color
      if (isInfoCol(mycolumn))
            _cg.setColor(QColorGroup::Base, isEvenLine ? EVEN_LINE_COL : ODD_LINE_COL);

      // tags, heads, refs and working dir colouring
      if (mycolumn == LOG_COL) {

            if (isHighlighted) {
                  QFont f(p->font());
                  f.setBold(true);
                  p->save();
                  p->setFont(f);
            }
            if (c.isDiffCache) {
                  if (changedFiles(ZERO_SHA))
                        _cg.setColor(QColorGroup::Base, ORANGE);
                  else
                        _cg.setColor(QColorGroup::Base, DARK_ORANGE);
            }
      }
      // diff target colouring
      if (isDiffTarget && isInfoCol(mycolumn))
            _cg.setColor(QColorGroup::Base, LIGHT_BLUE);

      QListViewItem::paintCell(p, _cg, column, width, alignment);

      if (isHighlighted && mycolumn == LOG_COL)
            p->restore();
}

void ListViewItem::addTextPixmap(SCRef text, const QColor& color, bool bold) {

      int col = LOG_COL + (fh ? 0 : -1);
      QStringList sl = QStringList::split('\n', text);
      loopList(it, sl) {
            QPixmap* pm = doAddTextPixmap(*it, color, col, bold);
            setPixmap(col, *pm);
            delete pm;
      }
}

QPixmap* ListViewItem::doAddTextPixmap(SCRef text, const QColor& color, int col, bool bold) {

      const QPixmap* oldPm = pixmap(col);
      QFont fnt(listView()->font());
      if (bold)
            fnt.setBold(true);

      QFontMetrics fm(fnt);
      int spacing = 2;
      int pw = fm.boundingRect(text).width() + 2 * (spacing + int(bold));
      int ph = fm.height() + 1;
      int ofs = oldPm ? oldPm->width() + 2 : 0;

      QPixmap* pm = new QPixmap(ofs + pw, ph);

      QPainter p;
      p.begin(pm);

      if (oldPm) {
            pm->fill(isEvenLine ? EVEN_LINE_COL : ODD_LINE_COL);
            p.drawPixmap(0, 0, *oldPm);
      }
      p.setPen(Qt::black);
      p.setBrush(color);
      p.setFont(fnt);
      p.drawRect(ofs, 0, pw, ph);
      p.drawText(ofs + spacing, fm.ascent(), text);
      p.end();
      return pm;
}

bool ListViewItem::changedFiles(SCRef c) {

      const RevFile* f = git->getFiles(c);
      for (uint i = 0; i < f->names.count(); i++)
            if (!f->statusCmp(i, UNKNOWN))
                  return true;
      return false;
}

void ListViewItem::setupData(const Rev& c) {

      populated = true;

      // calculate lanes
      if (c.lanes.count() == 0)
            git->setLane(c.sha(), fh);

      // set time/date column
      int adj = (fh) ? 0 : -1;
      if (c.sha() != ZERO_SHA) {
            if (secs != 0) { // secs passed by MainImpl is 0 for absolute date
                  secs -= c.authorDate().toULong();
                  setText(TIME_COL + adj, timeDiff(secs));
            } else
                  setText(TIME_COL + adj, git->getLocalDate(c.authorDate()));
      }
      setText(LOG_COL + adj, c.shortLog());
      setText(AUTH_COL + adj, c.author());

      if (c.isBranch || c.isCurrentBranch) {
            QColor color(c.isCurrentBranch ? Qt::green : DARK_GREEN);
            addTextPixmap(c.branch, color, c.isCurrentBranch);
      }
      if (c.isTag)
            addTextPixmap(c.tag, Qt::yellow);

      if (c.isRef)
            addTextPixmap(c.ref, PURPLE);
}

const QString ListViewItem::timeDiff(unsigned long secs) const {

      uint days  =  secs / (3600 * 24);
      uint hours = (secs - days * 3600 * 24) / 3600;
      uint min   = (secs - days * 3600 * 24 - hours * 3600) / 60;
      uint sec   =  secs - days * 3600 * 24 - hours * 3600 - min * 60;
      QString tmp;
      if (days > 0)
            tmp.append(QString::number(days) + "d ");

      if (hours > 0 || !tmp.isEmpty())
            tmp.append(QString::number(hours) + "h ");

      if (min > 0 || !tmp.isEmpty())
            tmp.append(QString::number(min) + "m ");

      tmp.append(QString::number(sec) + "s");
      return tmp;
}

QPixmap* ListViewItem::getGraph(const Rev& c) {

      const QValueVector<int>& lanes(c.lanes);
      uint laneNum = lanes.count();
      int pw = pms[0]->width();
      int ph = pms[0]->height();
      QPixmap* pm = new QPixmap(pw * laneNum, ph);
      pm->fill(ODD_LINE_COL); // faster then drawRect()
      int mergeLane = -1;
      for (uint i = 0; i < laneNum; i++)
            if (isMerge(lanes[i])) {
                  mergeLane = i;
                  break;
            }
      QPainter p;
      p.begin(pm);
      for (uint i = 0; i < laneNum; i++) {

            int ln = lanes[i], idx;
            if (ln == EMPTY)
                  continue;

            if (ln == CROSS)
                  idx = COLORS_NUM * (NOT_ACTIVE - 1);
            else
                  idx = COLORS_NUM * (ln - 1);

            int col = (   isHead(ln) || isTail(ln) || isJoin(ln)
                       || ln == CROSS_EMPTY) ? mergeLane : i;

            idx += col % COLORS_NUM;
            p.drawPixmap(i * pw, 0, *pms[idx]);
            if (ln == CROSS) {
                  idx = COLORS_NUM * (CROSS - 1) + mergeLane % COLORS_NUM;
                  p.drawPixmap(i * pw, 0, *pms[idx]);
            }
      }
      p.end();
      return pm;
}

// ***************** MainImpl related methods *********************

#define P_OR  pw/2, ph/2
#define P_0   pw,   ph/2
#define P_90  pw/2, 0
#define P_180 0,    ph/2
#define P_270 pw/2, ph

void MainImpl::setupPixmaps(int h) {

      // set dimensions
      ph = h;
      pw = 3 * ph / 4;
      int r = ph / 4; // radius of dots

      // create cross line mask
      QPixmap cm(pw, ph);
      cm.fill();
      QPainter p;
      p.begin(&cm);
      p.setPen(QPen(Qt::black, 2));
      p.drawLine(P_180, P_0);
      p.end();
      QBitmap crossMask = cm.createHeuristicMask();

      QBrush myWhiteBrush(ODD_LINE_COL, Qt::SolidPattern);
      QColor colors[COLORS_NUM] = {Qt::black, Qt::red, DARK_GREEN, Qt::blue,
                                   Qt::darkGray, BROWN, Qt::magenta, ORANGE};
      pixmaps.clear();
      pixmaps.resize(LANE_TYPES_NUM * COLORS_NUM);

      for (int i = 0; i < LANE_TYPES_NUM * COLORS_NUM; i++) {

            int type = (i / COLORS_NUM) + 1;
            QColor myColorNum(colors[i % COLORS_NUM]);
            QBrush myBrush(myColorNum, Qt::SolidPattern);

            QPixmap* pm = new QPixmap(pw, ph);
            pm->fill(ODD_LINE_COL);
            p.begin(pm);
            p.setPen(QPen(myColorNum, 2));

            switch (type) {
            case ACTIVE:
                  p.drawLine(P_90, P_270);
                  p.save();
                  p.setPen(Qt::NoPen);
                  p.setBrush(myBrush);
                  p.drawEllipse(pw/2 - r, ph/2 - r, 2*r, 2*r);
                  p.restore();
                  break;
            case NOT_ACTIVE:
                  p.drawLine(P_90, P_270);
                  break;
            case MERGE_FORK:
                  p.drawLine(P_90, P_270);
                  p.drawLine(P_180, P_0);
                  p.fillRect(pw/2 - r, ph/2 - r, 2*r, 2*r, myBrush);
                  break;
            case MERGE_FORK_R:
                  p.drawLine(P_90, P_270);
                  p.drawLine(P_180, P_OR);
                  p.fillRect(pw/2 - r, ph/2 - r, 2*r, 2*r, myBrush);
                  break;
            case MERGE_FORK_L:
                  p.drawLine(P_90, P_270);
                  p.drawLine(P_OR, P_0);
                  p.fillRect(pw/2 - r, ph/2 - r, 2*r, 2*r, myBrush);
                  break;
            case JOIN:
                  p.drawLine(P_90, P_270);
                  p.drawLine(P_180, P_0);
                  break;
            case JOIN_R:
                  p.drawLine(P_90, P_270);
                  p.drawLine(P_180, P_OR);
                  break;
            case JOIN_L:
                  p.drawLine(P_90, P_270);
                  p.drawLine(P_OR, P_0);
                  break;
            case HEAD:
                  p.drawLine(P_OR, P_270);
                  p.drawLine(P_180, P_0);
                  break;
            case HEAD_R:
                  p.drawLine(P_OR, P_270);
                  p.drawLine(P_180, P_OR);
                  break;
            case HEAD_L:
                  p.drawLine(P_OR, P_270);
                  p.drawLine(P_OR, P_0);
                  break;
            case TAIL:
                  p.drawLine(P_90, P_OR);
                  p.drawLine(P_180, P_0);
                  break;
            case TAIL_R:
                  p.drawLine(P_90, P_OR);
                  p.drawLine(P_180, P_OR);
                  break;
            case TAIL_L:
                  p.drawLine(P_90, P_OR);
                  p.drawLine(P_OR, P_0);
                  break;
            case CROSS:
                  pm->setMask(crossMask);
                  pm->fill(p.pen().color());
                  break;
            case CROSS_EMPTY:
                  p.drawLine(P_180, P_0);
                  break;
            case INITIAL:
                  p.drawLine(P_90, P_OR);
                  p.save();
                  p.setPen(Qt::NoPen);
                  p.setBrush(QBrush(myColorNum, Qt::SolidPattern));
                  p.drawEllipse(pw/2 - r, ph/2 - r, 2*r, 2*r);
                  p.restore();
                  break;
            case BRANCH:
                  p.drawLine(P_OR, P_270);
                  p.save();
                  p.setPen(Qt::NoPen);
                  p.setBrush(QBrush(myColorNum, Qt::SolidPattern));
                  p.drawEllipse(pw/2 - r, ph/2 - r, 2*r, 2*r);
                  p.restore();
                  break;
            case UNAPPLIED:
                  p.save();
                  p.setPen(Qt::NoPen);
                  p.setBrush(QBrush(Qt::red, Qt::SolidPattern));
                  p.drawRect(pw/2 - r, ph/2 - 1, 2*r, 2);
                  p.restore();
                  break;
            case APPLIED:
                  p.save();
                  p.setPen(Qt::NoPen);
                  p.setBrush(QBrush(DARK_GREEN, Qt::SolidPattern));
                  p.drawRect(pw/2 - r, ph/2 - 1, 2*r, 2);
                  p.drawRect(pw/2 - 1, ph/2 - r, 2, 2*r);
                  p.restore();
                  break;
            case BOUNDARY:
                  p.drawLine(P_90, P_OR);
                  p.save();
                  p.setBrush(myWhiteBrush);
                  p.drawEllipse(pw/2 - r, ph/2 - r, 2*r, 2*r);
                  p.restore();
                  p.drawEllipse(pw/2 - r, ph/2 - r, 2*r, 2*r);
                  break;
            case BOUNDARY_C:
                  p.drawLine(P_90, P_OR);
                  p.drawLine(P_180, P_0);
                  p.fillRect(pw/2 - r, ph/2 - r, 2*r, 2*r, myWhiteBrush);
                  p.drawRect(pw/2 - r, ph/2 - r, 2*r, 2*r);
                  break;
            case BOUNDARY_R:
                  p.drawLine(P_90, P_OR);
                  p.drawLine(P_180, P_OR);
                  p.fillRect(pw/2 - r, ph/2 - r, 2*r, 2*r, myWhiteBrush);
                  p.drawRect(pw/2 - r, ph/2 - r, 2*r, 2*r);
                  break;
            case BOUNDARY_L:
                  p.drawLine(P_90, P_OR);
                  p.drawLine(P_OR, P_0);
                  p.fillRect(pw/2 - r, ph/2 - r, 2*r, 2*r, myWhiteBrush);
                  p.drawRect(pw/2 - r, ph/2 - r, 2*r, 2*r);
                  break;
            }
            p.end();
            pixmaps.insert(i, pm); // pixmaps has autoDelete set
      }
}

Generated by  Doxygen 1.6.0   Back to index