1 /*
2 * Copyright (C) 1999-2002 Bernd Gehrmann
3 * bernd@mail.berlios.de
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20
21 #include "loglist.h"
22
23 #include <qapplication.h>
24 #include <qnamespace.h>
25
26 #include <QMouseEvent>
27 #include <QKeyEvent>
28 #include <QHeaderView>
29
30 #include <KConfigGroup>
31 #include <KConfig>
32 #include <klocalizedstring.h>
33
34 #include "loginfo.h"
35 #include "misc.h"
36 #include "tooltip.h"
37
38
39 class LogListViewItem : public QTreeWidgetItem
40 {
41 public:
42
43 enum { Revision, Author, Date, Branch, Comment, Tags };
44
45 LogListViewItem(QTreeWidget* list, const Cervisia::LogInfo& logInfo);
46
47 bool operator<(const QTreeWidgetItem &other) const override;
48
49 private:
50 static QString truncateLine(const QString &s);
51
52 Cervisia::LogInfo m_logInfo;
53 friend class LogListView;
54 };
55
56
LogListViewItem(QTreeWidget * list,const Cervisia::LogInfo & logInfo)57 LogListViewItem::LogListViewItem(QTreeWidget* list, const Cervisia::LogInfo& logInfo)
58 : QTreeWidgetItem(list),
59 m_logInfo(logInfo)
60 {
61 setText(Revision, logInfo.m_revision);
62 setText(Author, logInfo.m_author);
63 setText(Date, logInfo.dateTimeToString());
64 setText(Comment, truncateLine(logInfo.m_comment));
65
66 for (Cervisia::LogInfo::TTagInfoSeq::const_iterator it = logInfo.m_tags.begin();
67 it != logInfo.m_tags.end(); ++it)
68 {
69 const Cervisia::TagInfo& tagInfo(*it);
70
71 if (tagInfo.m_type == Cervisia::TagInfo::OnBranch)
72 {
73 setText(Branch, tagInfo.m_name);
74 }
75 }
76
77 setText(Tags, logInfo.tagsToString(Cervisia::TagInfo::Tag,
78 Cervisia::LogInfo::NoTagType,
79 QLatin1String(", ")));
80 }
81
82
truncateLine(const QString & s)83 QString LogListViewItem::truncateLine(const QString &s)
84 {
85 int pos;
86
87 QString res = s.simplified();
88 if ( (pos = res.indexOf('\n')) != -1 )
89 res = res.left(pos) + "...";
90
91 return res;
92 }
93
94
operator <(const QTreeWidgetItem & other) const95 bool LogListViewItem::operator<(const QTreeWidgetItem &other) const
96 {
97 const LogListViewItem &item = static_cast<const LogListViewItem &>(other);
98
99 switch ( treeWidget()->sortColumn() )
100 {
101 case Revision: return ::compareRevisions(m_logInfo.m_revision, item.m_logInfo.m_revision) == -1;
102 case Date: return ::compare(m_logInfo.m_dateTime, item.m_logInfo.m_dateTime) == -1;
103 }
104
105 return QTreeWidgetItem::operator<(other);
106 }
107
108
LogListView(KConfig & cfg,QWidget * parent)109 LogListView::LogListView(KConfig& cfg, QWidget *parent)
110 : QTreeWidget(parent)
111 , partConfig(cfg)
112 {
113 setAllColumnsShowFocus(true);
114 header()->setSortIndicatorShown(true);
115 setSelectionMode(QAbstractItemView::NoSelection);
116 setRootIsDecorated(false);
117 setSortingEnabled(true);
118 sortByColumn(LogListViewItem::Revision, Qt::DescendingOrder);
119 setHeaderLabels(QStringList() << i18n("Revision") << i18n("Author") << i18n("Date")
120 << i18n("Branch") << i18n("Comment") << i18n("Tags"));
121
122 Cervisia::ToolTip* toolTip = new Cervisia::ToolTip(viewport());
123
124 connect(toolTip, SIGNAL(queryToolTip(QPoint,QRect&,QString&)),
125 this, SLOT(slotQueryToolTip(QPoint,QRect&,QString&)));
126
127 QByteArray state = cfg.group("LogList view").readEntry<QByteArray>("Columns", QByteArray());
128 header()->restoreState(state);
129 }
130
131
~LogListView()132 LogListView::~LogListView()
133 {
134 partConfig.group("LogList view").writeEntry("Columns", header()->saveState());
135 }
136
137
addRevision(const Cervisia::LogInfo & logInfo)138 void LogListView::addRevision(const Cervisia::LogInfo& logInfo)
139 {
140 (void) new LogListViewItem(this, logInfo);
141 }
142
143
setSelectedPair(const QString & selectionA,const QString & selectionB)144 void LogListView::setSelectedPair(const QString &selectionA, const QString &selectionB)
145 {
146 for (int j = 0; j < topLevelItemCount(); j++)
147 {
148 LogListViewItem *i = static_cast<LogListViewItem*>(topLevelItem(j));
149 i->setSelected(selectionA == i->text(LogListViewItem::Revision) ||
150 selectionB == i->text(LogListViewItem::Revision));
151 }
152 }
153
mousePressEvent(QMouseEvent * e)154 void LogListView::mousePressEvent(QMouseEvent *e)
155 {
156 // Retrieve selected item
157 const LogListViewItem* selItem
158 = static_cast<LogListViewItem*>(itemAt(e->pos()));
159 if( !selItem )
160 return;
161
162 // Retrieve revision
163 const QString revision = selItem->text(LogListViewItem::Revision);
164
165 if ( e->button() == Qt::LeftButton )
166 {
167 // If the control key was pressed, then we change revision B not A
168 if( e->modifiers() & Qt::ControlModifier )
169 emit revisionClicked(revision, true);
170 else
171 emit revisionClicked(revision, false);
172 }
173 else if ( e->button() == Qt::MidButton )
174 emit revisionClicked(revision, true);
175 }
176
177
keyPressEvent(QKeyEvent * e)178 void LogListView::keyPressEvent(QKeyEvent *e)
179 {
180 switch (e->key()) {
181 case Qt::Key_A:
182 if (currentItem())
183 emit revisionClicked(currentItem()->text(LogListViewItem::Revision), false);
184 break;
185 break;
186 case Qt::Key_B:
187 if (currentItem())
188 emit revisionClicked(currentItem()->text(LogListViewItem::Revision), true);
189 break;
190 case Qt::Key_Backspace:
191 case Qt::Key_Delete:
192 case Qt::Key_Down:
193 case Qt::Key_Up:
194 case Qt::Key_Home:
195 case Qt::Key_End:
196 case Qt::Key_PageDown:
197 case Qt::Key_PageUp:
198 if (e->modifiers() == Qt::NoModifier)
199 QTreeWidget::keyPressEvent(e);
200 else
201 QApplication::postEvent(this, new QKeyEvent(QEvent::KeyPress, e->key(), Qt::NoModifier, e->text()));
202 break;
203 default:
204 // Ignore Key_Enter, Key_Return
205 e->ignore();
206 }
207 }
208
209
slotQueryToolTip(const QPoint & viewportPos,QRect & viewportRect,QString & text)210 void LogListView::slotQueryToolTip(const QPoint& viewportPos,
211 QRect& viewportRect,
212 QString& text)
213 {
214 if (const LogListViewItem* item = static_cast<LogListViewItem*>(itemAt(viewportPos)))
215 {
216 viewportRect = visualRect(indexAt(viewportPos));
217 text = item->m_logInfo.createToolTipText();
218 }
219 }
220
221
222 // Local Variables:
223 // c-basic-offset: 4
224 // End:
225