annotate src/changesetitem.cpp @ 558:d932ce55c364 find

Remove the single find widget from top, add one to each tab at the bottom instead. (Turns out you don't usually want to search for the same text in both types of widget.) Also provide sensible no-results text.
author Chris Cannam
date Mon, 27 Feb 2012 17:08:26 +0000
parents a1d210c767ab
children 533519ebc0cb
rev   line source
Chris@57 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@57 2
Chris@57 3 /*
Chris@57 4 EasyMercurial
Chris@57 5
Chris@57 6 Based on HgExplorer by Jari Korhonen
Chris@57 7 Copyright (c) 2010 Jari Korhonen
Chris@244 8 Copyright (c) 2011 Chris Cannam
Chris@244 9 Copyright (c) 2011 Queen Mary, University of London
Chris@57 10
Chris@57 11 This program is free software; you can redistribute it and/or
Chris@57 12 modify it under the terms of the GNU General Public License as
Chris@57 13 published by the Free Software Foundation; either version 2 of the
Chris@57 14 License, or (at your option) any later version. See the file
Chris@57 15 COPYING included with this distribution for more information.
Chris@57 16 */
Chris@57 17
Chris@43 18 #include "changesetitem.h"
Chris@281 19 #include "changesetscene.h"
Chris@117 20 #include "changesetdetailitem.h"
Chris@43 21 #include "changeset.h"
Chris@53 22 #include "textabbrev.h"
Chris@53 23 #include "colourset.h"
Chris@117 24 #include "debug.h"
Chris@43 25
Chris@43 26 #include <QPainter>
Chris@117 27 #include <QGraphicsScene>
Chris@132 28 #include <QGraphicsSceneMouseEvent>
Chris@140 29 #include <QMenu>
Chris@140 30 #include <QAction>
Chris@140 31 #include <QLabel>
Chris@140 32 #include <QWidgetAction>
Chris@153 33 #include <QApplication>
Chris@153 34 #include <QClipboard>
Chris@43 35
Chris@390 36 QImage *ChangesetItem::m_star = 0;
Chris@390 37
Chris@53 38 ChangesetItem::ChangesetItem(Changeset *cs) :
Chris@117 39 m_changeset(cs), m_detail(0),
Chris@133 40 m_showBranch(false), m_column(0), m_row(0), m_wide(false),
Chris@555 41 m_current(false), m_closing(false), m_new(false), m_searchMatches(false)
Chris@53 42 {
Chris@53 43 m_font = QFont();
Chris@53 44 m_font.setPixelSize(11);
Chris@53 45 m_font.setBold(false);
Chris@53 46 m_font.setItalic(false);
Chris@168 47 setCursor(Qt::ArrowCursor);
Chris@390 48
Chris@390 49 if (!m_star) m_star = new QImage(":images/star.png");
Chris@53 50 }
Chris@53 51
Chris@141 52 QString
Chris@141 53 ChangesetItem::getId()
Chris@141 54 {
Chris@141 55 return m_changeset->id();
Chris@141 56 }
Chris@141 57
Chris@43 58 QRectF
Chris@43 59 ChangesetItem::boundingRect() const
Chris@43 60 {
Chris@55 61 int w = 100;
Chris@55 62 if (m_wide) w = 180;
Chris@250 63 return QRectF(-((w-50)/2 - 1), -30, w - 3, 90);
Chris@43 64 }
Chris@43 65
Chris@43 66 void
Chris@119 67 ChangesetItem::showDetail()
Chris@117 68 {
Chris@119 69 if (m_detail) return;
Chris@117 70 m_detail = new ChangesetDetailItem(m_changeset);
Chris@117 71 m_detail->setZValue(zValue() + 1);
Chris@117 72 scene()->addItem(m_detail);
Chris@117 73 int w = 100;
Chris@117 74 if (m_wide) w = 180;
Chris@508 75 if (isMerge() || isClosingCommit()) w = 60;
Chris@124 76 int h = 80;
Chris@124 77 // m_detail->moveBy(x() - (m_detail->boundingRect().width() - 50) / 2,
Chris@124 78 // y() + 60);
Chris@124 79 m_detail->moveBy(x() + (w + 50) / 2 + 10 + 0.5,
Chris@430 80 y() - (m_detail->boundingRect().height() - h) / 3 + 0.5);
Chris@119 81 emit detailShown();
Chris@119 82 }
Chris@119 83
Chris@119 84 void
Chris@119 85 ChangesetItem::hideDetail()
Chris@119 86 {
Chris@124 87 if (!m_detail) return;
Chris@124 88 scene()->removeItem(m_detail);
Chris@119 89 delete m_detail;
Chris@119 90 m_detail = 0;
Chris@119 91 emit detailHidden();
Chris@119 92 }
Chris@119 93
Chris@555 94 bool
Chris@555 95 ChangesetItem::setSearchText(QString text)
Chris@555 96 {
Chris@555 97 m_searchText = text;
Chris@555 98 m_searchMatches = (m_changeset->comment().contains
Chris@555 99 (text, Qt::CaseInsensitive));
Chris@555 100 return m_searchMatches;
Chris@555 101 }
Chris@555 102
Chris@119 103 void
Chris@119 104 ChangesetItem::mousePressEvent(QGraphicsSceneMouseEvent *e)
Chris@119 105 {
Chris@119 106 DEBUG << "ChangesetItem::mousePressEvent" << endl;
Chris@132 107 if (e->button() == Qt::LeftButton) {
Chris@132 108 if (m_detail) {
Chris@132 109 hideDetail();
Chris@132 110 } else {
Chris@132 111 showDetail();
Chris@132 112 }
Chris@119 113 }
Chris@117 114 }
Chris@117 115
Chris@117 116 void
Chris@474 117 ChangesetItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *)
Chris@140 118 {
Chris@474 119 if (m_detail) {
Chris@474 120 hideDetail();
Chris@474 121 }
Chris@474 122
Chris@153 123 m_parentDiffActions.clear();
Chris@288 124 m_summaryActions.clear();
Chris@153 125
Chris@140 126 QMenu *menu = new QMenu;
Chris@165 127 QLabel *label = new QLabel(tr("<qt><b>&nbsp;Revision: </b>%1</qt>")
Chris@165 128 .arg(Changeset::hashOf(m_changeset->id())));
Chris@141 129 QWidgetAction *wa = new QWidgetAction(menu);
Chris@140 130 wa->setDefaultWidget(label);
Chris@140 131 menu->addAction(wa);
Chris@140 132 menu->addSeparator();
Chris@141 133
Chris@153 134 QAction *copyId = menu->addAction(tr("Copy identifier to clipboard"));
Chris@153 135 connect(copyId, SIGNAL(triggered()), this, SLOT(copyIdActivated()));
Chris@141 136
Chris@289 137 QAction *stat = menu->addAction(tr("Summarise changes"));
Chris@289 138 connect(stat, SIGNAL(triggered()), this, SLOT(showSummaryActivated()));
Chris@289 139
Chris@289 140 menu->addSeparator();
Chris@289 141
Chris@281 142 QStringList parents = m_changeset->parents();
Chris@153 143
Chris@288 144 QString leftId, rightId;
Chris@288 145 bool havePositions = false;
Chris@288 146
Chris@281 147 if (parents.size() > 1) {
Chris@281 148 ChangesetScene *cs = dynamic_cast<ChangesetScene *>(scene());
Chris@281 149 if (cs && parents.size() == 2) {
Chris@281 150 ChangesetItem *i0 = cs->getItemById(parents[0]);
Chris@281 151 ChangesetItem *i1 = cs->getItemById(parents[1]);
Chris@281 152 if (i0 && i1) {
Chris@281 153 if (i0->x() < i1->x()) {
Chris@281 154 leftId = parents[0];
Chris@281 155 rightId = parents[1];
Chris@281 156 } else {
Chris@281 157 leftId = parents[1];
Chris@281 158 rightId = parents[0];
Chris@281 159 }
Chris@281 160 havePositions = true;
Chris@281 161 }
Chris@281 162 }
Chris@288 163 }
Chris@281 164
Chris@288 165 if (parents.size() > 1) {
Chris@288 166 if (havePositions) {
Chris@281 167
Chris@288 168 QAction *diff = menu->addAction(tr("Diff to left parent"));
Chris@288 169 connect(diff, SIGNAL(triggered()), this, SLOT(diffToParentActivated()));
Chris@288 170 m_parentDiffActions[diff] = leftId;
Chris@281 171
Chris@288 172 diff = menu->addAction(tr("Diff to right parent"));
Chris@288 173 connect(diff, SIGNAL(triggered()), this, SLOT(diffToParentActivated()));
Chris@288 174 m_parentDiffActions[diff] = rightId;
Chris@281 175
Chris@281 176 } else {
Chris@281 177
Chris@281 178 foreach (QString parentId, parents) {
Chris@288 179 QString text = tr("Diff to parent %1").arg(Changeset::hashOf(parentId));
Chris@288 180 QAction *diff = menu->addAction(text);
Chris@288 181 connect(diff, SIGNAL(triggered()), this, SLOT(diffToParentActivated()));
Chris@288 182 m_parentDiffActions[diff] = parentId;
Chris@281 183 }
Chris@153 184 }
Chris@153 185
Chris@153 186 } else {
Chris@153 187
Chris@288 188 QAction *diff = menu->addAction(tr("Diff to parent"));
Chris@288 189 connect(diff, SIGNAL(triggered()), this, SLOT(diffToParentActivated()));
Chris@153 190 }
Chris@153 191
Chris@153 192 QAction *diffCurrent = menu->addAction(tr("Diff to current working folder"));
Chris@141 193 connect(diffCurrent, SIGNAL(triggered()), this, SLOT(diffToCurrentActivated()));
Chris@141 194
Chris@140 195 menu->addSeparator();
Chris@141 196
Chris@153 197 QAction *update = menu->addAction(tr("Update to this revision"));
Chris@153 198 connect(update, SIGNAL(triggered()), this, SLOT(updateActivated()));
Chris@153 199
Chris@140 200 QAction *merge = menu->addAction(tr("Merge from here to current"));
Chris@141 201 connect(merge, SIGNAL(triggered()), this, SLOT(mergeActivated()));
Chris@153 202
Chris@153 203 menu->addSeparator();
Chris@153 204
Chris@278 205 QAction *branch = menu->addAction(tr("Start new branch..."));
Chris@278 206 branch->setEnabled(m_current);
Chris@278 207 connect(branch, SIGNAL(triggered()), this, SLOT(newBranchActivated()));
Chris@278 208
Chris@514 209 QAction *closebranch = menu->addAction(tr("Close branch..."));
Chris@514 210 closebranch->setEnabled(m_current);
Chris@514 211 connect(closebranch, SIGNAL(triggered()), this, SLOT(closeBranchActivated()));
Chris@514 212
Chris@153 213 QAction *tag = menu->addAction(tr("Add tag..."));
Chris@141 214 connect(tag, SIGNAL(triggered()), this, SLOT(tagActivated()));
Chris@141 215
Chris@474 216 ungrabMouse();
Chris@474 217
Chris@148 218 menu->exec(QCursor::pos());
Chris@140 219 }
Chris@140 220
Chris@153 221 void
Chris@153 222 ChangesetItem::copyIdActivated()
Chris@153 223 {
Chris@153 224 QClipboard *clipboard = QApplication::clipboard();
Chris@153 225 clipboard->setText(Changeset::hashOf(m_changeset->id()));
Chris@153 226 }
Chris@153 227
Chris@153 228 void ChangesetItem::diffToParentActivated()
Chris@153 229 {
Chris@153 230 QAction *a = qobject_cast<QAction *>(sender());
Chris@153 231 QString parentId;
Chris@153 232 if (m_parentDiffActions.contains(a)) {
Chris@153 233 parentId = m_parentDiffActions[a];
Chris@153 234 DEBUG << "ChangesetItem::diffToParentActivated: specific parent "
Chris@153 235 << parentId << " selected" << endl;
Chris@153 236 } else {
Chris@153 237 parentId = m_changeset->parents()[0];
Chris@153 238 DEBUG << "ChangesetItem::diffToParentActivated: "
Chris@153 239 << "no specific parent selected, using first parent "
Chris@153 240 << parentId << endl;
Chris@153 241 }
Chris@153 242
Chris@153 243 emit diffToParent(getId(), parentId);
Chris@153 244 }
Chris@153 245
Chris@289 246 void ChangesetItem::showSummaryActivated()
Chris@288 247 {
Chris@289 248 emit showSummary(m_changeset);
Chris@288 249 }
Chris@288 250
Chris@141 251 void ChangesetItem::updateActivated() { emit updateTo(getId()); }
Chris@141 252 void ChangesetItem::diffToCurrentActivated() { emit diffToCurrent(getId()); }
Chris@141 253 void ChangesetItem::mergeActivated() { emit mergeFrom(getId()); }
Chris@141 254 void ChangesetItem::tagActivated() { emit tag(getId()); }
Chris@278 255 void ChangesetItem::newBranchActivated() { emit newBranch(getId()); }
Chris@514 256 void ChangesetItem::closeBranchActivated() { emit closeBranch(getId()); }
Chris@141 257
Chris@140 258 void
Chris@288 259 ChangesetItem::paint(QPainter *paint, const QStyleOptionGraphicsItem *, QWidget *)
Chris@43 260 {
Chris@508 261 if (isClosingCommit() || isMerge()) {
Chris@508 262 paintSimple(paint);
Chris@387 263 } else {
Chris@387 264 paintNormal(paint);
Chris@387 265 }
Chris@387 266 }
Chris@387 267
Chris@387 268 bool
Chris@387 269 ChangesetItem::isMerge() const
Chris@387 270 {
Chris@387 271 return (m_changeset && m_changeset->parents().size() > 1);
Chris@387 272 }
Chris@387 273
Chris@510 274 bool
Chris@510 275 ChangesetItem::isClosed() const
Chris@510 276 {
Chris@510 277 return (m_changeset && m_changeset->closed());
Chris@510 278 }
Chris@510 279
Chris@387 280 void
Chris@387 281 ChangesetItem::paintNormal(QPainter *paint)
Chris@387 282 {
Chris@53 283 paint->save();
Chris@53 284
Chris@506 285 int alpha = 255;
Chris@510 286 if (isClosed()) alpha = 90;
Chris@506 287
Chris@53 288 ColourSet *colourSet = ColourSet::instance();
Chris@53 289 QColor branchColour = colourSet->getColourFor(m_changeset->branch());
Chris@128 290 QColor userColour = colourSet->getColourFor(m_changeset->author());
Chris@53 291
Chris@506 292 branchColour.setAlpha(alpha);
Chris@506 293 userColour.setAlpha(alpha);
Chris@506 294
Chris@53 295 QFont f(m_font);
Chris@53 296
Chris@54 297 QTransform t = paint->worldTransform();
Chris@53 298 float scale = std::min(t.m11(), t.m22());
Chris@53 299 if (scale > 1.0) {
Chris@53 300 int ps = int((f.pixelSize() / scale) + 0.5);
Chris@53 301 if (ps < 8) ps = 8;
Chris@53 302 f.setPixelSize(ps);
Chris@53 303 }
Chris@54 304
Chris@250 305 bool showText = (scale >= 0.2);
Chris@250 306 bool showProperLines = (scale >= 0.1);
Chris@250 307
Chris@555 308 if (m_searchText != "") {
Chris@555 309 if (m_searchMatches) {
Chris@555 310 userColour = QColor("#008400");
Chris@555 311 showProperLines = true;
Chris@555 312 showText = true;
Chris@555 313 } else {
Chris@555 314 branchColour = Qt::gray;
Chris@555 315 userColour = Qt::gray;
Chris@555 316 }
Chris@555 317 }
Chris@555 318
Chris@250 319 if (!showProperLines) {
Chris@54 320 paint->setPen(QPen(branchColour, 0));
Chris@54 321 } else {
Chris@54 322 paint->setPen(QPen(branchColour, 2));
Chris@54 323 }
Chris@53 324
Chris@53 325 paint->setFont(f);
Chris@53 326 QFontMetrics fm(f);
Chris@53 327 int fh = fm.height();
Chris@55 328
Chris@55 329 int width = 100;
Chris@55 330 if (m_wide) width = 180;
Chris@55 331 int x0 = -((width - 50) / 2 - 1);
Chris@55 332
Chris@250 333 int textwid = width - 7;
Chris@250 334
Chris@250 335 QString comment;
Chris@250 336 QStringList lines;
Chris@250 337 int lineCount = 3;
Chris@250 338
Chris@250 339 if (showText) {
Chris@250 340
Chris@250 341 comment = m_changeset->comment().trimmed();
Chris@250 342 comment = comment.replace("\\n", " ");
Chris@250 343 comment = comment.replace(QRegExp("^\"\\s*\\**\\s*"), "");
Chris@250 344 comment = comment.replace(QRegExp("\"$"), "");
Chris@250 345 comment = comment.replace("\\\"", "\"");
Chris@250 346
Chris@250 347 comment = TextAbbrev::abbreviate(comment, fm, textwid,
Chris@250 348 TextAbbrev::ElideEnd, "...", 3);
Chris@250 349 // abbreviate() changes this (ouch!), restore it
Chris@250 350 textwid = width - 5;
Chris@250 351
Chris@250 352 lines = comment.split('\n');
Chris@250 353 lineCount = lines.size();
Chris@250 354
Chris@250 355 if (lineCount < 2) lineCount = 2;
Chris@250 356 }
Chris@250 357
Chris@250 358 int height = (lineCount + 1) * fh + 2;
Chris@56 359 QRectF r(x0, 0, width - 3, height);
Chris@250 360
Chris@521 361 QColor textColour = Qt::black;
Chris@521 362 textColour.setAlpha(alpha);
Chris@521 363
Chris@521 364 if (m_showBranch && showText) {
Chris@521 365 // write branch name
Chris@521 366 paint->save();
Chris@521 367 f.setBold(true);
Chris@521 368 paint->setFont(f);
Chris@521 369 paint->setPen(QPen(branchColour));
Chris@521 370 QString branch = m_changeset->branch();
Chris@521 371 if (branch == "") branch = "default";
Chris@521 372 int wid = width - 3;
Chris@521 373 branch = TextAbbrev::abbreviate(branch, QFontMetrics(f), wid);
Chris@521 374 paint->drawText(x0, -fh + fm.ascent() - 4, branch);
Chris@521 375 f.setBold(false);
Chris@521 376 paint->restore();
Chris@521 377 }
Chris@521 378
Chris@521 379 QStringList bookmarks = m_changeset->bookmarks();
Chris@521 380 if (!bookmarks.empty() && showText) {
Chris@521 381 QString bmText = bookmarks.join(" ").trimmed();
Chris@521 382 int bw = fm.width(bmText);
Chris@521 383 int bx = x0 + width - bw - 14;
Chris@521 384 if (m_current) bx = bx - fh*1.5 + 3;
Chris@521 385 paint->save();
Chris@521 386 paint->setPen(QPen(branchColour, 2));
Chris@521 387 // paint->setBrush(QBrush(Qt::white));
Chris@521 388 paint->setBrush(QBrush(branchColour));
Chris@521 389 paint->drawRoundedRect(QRectF(bx, -fh - 4, bw + 4, fh * 2), 5, 5);
Chris@521 390 paint->setPen(QPen(Qt::white));
Chris@521 391 paint->drawText(bx + 2, -fh + fm.ascent() - 4, bmText);
Chris@521 392 paint->restore();
Chris@521 393 }
Chris@521 394
Chris@250 395 if (showProperLines) {
Chris@250 396
Chris@393 397 if (m_new) {
Chris@396 398 paint->setBrush(QColor(255, 255, 220));
Chris@393 399 } else {
Chris@393 400 paint->setBrush(Qt::white);
Chris@393 401 }
Chris@250 402
Chris@250 403 if (m_current) {
Chris@386 404 paint->drawRoundedRect(QRectF(x0 - 4, -4, width + 5, height + 8),
Chris@386 405 10, 10);
Chris@393 406 if (m_new) {
Chris@393 407 paint->save();
Chris@393 408 paint->setPen(Qt::yellow);
Chris@393 409 paint->setBrush(Qt::NoBrush);
Chris@393 410 paint->drawRoundedRect(QRectF(x0 - 2, -2, width + 1, height + 4),
Chris@393 411 10, 10);
Chris@393 412 paint->restore();
Chris@393 413 }
Chris@250 414 }
Chris@250 415 }
Chris@250 416
Chris@250 417 if (!showText) {
Chris@386 418 paint->drawRoundedRect(r, 7, 7);
Chris@53 419 paint->restore();
Chris@53 420 return;
Chris@53 421 }
Chris@53 422
Chris@386 423 paint->save();
Chris@386 424 paint->setPen(Qt::NoPen);
Chris@386 425 paint->drawRoundedRect(r, 7, 7);
Chris@386 426 paint->setBrush(QBrush(userColour));
Chris@386 427 paint->drawRoundedRect(QRectF(x0 + 0.5, 0.5, width - 4, fh - 0.5), 7, 7);
chris@391 428 paint->drawRect(QRectF(x0 + 0.5, fh/2.0, width - 4, fh/2.0));
Chris@386 429 paint->restore();
Chris@53 430
Chris@53 431 paint->setPen(QPen(Qt::white));
Chris@53 432
Chris@250 433 QString person = TextAbbrev::abbreviate(m_changeset->authorName(),
Chris@250 434 fm, textwid);
Chris@55 435 paint->drawText(x0 + 3, fm.ascent(), person);
Chris@53 436
Chris@506 437 paint->setPen(QPen(textColour));
Chris@53 438
Chris@147 439 QStringList tags = m_changeset->tags();
Chris@147 440 if (!tags.empty()) {
Chris@147 441 QStringList nonTipTags;
Chris@147 442 foreach (QString t, tags) {
Chris@147 443 // I'm not convinced that showing the tip tag really
Chris@147 444 // works; I think perhaps it confuses as much as it
Chris@147 445 // illuminates. But also, our current implementation
Chris@147 446 // doesn't interact well with it because it moves -- it's
Chris@147 447 // the one thing that can actually (in normal use) change
Chris@147 448 // inside an existing changeset record even during an
Chris@147 449 // incremental update
Chris@147 450 if (t != "tip") nonTipTags.push_back(t);
Chris@147 451 }
Chris@147 452 if (!nonTipTags.empty()) {
Chris@147 453 QString tagText = nonTipTags.join(" ").trimmed();
Chris@147 454 int tw = fm.width(tagText);
Chris@147 455 paint->fillRect(QRectF(x0 + width - 8 - tw, 1, tw + 4, fh - 1),
Chris@147 456 QBrush(Qt::yellow));
Chris@147 457 paint->drawText(x0 + width - 6 - tw, fm.ascent(), tagText);
Chris@147 458 }
Chris@128 459 }
Chris@128 460
Chris@520 461 paint->setPen(QPen(branchColour, 2));
Chris@520 462 paint->setBrush(Qt::NoBrush);
Chris@520 463 paint->drawRoundedRect(r, 7, 7);
Chris@520 464
chris@392 465 if (m_current && showProperLines) {
chris@392 466 paint->setRenderHint(QPainter::SmoothPixmapTransform, true);
chris@392 467 int starSize = fh * 1.5;
chris@392 468 paint->drawImage(QRectF(x0 + width - starSize,
chris@392 469 -fh, starSize, starSize),
chris@392 470 *m_star);
chris@392 471 }
chris@392 472
Chris@53 473 paint->setFont(f);
Chris@53 474
Chris@555 475 if (m_searchMatches) paint->setPen(userColour);
Chris@555 476
Chris@53 477 for (int i = 0; i < lines.size(); ++i) {
Chris@55 478 paint->drawText(x0 + 3, i * fh + fh + fm.ascent(), lines[i].trimmed());
Chris@53 479 }
Chris@53 480
Chris@53 481 paint->restore();
Chris@43 482 }
Chris@387 483
Chris@387 484 void
Chris@508 485 ChangesetItem::paintSimple(QPainter *paint)
Chris@387 486 {
Chris@387 487 paint->save();
Chris@506 488
Chris@506 489 int alpha = 255;
Chris@510 490 if (isClosed()) alpha = 90;
Chris@387 491
Chris@387 492 ColourSet *colourSet = ColourSet::instance();
Chris@387 493 QColor branchColour = colourSet->getColourFor(m_changeset->branch());
Chris@387 494 QColor userColour = colourSet->getColourFor(m_changeset->author());
Chris@387 495
Chris@506 496 branchColour.setAlpha(alpha);
Chris@506 497 userColour.setAlpha(alpha);
Chris@506 498
Chris@387 499 QFont f(m_font);
Chris@387 500
Chris@387 501 QTransform t = paint->worldTransform();
Chris@387 502 float scale = std::min(t.m11(), t.m22());
Chris@387 503 if (scale > 1.0) {
Chris@387 504 int ps = int((f.pixelSize() / scale) + 0.5);
Chris@387 505 if (ps < 8) ps = 8;
Chris@387 506 f.setPixelSize(ps);
Chris@387 507 }
Chris@387 508
Chris@387 509 bool showText = (scale >= 0.2);
Chris@387 510 bool showProperLines = (scale >= 0.1);
Chris@387 511
Chris@387 512 if (!showProperLines) {
Chris@387 513 paint->setPen(QPen(branchColour, 0));
Chris@387 514 } else {
Chris@387 515 paint->setPen(QPen(branchColour, 2));
Chris@387 516 }
Chris@387 517
Chris@387 518 paint->setFont(f);
Chris@387 519 QFontMetrics fm(f);
Chris@387 520 int fh = fm.height();
Chris@387 521 int size = fh * 2;
Chris@387 522 int x0 = -size/2 + 25;
Chris@387 523
Chris@393 524 if (m_new) {
Chris@396 525 paint->setBrush(QColor(255, 255, 220));
Chris@393 526 } else {
Chris@393 527 paint->setBrush(Qt::white);
Chris@393 528 }
Chris@390 529
Chris@390 530 if (showProperLines) {
Chris@390 531
Chris@390 532 if (m_current) {
Chris@508 533 if (isClosingCommit()) {
Chris@508 534 paint->drawRect(QRectF(x0 - 4, fh - 4, size + 8, size + 8));
Chris@508 535 } else {
Chris@508 536 paint->drawEllipse(QRectF(x0 - 4, fh - 4, size + 8, size + 8));
Chris@508 537 }
Chris@508 538
Chris@393 539 if (m_new) {
Chris@393 540 paint->save();
Chris@393 541 paint->setPen(Qt::yellow);
Chris@393 542 paint->setBrush(Qt::NoBrush);
Chris@508 543 if (isClosingCommit()) {
Chris@508 544 paint->drawRect(QRectF(x0 - 2, fh - 2, size + 4, size + 4));
Chris@508 545 } else {
Chris@508 546 paint->drawEllipse(QRectF(x0 - 2, fh - 2, size + 4, size + 4));
Chris@508 547 }
Chris@393 548 paint->restore();
Chris@393 549 }
Chris@390 550 }
Chris@390 551 }
Chris@390 552
Chris@508 553 if (isClosingCommit()) {
Chris@508 554 paint->drawRect(QRectF(x0, fh, size, size));
Chris@508 555 } else {
Chris@508 556 paint->drawEllipse(QRectF(x0, fh, size, size));
Chris@508 557 }
Chris@387 558
Chris@387 559 if (m_showBranch) {
Chris@387 560 // write branch name
Chris@387 561 paint->save();
Chris@387 562 f.setBold(true);
Chris@387 563 paint->setFont(f);
Chris@387 564 paint->setPen(QPen(branchColour));
Chris@387 565 QString branch = m_changeset->branch();
Chris@387 566 if (branch == "") branch = "default";
Chris@387 567 int wid = size * 3;
Chris@387 568 branch = TextAbbrev::abbreviate(branch, QFontMetrics(f), wid);
Chris@387 569 paint->drawText(-wid/2 + 25, fm.ascent() - 4, branch);
Chris@387 570 f.setBold(false);
Chris@387 571 paint->restore();
Chris@387 572 }
Chris@387 573
Chris@390 574 if (m_current && showProperLines) {
Chris@390 575 paint->setRenderHint(QPainter::SmoothPixmapTransform, true);
Chris@390 576 int starSize = fh * 1.5;
Chris@390 577 paint->drawImage(QRectF(x0 + size - starSize/2,
Chris@390 578 0, starSize, starSize),
Chris@390 579 *m_star);
Chris@390 580 }
Chris@390 581
Chris@387 582 paint->restore();
Chris@387 583 }
Chris@387 584