annotate filestates.cpp @ 344:ccc55539e066

If the user cancels the first startup dialog (it has no cancel button, but they could use the WM close button), go no further
author Chris Cannam
date Wed, 16 Mar 2011 10:25:06 +0000
parents ea62eb083ed4
children 4cd753e083cc
rev   line source
Chris@109 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@109 2
Chris@109 3 /*
Chris@109 4 EasyMercurial
Chris@109 5
Chris@109 6 Based on HgExplorer by Jari Korhonen
Chris@109 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@109 10
Chris@109 11 This program is free software; you can redistribute it and/or
Chris@109 12 modify it under the terms of the GNU General Public License as
Chris@109 13 published by the Free Software Foundation; either version 2 of the
Chris@109 14 License, or (at your option) any later version. See the file
Chris@109 15 COPYING included with this distribution for more information.
Chris@109 16 */
Chris@109 17
Chris@92 18 #include "filestates.h"
Chris@74 19
Chris@86 20 #include "debug.h"
Chris@86 21
Chris@74 22 #include <QMap>
Chris@74 23
Chris@94 24 FileStates::FileStates()
Chris@94 25 {
Chris@94 26 }
Chris@94 27
Chris@94 28 void FileStates::clearBuckets()
Chris@94 29 {
Chris@199 30 m_clean.clear();
Chris@94 31 m_modified.clear();
Chris@94 32 m_added.clear();
Chris@94 33 m_removed.clear();
Chris@94 34 m_missing.clear();
Chris@159 35 m_inConflict.clear();
Chris@94 36 m_unknown.clear();
Chris@199 37 m_ignored.clear();
Chris@94 38 }
Chris@94 39
Chris@94 40 FileStates::State FileStates::charToState(QChar c, bool *ok)
Chris@94 41 {
Chris@159 42 // Note that InConflict does not correspond to a stat char -- it's
Chris@163 43 // reported separately, by resolve --list, which shows U for
Chris@163 44 // Unresolved -- stat reports files in conflict as M, which means
Chris@163 45 // they will appear in more than one bin if we handle them
Chris@163 46 // naively. 'u' is also used by stat as the command option for
Chris@163 47 // Unknown, but the stat output uses ? for these so there's no
Chris@163 48 // ambiguity in parsing.
Chris@159 49
Chris@94 50 if (ok) *ok = true;
Chris@94 51 if (c == 'M') return Modified;
Chris@94 52 if (c == 'A') return Added;
Chris@94 53 if (c == 'R') return Removed;
Chris@94 54 if (c == '!') return Missing;
Chris@163 55 if (c == 'U') return InConflict;
Chris@94 56 if (c == '?') return Unknown;
Chris@94 57 if (c == 'C') return Clean;
Chris@199 58 if (c == 'I') return Ignored;
Chris@94 59 if (ok) *ok = false;
Chris@94 60 return Unknown;
Chris@94 61 }
Chris@94 62
Chris@94 63 QStringList *FileStates::stateToBucket(State s)
Chris@94 64 {
Chris@94 65 switch (s) {
Chris@324 66 case Clean: return &m_clean;
Chris@94 67 case Modified: return &m_modified;
Chris@94 68 case Added: return &m_added;
Chris@94 69 case Unknown: return &m_unknown;
Chris@94 70 case Removed: return &m_removed;
Chris@94 71 case Missing: return &m_missing;
Chris@159 72 case InConflict: return &m_inConflict;
Chris@199 73 case Ignored: return &m_ignored;
Chris@205 74
Chris@205 75 default: return &m_clean;
Chris@94 76 }
Chris@94 77 }
Chris@94 78
Chris@94 79 void FileStates::parseStates(QString text)
Chris@74 80 {
Chris@74 81 text.replace("\r\n", "\n");
Chris@74 82
Chris@94 83 clearBuckets();
Chris@163 84 m_stateMap.clear();
Chris@74 85
Chris@74 86 QStringList lines = text.split("\n", QString::SkipEmptyParts);
Chris@94 87
Chris@74 88 foreach (QString line, lines) {
Chris@94 89
Chris@86 90 if (line.length() < 3 || line[1] != ' ') {
Chris@86 91 continue;
Chris@86 92 }
Chris@94 93
Chris@94 94 QChar c = line[0];
Chris@94 95 bool ok = false;
Chris@94 96 State s = charToState(c, &ok);
Chris@94 97 if (!ok) continue;
Chris@94 98
Chris@74 99 QString file = line.right(line.length() - 2);
Chris@163 100 m_stateMap[file] = s;
Chris@163 101 }
Chris@163 102
Chris@163 103 foreach (QString file, m_stateMap.keys()) {
Chris@163 104 QStringList *bucket = stateToBucket(m_stateMap[file]);
Chris@199 105 if (bucket) bucket->push_back(file);
Chris@74 106 }
Chris@86 107
Chris@199 108 DEBUG << "FileStates: "
Chris@199 109 << m_modified.size() << " modified, " << m_added.size()
Chris@159 110 << " added, " << m_removed.size() << " removed, " << m_missing.size()
Chris@159 111 << " missing, " << m_inConflict.size() << " in conflict, "
Chris@159 112 << m_unknown.size() << " unknown" << endl;
Chris@74 113 }
Chris@92 114
Chris@324 115 QStringList FileStates::filesInState(State s) const
Chris@92 116 {
Chris@94 117 QStringList *sl = const_cast<FileStates *>(this)->stateToBucket(s);
Chris@94 118 if (sl) return *sl;
Chris@94 119 else return QStringList();
Chris@92 120 }
Chris@92 121
Chris@324 122 bool FileStates::isInState(QString file, State s) const
Chris@324 123 {
Chris@324 124 return filesInState(s).contains(file);
Chris@324 125 }
Chris@324 126
Chris@324 127 FileStates::State FileStates::stateOf(QString file) const
Chris@92 128 {
Chris@94 129 if (m_stateMap.contains(file)) {
Chris@94 130 return m_stateMap[file];
Chris@92 131 }
Chris@92 132 DEBUG << "FileStates: WARNING: getStateOfFile: file "
Chris@92 133 << file << " is unknown to us: returning Unknown state, "
Chris@92 134 << "but unknown to us is not supposed to be the same "
Chris@92 135 << "thing as unknown state..."
Chris@92 136 << endl;
Chris@92 137 return Unknown;
Chris@92 138 }
Chris@324 139
Chris@324 140 FileStates::Activities FileStates::activitiesSupportedBy(State s)
Chris@324 141 {
Chris@324 142 Activities a;
Chris@324 143
Chris@324 144 switch (s) {
Chris@324 145
Chris@324 146 case Modified:
Chris@324 147 a << Annotate << Diff << Commit << Revert << Remove;
Chris@324 148 break;
Chris@324 149
Chris@324 150 case Added:
Chris@324 151 a << Commit << Revert << Remove;
Chris@324 152 break;
Chris@324 153
Chris@324 154 case Removed:
Chris@324 155 a << Commit << Revert << Add;
Chris@324 156 break;
Chris@324 157
Chris@324 158 case InConflict:
Chris@328 159 a << Annotate << Diff << RedoMerge << MarkResolved << Revert;
Chris@324 160 break;
Chris@324 161
Chris@324 162 case Missing:
Chris@324 163 a << Revert << Remove;
Chris@324 164 break;
Chris@324 165
Chris@324 166 case Unknown:
Chris@324 167 a << Add << Ignore;
Chris@324 168 break;
Chris@324 169
Chris@324 170 case Clean:
Chris@328 171 a << Annotate << Remove;
Chris@324 172 break;
Chris@324 173
Chris@324 174 case Ignored:
Chris@324 175 a << UnIgnore;
Chris@324 176 break;
Chris@324 177 }
Chris@324 178
Chris@324 179 return a;
Chris@324 180 }
Chris@324 181
Chris@324 182 bool FileStates::supportsActivity(State s, Activity a)
Chris@324 183 {
Chris@324 184 return activitiesSupportedBy(s).contains(a);
Chris@324 185 }
Chris@324 186
Chris@325 187 int FileStates::activityGroup(Activity a)
Chris@325 188 {
Chris@325 189 switch (a) {
Chris@325 190 case Annotate: case Diff: return 0;
Chris@325 191 case Commit: case Revert: return 1;
Chris@325 192 case Add: case Remove: return 2;
Chris@325 193 case RedoMerge: case MarkResolved: return 3;
Chris@325 194 case Ignore: case UnIgnore: return 4;
Chris@325 195 }
Chris@326 196 return 0;
Chris@325 197 }
Chris@325 198
Chris@324 199 bool FileStates::supportsActivity(QString file, Activity a) const
Chris@324 200 {
Chris@324 201 return supportsActivity(stateOf(file), a);
Chris@324 202 }
Chris@324 203
Chris@324 204 QStringList FileStates::filesSupportingActivity(Activity a) const
Chris@324 205 {
Chris@324 206 QStringList f;
Chris@324 207 for (int i = int(FirstState); i <= int(LastState); ++i) {
Chris@324 208 State s = (State)i;
Chris@326 209 if (supportsActivity(s, a)) {
Chris@326 210 f << filesInState(s);
Chris@326 211 }
Chris@324 212 }
Chris@324 213 return f;
Chris@324 214 }
Chris@324 215
Chris@324 216 FileStates::Activities FileStates::activitiesSupportedBy(QString file) const
Chris@324 217 {
Chris@324 218 return activitiesSupportedBy(stateOf(file));
Chris@324 219 }
Chris@324 220