annotate common.cpp @ 363:f89e50d748ed feature_93

Enable Push button whenever the repo is non-empty, even when there is no remote location -- ask for remote location when it is pressed. Also change "Change Remote..." to "Set Remote..." to be consistent with this new usage
author Chris Cannam
date Thu, 17 Mar 2011 17:48:18 +0000
parents 8fd71f570884
children
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@244 8 Copyright (c) 2011 Chris Cannam
Chris@244 9 Copyright (c) 2011 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 */
jtkorhonen@0 17
Chris@62 18 #include "common.h"
Chris@62 19 #include "debug.h"
jtkorhonen@0 20
Chris@62 21 #include <QFileInfo>
Chris@62 22 #include <QProcessEnvironment>
Chris@62 23 #include <QStringList>
Chris@77 24 #include <QDir>
Chris@172 25 #include <QRegExp>
jtkorhonen@0 26
Chris@62 27 #include <sys/types.h>
Chris@76 28
Chris@76 29 #ifdef Q_OS_WIN32
Chris@76 30 #define _WIN32_WINNT 0x0500
Chris@166 31 #define SECURITY_WIN32
Chris@76 32 #include <windows.h>
Chris@76 33 #include <security.h>
Chris@76 34 #else
Chris@78 35 #include <errno.h>
Chris@62 36 #include <pwd.h>
Chris@78 37 #include <unistd.h>
Chris@80 38 #include <sys/ioctl.h>
Chris@80 39 #include <sys/types.h>
Chris@80 40 #include <sys/stat.h>
Chris@80 41 #include <fcntl.h>
Chris@105 42 #include <signal.h>
Chris@76 43 #endif
Chris@62 44
Chris@172 45 QString findInPath(QString name, QString installPath, bool executableRequired)
Chris@62 46 {
Chris@77 47 bool found = false;
Chris@62 48 if (name != "") {
Chris@172 49 if (name[0] != '/'
Chris@172 50 #ifdef Q_OS_WIN32
Chris@178 51 && (QRegExp("^\\w:").indexIn(name) != 0)
Chris@172 52 #endif
Chris@178 53 ) {
Chris@77 54 #ifdef Q_OS_WIN32
Chris@77 55 QChar pathSep = ';';
Chris@77 56 #else
Chris@77 57 QChar pathSep = ':';
Chris@77 58 #endif
Chris@62 59 name = QFileInfo(name).fileName();
Chris@62 60 QString path =
Chris@62 61 QProcessEnvironment::systemEnvironment().value("PATH");
Chris@214 62 DEBUG << "findInPath: seeking location for binary " << name
Chris@74 63 << ": system path is " << path << endl;
Chris@172 64 if (installPath != "") {
Chris@214 65 DEBUG << "findInPath: install path is " << installPath
Chris@172 66 << ", adding to system path" << endl;
Chris@172 67 //!!! path = path + pathSep + installPath;
Chris@172 68 path = installPath + pathSep + path;
Chris@172 69 }
Chris@74 70 #ifndef Q_OS_WIN32
Chris@178 71 //!!!
Chris@74 72 path = path + ":/usr/local/bin";
Chris@74 73 DEBUG << "... adding /usr/local/bin just in case (fix and add settings dlg please)"
Chris@74 74 << endl;
Chris@74 75 #endif
Chris@62 76 QStringList elements = path.split(pathSep, QString::SkipEmptyParts);
Chris@62 77 foreach (QString element, elements) {
Chris@77 78 QString full = QDir(element).filePath(name);
Chris@62 79 QFileInfo fi(full);
Chris@214 80 DEBUG << "findInPath: looking at " << full << endl;
Chris@172 81 if (fi.exists() && fi.isFile()) {
Chris@214 82 DEBUG << "findInPath: it's a file" << endl;
Chris@172 83 if (!executableRequired || fi.isExecutable()) {
Chris@172 84 name = full;
Chris@214 85 DEBUG << "findInPath: found at " << name << endl;
Chris@172 86 found = true;
Chris@172 87 break;
Chris@172 88 }
Chris@62 89 }
Chris@62 90 }
Chris@214 91 } else {
Chris@214 92 // absolute path given
Chris@214 93 QFileInfo fi(name);
Chris@214 94 DEBUG << "findInPath: looking at absolute path " << name << endl;
Chris@214 95 if (fi.exists() && fi.isFile()) {
Chris@214 96 DEBUG << "findInPath: it's a file" << endl;
Chris@214 97 if (!executableRequired || fi.isExecutable()) {
Chris@214 98 DEBUG << "findInPath: found at " << name << endl;
Chris@214 99 found = true;
Chris@214 100 }
Chris@214 101 }
Chris@62 102 }
Chris@62 103 }
Chris@77 104 #ifdef Q_OS_WIN32
Chris@77 105 if (!found) {
Chris@77 106 if (!name.endsWith(".exe")) {
Chris@172 107 return findInPath(name + ".exe", installPath, executableRequired);
Chris@77 108 }
Chris@77 109 }
Chris@77 110 #endif
Chris@213 111 if (found) {
Chris@213 112 return name;
Chris@213 113 } else {
Chris@213 114 return "";
Chris@213 115 }
Chris@62 116 }
jtkorhonen@0 117
Chris@62 118 #ifdef Q_OS_WIN32
Chris@62 119 QString getUserRealName()
Chris@62 120 {
Chris@76 121 TCHAR buf[1024];
Chris@76 122 long unsigned int maxlen = 1000;
Chris@62 123 LPTSTR info = buf;
jtkorhonen@0 124
Chris@76 125 if (!GetUserNameEx(NameDisplay, info, &maxlen)) {
Chris@76 126 DEBUG << "GetUserNameEx failed: " << GetLastError() << endl;
Chris@62 127 return "";
Chris@62 128 }
jtkorhonen@0 129
Chris@76 130 #ifdef UNICODE
Chris@76 131 return QString::fromUtf16((const unsigned short *)info);
Chris@76 132 #else
Chris@76 133 return QString::fromLocal8Bit(info);
Chris@76 134 #endif
Chris@62 135 }
luisf@71 136 #else
luisf@71 137 #ifdef Q_OS_MAC
Chris@62 138 // Nothing here: definition is in common_osx.mm
Chris@62 139 #else
Chris@62 140 QString getUserRealName()
Chris@62 141 {
Chris@62 142 const int maxlen = 1023;
Chris@62 143 char buf[maxlen + 2];
jtkorhonen@0 144
Chris@62 145 if (getlogin_r(buf, maxlen)) return "";
jtkorhonen@0 146
Chris@62 147 struct passwd *p = getpwnam(buf);
Chris@62 148 if (!p) return "";
Chris@62 149
Chris@62 150 QString s(p->pw_gecos);
Chris@62 151 if (s != "") s = s.split(',')[0];
Chris@62 152 return s;
Chris@62 153 }
Chris@62 154 #endif
luisf@71 155 #endif
jtkorhonen@0 156
Chris@78 157 void loseControllingTerminal()
Chris@78 158 {
Chris@78 159 #ifndef Q_OS_WIN32
Chris@80 160
Chris@80 161 if (!isatty(0)) {
Chris@80 162 DEBUG << "stdin is not a terminal" << endl;
Chris@80 163 } else {
Chris@80 164 DEBUG << "stdin is a terminal, detaching from it" << endl;
Chris@80 165 if (ioctl(0, TIOCNOTTY, NULL) < 0) {
Chris@80 166 perror("ioctl failed");
Chris@83 167 DEBUG << "ioctl for TIOCNOTTY on stdin failed (errno = " << errno << ")" << endl;
Chris@78 168 } else {
Chris@83 169 DEBUG << "ioctl for TIOCNOTTY on stdin succeeded" << endl;
Chris@83 170 return;
Chris@78 171 }
Chris@80 172 }
Chris@80 173
Chris@80 174 int ttyfd = open("/dev/tty", O_RDWR);
Chris@80 175 if (ttyfd < 0) {
Chris@80 176 DEBUG << "failed to open controlling terminal" << endl;
Chris@80 177 } else {
Chris@80 178 if (ioctl(ttyfd, TIOCNOTTY, NULL) < 0) {
Chris@80 179 perror("ioctl failed");
Chris@83 180 DEBUG << "ioctl for TIOCNOTTY on controlling terminal failed (errno = " << errno << ")" << endl;
Chris@80 181 } else {
Chris@83 182 DEBUG << "ioctl for TIOCNOTTY on controlling terminal succeeded" << endl;
Chris@83 183 return;
Chris@78 184 }
Chris@78 185 }
Chris@80 186
Chris@78 187 #endif
Chris@78 188 }
Chris@79 189
Chris@105 190 void installSignalHandlers()
Chris@105 191 {
Chris@105 192 #ifndef Q_OS_WIN32
Chris@105 193 sigset_t sgnals;
Chris@105 194 sigemptyset (&sgnals);
Chris@105 195 sigaddset(&sgnals, SIGHUP);
Chris@105 196 sigaddset(&sgnals, SIGCONT);
Chris@105 197 pthread_sigmask(SIG_BLOCK, &sgnals, 0);
Chris@105 198 #endif
Chris@105 199 }
Chris@105 200
Chris@79 201 FolderStatus getFolderStatus(QString path)
Chris@79 202 {
Chris@85 203 if (path != "/" && path.endsWith("/")) {
Chris@85 204 path = path.left(path.length()-1);
Chris@85 205 }
Chris@84 206 DEBUG << "getFolderStatus: " << path << endl;
Chris@79 207 QFileInfo fi(path);
Chris@79 208 if (fi.exists()) {
Chris@84 209 DEBUG << "exists" << endl;
Chris@79 210 QDir dir(path);
Chris@79 211 if (!dir.exists()) { // returns false for files
Chris@84 212 DEBUG << "not directory" << endl;
Chris@79 213 return FolderIsFile;
Chris@79 214 }
Chris@79 215 if (QDir(dir.filePath(".hg")).exists()) {
Chris@84 216 DEBUG << "has repo" << endl;
Chris@79 217 return FolderHasRepo;
Chris@79 218 }
Chris@79 219 return FolderExists;
Chris@79 220 } else {
Chris@79 221 QDir parent = fi.dir();
Chris@79 222 if (parent.exists()) {
Chris@84 223 DEBUG << "parent exists" << endl;
Chris@79 224 return FolderParentExists;
Chris@79 225 }
Chris@79 226 return FolderUnknown;
Chris@79 227 }
Chris@79 228 }
Chris@79 229
Chris@79 230 QString getContainingRepoFolder(QString path)
Chris@79 231 {
Chris@79 232 if (getFolderStatus(path) == FolderHasRepo) return "";
Chris@79 233
Chris@79 234 QFileInfo me(path);
Chris@79 235 QFileInfo parent(me.dir().absolutePath());
Chris@79 236
Chris@79 237 while (me != parent) {
Chris@79 238 QString parentPath = parent.filePath();
Chris@79 239 if (getFolderStatus(parentPath) == FolderHasRepo) {
Chris@79 240 return parentPath;
Chris@79 241 }
Chris@79 242 me = parent;
Chris@79 243 parent = me.dir().absolutePath();
Chris@79 244 }
Chris@79 245
Chris@79 246 return "";
Chris@79 247 }
Chris@79 248
Chris@79 249 QString xmlEncode(QString s)
Chris@79 250 {
Chris@79 251 s
Chris@79 252 .replace("&", "&amp;")
Chris@79 253 .replace("<", "&lt;")
Chris@79 254 .replace(">", "&gt;")
Chris@79 255 .replace("\"", "&quot;")
Chris@79 256 .replace("'", "&apos;");
Chris@79 257
Chris@79 258 return s;
Chris@79 259 }