2 Author: Marco Costalba (C) 2005-2007
4 Copyright: See COPYING file that comes with this distribution
14 #include <QLatin1String>
19 QVariant does not support size_t type used in Qt containers, this is
20 a problem on 64bit systems where size_t != uint and when using debug
21 macros on size_t variables, as example dbg(vector.count()), a compile
23 Workaround this using a function template and a specialization.
24 Function _valueOf() is used by debug macros
26 template<typename T
> inline const QString
_valueOf(const T
& x
) { return QVariant(x
).toString(); }
27 template<> inline const QString
_valueOf(const QStringList
& x
) { return x
.join(" "); }
28 inline const QString
& _valueOf(const QString
& x
) { return x
; }
29 inline const QString
_valueOf(size_t x
) { return QString::number((uint
)x
); }
32 #define dbg(x) qDebug(#x " is <%s>", _valueOf(x).toLatin1().constData())
33 #define dbs(x) qDebug(_valueOf(x).toLatin1().constData())
34 #define dbp(s, x) qDebug(QString(s).arg(_valueOf(x)).toLatin1().constData())
35 #define db1 qDebug("Mark Nr. 1")
36 #define db2 qDebug("Mark Nr. 2")
37 #define db3 qDebug("Mark Nr. 3")
38 #define db4 qDebug("Mark Nr. 4")
39 #define dbStart dbs("Starting timer..."); QTime _t; _t.start()
40 #define dbRestart dbp("Elapsed time is %1 ms", _t.restart())
42 // some syntactic sugar
43 #define FOREACH(type, i, c) for (type::const_iterator i((c).constBegin()), \
44 _e##i##_((c).constEnd()); i != _e##i##_; ++i)
46 #define FOREACH_SL(i, c) FOREACH(QStringList, i, c)
55 typedef const QString
& SCRef
;
56 typedef QStringList
& SList
;
57 typedef const QStringList
& SCList
;
58 typedef QVector
<QString
> StrVect
;
59 typedef QVector
<ShaString
> ShaVect
;
60 typedef QSet
<QString
> ShaSet
;
62 uint
qHash(const ShaString
&); // optimized custom hash for sha strings
66 // minimum git version required
67 extern const QString GIT_VERSION
;
121 BOUNDARY_C
, // corresponds to MERGE_FORK
122 BOUNDARY_R
, // corresponds to MERGE_FORK_R
123 BOUNDARY_L
, // corresponds to MERGE_FORK_L
127 const int COLORS_NUM
= 8;
130 inline bool isHead(int x
) { return (x
== HEAD
|| x
== HEAD_R
|| x
== HEAD_L
); }
131 inline bool isTail(int x
) { return (x
== TAIL
|| x
== TAIL_R
|| x
== TAIL_L
); }
132 inline bool isJoin(int x
) { return (x
== JOIN
|| x
== JOIN_R
|| x
== JOIN_L
); }
133 inline bool isFreeLane(int x
) { return (x
== NOT_ACTIVE
|| x
== CROSS
|| isJoin(x
)); }
134 inline bool isBoundary(int x
) { return (x
== BOUNDARY
|| x
== BOUNDARY_C
||
135 x
== BOUNDARY_R
|| x
== BOUNDARY_L
); }
136 inline bool isMerge(int x
) { return (x
== MERGE_FORK
|| x
== MERGE_FORK_R
||
137 x
== MERGE_FORK_L
|| isBoundary(x
)); }
138 inline bool isActive(int x
) { return (x
== ACTIVE
|| x
== INITIAL
|| x
== BRANCH
||
144 POPUP_LIST_EV
= 65433,
145 POPUP_FILE_EV
= 65434,
146 POPUP_TREE_EV
= 65435,
150 UPD_DM_MST_EV
= 65439
153 // list views columns
160 COMMIT_COL
= 97, // dummy col used for sha searching
161 LOG_MSG_COL
= 98, // dummy col used for log messages searching
162 SHA_MAP_COL
= 99 // dummy col used when filter output is a set of matching sha
165 inline bool isInfoCol(int x
) { return (x
== TIME_COL
|| x
== LOG_COL
|| x
== AUTH_COL
); }
167 // default list view widths
168 const int DEF_GRAPH_COL_WIDTH
= 80;
169 const int DEF_LOG_COL_WIDTH
= 500;
170 const int DEF_AUTH_COL_WIDTH
= 230;
171 const int DEF_TIME_COL_WIDTH
= 160;
174 extern const QColor BROWN
;
175 extern const QColor ORANGE
;
176 extern const QColor DARK_ORANGE
;
177 extern const QColor LIGHT_ORANGE
;
178 extern const QColor LIGHT_BLUE
;
179 extern const QColor PURPLE
;
180 extern const QColor DARK_GREEN
;
182 // initialized at startup according to system wide settings
183 extern QColor ODD_LINE_COL
;
184 extern QColor EVEN_LINE_COL
;
185 extern QFont STD_FONT
;
186 extern QFont TYPE_WRITER_FONT
;
187 extern QString GIT_DIR
;
189 // patches drag and drop
190 extern const QString PATCHES_DIR
;
191 extern const QString PATCHES_NAME
;
193 // git index parameters
194 extern const QByteArray ZERO_SHA_BA
;
195 extern const ShaString ZERO_SHA_RAW
;
197 extern const QString ZERO_SHA
;
198 extern const QString CUSTOM_SHA
;
199 extern const QString ALL_MERGE_FILES
;
202 extern const QString ORG_KEY
;
203 extern const QString APP_KEY
;
204 extern const QString GIT_DIR_KEY
;
205 extern const QString PATCH_DIR_KEY
;
206 extern const QString FMT_P_OPT_KEY
;
207 extern const QString AM_P_OPT_KEY
;
208 extern const QString STD_FNT_KEY
;
209 extern const QString TYPWRT_FNT_KEY
;
210 extern const QString FLAGS_KEY
;
211 extern const QString CON_GEOM_KEY
;
212 extern const QString CMT_GEOM_KEY
;
213 extern const QString MAIN_GEOM_KEY
;
214 extern const QString REV_GEOM_KEY
;
215 extern const QString CMT_TEMPL_KEY
;
216 extern const QString CMT_ARGS_KEY
;
217 extern const QString RANGE_FROM_KEY
;
218 extern const QString RANGE_TO_KEY
;
219 extern const QString RANGE_OPT_KEY
;
220 extern const QString EX_KEY
;
221 extern const QString EX_PER_DIR_KEY
;
222 extern const QString EXT_DIFF_KEY
;
223 extern const QString REC_REP_KEY
;
224 extern const QString ACT_LIST_KEY
;
225 extern const QString ACT_GEOM_KEY
;
226 extern const QString ACT_GROUP_KEY
;
227 extern const QString ACT_TEXT_KEY
;
228 extern const QString ACT_FLAGS_KEY
;
230 // settings default values
231 extern const QString CMT_TEMPL_DEF
;
232 extern const QString EX_DEF
;
233 extern const QString EX_PER_DIR_DEF
;
234 extern const QString EXT_DIFF_DEF
;
238 MSG_ON_NEW_F
= 1 << 0,
239 ACT_REFRESH_F
= 1 << 1,
241 LOG_DIFF_TAB_F
= 1 << 3,
242 ACT_CMD_LINE_F
= 1 << 4,
243 DIFF_INDEX_F
= 1 << 5,
244 SIGN_PATCH_F
= 1 << 6,
246 VERIFY_CMT_F
= 1 << 8,
247 SMART_LBL_F
= 1 << 9,
248 REL_DATE_F
= 1 << 10,
249 ALL_BRANCHES_F
= 1 << 11,
250 WHOLE_HISTORY_F
= 1 << 12,
251 RANGE_SELECT_F
= 1 << 13,
252 REOPEN_REPO_F
= 1 << 14,
253 USE_CMT_MSG_F
= 1 << 15
255 const int FLAGS_DEF
= USE_CMT_MSG_F
| RANGE_SELECT_F
| SMART_LBL_F
| VERIFY_CMT_F
| SIGN_PATCH_F
| LOG_DIFF_TAB_F
| MSG_ON_NEW_F
;
258 const ShaString
toTempSha(const QString
&); // use as argument only, see definition
259 const ShaString
toPersistentSha(const QString
&, QVector
<QByteArray
>&);
262 uint
flags(SCRef flagsVariable
);
263 bool testFlag(uint f
, SCRef fv
= FLAGS_KEY
);
264 void setFlag(uint f
, bool b
, SCRef fv
= FLAGS_KEY
);
266 // tree view icons helpers
269 const QPixmap
* mimePix(SCRef fileName
);
271 // geometry settings helers
272 typedef QVector
<QSplitter
*> splitVect
;
273 void saveGeometrySetting(SCRef name
, QWidget
* w
= NULL
, splitVect
* svPtr
= NULL
);
274 void restoreGeometrySetting(SCRef name
, QWidget
* w
= NULL
, splitVect
* svPtr
= NULL
);
277 bool stripPartialParaghraps(const QByteArray
& src
, QString
* dst
, QString
* prev
);
278 bool writeToFile(SCRef fileName
, SCRef data
, bool setExecutable
= false);
279 bool writeToFile(SCRef fileName
, const QByteArray
& data
, bool setExecutable
= false);
280 bool readFromFile(SCRef fileName
, QString
& data
);
281 bool startProcess(QProcess
* proc
, SCList args
, SCRef buf
= "", bool* winShell
= NULL
);
284 const uint C_MAGIC
= 0xA0B0C0D0;
285 const int C_VERSION
= 15;
287 extern const QString BAK_EXT
;
288 extern const QString C_DAT_FILE
;
291 const int MAX_DICT_SIZE
= 100003; // must be a prime number see QDict docs
292 const int MAX_MENU_ENTRIES
= 20;
293 const int MAX_RECENT_REPOS
= 7;
294 extern const QString QUOTE_CHAR
;
295 extern const QString SCRIPT_EXT
;
298 class ShaString
: public QLatin1String
{
300 inline ShaString() : QLatin1String(NULL
) {}
301 inline ShaString(const ShaString
& sha
) : QLatin1String(sha
.latin1()) {}
302 inline explicit ShaString(const char* sha
) : QLatin1String(sha
) {}
304 inline bool operator!=(const ShaString
& o
) const { return !operator==(o
); }
305 inline bool operator==(const ShaString
& o
) const {
307 return (latin1() == o
.latin1()) || !qstrcmp(latin1(), o
.latin1());
312 // prevent implicit C++ compiler defaults
315 Rev
& operator=(const Rev
&);
317 Rev(const QByteArray
& b
, uint s
, int idx
, int* next
, bool withDiff
)
318 : orderIdx(idx
), ba(b
), start(s
) {
320 indexed
= isDiffCache
= isApplied
= isUnApplied
= false;
321 descRefsMaster
= ancRefsMaster
= descBrnMaster
= -1;
322 *next
= indexData(true, withDiff
);
324 bool isBoundary() const { return (ba
.at(shaStart
- 1) == '-'); }
325 uint
parentsCount() const { return parentsCnt
; }
326 const ShaString
parent(int idx
) const;
327 const QStringList
parents() const;
328 const ShaString
sha() const { return ShaString(ba
.constData() + shaStart
); }
329 const QString
author() const { setup(); return mid(autStart
, autDateStart
- autStart
- 1); }
330 const QString
authorDate() const { setup(); return mid(autDateStart
, 10); }
331 const QString
shortLog() const { setup(); return mid(sLogStart
, sLogLen
); }
332 const QString
longLog() const { setup(); return mid(lLogStart
, lLogLen
); }
333 const QString
diff() const { setup(); return mid(diffStart
, diffLen
); }
335 QVector
<int> lanes
, childs
;
336 QVector
<int> descRefs
; // list of descendant refs index, normally tags
337 QVector
<int> ancRefs
; // list of ancestor refs index, normally tags
338 QVector
<int> descBranches
; // list of descendant branches index
339 int descRefsMaster
; // in case of many Rev have the same descRefs, ancRefs or
340 int ancRefsMaster
; // descBranches these are stored only once in a Rev pointed
341 int descBrnMaster
; // by corresponding index xxxMaster
344 inline void setup() const { if (!indexed
) indexData(false, false); }
345 int indexData(bool quick
, bool withDiff
) const;
346 const QString
mid(int start
, int len
) const;
347 const QString
midSha(int start
, int len
) const;
349 const QByteArray
& ba
; // reference here!
351 mutable int parentsCnt
, shaStart
, autStart
, autDateStart
;
352 mutable int sLogStart
, sLogLen
, lLogStart
, lLogLen
, diffStart
, diffLen
;
353 mutable bool indexed
;
355 bool isDiffCache
, isApplied
, isUnApplied
; // put here to optimize padding
357 typedef QHash
<ShaString
, const Rev
*> RevMap
; // faster then a map
362 friend class Cache
; // to directly load status
365 // Status information is splitted in a flags vector and in a string
366 // vector in 'status' are stored flags according to the info returned
367 // by 'git diff-tree' without -C option.
368 // In case of a working dir file an IN_INDEX flag is or-ed togheter in
369 // case file is present in git index.
370 // If file is renamed or copied an entry in 'extStatus' stores the
371 // value returned by 'git diff-tree -C' plus source and destination
373 // When status of all the files is 'modified' then onlyModified is
374 // set, this let us to do some optimization in this common case
377 QVector
<QString
> extStatus
;
379 // prevent implicit C++ compiler defaults
380 RevFile(const RevFile
&);
381 RevFile
& operator=(const RevFile
&);
395 RevFile() : onlyModified(true) {}
397 /* This QByteArray keeps indices in some dir and names vectors,
398 * defined outside RevFile. Paths are splitted in dir and file
399 * name, first all the dirs are listed then the file names to
400 * achieve a better compression when saved to disk.
401 * A single QByteArray is used instead of two vectors because it's
402 * much faster to load from disk when using a QDataStream
406 int dirAt(uint idx
) const { return ((int*)pathsIdx
.constData())[idx
]; }
407 int nameAt(uint idx
) const { return ((int*)pathsIdx
.constData())[count() + idx
]; }
409 QVector
<int> mergeParent
;
414 return pathsIdx
.size() / ((int)sizeof(int) * 2);
416 bool statusCmp(int idx
, StatusFlag sf
) const {
418 return ((onlyModified
? MODIFIED
: status
.at(idx
)) & sf
);
420 const QString
extendedStatus(int idx
) const {
422 rf.extStatus has size equal to position of latest copied/renamed file,
423 that could be lower then count(), so we have to explicitly check for
424 an out of bound condition.
426 return (!extStatus
.isEmpty() && idx
< extStatus
.count() ? extStatus
.at(idx
) : "");
428 const RevFile
& operator>>(QDataStream
&) const;
429 RevFile
& operator<<(QDataStream
&);
431 typedef QHash
<ShaString
, const RevFile
*> RevFileMap
;
434 class FileAnnotation
{
436 explicit FileAnnotation(int id
) : isValid(false), annId(id
) {}
437 FileAnnotation() : isValid(false) {}
443 typedef QHash
<ShaString
, FileAnnotation
> AnnotateHistory
;
446 class BaseEvent
: public QEvent
{
448 BaseEvent(SCRef d
, int id
) : QEvent((QEvent::Type
)id
), payLoad(d
) {}
449 const QString
myData() const { return payLoad
; }
451 const QString payLoad
; // passed by copy
454 #define DEF_EVENT(X, T) class X : public BaseEvent { public: \
455 explicit X (SCRef d) : BaseEvent(d, T) {} }
457 DEF_EVENT(MessageEvent
, QGit::MSG_EV
);
458 DEF_EVENT(AnnotateProgressEvent
, QGit::ANN_PRG_EV
);
460 class DeferredPopupEvent
: public BaseEvent
{
462 DeferredPopupEvent(SCRef msg
, int type
) : BaseEvent(msg
, type
) {}
465 class MainExecErrorEvent
: public BaseEvent
{
467 MainExecErrorEvent(SCRef c
, SCRef e
) : BaseEvent("", QGit::ERROR_EV
), cmd(c
), err(e
) {}
468 const QString
command() const { return cmd
; }
469 const QString
report() const { return err
; }
471 const QString cmd
, err
;