/*************************************************************************** * Copyright (C) 2005-2007 by Rajko Albrecht * * ral@alwins-world.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "commandexec.h" #include "src/settings/tdesvnsettings.h" #include "svnfrontend/svnactions.h" #include "svnfrontend/dummydisplay.h" #include "src/svnqt/targets.hpp" #include "src/svnqt/url.hpp" #include "src/svnqt/dirent.hpp" #include "src/helpers/sub2qt.h" #include "src/helpers/ktranslateurl.h" #include "src/helpers/sshagent.h" #include "src/svnfrontend/fronthelpers/rangeinput_impl.h" #include "src/svnfrontend/copymoveview_impl.h" #include #include #include #include #include #include #include #include #include #include #include #include class pCPart { public: pCPart(); ~pCPart(); TQString cmd; TQStringList url; bool ask_revision; bool rev_set; bool outfile_set; bool single_revision; bool force; int log_limit; SvnActions*m_SvnWrapper; KCmdLineArgs *args; svn::Revision start,end; // for output TQFile toStdout,toStderr; TQString outfile; TQTextStream Stdout,Stderr; DummyDisplay * disp; TQMap extraRevisions; TQMap baseUrls; }; pCPart::pCPart() :cmd(""),url(),ask_revision(false),rev_set(false),outfile_set(false),single_revision(false),log_limit(0) { m_SvnWrapper = 0; start = svn::Revision::UNDEFINED; end = svn::Revision::UNDEFINED; toStdout.open(IO_WriteOnly, stdout); toStderr.open(IO_WriteOnly, stderr); Stdout.setDevice(TQT_TQIODEVICE(&toStdout)); Stderr.setDevice(TQT_TQIODEVICE(&toStderr)); disp = new DummyDisplay(); m_SvnWrapper = new SvnActions(disp,0,true); } pCPart::~pCPart() { delete m_SvnWrapper; delete disp; } CommandExec::CommandExec(TQObject*parent, const char *name,KCmdLineArgs *args) : TQObject(parent,name) { m_pCPart = new pCPart; m_pCPart->args = args; SshAgent ag; ag.querySshAgent(); connect(m_pCPart->m_SvnWrapper,TQT_SIGNAL(clientException(const TQString&)),this,TQT_SLOT(clientException(const TQString&))); connect(m_pCPart->m_SvnWrapper,TQT_SIGNAL(sendNotify(const TQString&)),this,TQT_SLOT(slotNotifyMessage(const TQString&))); m_pCPart->m_SvnWrapper->reInitClient(); } CommandExec::~CommandExec() { delete m_pCPart; } int CommandExec::exec() { if (!m_pCPart->args) { return -1; } m_lastMessages = ""; m_lastMessagesLines = 0; m_pCPart->m_SvnWrapper->reInitClient(); bool dont_check_second = false; bool dont_check_all = false; bool path_only = false; bool no_revision = false; bool check_force=false; if (m_pCPart->args->count()>=2) { m_pCPart->cmd=m_pCPart->args->arg(1); m_pCPart->cmd=m_pCPart->cmd.lower(); } TQString slotCmd; if (!TQString::compare(m_pCPart->cmd,"log")) { slotCmd=TQT_SLOT(slotCmd_log()); } else if (!TQString::compare(m_pCPart->cmd,"cat")) { slotCmd=TQT_SLOT(slotCmd_cat()); m_pCPart->single_revision=true; } else if (!TQString::compare(m_pCPart->cmd,"get")) { slotCmd=TQT_SLOT(slotCmd_get()); m_pCPart->single_revision=true; } else if (!TQString::compare(m_pCPart->cmd,"help")) { slotCmd=TQT_SLOT(slotCmd_help()); } else if (!TQString::compare(m_pCPart->cmd,"blame")|| !TQString::compare(m_pCPart->cmd,"annotate")) { slotCmd=TQT_SLOT(slotCmd_blame()); } else if (!TQString::compare(m_pCPart->cmd,"update")) { slotCmd=TQT_SLOT(slotCmd_update()); m_pCPart->single_revision=true; } else if (!TQString::compare(m_pCPart->cmd,"diff")) { m_pCPart->start = svn::Revision::WORKING; slotCmd=TQT_SLOT(slotCmd_diff()); } else if (!TQString::compare(m_pCPart->cmd,"info")) { slotCmd=TQT_SLOT(slotCmd_info()); m_pCPart->single_revision=true; } else if (!TQString::compare(m_pCPart->cmd,"commit")|| !TQString::compare(m_pCPart->cmd,"ci")) { slotCmd=TQT_SLOT(slotCmd_commit()); } else if (!TQString::compare(m_pCPart->cmd,"list")|| !TQString::compare(m_pCPart->cmd,"ls")) { slotCmd=TQT_SLOT(slotCmd_list()); } else if (!TQString::compare(m_pCPart->cmd,"copy")|| !TQString::compare(m_pCPart->cmd,"cp")) { slotCmd=TQT_SLOT(slotCmd_copy()); dont_check_second = true; } else if (!TQString::compare(m_pCPart->cmd,"move")|| !TQString::compare(m_pCPart->cmd,"rename")|| !TQString::compare(m_pCPart->cmd,"mv")) { slotCmd=TQT_SLOT(slotCmd_move()); dont_check_second = true; } else if (!TQString::compare(m_pCPart->cmd,"checkout")|| !TQString::compare(m_pCPart->cmd,"co")) { slotCmd=TQT_SLOT(slotCmd_checkout()); dont_check_second = true; } else if (!TQString::compare(m_pCPart->cmd,"checkoutto")|| !TQString::compare(m_pCPart->cmd,"coto")) { slotCmd=TQT_SLOT(slotCmd_checkoutto()); dont_check_second = true; } else if (!TQString::compare(m_pCPart->cmd,"export")) { slotCmd=TQT_SLOT(slotCmd_export()); dont_check_second = true; } else if (!TQString::compare(m_pCPart->cmd,"exportto")) { slotCmd=TQT_SLOT(slotCmd_exportto()); dont_check_second = true; } else if (!TQString::compare(m_pCPart->cmd,"delete")|| !TQString::compare(m_pCPart->cmd,"del")|| !TQString::compare(m_pCPart->cmd,"rm")|| !TQString::compare(m_pCPart->cmd,"remove")) { slotCmd=TQT_SLOT(slotCmd_delete()); } else if (!TQString::compare(m_pCPart->cmd,"add")) { slotCmd=TQT_SLOT(slotCmd_add()); dont_check_all = true; path_only=true; } else if (!TQString::compare(m_pCPart->cmd,"undo")|| !TQString::compare(m_pCPart->cmd,"revert")) { slotCmd=TQT_SLOT(slotCmd_revert()); } else if (!TQString::compare(m_pCPart->cmd,"checknew")|| !TQString::compare(m_pCPart->cmd,"addnew")) { slotCmd=TQT_SLOT(slotCmd_addnew()); } else if (!TQString::compare(m_pCPart->cmd,"switch")) { slotCmd=TQT_SLOT(slotCmd_switch()); } else if (!TQString::compare(m_pCPart->cmd,"tree")) { slotCmd=TQT_SLOT(slotCmd_tree()); } else if (!TQString::compare(m_pCPart->cmd,"lock")) { slotCmd=TQT_SLOT(slotCmd_lock()); no_revision = true; check_force=true; } else if (!TQString::compare(m_pCPart->cmd,"unlock")) { slotCmd=TQT_SLOT(slotCmd_unlock()); no_revision=true; check_force=true; } bool found = connect(this,TQT_SIGNAL(executeMe()),this,slotCmd.ascii()); if (!found) { slotCmd=i18n("Command \"%1\" not implemented or known").tqarg(m_pCPart->cmd); KMessageBox::sorry(0,slotCmd,i18n("SVN Error")); return -1; } TQString tmp,query,proto,v; TQMap q; KURL tmpurl; TQString mainProto; TQString _baseurl; for (int j = 2; jargs->count();++j) { tmpurl = helpers::KTranslateUrl::translateSystemUrl(m_pCPart->args->url(j).prettyURL()); query = tmpurl.query(); q = m_pCPart->args->url(j).queryItems(); if (q.find("rev")!=q.end()) { v = q["rev"]; } else { v = ""; } tmpurl.setProtocol(svn::Url::transformProtokoll(tmpurl.protocol())); if (tmpurl.protocol().find("ssh")!=-1) { SshAgent ag; // this class itself checks if done before ag.addSshIdentities(); } m_pCPart->extraRevisions[j-2]=svn::Revision::HEAD; if (tmpurl.isLocalFile() && (j==2 || !dont_check_second) && !dont_check_all) { if (m_pCPart->m_SvnWrapper->isLocalWorkingCopy("file://"+tmpurl.path(),_baseurl)) { tmp = tmpurl.path(); m_pCPart->baseUrls[j-2]=_baseurl; m_pCPart->extraRevisions[j-2]=svn::Revision::WORKING; if (j==2) mainProto = ""; } else { tmp = "file://"+tmpurl.path(); if (j==2) mainProto = "file://"; } } else if (path_only){ tmp = tmpurl.path(); } else { tmp = tmpurl.url(); if (j==2) mainProto=tmpurl.protocol(); } if ( (j>2 && dont_check_second) || dont_check_all) { if (mainProto.isEmpty()) { tmp = tmpurl.path(); } } TQStringList l = TQStringList::split('?',tmp); if (l.count()>0) { tmp=l[0]; } while (tmp.endsWith("/")) { tmp.truncate(tmp.length()-1); } m_pCPart->url.append(tmp); if ( (j>2 && dont_check_second) || dont_check_all) { continue; } svn::Revision re = v; if (re) { m_pCPart->extraRevisions[j-2]=re; } } if (m_pCPart->url.count()==0) { m_pCPart->url.append("."); } if (!no_revision) { if (m_pCPart->args->isSet("R")) { m_pCPart->ask_revision = true; if (!askRevision()) { return 0; } } else if (m_pCPart->args->isSet("r")) { scanRevision(); } } m_pCPart->force=check_force && m_pCPart->args->isSet("f"); if (m_pCPart->args->isSet("o")) { m_pCPart->outfile_set=true; m_pCPart->outfile = m_pCPart->args->getOption("o"); } if (m_pCPart->args->isSet("l")) { TQString s = m_pCPart->args->getOption("l"); m_pCPart->log_limit = s.toInt(); if (m_pCPart->log_limit<0) { m_pCPart->log_limit = 0; } } emit executeMe(); if (Kdesvnsettings::self()->cmdline_show_logwindow() && m_lastMessagesLines >= Kdesvnsettings::self()->cmdline_log_minline()) { KDialogBase dlg ( TQT_TQWIDGET(KApplication::activeModalWidget()), "execution_log", true, i18n("Execution log"), KDialogBase::Ok); TQWidget* Dialog1Layout = dlg.makeVBoxMainWidget(); KTextBrowser*ptr = new KTextBrowser(Dialog1Layout); ptr->setText(m_lastMessages); dlg.resize(dlg.configDialogSize(*(Kdesvnsettings::self()->config()),"tdesvn_cmd_log")); dlg.exec(); dlg.saveDialogSize(*(Kdesvnsettings::self()->config()),"tdesvn_cmd_log",false); } return 0; } /*! \fn CommandExec::clientException(const TQString&) */ void CommandExec::clientException(const TQString&what) { m_pCPart->Stderr<log_limit; if (m_pCPart->end == svn::Revision::UNDEFINED) { m_pCPart->end = svn::Revision::HEAD; limit = 0; } if (m_pCPart->start == svn::Revision::UNDEFINED) { m_pCPart->start = 1; limit = 0; } bool list = Kdesvnsettings::self()->log_always_list_changed_files(); if (m_pCPart->extraRevisions[0]==svn::Revision::WORKING) { m_pCPart->extraRevisions[0]=svn::Revision::UNDEFINED; } m_pCPart->m_SvnWrapper->makeLog(m_pCPart->start,m_pCPart->end,m_pCPart->extraRevisions[0],m_pCPart->url[0],list,limit); } /*! \fn CommandExec::slotCmdLog */ void CommandExec::slotCmd_tree() { if (m_pCPart->end == svn::Revision::UNDEFINED) { m_pCPart->end = svn::Revision::HEAD; } if (m_pCPart->start == svn::Revision::UNDEFINED) { m_pCPart->start = 1; } m_pCPart->m_SvnWrapper->makeTree(m_pCPart->url[0],m_pCPart->extraRevisions[0],m_pCPart->start,m_pCPart->end); } void CommandExec::slotCmd_checkout() { m_pCPart->m_SvnWrapper->CheckoutExport(m_pCPart->url[0],false); } void CommandExec::slotCmd_checkoutto() { m_pCPart->m_SvnWrapper->CheckoutExport(m_pCPart->url[0],false,true); } void CommandExec::slotCmd_export() { m_pCPart->m_SvnWrapper->CheckoutExport(m_pCPart->url[0],true); } void CommandExec::slotCmd_exportto() { m_pCPart->m_SvnWrapper->CheckoutExport(m_pCPart->url[0],true,true); } void CommandExec::slotCmd_blame() { if (!m_pCPart->end) { m_pCPart->end = svn::Revision::HEAD; } if (!m_pCPart->start) { m_pCPart->start = 1; } m_pCPart->m_SvnWrapper->makeBlame(m_pCPart->start,m_pCPart->end,m_pCPart->url[0]); } void CommandExec::slotCmd_cat() { if (m_pCPart->extraRevisions.find(0)!=m_pCPart->extraRevisions.end()) { m_pCPart->rev_set=true; m_pCPart->start=m_pCPart->extraRevisions[0]; } else { m_pCPart->end = svn::Revision::HEAD; } m_pCPart->m_SvnWrapper->slotMakeCat( (m_pCPart->rev_set?m_pCPart->start:m_pCPart->end),m_pCPart->url[0],m_pCPart->url[0] ,(m_pCPart->rev_set?m_pCPart->start:m_pCPart->end),0); } void CommandExec::slotCmd_get() { if (m_pCPart->extraRevisions.find(0)!=m_pCPart->extraRevisions.end()) { m_pCPart->rev_set=true; m_pCPart->start=m_pCPart->extraRevisions[0]; } else { m_pCPart->end = svn::Revision::HEAD; } if (!m_pCPart->outfile_set || m_pCPart->outfile.isEmpty()) { clientException(i18n("\"GET\" requires output file!")); return; } m_pCPart->m_SvnWrapper->makeGet((m_pCPart->rev_set?m_pCPart->start:m_pCPart->end),m_pCPart->url[0], m_pCPart->outfile, (m_pCPart->rev_set?m_pCPart->start:m_pCPart->end)); } void CommandExec::slotCmd_update() { m_pCPart->m_SvnWrapper->makeUpdate(m_pCPart->url, (m_pCPart->rev_set?m_pCPart->start:svn::Revision::HEAD),true); } void CommandExec::slotCmd_diff() { if (m_pCPart->url.count()==1) { if (!m_pCPart->rev_set && !svn::Url::isValid(m_pCPart->url[0])) { m_pCPart->start = svn::Revision::BASE; m_pCPart->end = svn::Revision::WORKING; } m_pCPart->m_SvnWrapper->makeDiff(m_pCPart->url[0],m_pCPart->start,m_pCPart->url[0],m_pCPart->end); } else { svn::Revision r1 = svn::Revision::HEAD; svn::Revision r2 = svn::Revision::HEAD; if (m_pCPart->extraRevisions.find(0)!=m_pCPart->extraRevisions.end()) { r1 = m_pCPart->extraRevisions[0]; } else if (!svn::Url::isValid(m_pCPart->url[0])) { r1 = svn::Revision::WORKING; } if (m_pCPart->extraRevisions.find(1)!=m_pCPart->extraRevisions.end()) { r2 = m_pCPart->extraRevisions[1]; } else if (!svn::Url::isValid(m_pCPart->url[1])) { r2 = svn::Revision::WORKING; } m_pCPart->m_SvnWrapper->makeDiff(m_pCPart->url[0],r1,m_pCPart->url[1],r2); } } void CommandExec::slotCmd_info() { if (m_pCPart->extraRevisions.find(0)!=m_pCPart->extraRevisions.end()) { m_pCPart->rev_set=true; m_pCPart->start=m_pCPart->extraRevisions[0]; } m_pCPart->m_SvnWrapper->makeInfo(m_pCPart->url,(m_pCPart->rev_set?m_pCPart->start:m_pCPart->end),svn::Revision::UNDEFINED,false); } void CommandExec::slotCmd_commit() { TQValueList targets; for (unsigned j=0; jurl.count();++j) { targets.push_back(svn::Path(m_pCPart->url[j])); } m_pCPart->m_SvnWrapper->makeCommit(svn::Targets(targets)); } void CommandExec::slotCmd_list() { svn::DirEntries res; svn::Revision rev = m_pCPart->end; if (m_pCPart->rev_set){ rev = m_pCPart->start; } else if (m_pCPart->extraRevisions[0]) { rev = m_pCPart->extraRevisions[0]; } if (!m_pCPart->m_SvnWrapper->makeList(m_pCPart->url[0],res,rev,false)) { return; } for (unsigned int i = 0; i < res.count();++i) { TQString d = svn::DateTime(res[i]->time()).toString(TQString("yyyy-MM-dd hh:mm::ss")); m_pCPart->Stdout << (res[i]->kind()==svn_node_dir?"D":"F")<<" " << d << " " << res[i]->name()<url.count()<2) { bool force_move,ok; target = CopyMoveView_impl::getMoveCopyTo(&ok,&force_move,false, m_pCPart->url[0],"",0,"move_name"); if (!ok) { return; } } else { target = m_pCPart->url[1]; } if (m_pCPart->extraRevisions.find(0)!=m_pCPart->extraRevisions.end()) { m_pCPart->rev_set=true; m_pCPart->start=m_pCPart->extraRevisions[0]; } else { m_pCPart->end = svn::Revision::HEAD; } m_pCPart->m_SvnWrapper->makeCopy(m_pCPart->url[0],target,(m_pCPart->rev_set?m_pCPart->start:m_pCPart->end)); } void CommandExec::slotCmd_move() { bool force_move,ok; force_move = false; TQString target; if (m_pCPart->url.count()<2) { target = CopyMoveView_impl::getMoveCopyTo(&ok,&force_move,true, m_pCPart->url[0],"",0,"move_name"); if (!ok) { return; } } else { target = m_pCPart->url[1]; } m_pCPart->m_SvnWrapper->makeMove(m_pCPart->url[0],target,force_move); } void CommandExec::slotCmd_delete() { m_pCPart->m_SvnWrapper->makeDelete(m_pCPart->url); } void CommandExec::slotCmd_add() { m_pCPart->m_SvnWrapper->addItems(m_pCPart->url,svn::DepthInfinity); } void CommandExec::slotCmd_revert() { m_pCPart->m_SvnWrapper->slotRevertItems(m_pCPart->url); } void CommandExec::slotCmd_addnew() { m_pCPart->m_SvnWrapper->checkAddItems(m_pCPart->url[0]); } /*! \fn CommandExec::scanRevision() */ bool CommandExec::scanRevision() { TQString revstring = m_pCPart->args->getOption("r"); TQStringList revl = TQStringList::split(":",revstring); if (revl.count()==0) { return false; } m_pCPart->start = revl[0]; if (revl.count()>1) { m_pCPart->end = revl[1]; } m_pCPart->rev_set=true; return true; } void CommandExec::slotNotifyMessage(const TQString&msg) { m_pCPart->m_SvnWrapper->slotExtraLogMsg(msg); if (Kdesvnsettings::self()->cmdline_show_logwindow()) { ++m_lastMessagesLines; if (!m_lastMessages.isEmpty()) m_lastMessages.append("\n"); m_lastMessages.append(msg); } } bool CommandExec::askRevision() { TQString _head = m_pCPart->cmd+" - Revision"; KDialogBase dlg( 0, "Revisiondlg", true, _head, KDialogBase::Ok|KDialogBase::Cancel); TQWidget* Dialog1Layout = dlg.makeVBoxMainWidget(); Rangeinput_impl*rdlg; rdlg = new Rangeinput_impl(Dialog1Layout); dlg.resize( TQSize(120,60).expandedTo(dlg.tqminimumSizeHint())); rdlg->setStartOnly(m_pCPart->single_revision); if (dlg.exec()==TQDialog::Accepted) { Rangeinput_impl::revision_range range = rdlg->getRange(); m_pCPart->start = range.first; m_pCPart->end = range.second; m_pCPart->rev_set = true; return true; } return false; } /*! \fn CommandExec::slotCmd_switch() */ void CommandExec::slotCmd_switch() { TQString base; if (m_pCPart->url.count()>1) { clientException(i18n("May only switch one url at time!")); return; } if (m_pCPart->baseUrls.find(0)==m_pCPart->baseUrls.end()) { clientException(i18n("Switch only on working copies!")); return; } base = m_pCPart->baseUrls[0]; m_pCPart->m_SvnWrapper->makeSwitch(m_pCPart->url[0],base); } void CommandExec::slotCmd_lock() { m_pCPart->m_SvnWrapper->makeLock(m_pCPart->url[0],"",m_pCPart->force); } void CommandExec::slotCmd_unlock() { m_pCPart->m_SvnWrapper->makeUnlock(m_pCPart->url[0],m_pCPart->force); } #include "commandexec.moc"