diff options
Diffstat (limited to 'src/unite')
-rw-r--r-- | src/unite/CMakeLists.txt | 46 | ||||
-rw-r--r-- | src/unite/fqterm_mini_server.cpp | 71 | ||||
-rw-r--r-- | src/unite/fqterm_mini_server.h | 69 | ||||
-rw-r--r-- | src/unite/internal/article.cpp | 19 | ||||
-rw-r--r-- | src/unite/internal/article.h | 28 | ||||
-rw-r--r-- | src/unite/internal/board.cpp | 19 | ||||
-rw-r--r-- | src/unite/internal/board.h | 28 | ||||
-rw-r--r-- | src/unite/internal/session.cpp | 138 | ||||
-rw-r--r-- | src/unite/internal/session.h | 77 | ||||
-rw-r--r-- | src/unite/internal/state.cpp | 676 | ||||
-rw-r--r-- | src/unite/internal/state.h | 219 | ||||
-rw-r--r-- | src/unite/internal/statebuilder.cpp | 32 | ||||
-rw-r--r-- | src/unite/internal/statebuilder.h | 16 | ||||
-rw-r--r-- | src/unite/internal/unite.h | 35 | ||||
-rw-r--r-- | src/unite/internal/user.cpp | 19 | ||||
-rw-r--r-- | src/unite/internal/user.h | 35 |
16 files changed, 1527 insertions, 0 deletions
diff --git a/src/unite/CMakeLists.txt b/src/unite/CMakeLists.txt new file mode 100644 index 0000000..b093576 --- /dev/null +++ b/src/unite/CMakeLists.txt @@ -0,0 +1,46 @@ +set(fqunite_SRCS + fqterm_mini_server.h + fqterm_mini_server.cpp +) + +set(fqunite_internal_SRCS + internal/unite.h + internal/user.h + internal/user.cpp + internal/board.h + internal/board.cpp + internal/article.h + internal/article.cpp + internal/session.h + internal/session.cpp + internal/state.h + internal/state.cpp + internal/statebuilder.h + internal/statebuilder.cpp +) + +qt4_automoc( + ${fqunite_SRCS} + ${fqunite_internal_SRCS} +) + +include_directories( + ${QT_INCLUDE_DIR} + ${QT_QTCORE_INCLUDE_DIR} + ${QT_QTNETWORK_INCLUDE_DIR} + ${QT_QTXML_INCLUDE_DIR} + ${QT_QTGUI_INCLUDE_DIR} + ${OPENSSL_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/internal + ${CMAKE_CURRENT_SOURCE_DIR}/../common + ${CMAKE_CURRENT_BINARY_DIR} +) + +add_library(fqterm_unite + ${fqunite_SRCS} + ${fqunite_internal_SRCS} +) + +add_dependencies(fqterm_unite + fqterm_common +) diff --git a/src/unite/fqterm_mini_server.cpp b/src/unite/fqterm_mini_server.cpp new file mode 100644 index 0000000..2b18faf --- /dev/null +++ b/src/unite/fqterm_mini_server.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** +* fqterm, a terminal emulator for both BBS and *nix. * +* Copyright (C) 2008 fqterm development group. * +* * +* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. * +***************************************************************************/ + +#include "fqterm_mini_server.h" +#include "fqterm_trace.h" +#include "fqterm_path.h" +#include "fqterm.h" +#include <QByteArray> +#include <QTimer> +#include <QFile> +#include <QtGui/QApplication> +#include <queue> +namespace FQTerm { + + +void FQTermMiniServerThread::run() +{ + setTerminationEnabled(); + FQTermMiniServer miniServer; + //miniServer.setMaxPendingConnections(1); + miniServer.listen(QHostAddress::LocalHost, 35172); + exec(); + miniServer.close(); + miniServer.finalizeMiniServer(); +} + +FQTermMiniServer::FQTermMiniServer(QObject * parent) + : QTcpServer(parent) { +} + + +FQTermMiniServer::~FQTermMiniServer() { +} + +void FQTermMiniServer::incomingConnection( int socketDescriptor ) { + FQTermUniteSession* session = new FQTermUniteSession(socketDescriptor); + FQ_VERIFY(connect(this, SIGNAL(quit()), session, SLOT(quit()), Qt::QueuedConnection)); + session->start(); +} + +void FQTermMiniServer::finalizeMiniServer() { + emit quit(); +} + + + + + + + + +} //namespace FQTerm + +#include "fqterm_mini_server.moc" diff --git a/src/unite/fqterm_mini_server.h b/src/unite/fqterm_mini_server.h new file mode 100644 index 0000000..3295137 --- /dev/null +++ b/src/unite/fqterm_mini_server.h @@ -0,0 +1,69 @@ +/*************************************************************************** +* fqterm, a terminal emulator for both BBS and *nix. * +* Copyright (C) 2008 fqterm development group. * +* * +* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. * +***************************************************************************/ + +#ifndef FQTERM_MINI_SERVER_H +#define FQTERM_MINI_SERVER_H + +#include <QThread> +#include <QByteArray> +#include <map> +#include <vector> +#include <algorithm> +#include <QString> +#include "internal/session.h" + +namespace FQTerm { + + +class FQTermMiniServer : public QTcpServer { + Q_OBJECT; +public: + FQTermMiniServer( QObject * parent = 0 ); + ~FQTermMiniServer(); + void finalizeMiniServer(); +protected: + void incomingConnection(int socketDescriptor); +signals: + void quit(); +}; + + +class FQTermMiniServerThread : public QThread{ +protected: + virtual void run(); + +}; +//---------------------------------------------------------------------------------- +// this for FSM +class FQTermUniteDecode; + +//---------------------------------------------------------------------------------- + + +class FQTermUniteSession; +class FQTermUniteState; + + + +//use XML to describe the site. +//each session contains user info, not in the reverse way. +//each session has 1. state (edit, read, menu), 2. strategy (decided by state) 3. context (with which strategy could decide next step. i.e. inner state) +} //namespace FQTerm +#endif diff --git a/src/unite/internal/article.cpp b/src/unite/internal/article.cpp new file mode 100644 index 0000000..c5905f8 --- /dev/null +++ b/src/unite/internal/article.cpp @@ -0,0 +1,19 @@ +/*************************************************************************** +* fqterm, a terminal emulator for both BBS and *nix. * +* Copyright (C) 2008 fqterm development group. * +* * +* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. * +***************************************************************************/ diff --git a/src/unite/internal/article.h b/src/unite/internal/article.h new file mode 100644 index 0000000..43ca0cb --- /dev/null +++ b/src/unite/internal/article.h @@ -0,0 +1,28 @@ +/*************************************************************************** +* fqterm, a terminal emulator for both BBS and *nix. * +* Copyright (C) 2008 fqterm development group. * +* * +* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. * +***************************************************************************/ + +#ifndef FQTERM_UNITE_ARTICLE +#define FQTERM_UNITE_ARTICLE + +namespace FQTerm { + +} //namespace FQTerm + +#endif //FQTERM_UNITE_USER
\ No newline at end of file diff --git a/src/unite/internal/board.cpp b/src/unite/internal/board.cpp new file mode 100644 index 0000000..c5905f8 --- /dev/null +++ b/src/unite/internal/board.cpp @@ -0,0 +1,19 @@ +/*************************************************************************** +* fqterm, a terminal emulator for both BBS and *nix. * +* Copyright (C) 2008 fqterm development group. * +* * +* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. * +***************************************************************************/ diff --git a/src/unite/internal/board.h b/src/unite/internal/board.h new file mode 100644 index 0000000..a23db18 --- /dev/null +++ b/src/unite/internal/board.h @@ -0,0 +1,28 @@ +/*************************************************************************** +* fqterm, a terminal emulator for both BBS and *nix. * +* Copyright (C) 2008 fqterm development group. * +* * +* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. * +***************************************************************************/ + +#ifndef FQTERM_UNITE_BOARD +#define FQTERM_UNITE_BOARD + +namespace FQTerm { + +} //namespace FQTerm + +#endif //FQTERM_UNITE_USER
\ No newline at end of file diff --git a/src/unite/internal/session.cpp b/src/unite/internal/session.cpp new file mode 100644 index 0000000..6964287 --- /dev/null +++ b/src/unite/internal/session.cpp @@ -0,0 +1,138 @@ +/*************************************************************************** +* fqterm, a terminal emulator for both BBS and *nix. * +* Copyright (C) 2008 fqterm development group. * +* * +* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. * +***************************************************************************/ + +#include "state.h" +#include "fqterm.h" +#include <QApplication> +#include <algorithm> +#include "statebuilder.h" +namespace FQTerm{ + +void FQTermUniteSessionContext::write(const QByteArray& str) { + session_->write(str); +} + +FQTermUniteSessionContext::FQTermUniteSessionContext(FQTermUniteSession* session) : QObject(session), session_(session) { + stateTable_[WELCOME] = new FQTermWelcomeState(this); + stateTable_[EXITING] = new FQTermExitState(this); + stateTable_[READING] = new FQTermReadingState(this); + stateTable_[HELP] = new FQTermHelpState(this); + setCurrentState(WELCOME); +} + +void FQTermUniteSessionContext::processInput(const QByteArray& input) { + inputBuffer_ += input; + while(true) { + int consumed = currentState_->processInput(inputBuffer_); + inputBuffer_ = inputBuffer_.mid(consumed); + if (!consumed || inputBuffer_.size() == 0) { + break; + } + } +} + +void FQTermUniteSessionContext::quit() { + session_->quit(); +} + + + +FQTermUniteState* FQTermUniteSessionContext::setCurrentState(int state, bool init /*= true*/) { + StateTableIterator it = stateTable_.find(state); + if (it != stateTable_.end()) { + currentState_ = it->second; + if (init) + currentState_->initialize(); + } + return currentState_; +} + + + +FQTermUniteSession::FQTermUniteSession(int socketDescriptor ) : context_(NULL) { + moveToThread(this); + socket_ = new QTcpSocket; + FQ_VERIFY(connect(socket_, SIGNAL(readyRead()), + this, SLOT(readyRead()),Qt::DirectConnection)); + FQ_VERIFY(connect(socket_, SIGNAL(disconnected()), + this, SLOT(disconnected()),Qt::DirectConnection)); + FQ_VERIFY(connect(socket_, SIGNAL(stateChanged(QAbstractSocket::SocketState)), + this, SLOT(stateChanged(QAbstractSocket::SocketState)),Qt::DirectConnection)); + FQ_VERIFY(connect(socket_, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(error(QAbstractSocket::SocketError)),Qt::DirectConnection)); + + // FQ_VERIFY(connect(socket_, SIGNAL(connected()), + // this, SLOT(welcome()),Qt::DirectConnection)); + + socket_->setSocketDescriptor(socketDescriptor); + socket_->moveToThread(this); + setTerminationEnabled(); + + StateBuilder sb; + sb.BuildState(); +} + + +FQTermUniteSession::~FQTermUniteSession() { + socket_->close(); + delete socket_; + socket_ = NULL; +} + +void FQTermUniteSession::welcome() +{ + context_ = new FQTermUniteSessionContext(this); +} + +void FQTermUniteSession::readyRead() { + if (context_) { + context_->processInput(socket_->readAll()); + } +} + +void FQTermUniteSession::write( const QByteArray& output ) { + socket_->write(output); +} + +void FQTermUniteSession::run() { + welcome(); + exec(); + disconnected(); +} + + +void FQTermUniteSession::disconnected() { + if (!isRunning()) + return; + quit(); + moveToThread(QApplication::instance()->thread()); + deleteLater(); +} + +void FQTermUniteSession::stateChanged( QAbstractSocket::SocketState socketState ) { +} + +void FQTermUniteSession::error(QAbstractSocket::SocketError socketError) { +} + + +} + +#include "session.moc"
\ No newline at end of file diff --git a/src/unite/internal/session.h b/src/unite/internal/session.h new file mode 100644 index 0000000..a5959a1 --- /dev/null +++ b/src/unite/internal/session.h @@ -0,0 +1,77 @@ +/*************************************************************************** +* fqterm, a terminal emulator for both BBS and *nix. * +* Copyright (C) 2008 fqterm development group. * +* * +* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. * +***************************************************************************/ +#ifndef FQTERM_UNITE_SESSION +#define FQTERM_UNITE_SESSION + +#include <QObject> +#include <QThread> +#include <QTcpServer> +#include <QTcpSocket> +#include <map> +namespace FQTerm { + +class FQTermUniteState; +class FQTermUniteSession; +class FQTermUniteSessionContext : public QObject { + Q_OBJECT; +public: + FQTermUniteSessionContext(FQTermUniteSession* session); + void write(const QByteArray& str); + void processInput(const QByteArray& input); + void quit(); + enum STATE{WELCOME = 0, EXITING = 1, READING = 2, HELP = 3}; + FQTermUniteState* setCurrentState(int state, bool init = true); + + int row() {return 24;} + int column() {return 80;} +private: + FQTermUniteSession* session_; + FQTermUniteState* currentState_; + QByteArray inputBuffer_; + typedef std::map<int, FQTermUniteState*> StateTable; + typedef std::map<int, FQTermUniteState*>::iterator StateTableIterator; + StateTable stateTable_; +}; + + +class FQTermUniteSession : public QThread { + Q_OBJECT; +public: + FQTermUniteSession(int socketDescriptor); + ~FQTermUniteSession(); + void write(const QByteArray& output); + +protected: + virtual void run(); + protected slots: + void readyRead(); + void disconnected(); + void stateChanged(QAbstractSocket::SocketState socketState); + void error(QAbstractSocket::SocketError socketError); + void welcome(); +private: + QTcpSocket* socket_; + FQTermUniteSessionContext* context_; + +}; + +} //namespace FQTerm + +#endif //FQTERM_UNITE_USER
\ No newline at end of file diff --git a/src/unite/internal/state.cpp b/src/unite/internal/state.cpp new file mode 100644 index 0000000..39241b0 --- /dev/null +++ b/src/unite/internal/state.cpp @@ -0,0 +1,676 @@ +#include "fqterm.h" +#include "fqterm_path.h" +#include <algorithm> +#include "state.h" +#include <QDomDocument> + +namespace FQTerm{ + +int FQTermUniteMenu::addEntry( char key ) +{ + entries_.push_back(tolower(key)); + return entries_.size() - 1; +} + +int FQTermUniteMenu::findEntry( char key ) +{ + std::vector<char>::iterator it = std::find(entries_.begin(), entries_.end(), tolower(key)); + if (it == entries_.end()) {return -1;} + return std::distance(entries_.begin(), it); +} + +void FQTermUniteMenu::clearEntry() +{ + entries_.clear(); + clearPointer(current_); + current_ = 0; +} + +int FQTermUniteMenu::currentEntry() +{ + return current_; +} + +int FQTermUniteMenu::setCurrentEntry( char key ) +{ + int next = findEntry(key); + if (next == -1) + return currentEntry(); + clearPointer(current_); + current_ = next; + drawPointer(current_); + return current_; +} + +int FQTermUniteMenu::setCurrentIndex( int index ) +{ + clearPointer(current_); + current_ = index; + drawPointer(current_); + return current_; +} + +int FQTermUniteMenu::nextEntry() +{ + if (!entries_.size()) + return current_; + clearPointer(current_); + current_++; + current_ %= entries_.size(); + drawPointer(current_); + return current_; +} + +int FQTermUniteMenu::prevEntry() +{ + if (!entries_.size()) + return current_; + clearPointer(current_); + current_--; + current_ += entries_.size(); + current_ %= entries_.size(); + drawPointer(current_); + return current_; +} + + +StateOption FQTermUniteDecode::EscStateMachine::normal_state_[] = { + { + CHAR_ESC, 0, esc_state_ + }, { + CHAR_NORMAL, &FQTermUniteDecode::normalInput, normal_state_ + } +}; + +// state after a ESC_CHAR +StateOption FQTermUniteDecode::EscStateMachine::esc_state_[] = { + { + '[', &FQTermUniteDecode::clearParam, bracket_state_ + }, { + CHAR_ESC, &FQTermUniteDecode::doubleEsc, normal_state_ + },{ + CHAR_NORMAL, 0, normal_state_ + } +}; + +// state after ESC [ +StateOption FQTermUniteDecode::EscStateMachine::bracket_state_[] = { + { + '0', &FQTermUniteDecode::paramDigit, bracket_state_ + }, { + '1', &FQTermUniteDecode::paramDigit, bracket_state_ + }, { + '2', &FQTermUniteDecode::paramDigit, bracket_state_ + }, { + '3', &FQTermUniteDecode::paramDigit, bracket_state_ + }, { + '4', &FQTermUniteDecode::paramDigit, bracket_state_ + }, { + '5', &FQTermUniteDecode::paramDigit, bracket_state_ + }, { + '6', &FQTermUniteDecode::paramDigit, bracket_state_ + }, { + '7', &FQTermUniteDecode::paramDigit, bracket_state_ + }, { + '8', &FQTermUniteDecode::paramDigit, bracket_state_ + }, { + '9', &FQTermUniteDecode::paramDigit, bracket_state_ + }, { + 'A', &FQTermUniteDecode::cursorUp, normal_state_ + }, { + 'B', &FQTermUniteDecode::cursorDown, normal_state_ + }, { + 'C', &FQTermUniteDecode::cursorRight, normal_state_ + }, { + 'D', &FQTermUniteDecode::cursorLeft, normal_state_ + }, { + '~', &FQTermUniteDecode::functionKey, normal_state_ + }, { + CHAR_NORMAL, 0, normal_state_ + } +}; + +int FQTermUniteDecode::processInput(const QByteArray& input) { + data_ = input.data(); + currentByte_ = 0; + inputLength_ = input.size(); + /* + for (int i = 0; i < input.size(); ++i) { + bool res = keyReceived(input[i]); + if (!res) { + return i + 1; + } + } + */ + + int i; + StateOption *lastState; + + while (currentByte_ < inputLength_) { + // current state always be initialized to point to the beginning of three structures + // ( normalState, escState, bracketState ) + i = 0; + while (current_state_[i].byte != CHAR_NORMAL && current_state_[i].byte != + data_[currentByte_]) { + i++; + } + + lastState = current_state_ + i; + + bool stopDecode; + if (lastState->action != 0) { + stopDecode = (this->*(lastState->action))(); + } + + // reinit current state + current_state_ = lastState->nextState; + + currentByte_++; + if (stopDecode) + break; + + } + + return currentByte_; +} + +FQTermUniteDecode::FQTermUniteDecode() { + current_state_ = EscStateMachine::normal_state_; + data_ = NULL; + inputLength_ = 0; + currentByte_ = 0; +} + +bool FQTermUniteDecode::clearParam() { + param_ = -1; + return true; +} + +bool FQTermUniteDecode::cursorLeft() { + return keyReceived(LEFT); +} + +bool FQTermUniteDecode::cursorDown() { + return keyReceived(DOWN); +} + +bool FQTermUniteDecode::cursorRight() { + return keyReceived(RIGHT); +} + +bool FQTermUniteDecode::cursorUp() { + return keyReceived(UP); +} + +bool FQTermUniteDecode::normalInput() { + return keyReceived(data_[currentByte_]); +} + +bool FQTermUniteDecode::doubleEsc() { + return keyReceived(DOUBLEESC); +} + +bool FQTermUniteDecode::paramDigit() { + if (param_ < 0) { + param_ = 0; + } + param_ = param_ * 10 + (data_[currentByte_] - '0'); + return true; +} + +bool FQTermUniteDecode::functionKey() { + int key; + switch (param_) { + case 1: key = HOME; break; + case 3: key = DELETE; break; + case 4: key = END; break; + case 5: key = PGUP; break; + case 6: key = PGDOWN; break; + case 11: key = F1; break; + case 12: key = F2; break; + case 13: key = F3; break; + case 14: key = F4; break; + case 15: key = F5; break; + case 17: key = F6; break; + case 18: key = F7; break; + case 19: key = F8; break; + case 20: key = F9; break; + case 21: key = F10; break; + case 23: key = F11; break; + case 24: key = F12; break; + default: + break; + } + return keyReceived(key); +} + +FQTermUniteState::FQTermUniteState(FQTermUniteSessionContext* context) : context_(context) { + +} + +void FQTermUniteState::write( const QByteArray& output ) { + context_->write(output); +} + +QByteArray FQTermUniteState::escape() { + return "\x1b"; +} + +void FQTermUniteState::moveCursorRelative(int dx, int dy) { + //Esc[ValueA Move cursor up n lines CUU + //Esc[ValueB Move cursor down n lines CUD + //Esc[ValueC Move cursor right n lines CUF + //Esc[ValueD Move cursor left n lines CUB + if (dy > 0) { + write(escape() + QString("[%1").arg(dy).toLocal8Bit() + "B"); + } + if (dy < 0) { + write(escape() + QString("[%1").arg(-dy).toLocal8Bit() + "A"); + } + if (dx > 0) { + write(escape() + QString("[%1").arg(dx).toLocal8Bit() + "C"); + } + if (dx < 0) { + write(escape() + QString("[%1").arg(-dx).toLocal8Bit() + "D"); + } + +} + + +void FQTermUniteState::moveCursorAbsolute(int x, int y) { + //Esc[Line;ColumnH Move cursor to screen location v,h CUP + write(escape() + QString("[%1;%2H").arg(y).arg(x).toLocal8Bit()); +} + +void FQTermUniteState::moveCursorHome() { + write(escape() + "[H"); +} + +void FQTermUniteState::scrollWindow(int dy) { + //EscD Move/scroll window up one line IND + //EscM Move/scroll window down one line RI + + if (dy > 0) { + for (int i = 0; i < dy; ++i) + write(escape() + "D"); + } + if (dy < 0) { + dy = -dy; + for (int i = 0; i < dy; ++i) + write(escape() + "M"); + } +} + +void FQTermUniteState::moveCursorNextLine() { + //EscE Move to next line NEL + write(escape() + "E"); + +} + +void FQTermUniteState::saveCursor() { + //Esc7 Save cursor position and attributes DECSC + write(escape() + "7"); +} + +void FQTermUniteState::restoreCursor() { + //Esc8 Restore cursor position and attributes DECSC + write(escape() + "8"); +} + +void FQTermUniteState::setAttr(int attr) { + if (attr == -1) { + write(escape() + "[m"); + } else { + write(escape() + QString("[%1m").arg(attr).toLocal8Bit()); + } +} + +void FQTermUniteState::setForegroundColor(int color, bool highlight /*= true*/) { + int hl = highlight?1:0; + write(escape() + QString("[%1;3%2m").arg(hl).arg(color).toLocal8Bit()); +} + +void FQTermUniteState::setBackgroundColor(int color) { + write(escape() + QString("[4%1m").arg(color).toLocal8Bit()); +} + +void FQTermUniteState::clearLine(int part) { + write(escape() + QString("[%1K").arg(part).toLocal8Bit()); +} + +void FQTermUniteState::clearScreen(int part) { + write(escape() + QString("[%1J").arg(part).toLocal8Bit()); +} + +void FQTermUniteState::setWindowRange(int startLine, int endLine) { + write(escape() + QString("[%1;%2r").arg(startLine).arg(endLine).toLocal8Bit()); +} + + +QByteArray FQTermUniteState::cursorStr() { + QChar c(0x25c6); + QString str(c); + return str.toUtf8(); +} +FQTermWelcomeState::FQTermWelcomeState( FQTermUniteSessionContext* context ) : FQTermUniteState(context) { + addEntry('h'); + addEntry('x'); +} + +void FQTermWelcomeState::initialize() { + moveCursorHome(); + clearScreen(WHOLESCREEN); + + + + QFile welcomeFile(getPath(RESOURCE) + "unite/welcome"); + welcomeFile.open(QIODevice::ReadOnly); + QByteArray str = welcomeFile.readAll(); + write(str); + setCurrentIndex(currentEntry()); + return; +} + +bool FQTermWelcomeState::keyReceived(int key) { + if (tolower(key) == 'j' || key == UP) { + prevEntry(); + } else if (tolower(key) == 'k' || key == DOWN) { + nextEntry(); + } else if (key == '\r' || key == RIGHT) { + enterEntry(); + return false; + } else if (tolower(key) <= 'z' && tolower(key) >= 'a') { + setCurrentEntry(key); + } + return true; +} + +void FQTermWelcomeState::enterEntry() { + if (currentEntry() == 1) { + setNextState(FQTermUniteSessionContext::EXITING); + } else if (currentEntry() == 0) { + setNextState(FQTermUniteSessionContext::HELP); + } +} + +void FQTermWelcomeState::clearPointer(int index) { + moveCursorAbsolute(7, 11 + index); + write(" "); + moveCursorHome(); +} + +void FQTermWelcomeState::drawPointer(int index) { + moveCursorAbsolute(7, 11 + index); + write(cursorStr()); + moveCursorHome(); +} + + + +void FQTermExitState::initialize() { + clearScreen(WHOLESCREEN); + QFile welcomeFile(getPath(RESOURCE) + "unite/exit"); + welcomeFile.open(QIODevice::ReadOnly); + QByteArray str = welcomeFile.readAll(); + write(str); + setCurrentIndex(0); +} + +void FQTermExitState::clearPointer(int index) { + moveCursorAbsolute(28, 10 + index); + setBackgroundColor(BLUE); + write(" "); + //moveCursorHome(); +} + +void FQTermExitState::drawPointer( int index ) { + moveCursorAbsolute(28, 10 + index); + setBackgroundColor(BLUE); + write(cursorStr()); + //moveCursorHome(); +} + +void FQTermExitState::enterEntry() { + if (currentEntry() == 1) { + quit(); + } else { + setNextState(FQTermUniteSessionContext::WELCOME); + } +} + +bool FQTermExitState::keyReceived( int key ) +{ + if (tolower(key) == 'j' || key == UP) { + prevEntry(); + } else if (tolower(key) == 'k' || key == DOWN) { + nextEntry(); + } else if (key == '\r') { + enterEntry(); + return false; + } else if (key >= '0' && key <= '9') { + setCurrentEntry(key); + } else if (tolower(key) == 'c') { + setCurrentIndex(0); + enterEntry(); + return false; + } + //moveCursorHome(); + return true; +} + +FQTermExitState::FQTermExitState( FQTermUniteSessionContext* context ) : FQTermUniteState(context) { + addEntry('1'); + addEntry('2'); +} + +SplittedArticleBuffer::SplittedArticleBuffer(const QByteArray& utf8Content, int column, int row) { + std::vector<QString> strList; + QString content = QString::fromUtf8(utf8Content); + lines_.reserve(row); + int start = 0; + for(;;) { + int newStart = findNextLine(content, start, column); + if (newStart == -1) { + lines_.push_back(content.mid(start).toUtf8()); + break; + } else { + lines_.push_back(content.mid(start, newStart - start).toUtf8()); + start = newStart; + } + } +} + +int SplittedArticleBuffer::findNextLine(const QString& str, int start, int column) { + int count = 0; + for (int i = start; i < str.length(); ++i) { + if (str[i] == '\t') { + count += 2; + } else { + count += str[i] <= 0x7F ? 1 : 2; + } + if (count > column) { + return i; + } + if (str[i] == '\n') { + if (i + 1 < str.length()) + return i + 1; + } + } + return -1; +} + +void FQTermReadingState::initialize() { + clearScreen(WHOLESCREEN); + moveCursorHome(); + drawLines(row() - 1, 1); + drawFooter(); + moveCursorAbsolute(column(), row()); +} + + +void FQTermReadingState::setFile(const QString& filename) { + currentStartLine_ = 0; + QFile file(filename); + file.open(QIODevice::ReadOnly); + content_ = file.readAll(); + delete saBuffer_; + saBuffer_ = new SplittedArticleBuffer(content_, column(), row()); +} + +FQTermReadingState::FQTermReadingState( FQTermUniteSessionContext* context ) : FQTermUniteState(context) { + returnState_ = FQTermUniteSessionContext::WELCOME; + currentStartLine_ = 0; + saBuffer_ = 0; +} + +bool FQTermReadingState::keyReceived( int key ) { + if (tolower(key) == 'q' || key == LEFT || !saBuffer_) { + setNextState(returnState_); + return false; + } else if (tolower(key) == 'k' || key == DOWN) { + adjustLineByDiff(1); + drawLines(row() - 1, 1); + drawFooter(); + } else if (tolower(key) == 'j' || key == UP) { + adjustLineByDiff(-1); + drawLines(row() - 1, 1); + drawFooter(); + } else if (key == PGDOWN || key == ' ' || key == RIGHT) { + adjustLineByDiff(row() - 2); + drawLines(row() - 1, 1); + drawFooter(); + } else if (key == PGUP) { + adjustLineByDiff(-row() + 2); + drawLines(row() - 1, 1); + drawFooter(); + } else if (key == HOME) { + adjustLineByDiff(-saBuffer_->count()); + drawLines(row() - 1, 1); + drawFooter(); + } else if (key == END) { + adjustLineByDiff(saBuffer_->count()); + drawLines(row() - 1, 1); + drawFooter(); + } + return true; +} + +void FQTermReadingState::drawFooter() { + if (!saBuffer_) + return; + cursorGuard(*this); + moveCursorAbsolute(1, row()); + setBackgroundColor(BLUE); + QByteArray footer = QString("Current Line: (%1-%2) Total: %3").arg(currentStartLine_ + 1).arg(qMin(saBuffer_->count(), currentStartLine_ + row() - 1)).arg(saBuffer_->count()).toLocal8Bit(); + footer += QByteArray(column() - footer.size(), ' '); + write(footer); + setAttr(CLEARATTR); +} + +void FQTermReadingState::adjustLineByDiff(int delta) { + if (!saBuffer_) + return; + currentStartLine_ += delta; + if (currentStartLine_ + row() - 1 >= saBuffer_->count()) + currentStartLine_ = saBuffer_->count() - (row() - 1); + if (currentStartLine_ < 0) + currentStartLine_ = 0; +} + + +void FQTermReadingState::drawLines(int count, int yPos) { + if (!saBuffer_) + return; + cursorGuard cg(*this); + QByteArray blankLine(column(), ' '); + for (int i = 0; i < count; ++i) { + moveCursorAbsolute(1, yPos + i); + clearLine(WHOLELINE); + if (currentStartLine_ + yPos + i - 1 >= saBuffer_->count()) { + write(blankLine); + } else { + write(saBuffer_->retriveLine(currentStartLine_ + yPos + i - 1)); + } + } +} + +FQTermReadingState::~FQTermReadingState() { + delete saBuffer_; +} + + + + + +FQTermHelpState::FQTermHelpState(FQTermUniteSessionContext* context) : FQTermUniteState(context) { + addEntry('s'); //0.entry for script + addEntry('t'); //1.entry for shortcut + addEntry('u'); //2.entry for unix host + addEntry('x'); //3.entry for quit to welcome +} + +void FQTermHelpState::initialize() { + moveCursorHome(); + clearScreen(WHOLESCREEN); + QFile welcomeFile(getPath(RESOURCE) + "unite/help"); + welcomeFile.open(QIODevice::ReadOnly); + QByteArray str = welcomeFile.readAll(); + write(str); + setCurrentIndex(currentEntry()); + return; +} + +bool FQTermHelpState::keyReceived(int key) { + if (tolower(key) == 'j' || key == UP) { + prevEntry(); + } else if (tolower(key) == 'k' || key == DOWN) { + nextEntry(); + } else if (key == '\r' || key == RIGHT) { + enterEntry(); + return false; + } else if (tolower(key) <= 'z' && tolower(key) >= 'a') { + setCurrentEntry(key); + } + return true; +} + +void FQTermHelpState::enterEntry() { + if (currentEntry() == 3) { + setNextState(FQTermUniteSessionContext::WELCOME); + return; + } + + QString doc; + switch(currentEntry()) + { + case 0: + doc = "script-doc"; + break; + case 1: + doc = "shortcut-doc"; + break; + case 2: + doc = "ssh-unix-doc"; + break; + } + FQTermUniteState* reader = setNextState(FQTermUniteSessionContext::READING, false); + ((FQTermReadingState*)reader)->setFile(getPath(RESOURCE) + "unite/" + doc); + ((FQTermReadingState*)reader)->setReturnState(FQTermUniteSessionContext::HELP); + reader->initialize(); +} + +void FQTermHelpState::clearPointer(int index) { + moveCursorAbsolute(7, 11 + index); + write(" "); + moveCursorHome(); +} + +void FQTermHelpState::drawPointer(int index) { + moveCursorAbsolute(7, 11 + index); + write(cursorStr()); + moveCursorHome(); +} + +} // namespace FQTerm + +#include "state.moc"
\ No newline at end of file diff --git a/src/unite/internal/state.h b/src/unite/internal/state.h new file mode 100644 index 0000000..e294372 --- /dev/null +++ b/src/unite/internal/state.h @@ -0,0 +1,219 @@ +#ifndef FQTERM_UNITE_STATE +#define FQTERM_UNITE_STATE + +#include <QByteArray> +#include "session.h" + +namespace FQTerm { +class FQTermUniteDecode; +typedef bool (FQTermUniteDecode:: *StateFunc)(); + +struct StateOption { + int byte; // char value to look for; -1==end/default + StateFunc action; + StateOption *nextState; +}; + + + +class FQTermUniteDecode { +public: + FQTermUniteDecode(); + virtual ~FQTermUniteDecode() {} + //should return number of chars consumed + virtual int processInput(const QByteArray& input); +protected: + virtual bool keyReceived(int key) = 0; + //tab = 7, backspace = 8, delete is *[3~, page up is 5~, page down is 6~, home is 1~, end is 4~, double esc is double esc, + //up is A, down is B, left is D, right is C. + //F1 - F12 11~ 12~ 13~ 14~ 15~ 17~ 18~ 19~ 20~ 21~ 23~ 24~ + //static char* specialKeys[]; + enum SPECIALKEY{SPECIALKEYSTART = 0x10000, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, + UP, DOWN, LEFT, RIGHT, DOUBLEESC, INSERT, HOME, END, PGUP, PGDOWN, DELETE}; + + // Virtual Keys: move cursor + bool cursorLeft(); + bool cursorDown(); + bool cursorRight(); + bool cursorUp(); + + // other escape sequence actions + bool normalInput(); + + //double esc pressed + bool doubleEsc(); + + // action parameters + bool clearParam(); + bool paramDigit(); + //function key map + bool functionKey(); +private: + // ********** decoder states **************** + StateOption *current_state_; + int param_; //valid when > 0. + const char* data_; + int inputLength_; + int currentByte_; + QByteArray leftToDecode_; + struct EscStateMachine { + static StateOption normal_state_[], esc_state_[], bracket_state_[]; + }; +}; + +class FQTermUniteState : public QObject, + public FQTermUniteDecode { + Q_OBJECT; +public: + FQTermUniteState(FQTermUniteSessionContext* context); + virtual ~FQTermUniteState() {} + virtual void initialize() = 0; + + +protected: + //util functions + //cursor manipulations + void moveCursorRelative(int dx, int dy); + void moveCursorAbsolute(int x, int y); + void moveCursorHome(); + //To scroll up, dy < 0, scroll down, dy > 0. + void scrollWindow(int dy); + void moveCursorNextLine(); + void saveCursor(); + void restoreCursor(); + + //attr control + enum CHARATTR{DEFAULTATTR = -1, CLEARATTR = 0, BOLD = 1, LOWINTENSITY = 2, UNDERLINE = 4, BLINK = 5, REVERSECOLOR = 7, INVISIBLE = 8}; + void setAttr(int attr); + enum CHARCOLOR{BLACK = 0, RED = 1, GREEN = 2, YELLOW = 3, BLUE = 4, PURPLE = 5, INDIGO = 6, WHITE = 7}; + void setForegroundColor(int color, bool highlight = true); + void setBackgroundColor(int color); + + //clear lines/screen + enum CLEARLINE{CURSORRIGHT = 0, CURSORLEFT = 1, WHOLELINE = 2}; + void clearLine(int part); + enum CLEARSCREEN{CURSORDOWN = 0, CURSORUP = 1, WHOLESCREEN = 2}; + void clearScreen(int part); + + //window setting + void setWindowRange(int startLine, int endLine); + + QByteArray escape(); + QByteArray cursorStr(); + void write(const QByteArray& output); + void quit() {context_->quit();} + FQTermUniteState* setNextState(int state, bool init = true) {return context_->setCurrentState(state, init);} + int row() {return context_->row();} + int column() {return context_->column();} + + + friend struct cursorGuard; + struct cursorGuard { + cursorGuard(FQTermUniteState& state) : state_(state) {state_.saveCursor();} + ~cursorGuard() {state_.restoreCursor();} + private: + FQTermUniteState& state_; + }; +private: + FQTermUniteSessionContext* context_; + int lastState_; +}; + +class FQTermUniteMenu { +public: + FQTermUniteMenu() {current_ = 0;} + virtual ~FQTermUniteMenu() {} +protected: + int addEntry(char key); + int findEntry(char key); + void clearEntry(); + int currentEntry(); + int setCurrentEntry(char key); + int setCurrentIndex(int index); + + int nextEntry(); + int prevEntry(); + virtual void clearPointer(int index) = 0; + virtual void drawPointer(int index) = 0; + virtual void enterEntry() = 0; +private: + std::vector<char> entries_; + int current_; +}; + + +class FQTermWelcomeState : public FQTermUniteState, public FQTermUniteMenu { + Q_OBJECT; +public: + FQTermWelcomeState(FQTermUniteSessionContext* context); + virtual void initialize(); +protected: + virtual bool keyReceived(int key); +private: + virtual void clearPointer(int index); + virtual void drawPointer(int index); + virtual void enterEntry(); +}; + +class FQTermExitState : public FQTermUniteState, public FQTermUniteMenu { + Q_OBJECT; +public: + FQTermExitState(FQTermUniteSessionContext* context); + virtual void initialize(); +protected: + virtual bool keyReceived(int key); +private: + virtual void clearPointer(int index); + virtual void drawPointer(int index); + void enterEntry(); +}; + +class SplittedArticleBuffer { +public: + SplittedArticleBuffer(const QByteArray& utf8Content, int column, int row = 24); + ~SplittedArticleBuffer() {} + int count() {return lines_.size();} + QByteArray& retriveLine(size_t index) {return lines_[index];} +private: + static int findNextLine(const QString& str, int start, int column); + std::vector<QByteArray> lines_; +}; + +//TODO: content should be shared. +//TODO: buffer should be opt-ed. +class FQTermReadingState : public FQTermUniteState { + Q_OBJECT; +public: + FQTermReadingState(FQTermUniteSessionContext* context); + ~FQTermReadingState(); + virtual void initialize(); + void setFile(const QString& filename); + void setReturnState(int state) {returnState_ = state;} +protected: + virtual bool keyReceived(int key); +private: + void drawLines(int count, int yPos); + void drawFooter(); + void adjustLineByDiff(int delta); + SplittedArticleBuffer* saBuffer_; + QByteArray content_; + int currentStartLine_; + int returnState_; +}; + + +class FQTermHelpState : public FQTermUniteState, public FQTermUniteMenu { + Q_OBJECT; +public: + FQTermHelpState(FQTermUniteSessionContext* context); + virtual void initialize(); +protected: + virtual bool keyReceived(int key); +private: + virtual void clearPointer(int index); + virtual void drawPointer(int index); + virtual void enterEntry(); +}; + +} // namespace FQTerm +#endif
\ No newline at end of file diff --git a/src/unite/internal/statebuilder.cpp b/src/unite/internal/statebuilder.cpp new file mode 100644 index 0000000..48ea6f6 --- /dev/null +++ b/src/unite/internal/statebuilder.cpp @@ -0,0 +1,32 @@ + +#include "statebuilder.h" +#include "fqterm.h" +#include "fqterm_path.h" + +#include <QDomDocument> +#include <QFile> + +namespace FQTerm { + +void StateBuilder::BuildState() +{ + QDomDocument domDocument; + QFile welcome(getPath(RESOURCE) + "unite/welcom.xml"); + welcome.open(QIODevice::ReadOnly); + QString errorStr; + int errorLine; + int errorColumn; + domDocument.setContent(welcome.readAll(), true, &errorStr, &errorLine, &errorColumn); + QDomElement root = domDocument.firstChildElement("page"); + if (root.isNull()) + { + + } + QDomAttr a = root.attributeNode("type"); + //cout << a.value() << endl; + + +} + + +}
\ No newline at end of file diff --git a/src/unite/internal/statebuilder.h b/src/unite/internal/statebuilder.h new file mode 100644 index 0000000..f323ecd --- /dev/null +++ b/src/unite/internal/statebuilder.h @@ -0,0 +1,16 @@ + +#ifndef FQTERM_UNITE_STATEBUILDER +#define FQTERM_UNITE_STATEBUILDER + +namespace FQTerm { + +class FQTermState; + +class StateBuilder +{ +public: + void BuildState(); +}; + +} +#endif
\ No newline at end of file diff --git a/src/unite/internal/unite.h b/src/unite/internal/unite.h new file mode 100644 index 0000000..cc614a7 --- /dev/null +++ b/src/unite/internal/unite.h @@ -0,0 +1,35 @@ +/*************************************************************************** +* fqterm, a terminal emulator for both BBS and *nix. * +* Copyright (C) 2008 fqterm development group. * +* * +* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. * +***************************************************************************/ + +#ifndef FQTERM_UNITE_USER +#define FQTERM_UNITE_USER + +namespace FQTerm { +//to make it more clear, a general method to serialize c++ +//classes is needed. +class FQUUser { +public: +private: + +}; + +} //namespace FQTerm + +#endif //FQTERM_UNITE_USER
\ No newline at end of file diff --git a/src/unite/internal/user.cpp b/src/unite/internal/user.cpp new file mode 100644 index 0000000..c5905f8 --- /dev/null +++ b/src/unite/internal/user.cpp @@ -0,0 +1,19 @@ +/*************************************************************************** +* fqterm, a terminal emulator for both BBS and *nix. * +* Copyright (C) 2008 fqterm development group. * +* * +* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. * +***************************************************************************/ diff --git a/src/unite/internal/user.h b/src/unite/internal/user.h new file mode 100644 index 0000000..cc614a7 --- /dev/null +++ b/src/unite/internal/user.h @@ -0,0 +1,35 @@ +/*************************************************************************** +* fqterm, a terminal emulator for both BBS and *nix. * +* Copyright (C) 2008 fqterm development group. * +* * +* 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 St, Fifth Floor, Boston, MA 02110-1301 USA. * +***************************************************************************/ + +#ifndef FQTERM_UNITE_USER +#define FQTERM_UNITE_USER + +namespace FQTerm { +//to make it more clear, a general method to serialize c++ +//classes is needed. +class FQUUser { +public: +private: + +}; + +} //namespace FQTerm + +#endif //FQTERM_UNITE_USER
\ No newline at end of file |