aboutsummaryrefslogtreecommitdiff
path: root/src/gui
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2013-04-07 12:37:06 +0000
committerdos-reis <gdr@axiomatics.org>2013-04-07 12:37:06 +0000
commitb5d890ae837ea35d9f5077cf260bf85922259be9 (patch)
treecc5e1cd591a2cae525392c46464a4f9c57049644 /src/gui
parenta4633748286e4701f9430991b27a0ffa4fb49bb6 (diff)
downloadopen-axiom-b5d890ae837ea35d9f5077cf260bf85922259be9.tar.gz
gui: misc cleanup
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/conversation.cc55
-rw-r--r--src/gui/conversation.h42
-rw-r--r--src/gui/debate.cc23
-rw-r--r--src/gui/debate.h8
-rw-r--r--src/gui/gui.pro.in2
-rw-r--r--src/gui/main-window.cc48
-rw-r--r--src/gui/main-window.h7
-rw-r--r--src/gui/server.cc1
-rw-r--r--src/gui/widget.h51
9 files changed, 123 insertions, 114 deletions
diff --git a/src/gui/conversation.cc b/src/gui/conversation.cc
index cb0b82b8..4cca97df 100644
--- a/src/gui/conversation.cc
+++ b/src/gui/conversation.cc
@@ -119,7 +119,7 @@ namespace OpenAxiom {
// --------------
// -- Question --
// --------------
- Question::Question(Exchange& e) : Base(&e), parent(&e) {
+ Question::Question(Exchange* e) : super(e) {
setBackgroundRole(QPalette::AlternateBase);
setFrame(true);
}
@@ -127,19 +127,19 @@ namespace OpenAxiom {
void Question::focusInEvent(QFocusEvent* e) {
setFrame(true);
update();
- Base::focusInEvent(e);
+ super::focusInEvent(e);
}
void Question::enterEvent(QEvent* e) {
setFrame(true);
update();
- Base::enterEvent(e);
+ super::enterEvent(e);
}
// ------------
// -- Answer --
// ------------
- Answer::Answer(Exchange& e) : Base(&e), parent(&e) {
+ Answer::Answer(Exchange* e) : super(e) {
setFrameStyle(StyledPanel | Raised);
}
@@ -170,40 +170,39 @@ namespace OpenAxiom {
// Dress the query area with initial properties.
static void
- prepare_query_widget(Conversation& conv, Exchange* e) {
+ prepare_query_widget(Conversation* conv, Exchange* e) {
Question* q = e->question();
q->setFrame(false);
- q->setFont(conv.font());
+ q->setFont(conv->font());
const int m = our_margin(e);
- q->setGeometry(m, m, conv.width() - 2 * m, q->height());
+ q->setGeometry(m, m, conv->width() - 2 * m, q->height());
}
// Dress the reply aread with initial properties.
// Place the reply widget right below the frame containing
// the query widget; make both of the same width, of course.
static void
- prepare_reply_widget(Conversation& conv, Exchange* e) {
+ prepare_reply_widget(Conversation* conv, Exchange* e) {
Answer* a = e->answer();
Question* q = e->question();
const QPoint pt = e->question()->geometry().bottomLeft();
const int m = our_margin(a);
a->setGeometry(pt.x(), pt.y() + spacing,
- conv.width() - 2 * m, q->height());
+ conv->width() - 2 * m, q->height());
a->setBackgroundRole(q->backgroundRole());
a->hide(); // nothing to show yet
}
static void
- finish_exchange_make_up(Conversation& conv, Exchange* e) {
+ finish_exchange_make_up(Conversation* conv, Exchange* e) {
e->setAutoFillBackground(true);
- e->move(conv.bottom_left());
+ e->move(conv->bottom_left());
}
- Exchange::Exchange(Conversation& conv, int n)
- : QFrame(&conv), parent(&conv), no(n),
- query(*this), reply(*this) {
+ Exchange::Exchange(Conversation* conv, int n)
+ : super(conv), no(n), query(this), reply(this) {
setLineWidth(1);
- setFont(conv.font());
+ setFont(conv->font());
prepare_query_widget(conv, this);
prepare_reply_widget(conv, this);
finish_exchange_make_up(conv, this);
@@ -234,7 +233,7 @@ namespace OpenAxiom {
QString input = question()->text().trimmed();
if (empty_string(input))
return;
- topic()->server()->input(input);
+ parent()->parent()->server()->input(input);
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
}
@@ -271,14 +270,12 @@ namespace OpenAxiom {
// Set a minimum preferred widget size, so no layout manager
// messes with it. Indicate we can make use of more space.
- Conversation::Conversation(Debate& parent, const Command& cmd)
- : group(&parent), greatings(this), srv(cmd), cur_ex(), cur_out(&greatings) {
+ Conversation::Conversation(Debate* debate)
+ : super(debate), greatings(this), cur_ex(), cur_out(&greatings) {
setFont(monospace_font());
setBackgroundRole(QPalette::Base);
greatings.setFont(font());
- connect(server(), SIGNAL(readyReadStandardOutput()),
- this, SLOT(read_reply()));
- // connect(oracle(), SIGNAL(readyReadStandardError()),
+ // connect(parent()->server(), SIGNAL(readyReadStandardOutput()),
// this, SLOT(read_reply()));
}
@@ -302,10 +299,10 @@ namespace OpenAxiom {
}
QSize Conversation::sizeHint() const {
- const int view_height = debate()->viewport()->height();
const int n = length();
if (n == 0)
- return round_up_height(minimum_preferred_size(this), view_height);
+ return minimum_preferred_size(this);
+ const int view_height = parent()->viewport()->height();
QSize sz = greatings.size();
for (int i = 0; i < n; ++i)
sz.rheight() += children[i]->height();
@@ -313,7 +310,7 @@ namespace OpenAxiom {
}
void Conversation::resizeEvent(QResizeEvent* e) {
- Base::resizeEvent(e);
+ super::resizeEvent(e);
setMinimumSize(size());
const QSize sz = size();
if (e->oldSize() == sz)
@@ -333,7 +330,7 @@ namespace OpenAxiom {
Exchange*
Conversation::new_topic() {
- Exchange* w = new Exchange(*this, length() + 1);
+ Exchange* w = new Exchange(this, length() + 1);
w->show();
children.push_back(w);
adjustSize();
@@ -381,7 +378,7 @@ namespace OpenAxiom {
void
Conversation::read_reply() {
- OracleOutput output = read_output(server());
+ OracleOutput output = read_output(parent()->server());
if (empty(output))
return;
if (not empty_string(output.result)) {
@@ -390,16 +387,16 @@ namespace OpenAxiom {
}
if (length() == 0) {
if (not empty_string(output.prompt))
- ensure_visibility(debate(), new_topic());
+ ensure_visibility(parent(), new_topic());
}
else {
exchange()->adjustSize();
exchange()->update();
exchange()->updateGeometry();
if (empty_string(output.prompt))
- ensure_visibility(debate(), exchange());
+ ensure_visibility(parent(), exchange());
else {
- ensure_visibility(debate(), next(exchange()));
+ ensure_visibility(parent(), next(exchange()));
QApplication::restoreOverrideCursor();
}
}
diff --git a/src/gui/conversation.h b/src/gui/conversation.h
index 01847e6e..b9f27e0c 100644
--- a/src/gui/conversation.h
+++ b/src/gui/conversation.h
@@ -40,6 +40,7 @@
#include <QEvent>
#include <QResizeEvent>
#include <QPaintEvent>
+#include "widget.h"
#include "server.h"
namespace OpenAxiom {
@@ -74,43 +75,28 @@ namespace OpenAxiom {
// -- Question --
// ---------------
// A question is just a one-liner query area.
- class Question : public QLineEdit {
- typedef QLineEdit Base;
- public:
- explicit Question(Exchange&);
- Exchange* exchange() const { return parent; }
+ struct Question : managed_by<QLineEdit, Exchange> {
+ explicit Question(Exchange*);
protected:
void enterEvent(QEvent*);
void focusInEvent(QFocusEvent*);
-
- private:
- Exchange* const parent;
};
// ------------
// -- Answer --
// ------------
- class Answer : public OutputTextArea {
- typedef OutputTextArea Base;
- public:
- explicit Answer(Exchange&);
- Exchange* exchange() const { return parent; }
-
- private:
- Exchange* const parent;
+ struct Answer : managed_by<OutputTextArea, Exchange> {
+ explicit Answer(Exchange*);
};
// --------------
// -- Exchange --
// --------------
- class Exchange : public QFrame {
+ class Exchange : public managed_by<QFrame, Conversation> {
Q_OBJECT;
public:
- Exchange(Conversation&, int);
-
- // Return the parent widget of this conversation topic
- Conversation* topic() const { return parent; }
+ Exchange(Conversation*, int);
// The widget holding the query area
Question* question() { return &query; }
@@ -130,7 +116,6 @@ namespace OpenAxiom {
void resizeEvent(QResizeEvent*);
private:
- Conversation* const parent;
const int no;
Question query;
Answer reply;
@@ -150,11 +135,10 @@ namespace OpenAxiom {
// -- We remember and number each topic so that we
// -- can go back in the conversation set and reevaluate
// -- queries.
- class Conversation : public QWidget {
+ class Conversation : public managed_by<QWidget, Debate> {
Q_OBJECT;
- typedef QWidget Base;
public:
- explicit Conversation(Debate&, const Command&);
+ explicit Conversation(Debate*);
~Conversation();
// Holds if this conversation just started.
@@ -177,14 +161,8 @@ namespace OpenAxiom {
// of all conversations so far.
QSize sizeHint() const;
- // Return a pointer to the oracle in this conversation.
- Server* server() { return &srv; }
-
// Return a pointer to the current exchange, if any.
Exchange* exchange() { return cur_ex; }
-
- // Return the parent engine widget.
- Debate* debate() const { return group; }
public slots:
// Return the topic following a given topic in this set of conversations
@@ -199,10 +177,8 @@ namespace OpenAxiom {
private:
typedef std::vector<Exchange*> Children;
- Debate* group;
Banner greatings;
Children children;
- Server srv;
Exchange* cur_ex;
OutputTextArea* cur_out;
};
diff --git a/src/gui/debate.cc b/src/gui/debate.cc
index deaed417..9cb19438 100644
--- a/src/gui/debate.cc
+++ b/src/gui/debate.cc
@@ -35,25 +35,15 @@
namespace OpenAxiom {
- Debate::Debate(QTabWidget* parent, Command& cmd)
- : QScrollArea(parent), conv(*this, cmd) {
+ Debate::Debate(QTabWidget* tab)
+ : super(tab), conv(this) {
setWidget(&conv);
setViewportMargins(0, 0, 0, 0);
viewport()->setAutoFillBackground(true);
viewport()->setBackgroundRole(conv.backgroundRole());
setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
- adjustSize();
-
- exchanges()->server()->launch();
- // When invoked in a --role=server mode, OpenAxiom would
- // wait to be pinged before displaying a prompt. This is
- // an unfortunate result of a rather awkward hack.
- exchanges()->server()->input("");
-
- connect(exchanges()->server(),
- SIGNAL(finished(int,QProcess::ExitStatus)),
- this, SLOT(done(int)));
+ // adjustSize();
}
Debate::~Debate() { }
@@ -65,11 +55,4 @@ namespace OpenAxiom {
setSizePolicy(QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding);
}
-
- void Debate::done(int exit_code) {
- // For the time being, shut done the whole application
- // if the interpreter quits. FIXME.
- QApplication::exit(exit_code);
- }
-
}
diff --git a/src/gui/debate.h b/src/gui/debate.h
index 7dca347c..60749816 100644
--- a/src/gui/debate.h
+++ b/src/gui/debate.h
@@ -37,15 +37,16 @@
#include <QScrollArea>
#include <QResizeEvent>
#include "open-axiom.h"
+#include "widget.h"
#include "conversation.h"
#include "main-window.h"
namespace OpenAxiom {
- class Debate : public QScrollArea {
+ class Debate : public managed_by<QScrollArea, QTabWidget> {
Q_OBJECT;
public:
- explicit Debate(QTabWidget*, Command&);
+ explicit Debate(QTabWidget*);
~Debate();
Conversation* exchanges() { return &conv; }
@@ -57,9 +58,6 @@ namespace OpenAxiom {
protected:
void resizeEvent(QResizeEvent*);
- private slots:
- void done(int);
-
private:
Conversation conv;
};
diff --git a/src/gui/gui.pro.in b/src/gui/gui.pro.in
index 30e70349..491b0a9c 100644
--- a/src/gui/gui.pro.in
+++ b/src/gui/gui.pro.in
@@ -27,7 +27,7 @@ TARGET = gui
VPATH += @srcdir@
## Our headers
-HEADERS += server.h conversation.h main-window.h debate.h
+HEADERS += widget.h server.h conversation.h main-window.h debate.h
INCLUDEPATH += $$OA_INC
INCLUDEPATH += @srcdir@
INCLUDEPATH += @top_srcdir@/src/include
diff --git a/src/gui/main-window.cc b/src/gui/main-window.cc
index 9912bf41..b3063638 100644
--- a/src/gui/main-window.cc
+++ b/src/gui/main-window.cc
@@ -31,42 +31,46 @@
#include <QMenuBar>
#include <QAction>
+#include <QApplication>
+#include <QMessageBox>
#include "debate.h"
#include "main-window.h"
namespace OpenAxiom {
-
- // Attempt to resize the main window so that on the first exposure
- // the exchanges in this debate have the preferred geometry and the
- // horizontal scroll bar is not needed.
- static void
- try_to_honor_widget_size(MainWindow* w, Debate* debate) {
- // Force a show first, to provoke conversation size.
- // That helps getting the sizes right. On the other hand, it
- // makes for several resize event roundring leading to
- // an awkward looking brief window showing. FIXME.
- w->show();
- QSize diff = debate->exchanges()->size() - debate->viewport()->size();
- if (diff.width() < 0)
- diff.setWidth(0);
- if (diff.height() < 0)
- diff.setHeight(0);
- w->resize(w->size() + diff);
- }
-
- MainWindow::MainWindow(Command& cmd) : fs(cmd.root_dir), srv(cmd), tabs(this) {
+ MainWindow::MainWindow(Command& cmd) : srv(cmd), tabs(this) {
setCentralWidget(&tabs);
- Debate* debate = new Debate(&tabs, cmd);
+ Debate* debate = new Debate(&tabs);
tabs.addTab(debate, "Main Frame");
QMenu* file = menuBar()->addMenu(tr("&File"));
QAction* action = new QAction(tr("Quit"), this);
file->addAction(action);
action->setShortcut(tr("Ctrl+Q"));
connect(action, SIGNAL(triggered()), this, SLOT(close()));
- try_to_honor_widget_size(this, debate);
+
+ connect(server(), SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SLOT(done(int, QProcess::ExitStatus)));
+ connect(server(), SIGNAL(readyReadStandardError()),
+ this, SLOT(display_error()));
+
+ server()->launch();
+ // When invoked in a --role=server mode, OpenAxiom would
+ // wait to be pinged before displaying a prompt. This is
+ // an unfortunate result of a rather awkward hack.
+ server()->input("");
}
MainWindow::~MainWindow() {
}
+
+ void MainWindow::done(int s, QProcess::ExitStatus) {
+ // For the time being, shut done the whole application
+ // if the interpreter quits. FIXME.
+ QApplication::exit(s);
+ }
+
+ void MainWindow::display_error() {
+ auto s = server()->readAllStandardError();
+ QMessageBox::critical(this, tr("System error"), QString(s));
+ }
}
diff --git a/src/gui/main-window.h b/src/gui/main-window.h
index 74e5effd..c16c4136 100644
--- a/src/gui/main-window.h
+++ b/src/gui/main-window.h
@@ -45,12 +45,13 @@ namespace OpenAxiom {
MainWindow(Command&);
~MainWindow();
- // Pointer to the root file system of the OpenAxiom installation
- Filesystem* filesystem() { return &fs; }
Server* server() { return &srv; }
+
+ private slots:
+ void done(int, QProcess::ExitStatus);
+ void display_error();
private:
- Filesystem fs;
Server srv;
QTabWidget tabs;
};
diff --git a/src/gui/server.cc b/src/gui/server.cc
index 461c22b8..601599e9 100644
--- a/src/gui/server.cc
+++ b/src/gui/server.cc
@@ -34,7 +34,6 @@
namespace OpenAxiom {
Server::Server(const Command& c) : cmd(c), fs(c.root_dir) {
- setProcessChannelMode(QProcess::MergedChannels);
}
Server::~Server() {
diff --git a/src/gui/widget.h b/src/gui/widget.h
new file mode 100644
index 00000000..1ccf8573
--- /dev/null
+++ b/src/gui/widget.h
@@ -0,0 +1,51 @@
+// Copyright (C) 2013, Gabriel Dos Reis.
+// All rights reserved.
+// Written by Gabriel Dos Reis.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// - Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+//
+// - Neither the name of OpenAxiom. nor the names of its contributors
+// may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef OPENAXIOM_WIDGET_included
+#define OPENAXIOM_WIDGET_included
+
+#include <QWidget>
+
+namespace OpenAxiom {
+ template<typename S, typename T>
+ struct managed_by : S {
+ using super = managed_by<S, T>;
+ managed_by(T* t) : S(t) { }
+ T* parent() const { return qobject_cast<T*>(S::parent()); }
+ };
+}
+
+#endif // OPENAXIOM_WIDGET_included
+
+// Local Variables:
+// mode: c++
+// End: