00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "svn.hpp"
00016 #include "gui/principal.h"
00017
00018 Svn::Svn(Principal* cl) :
00019 needs_refresh_(false), out_win_(cl->messagesBrowser), show_enable_(true), parent_(cl)
00020 {
00021 caller = cl;
00022 proc = new QProcess(this);
00023 svn_ = "svn";
00024 is_ready_for_last_command_ = false;
00025 connect(proc, SIGNAL(readyReadStdout()), this, SLOT(readFromStdout()) );
00026 connect(proc, SIGNAL(readyReadStderr()), this, SLOT(readFromStderr()) );
00027 connect(proc, SIGNAL(processExited()), this, SLOT(procFinished()) );
00028 };
00029
00030 void Svn::common(QString command)
00031 {
00032 proc->clearArguments();
00033 proc->addArgument(svn_);
00034 proc->addArgument(command);
00035 }
00036
00037 int Svn::diff(const QString& file_dir_name_1, const QString& file_dir_name_2,
00038 const QString& rev, bool use_external_cmd, bool non_recursive, bool notice_ancestry,
00039 const QString& extensions, QStringList& out_txt)
00040 {
00041 common("diff");
00042
00043 if (rev != "") {
00044 proc->addArgument("-r");
00045 proc->addArgument(rev);
00046 }
00047
00048 if (!file_dir_name_1.isEmpty()) {
00049 if (!file_dir_name_2.isEmpty()) {
00050 proc->addArgument("--old");
00051 proc->addArgument(QDir::convertSeparators(file_dir_name_1));
00052 proc->addArgument("--new");
00053 proc->addArgument(QDir::convertSeparators(file_dir_name_2));
00054 } else {
00055
00056 proc->addArgument(QDir::convertSeparators(file_dir_name_1));
00057 }
00058 }
00059
00060 if (non_recursive)
00061 proc->addArgument("--non-recursive");
00062
00063 if (notice_ancestry)
00064 proc->addArgument("--notice-ancestry");
00065
00066 if (!extensions.isEmpty()) {
00067 proc->addArgument("--extensions");
00068 proc->addArgument(extensions);
00069 }
00070
00071 if (use_external_cmd) {
00072 proc->addArgument("--diff-cmd");
00073 return execCommand(false);
00074 }
00075 else
00076 return execCommand(SC_APPEND_USER_PASS, &out_txt);
00077 }
00078
00079 int Svn::update(const QString& revision)
00080 {
00081 common("update");
00082
00083 if (revision != "") {
00084 proc->addArgument("-r");
00085 proc->addArgument(revision);
00086 }
00087 proc->addArgument(caller->wd);
00088 return execCommand(SC_REFRESH | SC_APPEND_USER_PASS | SC_WAIT);
00089 }
00090
00091 int Svn::log(const QString& filename, bool is_verbouse, bool stop_on_copy, QStringList& out_txt)
00092 {
00093 common("log");
00094 if (is_verbouse)
00095 proc->addArgument("--verbose");
00096 if (stop_on_copy)
00097 proc->addArgument("--stop-on-copy");
00098 proc->addArgument(filename);
00099 return execCommand(SC_APPEND_USER_PASS, &out_txt);
00100 }
00101
00102 int Svn::status() {
00103 common("status");
00104 proc->addArgument(caller->wd);
00105 proc->addArgument("--verbose");
00106 return execCommand(SC_APPEND_USER_PASS | SC_WAIT);
00107 }
00108
00109 int Svn::info(const QString& filename, QStringList& out_txt, bool hideOutput) {
00110 common("info");
00111 proc->addArgument(filename);
00112 if (hideOutput)
00113 return execCommand(SC_HIDE, &out_txt);
00114 else
00115 return execCommand(0, &out_txt);
00116 }
00117
00118 int Svn::commit(const QString& wd, QString msg) {
00119 common("commit");
00120
00121 if (msg == "")
00122 msg = "nomsg";
00123 proc->addArgument("-m");
00124 proc->addArgument(msg);
00125 if (wd != "")
00126 proc->addArgument(wd);
00127 return execCommand(SC_REFRESH | SC_WAIT | SC_APPEND_USER_PASS);
00128 }
00129
00130 int Svn::cleanup(QString& wd) {
00131 common("cleanup");
00132 if (wd != "")
00133 proc->addArgument(wd);
00134 return execCommand(SC_WAIT);
00135 }
00136
00137 int Svn::revert(const QString& filename, bool recursive) {
00138 common("revert");
00139 if (recursive)
00140 proc->addArgument("--recursive");
00141 if (filename != "")
00142 proc->addArgument(filename);
00143 return execCommand(SC_REFRESH | SC_WAIT);
00144 }
00145
00146 int Svn::resolve(const QString& filename) {
00147 common("resolved");
00148 if (filename != "")
00149 proc->addArgument(filename);
00150 return execCommand(SC_REFRESH | SC_WAIT);
00151 }
00152
00153 int Svn::add(const QString& filename, bool recursive) {
00154 common("add");
00155 if (!recursive)
00156 proc->addArgument("-N");
00157 proc->addArgument(filename);
00158 return execCommand(SC_REFRESH | SC_WAIT);
00159 }
00160
00161 int Svn::del(const QString filename) {
00162 common("delete");
00163 proc->addArgument(filename);
00164 return execCommand(SC_REFRESH | SC_APPEND_USER_PASS | SC_WAIT);
00165 }
00166
00167 int Svn::copy(QString& src, const QString &dst, const QString& msg, const QString& rev) {
00168 common("copy");
00169 proc->addArgument(src);
00170 proc->addArgument(dst);
00171 proc->addArgument("-m");
00172 if (msg == "")
00173 proc->addArgument("\"copied\"");
00174 else
00175 proc->addArgument(msg);
00176 if (rev != "") {
00177 proc->addArgument("-r");
00178 proc->addArgument(rev);
00179 }
00180 return execCommand(SC_REFRESH | SC_APPEND_USER_PASS | SC_WAIT);
00181 }
00182
00183 int Svn::move(const QString& src, const QString &dst, const QString& msg, const QString& rev) {
00184 common("move");
00185 proc->addArgument(src);
00186 proc->addArgument(dst);
00187 proc->addArgument("-m");
00188 if (msg == "")
00189 proc->addArgument("\"moved\"");
00190 else
00191 proc->addArgument(msg);
00192 if (rev != "") {
00193 proc->addArgument("-r");
00194 proc->addArgument(rev);
00195 }
00196 return execCommand(SC_REFRESH | SC_APPEND_USER_PASS | SC_WAIT);
00197 }
00198
00199 int Svn::switch_cmd(const QString& url, const QString &rev, bool non_recursive) {
00200 common("switch");
00201 if (rev != "") {
00202 proc->addArgument("-r");
00203 proc->addArgument(rev);
00204 }
00205 if (non_recursive)
00206 proc->addArgument("--non-recursive");
00207 proc->addArgument(url);
00208 return execCommand(SC_REFRESH | SC_APPEND_USER_PASS | SC_WAIT);
00209 }
00210
00211 int Svn::merge(const QString& file_dir_name, const QString& first, const QString &second,
00212 const QString& wcpath, bool use_rev, bool non_recursive, bool dryrun) {
00213 common("merge");
00214 if (non_recursive)
00215 proc->addArgument("--non-recursive");
00216 if (dryrun)
00217 proc->addArgument("--dry-run");
00218 if (use_rev) {
00219 proc->addArgument("-r");
00220 proc->addArgument(first+":"+second);
00221 proc->addArgument(file_dir_name);
00222 }
00223 else {
00224 proc->addArgument(first);
00225 proc->addArgument(second);
00226 }
00227 if (!wcpath.isEmpty())
00228 proc->addArgument(wcpath);
00229 return execCommand(SC_REFRESH | SC_WAIT);
00230 }
00231
00232 int Svn::cat(const QString& filename, const QString& rev, QStringList& out_txt) {
00233 common("cat");
00234 proc->addArgument(filename);
00235 if (rev != "") {
00236 proc->addArgument("-r");
00237 proc->addArgument(rev);
00238 }
00239 return execCommand(SC_APPEND_USER_PASS, &out_txt);
00240 }
00241
00242 int Svn::blame(const QString& filename, const QString& rev, QStringList& out_txt) {
00243 common("blame");
00244 proc->addArgument(filename);
00245 if (rev != "") {
00246 proc->addArgument("-r");
00247 proc->addArgument(rev);
00248 }
00249 return execCommand(SC_APPEND_USER_PASS, &out_txt);
00250 }
00251
00252 int Svn::checkout(const QString &rev, bool non_recursive) {
00253 common("checkout");
00254 proc->addArgument(caller->adress + caller->wd);
00255 proc->addArgument(caller->wd);
00256
00257 if (rev != "") {
00258 proc->addArgument("-r");
00259 proc->addArgument(rev);
00260 }
00261 if (non_recursive)
00262 proc->addArgument("--non-recursive");
00263 proc->addArgument("--non-interactive");
00264
00265 return execCommand(SC_REFRESH | SC_APPEND_USER_PASS | SC_WAIT);
00266 }
00267
00268 int Svn::export_cmd(const QString& url, const QString& local_path, const QString &rev) {
00269 common("export");
00270 proc->addArgument(url);
00271 proc->addArgument(local_path);
00272 if (rev != "") {
00273 proc->addArgument("-r");
00274 proc->addArgument(rev);
00275 }
00276 return execCommand(SC_REFRESH | SC_APPEND_USER_PASS | SC_WAIT);
00277 }
00278
00279 int Svn::import(const QString& url, const QString& local_path, QString msg, bool non_recursive) {
00280 common("import");
00281 proc->addArgument(local_path);
00282 proc->addArgument(url);
00283 if (msg == "")
00284 msg = "nomsg";
00285 proc->addArgument("-m");
00286 proc->addArgument(msg);
00287 if (non_recursive)
00288 proc->addArgument("--non-recursive");
00289 return execCommand(SC_REFRESH | SC_APPEND_USER_PASS | SC_WAIT);
00290 }
00291
00292 int Svn::mkdir(const QString& dir) {
00293 common("mkdir");
00294 proc->addArgument(dir);
00295 return execCommand(SC_REFRESH | SC_APPEND_USER_PASS | SC_WAIT);
00296 }
00297
00298 int Svn::proplist(const QString& filename, const QString& rev, QStringList& out_txt) {
00299 common("proplist");
00300 proc->addArgument(filename);
00301 proc->addArgument("--verbose");
00302 if (!rev.isEmpty()) {
00303 proc->addArgument("-r");
00304 proc->addArgument(rev);
00305 }
00306 return execCommand(SC_WAIT | SC_APPEND_USER_PASS, &out_txt);
00307 }
00308
00309 int Svn::propset(const QString& filename, const QString& rev, const QString& key, const QString &value) {
00310 common("propset");
00311 proc->addArgument(key);
00312 proc->addArgument(value);
00313 proc->addArgument(filename);
00314 if (rev != "") {
00315 proc->addArgument("-r");
00316 proc->addArgument(rev);
00317 }
00318 return execCommand(SC_WAIT | SC_APPEND_USER_PASS);
00319 }
00320
00321 int Svn::propdel(const QString& filename, const QString& rev, const QString& key) {
00322 common("propdel");
00323 proc->addArgument(key);
00324 proc->addArgument(filename);
00325 if (rev != "") {
00326 proc->addArgument("-r");
00327 proc->addArgument(rev);
00328 }
00329 return execCommand(SC_WAIT | SC_APPEND_USER_PASS);
00330 }
00331
00332 int Svn::list(const QString& url, const QString& rev, QStringList& out_txt, bool is_hide,
00333 bool recursive, bool dont_change_cursor) {
00334 common("list");
00335 proc->addArgument(url);
00336 if (recursive)
00337 proc->addArgument("--recursive");
00338 proc->addArgument("--verbose");
00339 if (rev != "") {
00340 proc->addArgument("-r");
00341 proc->addArgument(rev);
00342 }
00343 return execCommand(SC_WAIT | SC_APPEND_USER_PASS | (dont_change_cursor ? SC_DISABLE_CURSOR_CHANGE : 0) | (is_hide ? SC_HIDE : 0), &out_txt);
00344 }
00345
00346 void Svn::setSvn(QString svn){
00347 svn_ = svn;
00348 }
00349
00350 int Svn::getLastRev() {
00351 QStringList infoOutput;
00352 if (info(caller->adress + caller->wd + "/prop.graphml", infoOutput,true))
00353 info(caller->wd + "/prop.graphml", infoOutput,true);
00354 infoOutput = infoOutput.grep("Revision");
00355 QString stemp = infoOutput.first();
00356 stemp = stemp.right( stemp.length() - 10);
00357 return stemp.toInt();
00358 }
00359
00360
00361
00362 void Svn::readFromStdout() {
00363 while (proc->canReadLineStdout()) {
00364 QString src_msg = proc->readLineStdout();
00365 QString str = QTextCodec::codecForLocale()->toUnicode(src_msg);
00366 if(!str.isNull()){
00367 if (show_enable_)
00368 out_win_->append(QString("<font color=black>") + str + QString("</font>") );
00369 out_text_.push_back(str);
00370 }
00371 }
00372 }
00373
00374 void Svn::readFromStderr() {
00375 while (proc->canReadLineStderr()) {
00376 QString str = QTextCodec::codecForLocale()->toUnicode(proc->readLineStderr());
00377 out_win_->append(QString("<font color=red>") + str + QString("</font>") );
00378 if (!disable_cursor_change_)
00379 QApplication::restoreOverrideCursor();
00380 }
00381 }
00382
00383 void Svn::procFinished() {
00384 parent_->blockSignals(false);
00385 if (!disable_cursor_change_)
00386 QApplication::restoreOverrideCursor();
00387 if (!is_hide_all_) {
00388 int ret_code = proc->exitStatus();
00389 char ret_code_buff[64];
00390 if (ret_code == 0)
00391 sprintf(ret_code_buff, "<font color=darkgreen>successfully (%d)</font>", ret_code);
00392 else
00393 sprintf(ret_code_buff, "<font color=darkred>error (%d)</font>", ret_code);
00394 out_win_->append(ret_code_buff);
00395 }
00396 if (is_refreshable_command_)
00397 needs_refresh_ = true;
00398 is_ready_for_last_command_ = true;
00399 }
00400
00401 QString Svn::getLastCommand() {
00402 if (is_ready_for_last_command_) {
00403 QStringList args = proc->arguments();
00404 if (args.empty())
00405 return "";
00406 else {
00407 is_ready_for_last_command_ = false;
00408 return args[1];
00409 }
00410 }
00411 else
00412 return "";
00413 }
00414
00415
00416 int Svn::execCommand(unsigned int flags, QStringList* out_list) {
00417 disable_cursor_change_ = (flags & SC_DISABLE_CURSOR_CHANGE);
00418
00419 if (!disable_cursor_change_)
00420 QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) );
00421 is_refreshable_command_ = (flags & SC_REFRESH);
00422
00423 if (flags & SC_APPEND_USER_PASS) {
00424 proc->addArgument("--username");
00425 proc->addArgument(caller->login());
00426 proc->addArgument("--password");
00427 proc->addArgument(caller->password());
00428 proc->addArgument("--non-interactive");
00429 }
00430 is_hide_all_ = (flags & SC_HIDE);
00431
00432 if (!is_hide_all_ ) {
00433 QString svn_cmd = showCommand();
00434 }
00435
00436 show_enable_ = (!out_list && !is_hide_all_);
00437 out_text_.clear();
00438 qApp->processEvents();
00439
00440 proc->setWorkingDirectory(qApp->applicationDirPath());
00441
00442 if (!proc->start()) {
00443 out_text_.append(tr("can't fork the process"));
00444
00445 if (!disable_cursor_change_)
00446 QApplication::restoreOverrideCursor();
00447 return 1;
00448 }
00449
00450 parent_->blockSignals(true);
00451 if (out_list || (flags & SC_WAIT) ) {
00452
00453 while (proc->isRunning()) {
00454 qApp->processEvents(QEventLoop::ExcludeUserInput);
00455 }
00456
00457 if (!disable_cursor_change_)
00458 QApplication::restoreOverrideCursor();
00459 }
00460
00461 if (out_list)
00462 *out_list = out_text_;
00463
00464 show_enable_ = true;
00465 int ret_code = proc->exitStatus();
00466 return ret_code;
00467 }
00468
00469 QString Svn::showCommand() {
00470 QStringList args = proc->arguments();
00471 QStringList::Iterator it = args.begin();
00472 QString out_str = "<font color=navy>";
00473 QString curr_str, prev_arg;
00474 int arg_num =0;
00475 while ( it != args.end() ) {
00476 if (arg_num && prev_arg == QString("--password") )
00477 curr_str = "******";
00478 else
00479 curr_str = (*it);
00480 if (arg_num++ == 1)
00481 out_str = out_str + curr_str + "</font> ";
00482 else
00483 out_str = out_str + curr_str + " ";
00484 ++it;
00485 prev_arg = curr_str;
00486 }
00487 out_win_->append(out_str);
00488 return out_str;
00489 }