Version 2.6
[qgit4/redivivus.git] / src / common.h
blobc2ae097af232b825c5cebbceaf868aa3108f6c18
1 /*
2 Author: Marco Costalba (C) 2005-2007
4 Copyright: See COPYING file that comes with this distribution
6 */
7 #ifndef COMMON_H
8 #define COMMON_H
10 #include <QColor>
11 #include <QEvent>
12 #include <QFont>
13 #include <QHash>
14 #include <QLatin1String>
15 #include <QSet>
16 #include <QVariant>
17 #include <QVector>
20 QVariant does not support size_t type used in Qt containers, this is
21 a problem on 64bit systems where size_t != uint and when using debug
22 macros on size_t variables, as example dbg(vector.count()), a compile
23 error occurs.
24 Workaround this using a function template and a specialization.
25 Function _valueOf() is used by debug macros
27 template<typename T> inline const QString _valueOf(const T& x) { return QVariant(x).toString(); }
28 template<> inline const QString _valueOf(const QStringList& x) { return x.join(" "); }
29 inline const QString& _valueOf(const QString& x) { return x; }
30 inline const QString _valueOf(size_t x) { return QString::number((uint)x); }
32 // some debug macros
33 #define constlatin(x) (_valueOf(x).toLatin1().constData())
34 #define dbg(x) qDebug(#x " is <%s>", constlatin(x))
35 #define dbs(x) qDebug(constlatin(x), "")
36 #define dbp(s, x) qDebug(constlatin(_valueOf(s).arg(x)), "")
37 #define db1 qDebug("Mark Nr. 1")
38 #define db2 qDebug("Mark Nr. 2")
39 #define db3 qDebug("Mark Nr. 3")
40 #define db4 qDebug("Mark Nr. 4")
41 #define dbStart dbs("Starting timer..."); QTime _t; _t.start()
42 #define dbRestart dbp("Elapsed time is %1 ms", _t.restart())
44 // some syntactic sugar
45 #define FOREACH(type, i, c) for (type::const_iterator i((c).constBegin()), \
46 _e##i##_((c).constEnd()); i != _e##i##_; ++i)
48 #define FOREACH_SL(i, c) FOREACH(QStringList, i, c)
50 class QDataStream;
51 class QProcess;
52 class QSplitter;
53 class QWidget;
54 class ShaString;
56 // type shortcuts
57 typedef const QString& SCRef;
58 typedef QStringList& SList;
59 typedef const QStringList& SCList;
60 typedef QVector<QString> StrVect;
61 typedef QVector<ShaString> ShaVect;
62 typedef QSet<QString> ShaSet;
64 uint qHash(const ShaString&); // optimized custom hash for sha strings
66 namespace QGit {
68 // minimum git version required
69 extern const QString GIT_VERSION;
71 // tab pages
72 enum TabType {
73 TAB_REV,
74 TAB_PATCH,
75 TAB_FILE
78 // graph elements
79 enum LaneType {
80 EMPTY,
81 ACTIVE,
82 NOT_ACTIVE,
83 MERGE_FORK,
84 MERGE_FORK_R,
85 MERGE_FORK_L,
86 JOIN,
87 JOIN_R,
88 JOIN_L,
89 HEAD,
90 HEAD_R,
91 HEAD_L,
92 TAIL,
93 TAIL_R,
94 TAIL_L,
95 CROSS,
96 CROSS_EMPTY,
97 INITIAL,
98 BRANCH,
99 UNAPPLIED,
100 APPLIED,
101 BOUNDARY,
102 BOUNDARY_C, // corresponds to MERGE_FORK
103 BOUNDARY_R, // corresponds to MERGE_FORK_R
104 BOUNDARY_L, // corresponds to MERGE_FORK_L
106 LANE_TYPES_NUM
108 const int COLORS_NUM = 8;
110 // graph helpers
111 inline bool isHead(int x) { return (x == HEAD || x == HEAD_R || x == HEAD_L); }
112 inline bool isTail(int x) { return (x == TAIL || x == TAIL_R || x == TAIL_L); }
113 inline bool isJoin(int x) { return (x == JOIN || x == JOIN_R || x == JOIN_L); }
114 inline bool isFreeLane(int x) { return (x == NOT_ACTIVE || x == CROSS || isJoin(x)); }
115 inline bool isBoundary(int x) { return (x == BOUNDARY || x == BOUNDARY_C ||
116 x == BOUNDARY_R || x == BOUNDARY_L); }
117 inline bool isMerge(int x) { return (x == MERGE_FORK || x == MERGE_FORK_R ||
118 x == MERGE_FORK_L || isBoundary(x)); }
119 inline bool isActive(int x) { return (x == ACTIVE || x == INITIAL || x == BRANCH ||
120 isMerge(x)); }
122 // custom events
123 enum EventType {
124 ERROR_EV = 65432,
125 POPUP_LIST_EV = 65433,
126 POPUP_FILE_EV = 65434,
127 POPUP_TREE_EV = 65435,
128 MSG_EV = 65436,
129 ANN_PRG_EV = 65437,
130 UPD_DM_EV = 65438,
131 UPD_DM_MST_EV = 65439
134 // list views columns
135 enum ColumnType {
136 GRAPH_COL = 0,
137 ANN_ID_COL = 1,
138 LOG_COL = 2,
139 AUTH_COL = 3,
140 TIME_COL = 4,
141 COMMIT_COL = 97, // dummy col used for sha searching
142 LOG_MSG_COL = 98, // dummy col used for log messages searching
143 SHA_MAP_COL = 99 // dummy col used when filter output is a set of matching sha
146 inline bool isInfoCol(int x) { return (x == TIME_COL || x == LOG_COL || x == AUTH_COL); }
148 // default list view widths
149 const int DEF_GRAPH_COL_WIDTH = 80;
150 const int DEF_LOG_COL_WIDTH = 500;
151 const int DEF_AUTH_COL_WIDTH = 230;
152 const int DEF_TIME_COL_WIDTH = 160;
154 // colors
155 extern const QColor BROWN;
156 extern const QColor ORANGE;
157 extern const QColor DARK_ORANGE;
158 extern const QColor LIGHT_ORANGE;
159 extern const QColor LIGHT_BLUE;
160 extern const QColor PURPLE;
161 extern const QColor DARK_GREEN;
163 // initialized at startup according to system wide settings
164 extern QColor ODD_LINE_COL;
165 extern QColor EVEN_LINE_COL;
166 extern QFont STD_FONT;
167 extern QFont TYPE_WRITER_FONT;
168 extern QString GIT_DIR;
170 // patches drag and drop
171 extern const QString PATCHES_DIR;
172 extern const QString PATCHES_NAME;
174 // git index parameters
175 extern const QByteArray ZERO_SHA_BA;
176 extern const ShaString ZERO_SHA_RAW;
178 extern const QString ZERO_SHA;
179 extern const QString CUSTOM_SHA;
180 extern const QString ALL_MERGE_FILES;
182 // settings keys
183 extern const QString ORG_KEY;
184 extern const QString APP_KEY;
185 extern const QString GIT_DIR_KEY;
186 extern const QString PATCH_DIR_KEY;
187 extern const QString FMT_P_OPT_KEY;
188 extern const QString AM_P_OPT_KEY;
189 extern const QString STD_FNT_KEY;
190 extern const QString TYPWRT_FNT_KEY;
191 extern const QString FLAGS_KEY;
192 extern const QString CON_GEOM_KEY;
193 extern const QString CMT_GEOM_KEY;
194 extern const QString MAIN_GEOM_KEY;
195 extern const QString REV_GEOM_KEY;
196 extern const QString CMT_TEMPL_KEY;
197 extern const QString CMT_ARGS_KEY;
198 extern const QString RANGE_FROM_KEY;
199 extern const QString RANGE_TO_KEY;
200 extern const QString RANGE_OPT_KEY;
201 extern const QString EX_KEY;
202 extern const QString EX_PER_DIR_KEY;
203 extern const QString EXT_DIFF_KEY;
204 extern const QString REC_REP_KEY;
205 extern const QString ACT_LIST_KEY;
206 extern const QString ACT_GEOM_KEY;
207 extern const QString ACT_GROUP_KEY;
208 extern const QString ACT_TEXT_KEY;
209 extern const QString ACT_FLAGS_KEY;
211 // settings default values
212 extern const QString CMT_TEMPL_DEF;
213 extern const QString EX_DEF;
214 extern const QString EX_PER_DIR_DEF;
215 extern const QString EXT_DIFF_DEF;
217 // settings booleans
218 enum FlagType {
219 MSG_ON_NEW_F = 1 << 0,
220 ACT_REFRESH_F = 1 << 1,
221 NUMBERS_F = 1 << 2,
222 LOG_DIFF_TAB_F = 1 << 3,
223 ACT_CMD_LINE_F = 1 << 4,
224 DIFF_INDEX_F = 1 << 5,
225 SIGN_PATCH_F = 1 << 6,
226 SIGN_CMT_F = 1 << 7,
227 VERIFY_CMT_F = 1 << 8,
228 SMART_LBL_F = 1 << 9,
229 REL_DATE_F = 1 << 10,
230 ALL_BRANCHES_F = 1 << 11,
231 WHOLE_HISTORY_F = 1 << 12,
232 RANGE_SELECT_F = 1 << 13,
233 REOPEN_REPO_F = 1 << 14,
234 USE_CMT_MSG_F = 1 << 15
236 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;
238 // ShaString helpers
239 const ShaString toTempSha(const QString&); // use as argument only, see definition
240 const ShaString toPersistentSha(const QString&, QVector<QByteArray>&);
242 // settings helpers
243 uint flags(SCRef flagsVariable);
244 bool testFlag(uint f, SCRef fv = FLAGS_KEY);
245 void setFlag(uint f, bool b, SCRef fv = FLAGS_KEY);
247 // tree view icons helpers
248 void initMimePix();
249 void freeMimePix();
250 const QPixmap* mimePix(SCRef fileName);
252 // geometry settings helers
253 typedef QVector<QSplitter*> splitVect;
254 void saveGeometrySetting(SCRef name, QWidget* w = NULL, splitVect* svPtr = NULL);
255 void restoreGeometrySetting(SCRef name, QWidget* w = NULL, splitVect* svPtr = NULL);
257 // misc helpers
258 bool stripPartialParaghraps(const QByteArray& src, QString* dst, QString* prev);
259 bool writeToFile(SCRef fileName, SCRef data, bool setExecutable = false);
260 bool writeToFile(SCRef fileName, const QByteArray& data, bool setExecutable = false);
261 bool readFromFile(SCRef fileName, QString& data);
262 bool startProcess(QProcess* proc, SCList args, SCRef buf = "", bool* winShell = NULL);
264 // cache file
265 const uint C_MAGIC = 0xA0B0C0D0;
266 const int C_VERSION = 15;
268 extern const QString BAK_EXT;
269 extern const QString C_DAT_FILE;
271 // misc
272 const int MAX_DICT_SIZE = 100003; // must be a prime number see QDict docs
273 const int MAX_MENU_ENTRIES = 20;
274 const int MAX_RECENT_REPOS = 7;
275 extern const QString QUOTE_CHAR;
276 extern const QString SCRIPT_EXT;
279 class ShaString : public QLatin1String {
280 public:
281 inline ShaString() : QLatin1String(NULL) {}
282 inline ShaString(const ShaString& sha) : QLatin1String(sha.latin1()) {}
283 inline explicit ShaString(const char* sha) : QLatin1String(sha) {}
285 inline bool operator!=(const ShaString& o) const { return !operator==(o); }
286 inline bool operator==(const ShaString& o) const {
288 return (latin1() == o.latin1()) || !qstrcmp(latin1(), o.latin1());
292 class Rev {
293 // prevent implicit C++ compiler defaults
294 Rev();
295 Rev(const Rev&);
296 Rev& operator=(const Rev&);
297 public:
298 Rev(const QByteArray& b, uint s, int idx, int* next, bool withDiff)
299 : orderIdx(idx), ba(b), start(s) {
301 indexed = isDiffCache = isApplied = isUnApplied = false;
302 descRefsMaster = ancRefsMaster = descBrnMaster = -1;
303 *next = indexData(true, withDiff);
305 bool isBoundary() const { return (ba.at(shaStart - 1) == '-'); }
306 uint parentsCount() const { return parentsCnt; }
307 const ShaString parent(int idx) const;
308 const QStringList parents() const;
309 const ShaString sha() const { return ShaString(ba.constData() + shaStart); }
310 const QString committer() const { setup(); return mid(comStart, autStart - comStart - 1); }
311 const QString author() const { setup(); return mid(autStart, autDateStart - autStart - 1); }
312 const QString authorDate() const { setup(); return mid(autDateStart, 10); }
313 const QString shortLog() const { setup(); return mid(sLogStart, sLogLen); }
314 const QString longLog() const { setup(); return mid(lLogStart, lLogLen); }
315 const QString diff() const { setup(); return mid(diffStart, diffLen); }
317 QVector<int> lanes, children;
318 QVector<int> descRefs; // list of descendant refs index, normally tags
319 QVector<int> ancRefs; // list of ancestor refs index, normally tags
320 QVector<int> descBranches; // list of descendant branches index
321 int descRefsMaster; // in case of many Rev have the same descRefs, ancRefs or
322 int ancRefsMaster; // descBranches these are stored only once in a Rev pointed
323 int descBrnMaster; // by corresponding index xxxMaster
324 int orderIdx;
325 private:
326 inline void setup() const { if (!indexed) indexData(false, false); }
327 int indexData(bool quick, bool withDiff) const;
328 const QString mid(int start, int len) const;
329 const QString midSha(int start, int len) const;
331 const QByteArray& ba; // reference here!
332 const int start;
333 mutable int parentsCnt, shaStart, comStart, autStart, autDateStart;
334 mutable int sLogStart, sLogLen, lLogStart, lLogLen, diffStart, diffLen;
335 mutable bool indexed;
336 public:
337 bool isDiffCache, isApplied, isUnApplied; // put here to optimize padding
339 typedef QHash<ShaString, const Rev*> RevMap; // faster then a map
342 class RevFile {
344 friend class Cache; // to directly load status
345 friend class Git;
347 // Status information is splitted in a flags vector and in a string
348 // vector in 'status' are stored flags according to the info returned
349 // by 'git diff-tree' without -C option.
350 // In case of a working directory file an IN_INDEX flag is or-ed togheter in
351 // case file is present in git index.
352 // If file is renamed or copied an entry in 'extStatus' stores the
353 // value returned by 'git diff-tree -C' plus source and destination
354 // files info.
355 // When status of all the files is 'modified' then onlyModified is
356 // set, this let us to do some optimization in this common case
357 bool onlyModified;
358 QVector<int> status;
359 QVector<QString> extStatus;
361 // prevent implicit C++ compiler defaults
362 RevFile(const RevFile&);
363 RevFile& operator=(const RevFile&);
364 public:
366 enum StatusFlag {
367 MODIFIED = 1,
368 DELETED = 2,
369 NEW = 4,
370 RENAMED = 8,
371 COPIED = 16,
372 UNKNOWN = 32,
373 IN_INDEX = 64,
374 ANY = 127
377 RevFile() : onlyModified(true) {}
379 /* This QByteArray keeps indices in some dir and names vectors,
380 * defined outside RevFile. Paths are splitted in dir and file
381 * name, first all the dirs are listed then the file names to
382 * achieve a better compression when saved to disk.
383 * A single QByteArray is used instead of two vectors because it's
384 * much faster to load from disk when using a QDataStream
386 QByteArray pathsIdx;
388 int dirAt(uint idx) const { return ((int*)pathsIdx.constData())[idx]; }
389 int nameAt(uint idx) const { return ((int*)pathsIdx.constData())[count() + idx]; }
391 QVector<int> mergeParent;
393 // helper functions
394 int count() const {
396 return pathsIdx.size() / ((int)sizeof(int) * 2);
398 bool statusCmp(int idx, StatusFlag sf) const {
400 return ((onlyModified ? MODIFIED : status.at(idx)) & sf);
402 const QString extendedStatus(int idx) const {
404 rf.extStatus has size equal to position of latest copied/renamed file,
405 that could be lower then count(), so we have to explicitly check for
406 an out of bound condition.
408 return (!extStatus.isEmpty() && idx < extStatus.count() ? extStatus.at(idx) : "");
410 const RevFile& operator>>(QDataStream&) const;
411 RevFile& operator<<(QDataStream&);
413 typedef QHash<ShaString, const RevFile*> RevFileMap;
416 class FileAnnotation {
417 public:
418 explicit FileAnnotation(int id) : isValid(false), annId(id) {}
419 FileAnnotation() : isValid(false) {}
420 QStringList lines;
421 bool isValid;
422 int annId;
423 QString fileSha;
425 typedef QHash<ShaString, FileAnnotation> AnnotateHistory;
428 class BaseEvent: public QEvent {
429 public:
430 BaseEvent(SCRef d, int id) : QEvent((QEvent::Type)id), payLoad(d) {}
431 const QString myData() const { return payLoad; }
432 private:
433 const QString payLoad; // passed by copy
436 #define DEF_EVENT(X, T) class X : public BaseEvent { public: \
437 explicit X (SCRef d) : BaseEvent(d, T) {} }
439 DEF_EVENT(MessageEvent, QGit::MSG_EV);
440 DEF_EVENT(AnnotateProgressEvent, QGit::ANN_PRG_EV);
442 class DeferredPopupEvent : public BaseEvent {
443 public:
444 DeferredPopupEvent(SCRef msg, int type) : BaseEvent(msg, type) {}
447 class MainExecErrorEvent : public BaseEvent {
448 public:
449 MainExecErrorEvent(SCRef c, SCRef e) : BaseEvent("", QGit::ERROR_EV), cmd(c), err(e) {}
450 const QString command() const { return cmd; }
451 const QString report() const { return err; }
452 private:
453 const QString cmd, err;
456 #endif
458 QString qt4and5escaping(QString toescape);