Make test more complete
[vng.git] / Interview.cpp
blob6520fe598e3c51773fe245bc54378d303e568f87
1 /*
2 * This file is part of the vng project
3 * Copyright (C) 2008 Thomas Zander <tzander@trolltech.com>
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 3 of the License, or
8 * (at your option) any later version.
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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "Interview.h"
20 #include "InterviewCursor.h"
21 #include "Logger.h"
23 #include <QDebug>
24 #include <QTextStream>
26 #ifndef Q_OS_WIN
27 #include <termios.h>
28 #endif
30 Interview::Interview(InterviewCursor &cursor, const QString &command)
31 : m_cursor(cursor),
32 m_command(command),
33 m_usePager(true)
37 bool Interview::start()
39 if (! m_usePager)
40 Logger::stopPager();
41 const QString prompt = "Shall I "+ m_command +" this change?";
42 int currentIndex = 1;
43 if (m_cursor.count() == 0)
44 return true;
45 QTextStream out(stdout);
46 while(true) {
47 if (m_usePager)
48 Logger::startPager();
49 QTextStream &patchOut = Logger::standardOut();
50 patchOut << m_cursor.currentText();
51 patchOut.flush();
52 Logger::stopPager();
54 bool askAgain = false;
55 do {
56 int count = m_cursor.count();
57 QString allowed = m_cursor.allowedOptions();
58 QString question = prompt +" ("+ QString::number(currentIndex) +"/"+
59 (count == -1 ? "?" : QString::number(count)) +") ["+ allowed + "], or ? for help: ";
61 QChar reply = askSingleChar(question);
62 if (reply.unicode() != '?' && reply.unicode() != 'h' && allowed.indexOf(reply) < 0)
63 reply = 0x00DF; // to generate an 'invalid response' message.
64 askAgain = false;
65 switch (reply.toAscii()) {
66 case 'j': currentIndex = m_cursor.forward(InterviewCursor::ItemScope, false); break;
67 case 'k':
68 if (currentIndex == 1) // at start.
69 askAgain = true;
70 else
71 currentIndex = m_cursor.back();
72 break;
73 case 'y': m_cursor.setResponse(true);
74 currentIndex = m_cursor.forward(); break;
75 case 'n': m_cursor.setResponse(false);
76 currentIndex = m_cursor.forward(); break;
77 case 'f': m_cursor.setResponse(true, InterviewCursor::BlockScope);
78 currentIndex = m_cursor.forward(InterviewCursor::BlockScope); break;
79 case 's': m_cursor.setResponse(false, InterviewCursor::BlockScope);
80 currentIndex = m_cursor.forward(InterviewCursor::BlockScope); break;
81 case 'a': m_cursor.setResponse(true, InterviewCursor::FullRange);
82 return true;
83 case 'd': return true;
84 case 'q': return false;
85 case 'h': // fall through
86 case '?':
87 out << m_cursor.helpMessage();
88 out.flush();
89 askAgain = true;
90 break;
91 case 'c':
92 m_cursor.forceCount();
93 askAgain = true;
94 break;
95 default:
96 out << "Invalid response, try again please." << endl;
97 askAgain = true;
98 break;
100 } while(askAgain);
101 if (! m_cursor.isValid())
102 return true;
106 QChar Interview::askSingleChar(const QString &prompt, const QString &allowedCharacters)
108 QTextStream out(stdout);
109 QTextStream in(stdin);
110 #ifndef Q_OS_WIN
111 struct termios oldT, newT;
112 tcgetattr(0, &oldT);
113 newT = oldT;
114 newT.c_lflag &= ~ECHO; // echo off
115 newT.c_lflag &= ~ICANON; //one char at a time
116 #endif
118 out << prompt;
119 out.flush();
121 #ifndef Q_OS_WIN
122 tcsetattr(0, TCSANOW, &newT);
123 #endif
124 QString answer;
125 do {
126 answer = in.read(1);
127 if (answer[0] == 93) // aka esc, used for things like 'arrow up'
128 in.read(1); // after an esc there always is a second character.
129 } while(answer.length() == 0 || (!allowedCharacters.isEmpty() && !allowedCharacters.contains(answer[0])));
130 #ifndef Q_OS_WIN
131 tcsetattr(0, TCSANOW, &oldT);
132 out << answer << endl;
133 #endif
134 return answer[0];
137 QString Interview::ask(const QString &prompt)
139 QTextStream out(stdout);
140 QTextStream in(stdin);
141 out << prompt;
142 out.flush();
143 QString answer = in.readLine();
144 return answer;