annotate src/changesetitem.cpp @ 600:641ccce7c771

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