1 /***************************************************************************
2  *   Copyright (C) 2005-2009 by Rajko Albrecht                             *
3  *   ral@alwins-world.de                                                   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
19  ***************************************************************************/
20 #include "commandexec.h"
21 #include "settings/kdesvnsettings.h"
22 #include "svnfrontend/svnactions.h"
23 #include "svnfrontend/dummydisplay.h"
24 #include "svnqt/targets.h"
25 #include "svnqt/url.h"
26 #include "svnqt/dirent.h"
27 #include "helpers/ktranslateurl.h"
28 #include "helpers/sshagent.h"
29 #include "helpers/windowgeometryhelper.h"
30 #include "svnfrontend/fronthelpers/rangeinput_impl.h"
31 #include "svnfrontend/copymoveview_impl.h"
32 #include "ksvnwidgets/ksvndialog.h"
33 
34 #include <KMessageBox>
35 
36 #include <QCommandLineParser>
37 #include <QDir>
38 #include <QTextBrowser>
39 #include <QTextStream>
40 #include <QUrlQuery>
41 
42 class pCPart
43 {
44 public:
45     pCPart();
46     ~pCPart();
47 
48     QString cmd;
49     QStringList urls;
50     bool ask_revision;
51     bool rev_set;
52     bool outfile_set;
53     bool single_revision;
54     bool force;
55     int log_limit;
56     SvnActions *m_SvnWrapper;
57     QCommandLineParser *parser;
58     QStringList args;
59     svn::Revision start, end;
60 
61     // for output
62     QString outfile;
63     QTextStream Stdout, Stderr;
64     DummyDisplay *disp;
65     QMap<int, svn::Revision> extraRevisions;
66     QMap<int, QUrl> repoUrls;
67 };
68 
pCPart()69 pCPart::pCPart()
70     : cmd()
71     , urls()
72     , ask_revision(false)
73     , rev_set(false)
74     , outfile_set(false)
75     , single_revision(false)
76     , force(false)
77     , log_limit(0)
78     , m_SvnWrapper(nullptr)
79     , parser(nullptr)
80     , start(svn::Revision::UNDEFINED)
81     , end(svn::Revision::UNDEFINED)
82     , Stdout(stdout)
83     , Stderr(stderr)
84     , disp(new DummyDisplay())
85 {
86     m_SvnWrapper = new SvnActions(disp, true);
87 }
88 
~pCPart()89 pCPart::~pCPart()
90 {
91     delete m_SvnWrapper;
92     delete disp;
93 }
94 
CommandExec(QObject * parent)95 CommandExec::CommandExec(QObject *parent)
96     : QObject(parent)
97     , m_lastMessagesLines(0)
98 {
99     m_pCPart = new pCPart;
100     m_pCPart->parser = nullptr;
101     SshAgent ag;
102     ag.querySshAgent();
103 
104     connect(m_pCPart->m_SvnWrapper, &SvnActions::clientException, this, &CommandExec::clientException);
105     connect(m_pCPart->m_SvnWrapper, &SvnActions::sendNotify, this, &CommandExec::slotNotifyMessage);
106     m_pCPart->m_SvnWrapper->reInitClient();
107 }
108 
109 
~CommandExec()110 CommandExec::~CommandExec()
111 {
112     delete m_pCPart;
113 }
114 
exec(const QCommandLineParser * parser)115 int CommandExec::exec(const QCommandLineParser *parser)
116 {
117     m_pCPart->parser = const_cast<QCommandLineParser*>(parser);
118     m_pCPart->args = parser->positionalArguments();
119     if (m_pCPart->args.isEmpty()) {
120         return -1;
121     }
122     m_lastMessages.clear();
123     m_lastMessagesLines = 0;
124     m_pCPart->m_SvnWrapper->reInitClient();
125     bool dont_check_second = false;
126     bool dont_check_all = false;
127     bool path_only = false;
128     bool no_revision = false;
129     bool check_force = false;
130 
131     if (m_pCPart->args.count() >= 2) {
132         m_pCPart->cmd = m_pCPart->args.at(1);
133         m_pCPart->cmd = m_pCPart->cmd.toLower();
134     }
135     QByteArray slotCmd;
136     if (!QString::compare(m_pCPart->cmd, QLatin1String("log"))) {
137         slotCmd = SLOT(slotCmd_log());
138     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("cat"))) {
139         slotCmd = SLOT(slotCmd_cat());
140         m_pCPart->single_revision = true;
141     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("get"))) {
142         slotCmd = SLOT(slotCmd_get());
143         m_pCPart->single_revision = true;
144     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("help"))) {
145         slotCmd = SLOT(slotCmd_help());
146     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("blame")) ||
147                !QString::compare(m_pCPart->cmd, QLatin1String("annotate"))) {
148         slotCmd = SLOT(slotCmd_blame());
149     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("update"))) {
150         slotCmd = SLOT(slotCmd_update());
151         m_pCPart->single_revision = true;
152     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("diff"))) {
153         m_pCPart->start = svn::Revision::WORKING;
154         slotCmd = SLOT(slotCmd_diff());
155     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("info"))) {
156         slotCmd = SLOT(slotCmd_info());
157         m_pCPart->single_revision = true;
158     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("commit")) ||
159                !QString::compare(m_pCPart->cmd, QLatin1String("ci"))) {
160         slotCmd = SLOT(slotCmd_commit());
161     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("list")) ||
162                !QString::compare(m_pCPart->cmd, QLatin1String("ls"))) {
163         slotCmd = SLOT(slotCmd_list());
164     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("copy")) ||
165                !QString::compare(m_pCPart->cmd, QLatin1String("cp"))) {
166         slotCmd = SLOT(slotCmd_copy());
167         dont_check_second = true;
168     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("move")) ||
169                !QString::compare(m_pCPart->cmd, QLatin1String("rename")) ||
170                !QString::compare(m_pCPart->cmd, QLatin1String("mv"))) {
171         slotCmd = SLOT(slotCmd_move());
172         dont_check_second = true;
173     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("checkout")) ||
174                !QString::compare(m_pCPart->cmd, QLatin1String("co"))) {
175         slotCmd = SLOT(slotCmd_checkout());
176         dont_check_second = true;
177     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("checkoutto")) ||
178                !QString::compare(m_pCPart->cmd, QLatin1String("coto"))) {
179         slotCmd = SLOT(slotCmd_checkoutto());
180         dont_check_second = true;
181     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("export"))) {
182         slotCmd = SLOT(slotCmd_export());
183         dont_check_second = true;
184     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("exportto"))) {
185         slotCmd = SLOT(slotCmd_exportto());
186         dont_check_second = true;
187     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("delete")) ||
188                !QString::compare(m_pCPart->cmd, QLatin1String("del")) ||
189                !QString::compare(m_pCPart->cmd, QLatin1String("rm")) ||
190                !QString::compare(m_pCPart->cmd, QLatin1String("remove"))) {
191         slotCmd = SLOT(slotCmd_delete());
192     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("add"))) {
193         slotCmd = SLOT(slotCmd_add());
194         dont_check_all = true;
195         path_only = true;
196     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("undo")) ||
197                !QString::compare(m_pCPart->cmd, QLatin1String("revert"))) {
198         slotCmd = SLOT(slotCmd_revert());
199     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("checknew")) ||
200                !QString::compare(m_pCPart->cmd, QLatin1String("addnew"))) {
201         slotCmd = SLOT(slotCmd_addnew());
202     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("switch"))) {
203         slotCmd = SLOT(slotCmd_switch());
204     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("tree"))) {
205         slotCmd = SLOT(slotCmd_tree());
206     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("lock"))) {
207         slotCmd = SLOT(slotCmd_lock());
208         no_revision = true;
209         check_force = true;
210     } else if (!QString::compare(m_pCPart->cmd, QLatin1String("unlock"))) {
211         slotCmd = SLOT(slotCmd_unlock());
212         no_revision = true;
213         check_force = true;
214     }
215 
216     bool found = connect(this, SIGNAL(executeMe()), this, slotCmd.constData());
217     if (!found) {
218         KMessageBox::sorry(nullptr,
219                            i18n("Command \"%1\" not implemented or known", m_pCPart->cmd),
220                            i18n("SVN Error"));
221         return -1;
222     }
223 
224     QString tmp;
225     QString mainProto;
226     for (int j = 2; j < m_pCPart->args.count(); ++j) {
227         QUrl tmpurl = QUrl::fromUserInput(m_pCPart->args.at(j),
228                                           QDir::currentPath());
229         tmpurl.setScheme(svn::Url::transformProtokoll(tmpurl.scheme()));
230         if (tmpurl.scheme().contains(QLatin1String("ssh"))) {
231             SshAgent ag;
232             // this class itself checks if done before
233             ag.addSshIdentities();
234         }
235         m_pCPart->extraRevisions[j - 2] = svn::Revision::HEAD;
236 
237         if (tmpurl.isLocalFile() && (j == 2 || !dont_check_second) && !dont_check_all) {
238             QUrl repoUrl;
239             if (m_pCPart->m_SvnWrapper->isLocalWorkingCopy(tmpurl.path(), repoUrl)) {
240                 tmp = tmpurl.path();
241                 m_pCPart->repoUrls[j - 2] = repoUrl;
242                 m_pCPart->extraRevisions[j - 2] = svn::Revision::WORKING;
243                 if (j == 2) {
244                     mainProto.clear();
245                 }
246             } else {
247                 tmp = tmpurl.url();
248                 if (j == 2) {
249                     mainProto = QLatin1String("file://");
250                 }
251             }
252         } else if (path_only) {
253             tmp = tmpurl.path();
254         } else {
255             tmp = tmpurl.url();
256             if (j == 2) {
257                 mainProto = tmpurl.scheme();
258             }
259         }
260         if ((j > 2 && dont_check_second) || dont_check_all) {
261             if (mainProto.isEmpty()) {
262                 tmp = tmpurl.path();
263             }
264         }
265         const QVector<QStringRef> l = tmp.splitRef(QLatin1Char('?'), QString::SkipEmptyParts);
266         if (!l.isEmpty()) {
267             tmp = l.first().toString();
268         }
269         while (tmp.endsWith(QLatin1Char('/'))) {
270             tmp.chop(1);
271         }
272         m_pCPart->urls.append(tmp);
273         if ((j > 2 && dont_check_second) || dont_check_all) {
274             continue;
275         }
276         const QList<QPair<QString, QString> > q = QUrlQuery(tmpurl).queryItems();
277         for (const auto &item : q) {
278             if (item.first == QLatin1String("rev")) {
279                 svn::Revision re = item.second;
280                 if (re) {
281                     m_pCPart->extraRevisions[j - 2] = re;
282                 }
283             }
284         }
285     }
286     if (m_pCPart->urls.isEmpty()) {
287         m_pCPart->urls.append(QLatin1String("."));
288     }
289 
290     if (!no_revision) {
291         if (m_pCPart->parser->isSet("R")) {
292             m_pCPart->ask_revision = true;
293             if (!askRevision()) {
294                 return 0;
295             }
296         } else if (m_pCPart->parser->isSet("r")) {
297             scanRevision();
298         }
299     }
300 
301     m_pCPart->force = check_force && m_pCPart->parser->isSet("f");
302 
303     if (m_pCPart->parser->isSet("o")) {
304         m_pCPart->outfile_set = true;
305         m_pCPart->outfile = m_pCPart->parser->value("o");
306     }
307     if (m_pCPart->parser->isSet("l")) {
308         QString s = m_pCPart->parser->value("l");
309         m_pCPart->log_limit = s.toInt();
310         if (m_pCPart->log_limit < 0) {
311             m_pCPart->log_limit = 0;
312         }
313     }
314 
315     emit executeMe();
316     if (Kdesvnsettings::self()->cmdline_show_logwindow() &&
317             m_lastMessagesLines >= Kdesvnsettings::self()->cmdline_log_minline()) {
318         QPointer<KSvnSimpleOkDialog> dlg(new KSvnSimpleOkDialog(QStringLiteral("kdesvn_cmd_log"), QApplication::activeModalWidget()));
319         QTextBrowser *ptr = new QTextBrowser(dlg);
320         ptr->setText(m_lastMessages);
321         ptr->setReadOnly(true);
322         dlg->addWidget(ptr);
323         QString cmd = qApp->arguments().join(QLatin1Char(' '));
324         dlg->setWindowTitle(cmd);
325         dlg->exec();
326         delete dlg;
327     }
328     return 0;
329 }
330 
331 
332 
333 /*!
334     \fn CommandExec::clientException(const QString&)
335  */
clientException(const QString & what)336 void CommandExec::clientException(const QString &what)
337 {
338     m_pCPart->Stderr << what << endl;
339     KMessageBox::sorry(nullptr, what, i18n("SVN Error"));
340 }
341 
342 
slotCmd_log()343 void CommandExec::slotCmd_log()
344 {
345     int limit = m_pCPart->log_limit;
346     if (m_pCPart->end == svn::Revision::UNDEFINED) {
347         m_pCPart->end = svn::Revision::HEAD;
348     }
349     if (m_pCPart->start == svn::Revision::UNDEFINED) {
350         m_pCPart->start = 1;
351     }
352     bool list = Kdesvnsettings::self()->log_always_list_changed_files();
353     if (m_pCPart->extraRevisions[0] == svn::Revision::WORKING) {
354         m_pCPart->extraRevisions[0] = svn::Revision::UNDEFINED;
355     }
356     m_pCPart->m_SvnWrapper->makeLog(m_pCPart->start, m_pCPart->end,
357                                     m_pCPart->extraRevisions.value(0),
358                                     m_pCPart->urls.at(0),
359                                     Kdesvnsettings::log_follows_nodes(),
360                                     list,
361                                     limit);
362 }
363 
slotCmd_tree()364 void CommandExec::slotCmd_tree()
365 {
366     if (m_pCPart->end == svn::Revision::UNDEFINED) {
367         m_pCPart->end = svn::Revision::HEAD;
368     }
369     if (m_pCPart->start == svn::Revision::UNDEFINED) {
370         m_pCPart->start = 1;
371     }
372     m_pCPart->m_SvnWrapper->makeTree(m_pCPart->urls.at(0), m_pCPart->extraRevisions.value(0),
373                                      m_pCPart->start, m_pCPart->end);
374 }
375 
slotCmd_checkout()376 void CommandExec::slotCmd_checkout()
377 {
378     m_pCPart->m_SvnWrapper->CheckoutExport(QUrl::fromUserInput(m_pCPart->urls.at(0),
379                                                                QDir::currentPath()), false);
380 }
381 
slotCmd_checkoutto()382 void CommandExec::slotCmd_checkoutto()
383 {
384     m_pCPart->m_SvnWrapper->CheckoutExport(QUrl::fromUserInput(m_pCPart->urls.at(0),
385                                                                QDir::currentPath()), false, true);
386 }
387 
slotCmd_export()388 void CommandExec::slotCmd_export()
389 {
390     m_pCPart->m_SvnWrapper->CheckoutExport(QUrl::fromUserInput(m_pCPart->urls.at(0),
391                                                                QDir::currentPath()), true);
392 }
393 
slotCmd_exportto()394 void CommandExec::slotCmd_exportto()
395 {
396     m_pCPart->m_SvnWrapper->CheckoutExport(QUrl::fromUserInput(m_pCPart->urls.at(0),
397                                                                QDir::currentPath()), true, true);
398 }
399 
slotCmd_blame()400 void CommandExec::slotCmd_blame()
401 {
402     if (!m_pCPart->end) {
403         m_pCPart->end = svn::Revision::HEAD;
404     }
405     if (!m_pCPart->start) {
406         m_pCPart->start = 1;
407     }
408     m_pCPart->m_SvnWrapper->makeBlame(m_pCPart->start, m_pCPart->end, m_pCPart->urls.at(0));
409 }
410 
slotCmd_cat()411 void CommandExec::slotCmd_cat()
412 {
413     QMap<int, svn::Revision>::const_iterator cIt = m_pCPart->extraRevisions.constFind(0);
414     if (cIt != m_pCPart->extraRevisions.constEnd()) {
415         m_pCPart->rev_set = true;
416         m_pCPart->start = cIt.value();
417     } else {
418         m_pCPart->end = svn::Revision::HEAD;
419     }
420     m_pCPart->m_SvnWrapper->slotMakeCat(
421         (m_pCPart->rev_set ? m_pCPart->start : m_pCPart->end), m_pCPart->urls.at(0), m_pCPart->urls.at(0)
422         , (m_pCPart->rev_set ? m_pCPart->start : m_pCPart->end), nullptr);
423 }
424 
slotCmd_get()425 void CommandExec::slotCmd_get()
426 {
427     if (m_pCPart->extraRevisions.find(0) != m_pCPart->extraRevisions.end()) {
428         m_pCPart->rev_set = true;
429         m_pCPart->start = m_pCPart->extraRevisions[0];
430     } else {
431         m_pCPart->end = svn::Revision::HEAD;
432     }
433     if (!m_pCPart->outfile_set || m_pCPart->outfile.isEmpty()) {
434         clientException(i18n("\"GET\" requires output file"));
435         return;
436     }
437     m_pCPart->m_SvnWrapper->makeGet((m_pCPart->rev_set ? m_pCPart->start : m_pCPart->end), m_pCPart->urls.at(0), m_pCPart->outfile,
438                                     (m_pCPart->rev_set ? m_pCPart->start : m_pCPart->end));
439 }
440 
slotCmd_update()441 void CommandExec::slotCmd_update()
442 {
443     const svn::Targets targets = svn::Targets::fromStringList(m_pCPart->urls);
444     m_pCPart->m_SvnWrapper->makeUpdate(targets,
445                                        (m_pCPart->rev_set ? m_pCPart->start : svn::Revision::HEAD), svn::DepthUnknown);
446 }
447 
slotCmd_diff()448 void CommandExec::slotCmd_diff()
449 {
450     if (m_pCPart->urls.count() == 1) {
451         if (!m_pCPart->rev_set && !svn::Url::isValid(m_pCPart->urls.at(0))) {
452             m_pCPart->start = svn::Revision::BASE;
453             m_pCPart->end = svn::Revision::WORKING;
454         }
455         m_pCPart->m_SvnWrapper->makeDiff(m_pCPart->urls.at(0), m_pCPart->start, m_pCPart->urls.at(0), m_pCPart->end);
456     } else {
457         svn::Revision r1 = svn::Revision::HEAD;
458         svn::Revision r2 = svn::Revision::HEAD;
459         QMap<int, svn::Revision>::const_iterator cIt = m_pCPart->extraRevisions.constFind(0);
460         if (cIt != m_pCPart->extraRevisions.constEnd()) {
461             r1 = cIt.value();
462         } else if (!svn::Url::isValid(m_pCPart->urls.at(0))) {
463             r1 = svn::Revision::WORKING;
464         }
465         if (m_pCPart->extraRevisions.find(1) != m_pCPart->extraRevisions.end()) {
466             r2 = m_pCPart->extraRevisions[1];
467         } else if (!svn::Url::isValid(m_pCPart->urls.at(1))) {
468             r2 = svn::Revision::WORKING;
469         }
470         m_pCPart->m_SvnWrapper->makeDiff(m_pCPart->urls.at(0), r1, m_pCPart->urls.at(1), r2);
471     }
472 }
473 
slotCmd_info()474 void CommandExec::slotCmd_info()
475 {
476     QMap<int, svn::Revision>::const_iterator cIt = m_pCPart->extraRevisions.constFind(0);
477     if (cIt != m_pCPart->extraRevisions.constEnd()) {
478         m_pCPart->rev_set = true;
479         m_pCPart->start = cIt.value();
480     }
481     m_pCPart->m_SvnWrapper->makeInfo(m_pCPart->urls, (m_pCPart->rev_set ? m_pCPart->start : m_pCPart->end),
482                                      svn::Revision::UNDEFINED, false);
483 }
484 
slotCmd_commit()485 void CommandExec::slotCmd_commit()
486 {
487     const svn::Targets targets(svn::Targets::fromStringList(m_pCPart->urls));
488     m_pCPart->m_SvnWrapper->makeCommit(targets);
489 }
490 
slotCmd_list()491 void CommandExec::slotCmd_list()
492 {
493     svn::DirEntries res;
494     svn::Revision rev = m_pCPart->end;
495     if (m_pCPart->rev_set) {
496         rev = m_pCPart->start;
497     } else if (m_pCPart->extraRevisions[0]) {
498         rev = m_pCPart->extraRevisions[0];
499     }
500     if (!m_pCPart->m_SvnWrapper->makeList(m_pCPart->urls.at(0), res, rev, svn::DepthInfinity)) {
501         return;
502     }
503     for (const svn::DirEntry &entry : qAsConst(res)) {
504         QString d = entry.time().toString(QStringLiteral("yyyy-MM-dd hh:mm::ss"));
505         m_pCPart->Stdout
506                 << (entry.kind() == svn_node_dir ? "D" : "F") << " "
507                 << d << " "
508                 << entry.name() << endl;
509     }
510 }
511 
slotCmd_copy()512 void CommandExec::slotCmd_copy()
513 {
514     QString target;
515     if (m_pCPart->urls.count() < 2) {
516         bool ok;
517         target = CopyMoveView_impl::getMoveCopyTo(&ok, false,
518                                                   m_pCPart->urls.at(0), QString(), nullptr);
519         if (!ok) {
520             return;
521         }
522     } else {
523         target = m_pCPart->urls.at(1);
524     }
525     QMap<int, svn::Revision>::const_iterator cIt = m_pCPart->extraRevisions.constFind(0);
526     if (cIt != m_pCPart->extraRevisions.constEnd()) {
527         m_pCPart->rev_set = true;
528         m_pCPart->start = cIt.value();
529     } else {
530         m_pCPart->end = svn::Revision::HEAD;
531     }
532     m_pCPart->m_SvnWrapper->makeCopy(m_pCPart->urls.at(0), target, (m_pCPart->rev_set ? m_pCPart->start : m_pCPart->end));
533 }
534 
slotCmd_move()535 void CommandExec::slotCmd_move()
536 {
537     bool ok;
538     QString target;
539     if (m_pCPart->urls.count() < 2) {
540         target = CopyMoveView_impl::getMoveCopyTo(&ok, true,
541                                                   m_pCPart->urls.at(0), QString(), nullptr);
542         if (!ok) {
543             return;
544         }
545     } else {
546         target = m_pCPart->urls.at(1);
547     }
548     m_pCPart->m_SvnWrapper->makeMove(m_pCPart->urls.at(0), target);
549 }
550 
slotCmd_delete()551 void CommandExec::slotCmd_delete()
552 {
553     m_pCPart->m_SvnWrapper->makeDelete(m_pCPart->urls);
554 }
555 
slotCmd_add()556 void CommandExec::slotCmd_add()
557 {
558     m_pCPart->m_SvnWrapper->addItems(svn::Targets::fromStringList(m_pCPart->urls), svn::DepthInfinity);
559 }
560 
slotCmd_revert()561 void CommandExec::slotCmd_revert()
562 {
563     m_pCPart->m_SvnWrapper->slotRevertItems(m_pCPart->urls);
564 }
565 
slotCmd_addnew()566 void CommandExec::slotCmd_addnew()
567 {
568     m_pCPart->m_SvnWrapper->checkAddItems(m_pCPart->urls.at(0));
569 }
570 
571 /*!
572     \fn CommandExec::scanRevision()
573  */
scanRevision()574 bool CommandExec::scanRevision()
575 {
576     const QString revstring = m_pCPart->parser->value(QStringLiteral("r"));
577     const QVector<QStringRef> revl = revstring.splitRef(QLatin1Char(':'), QString::SkipEmptyParts);
578     if (revl.isEmpty()) {
579         return false;
580     }
581     m_pCPart->start = revl[0].toString();
582     if (revl.count() > 1) {
583         m_pCPart->end = revl[1].toString();
584     }
585     m_pCPart->rev_set = true;
586     return true;
587 }
588 
slotNotifyMessage(const QString & msg)589 void CommandExec::slotNotifyMessage(const QString &msg)
590 {
591     m_pCPart->m_SvnWrapper->slotExtraLogMsg(msg);
592     if (Kdesvnsettings::self()->cmdline_show_logwindow()) {
593         ++m_lastMessagesLines;
594         if (!m_lastMessages.isEmpty()) {
595             m_lastMessages.append("\n");
596         }
597         m_lastMessages.append(msg);
598     }
599 }
600 
askRevision()601 bool CommandExec::askRevision()
602 {
603     bool ret = false;
604     Rangeinput_impl::revision_range range;
605     if (Rangeinput_impl::getRevisionRange(range, true, m_pCPart->single_revision)) {
606         m_pCPart->start = range.first;
607         m_pCPart->end = range.second;
608         m_pCPart->rev_set = true;
609         ret = true;
610     }
611     return ret;
612 }
613 
614 
615 /*!
616     \fn CommandExec::slotCmd_switch()
617  */
slotCmd_switch()618 void CommandExec::slotCmd_switch()
619 {
620     if (m_pCPart->urls.count() > 1) {
621         clientException(i18n("May only switch one URL at time"));
622         return;
623     }
624     if (m_pCPart->repoUrls.find(0) == m_pCPart->repoUrls.end()) {
625         clientException(i18n("Switch only on working copies"));
626         return;
627     }
628     m_pCPart->m_SvnWrapper->makeSwitch(m_pCPart->urls.at(0),
629                                        m_pCPart->repoUrls.value(0));
630 }
631 
slotCmd_lock()632 void CommandExec::slotCmd_lock()
633 {
634 //     m_pCPart->m_SvnWrapper->makeLock(m_pCPart->urls.at(0),"",m_pCPart->force);
635     m_pCPart->m_SvnWrapper->makeLock(m_pCPart->urls, QString(), m_pCPart->force);
636 }
637 
slotCmd_unlock()638 void CommandExec::slotCmd_unlock()
639 {
640 //     m_pCPart->m_SvnWrapper->makeUnlock(m_pCPart->urls.at(0),m_pCPart->force);
641     m_pCPart->m_SvnWrapper->makeUnlock(m_pCPart->urls, m_pCPart->force);
642 }
643