Rough PGN save support.
[tagua/yd.git] / src / console.cpp
blob32d1e46d7cf1321ee9ff4c2a74f3f9b67fabfbb6
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@gmail.com>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
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 */
11 #include "console.h"
13 #include <QApplication>
14 #include <QFile>
15 #include <QFont>
16 #include <QLabel>
17 #include <QLayout>
18 #include <QLineEdit>
19 #include <QScrollBar>
20 #include <QTextCursor>
21 #include <QTextEdit>
23 #include <iostream>
24 #include <boost/scoped_ptr.hpp>
25 #include <kstandarddirs.h>
26 #include <kglobal.h>
28 #include "common.h"
29 #include "foreach.h"
30 #include "histlineedit.h"
31 #include "highlighter.h"
32 #include "mastersettings.h"
35 class BackInserterPatternIteratorAdaptor : public PatternListAdaptorOutputIterator {
36 std::vector<Highlighter::Pattern>& m_vector;
37 public:
38 BackInserterPatternIteratorAdaptor(std::vector<Highlighter::Pattern>& vector)
39 : m_vector(vector) { }
41 virtual void add(const Highlighter::Pattern& p) {
42 m_vector.push_back(p);
47 ConsoleOutput::ConsoleOutput(QTextEdit* edit, bool force_scroll)
48 : m_edit(edit) {
49 m_old_val = m_edit->verticalScrollBar()->value();
50 m_scroll_to = force_scroll || (m_edit->verticalScrollBar()->value()
51 >= m_edit->verticalScrollBar()->maximum() );
53 QTextCursor cursor = m_edit->textCursor();
54 cursor.movePosition(QTextCursor::End);
55 m_edit->setTextCursor(cursor);
58 ConsoleOutput::~ConsoleOutput() {
59 if(m_scroll_to)
60 m_edit->verticalScrollBar()->setValue(m_edit->verticalScrollBar()->maximum());
61 else
62 m_edit->verticalScrollBar()->setValue(m_old_val);
63 //m_edit->ensureCursorVisible();
66 void ConsoleOutput::operator()(const QString& text) {
67 m_edit->insertPlainText(text);
70 LuaConsoleHighlighter::LuaConsoleHighlighter()
71 : m_display(0) {
72 KStandardDirs* dirs = KGlobal::dirs();
74 QString luaHighlightingLibrary = dirs->locate("appdata", "scripts/hllib.lua");
75 std::cout << "lua lib: " << luaHighlightingLibrary << std::endl;
76 m_api.runFile(qPrintable(luaHighlightingLibrary));
78 QStringList highlighting = dirs->findAllResources("appdata", "highlighting/*.lua", KStandardDirs::Recursive);
79 foreach (QString f, highlighting) {
80 std::cout << "lua highlighting file: " << f << std::endl;
81 m_api.runFile(qPrintable(f));
85 void LuaConsoleHighlighter::setDisplay(QTextEdit* display) {
86 m_display = display;
89 LuaConsoleHighlighter::Executor::Executor(QTextEdit* display, ConsoleOutput& output)
90 : m_display(display)
91 , m_output(output) { }
93 void LuaConsoleHighlighter::Executor::writeChunk(const QString& text) {
94 m_output(text);
97 void LuaConsoleHighlighter::Executor::setFormat(const QTextCharFormat& format) {
98 m_display->setCurrentCharFormat(format);
101 LuaConsoleHighlighter::Executor::~Executor() {
102 // m_output("\n");
105 void LuaConsoleHighlighter::operator()(const QString& text, ConsoleOutput& output) {
106 QStringList lines = text.split('\n');
108 for (int i = 0; i < lines.size(); i++) {
109 const QString& line = lines[i];
110 boost::scoped_ptr<HLine> hline(m_api.highlight(line));
111 if (hline) {
112 Executor executor(m_display, output);
113 hline->run(executor);
114 if (i < lines.size() - 1) output("\n");
119 #if 0
120 ConsoleHighlighter::ConsoleHighlighter()
121 : m_display(0) {
122 BackInserterPatternIteratorAdaptor out(m_patterns);
123 Highlighter::load(out);
126 void ConsoleHighlighter::setDisplay(QTextEdit* display) {
127 m_display = display;
128 m_basic_format = m_display->currentCharFormat();
131 void ConsoleHighlighter::operator()(const QString& text, ConsoleOutput& output) {
132 Q_ASSERT(m_display);
134 int offset = 0;
135 m_display->setCurrentCharFormat(m_basic_format);
137 while (true) {
138 int best = -1;
139 int best_offset = -1;
140 int best_length = 0;
142 // try each pattern and find the closest matching one
143 for (uint i = 0; i < m_patterns.size(); i++) {
144 int match_offset = text.indexOf(m_patterns[i].pattern, offset);
145 if (match_offset >= 0 &&
146 (best_offset == -1 || match_offset < best_offset)) {
147 int length = m_patterns[i].pattern.matchedLength();
148 if (length > 0) {
149 best = i;
150 best_offset = match_offset;
151 best_length = length;
156 if (best >= 0) {
157 // output the portion of the text before the matching
158 // substring
159 // std::cout << "outputting plain: " << text.mid(offset, best_offset - offset) << std::endl;
160 // std::cout << "weight = " << m_display->currentCharFormat().fontWeight() << std::endl;
161 output(text.mid(offset, best_offset - offset));
163 // change format
164 m_display->setCurrentCharFormat(m_patterns[best].format);
166 // output the matching substring
167 // std::cout << "outputting formatted: " << text.mid(best_offset, best_length) << std::endl;
168 // std::cout << "weight = " << m_display->currentCharFormat().fontWeight() << std::endl;
169 output(text.mid(best_offset, best_length));
171 // restore basic format
172 m_display->setCurrentCharFormat(m_basic_format);
173 // std::cout << "restored" << std::endl;
174 // std::cout << "weight = " << m_display->currentCharFormat().fontWeight() << std::endl;
176 // update offset
177 offset = best_offset + best_length;
179 else break;
182 // output the last portion of the text
183 // std::cout << "outputting plain: " << text.mid(offset) << std::endl;
184 output(text.mid(offset));
185 // std::cout << "weight = " << m_display->currentCharFormat().fontWeight() << std::endl;
187 #endif
189 QRegExp Console::promptRegexp("([a-zA-Z0-9]*% )");
191 Console::Console(QWidget* parent, const QString& caption)
192 : QWidget(parent) {
193 setObjectName("console");
195 resize(600,600);
196 setWindowTitle(caption);
198 QBoxLayout* layout = new QVBoxLayout(this);
199 QHBoxLayout* promptLayout = new QHBoxLayout;
200 layout->setMargin(0);
201 layout->setSpacing(0);
202 promptLayout->setMargin(0);
203 promptLayout->setSpacing(0);
205 edit = new HistLineEdit(this);
206 display = new QTextEdit(this);
207 prompt = new QLabel(this);
209 setFocusProxy(edit);
211 layout->addWidget(display);
212 layout->addLayout(promptLayout);
214 promptLayout->addWidget(prompt);
215 promptLayout->addWidget(edit);
217 display->setFocusProxy(edit);
218 display->setReadOnly(true);
219 ////display->setTextFormat(QTextEdit::PlainText);
220 display->setAcceptRichText(false);
221 display->setWordWrapMode (QTextOption::NoWrap);
222 display->setUndoRedoEnabled (false);
223 Settings s_console = settings().group("console");
224 if (!s_console["font"]) {
225 QFont f = QApplication::font();
226 f.setFamily("Monospace");
227 s_console["font"] = f;
229 display->setFont(s_console["font"].value<QFont>());
231 display->setFontWeight(QFont::Normal);
232 m_highlighter.setDisplay(display);
234 connect(edit, SIGNAL(receivedInput(const QString&)),
235 this, SLOT(input(const QString&)));
238 void Console::echo(const QString& text) {
239 ConsoleOutput output(display, true);
240 display->setFontWeight(QFont::Bold);
241 output(text + "\n");
242 display->setFontWeight(QFont::Normal);
245 void Console::input(const QString& text) {
246 if (edit->echoMode() == QLineEdit::Password) {
247 // edit->setEchoMode(QLineEdit::Normal);
248 echo("(password sent)");
250 else {
251 // echo inputted text
252 echo(text);
255 if (m_notifier)
256 m_notifier->textNotify(text);
257 receivedInput(text);
260 void Console::displayText(QString text, int offset) {
261 if (offset == 0 && promptRegexp.indexIn(text) == 0) {
262 prompt->setText(" " + promptRegexp.cap(1));
263 offset += promptRegexp.cap(1).length();
266 text = text.mid(offset);
267 text.replace("\t", " ");
269 QByteArray bytes = text.toAscii();
270 if (bytes.contains("\xff\xfc\x01")) {
271 edit->setEchoMode(QLineEdit::Normal);
273 else if (bytes.contains("\xff\xfb\x01")) {
274 edit->setEchoMode(QLineEdit::Password);
277 if (text[offset].isPrint()) {
278 ConsoleOutput output(display);
279 m_highlighter(text, output);
283 void Console::clear() {
284 display->clear();