diff options
Diffstat (limited to 'examples/network/infoprotocol')
19 files changed, 1343 insertions, 0 deletions
diff --git a/examples/network/infoprotocol/infoclient/client.cpp b/examples/network/infoprotocol/infoclient/client.cpp new file mode 100644 index 0000000..89bcfd2 --- /dev/null +++ b/examples/network/infoprotocol/infoclient/client.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include <qsocket.h> +#include <qapplication.h> +#include <qtextedit.h> +#include <qlineedit.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qtextstream.h> +#include <qlistbox.h> + +#include "client.h" + + +ClientInfo::ClientInfo( QWidget *parent, const char *name ) : + ClientInfoBase( parent, name ), socket( 0 ) +{ + edHost->setText( "localhost" ); + edPort->setText( QString::number( (uint)infoPort ) ); + + connect( infoList, SIGNAL(selected(const QString&)), SLOT(selectItem(const QString&)) ); + connect( btnConnect, SIGNAL(clicked()), SLOT(connectToServer()) ); + connect( btnBack, SIGNAL(clicked()), SLOT(stepBack()) ); + connect( btnQuit, SIGNAL(clicked()), qApp, SLOT(quit()) ); +} + + +void ClientInfo::connectToServer() +{ + delete socket; + socket = new QSocket( this ); + connect( socket, SIGNAL(connected()), SLOT(socketConnected()) ); + connect( socket, SIGNAL(connectionClosed()), SLOT(socketConnectionClosed()) ); + connect( socket, SIGNAL(readyRead()), SLOT(socketReadyRead()) ); + connect( socket, SIGNAL(error(int)), SLOT(socketError(int)) ); + + socket->connectToHost( edHost->text(), edPort->text().toInt() ); +} + +void ClientInfo::selectItem( const QString& item ) +{ + // item in listBox selected, use LIST or GET depending of the node type. + if ( item.endsWith( "/" ) ) { + sendToServer( List, infoPath->text() + item ); + infoPath->setText( infoPath->text() + item ); + } else + sendToServer( Get, infoPath->text() + item ); +} + +void ClientInfo::stepBack() +{ + // go back (up) in path hierarchy + int i = infoPath->text().findRev( '/', -2 ); + if ( i > 0 ) + infoPath->setText( infoPath->text().left( i + 1 ) ); + else + infoPath->setText( "/" ); + infoList->clear(); + sendToServer( List, infoPath->text() ); +} + + +void ClientInfo::socketConnected() +{ + sendToServer( List, "/" ); +} + +void ClientInfo::sendToServer( Operation op, const QString& location ) +{ + QString line; + switch (op) { + case List: + infoList->clear(); + line = "LIST " + location; + break; + case Get: + line = "GET " + location; + break; + } + infoText->clear(); + QTextStream os(socket); + os << line << "\r\n"; +} + +void ClientInfo::socketReadyRead() +{ + QTextStream stream( socket ); + QString line; + while ( socket->canReadLine() ) { + line = stream.readLine(); + if ( line.startsWith( "500" ) || line.startsWith( "550" ) ) { + infoText->append( tr( "error: " ) + line.mid( 4 ) ); + } else if ( line.startsWith( "212+" ) ) { + infoList->insertItem( line.mid( 6 ) + QString( ( line[ 4 ] == 'D' ) ? "/" : "" ) ); + } else if ( line.startsWith( "213+" ) ) { + infoText->append( line.mid( 4 ) ); + } + } +} + + +void ClientInfo::socketConnectionClosed() +{ + infoText->clear(); + infoText->append( tr( "error: Connection closed by the server\n" ) ); +} + +void ClientInfo::socketError( int code ) +{ + infoText->clear(); + infoText->append( tr( "error: Error number %1 occurred\n" ).arg( code ) ); +} + diff --git a/examples/network/infoprotocol/infoclient/client.h b/examples/network/infoprotocol/infoclient/client.h new file mode 100644 index 0000000..a3e09af --- /dev/null +++ b/examples/network/infoprotocol/infoclient/client.h @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef CLIENT_H +#define CLIENT_H + +#include "clientbase.h" + +class QSocket; +class QTextEdit; +class QLineEdit; +class QListBox; +class QLabel; + +static const Q_UINT16 infoPort = 42417; + +class ClientInfo : public ClientInfoBase +{ + Q_OBJECT +public: + ClientInfo( QWidget *parent = 0, const char *name = 0 ); + +private: + enum Operation { List, Get }; + +private slots: + void connectToServer(); + void selectItem( const QString& item ); + void stepBack(); + void sendToServer( Operation op, const QString& location ); + void socketConnected(); + void socketReadyRead(); + void socketConnectionClosed(); + void socketError( int code ); + +private: + QSocket *socket; +}; + +#endif // CLIENT_H + diff --git a/examples/network/infoprotocol/infoclient/clientbase.ui b/examples/network/infoprotocol/infoclient/clientbase.ui new file mode 100644 index 0000000..3f73c9a --- /dev/null +++ b/examples/network/infoprotocol/infoclient/clientbase.ui @@ -0,0 +1,276 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>ClientInfoBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ClientInfoBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>384</width> + <height>488</height> + </rect> + </property> + <property name="caption"> + <string>Info Client</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout15</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>btnConnect</cstring> + </property> + <property name="text"> + <string>&Connect</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>Host:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>edHost</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2_2</cstring> + </property> + <property name="text"> + <string>Port:</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>edPort</cstring> + </property> + </widget> + </hbox> + </widget> + <widget class="QSplitter"> + <property name="name"> + <cstring>Splitter4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout16</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout14</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>btnBack</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Back</string> + </property> + <property name="toolTip" stdset="0"> + <string>go one step back</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>infoPath</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>/</string> + </property> + <property name="toolTip" stdset="0"> + <string>current path</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QListBox"> + <property name="name"> + <cstring>infoList</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>double click to open</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>Data:</string> + </property> + </widget> + <widget class="QTextEdit"> + <property name="name"> + <cstring>infoText</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </vbox> + </widget> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout12</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name" stdset="0"> + <cstring>Spacer10</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>btnQuit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Quit</string> + </property> + </widget> + <spacer> + <property name="name" stdset="0"> + <cstring>Spacer9</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/examples/network/infoprotocol/infoclient/infoclient.pro b/examples/network/infoprotocol/infoclient/infoclient.pro new file mode 100644 index 0000000..46759dd --- /dev/null +++ b/examples/network/infoprotocol/infoclient/infoclient.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +TARGET = infoclient + +CONFIG += qt warn_on release + +REQUIRES = network full-config nocrosscompiler + +HEADERS = client.h +SOURCES = main.cpp \ + client.cpp +INTERFACES = clientbase.ui diff --git a/examples/network/infoprotocol/infoclient/main.cpp b/examples/network/infoprotocol/infoclient/main.cpp new file mode 100644 index 0000000..cc4950a --- /dev/null +++ b/examples/network/infoprotocol/infoclient/main.cpp @@ -0,0 +1,21 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include <qapplication.h> + +#include "client.h" + +int main( int argc, char** argv ) +{ + QApplication app( argc, argv ); + ClientInfo info; + app.setMainWidget( &info ); + info.show(); + return app.exec(); +} diff --git a/examples/network/infoprotocol/infoserver/infodata.cpp b/examples/network/infoprotocol/infoserver/infodata.cpp new file mode 100644 index 0000000..597f8a3 --- /dev/null +++ b/examples/network/infoprotocol/infoserver/infodata.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include "infodata.h" + + +// we hard code all nodes and data in InfoData class +InfoData::InfoData() : + nodes( 17, TRUE ), data( 17, TRUE ) +{ + nodes.setAutoDelete(TRUE); + data.setAutoDelete(TRUE); + QStringList *item; + + nodes.insert( "/", item = new QStringList( ) ); + (*item) << "D network"; + nodes.insert( "/network/", item = new QStringList() ); + (*item) << "D workstations" << "D printers" << "D fax"; + nodes.insert( "/network/workstations/", item = new QStringList() ); + (*item) << "D nibble" << "D douglas"; + nodes.insert( "/network/workstations/nibble/", item = new QStringList() ); + (*item) << "F os" << "F cpu" << "F memory"; + nodes.insert( "/network/workstations/douglas/", item = new QStringList() ); + (*item) << "F os" << "F cpu" << "F memory"; + nodes.insert( "/network/printers/", item = new QStringList() ); + (*item) << "D overbitt" << "D kroksleiven"; + nodes.insert( "/network/printers/overbitt/", item = new QStringList() ); + (*item) << "D jobs" << "F type"; + nodes.insert( "/network/printers/overbitt/jobs/", item = new QStringList() ); + (*item) << "F job1" << "F job2"; + nodes.insert( "/network/printers/kroksleiven/", item = new QStringList() ); + (*item) << "D jobs" << "F type"; + nodes.insert( "/network/printers/kroksleiven/jobs/", item = new QStringList() ); + nodes.insert( "/network/fax/", item = new QStringList() ); + (*item) << "F last_number"; + + data.insert( "/network/workstations/nibble/os", new QString( "Linux" ) ); + data.insert( "/network/workstations/nibble/cpu", new QString( "AMD Athlon 1000" ) ); + data.insert( "/network/workstations/nibble/memory", new QString( "256 MB" ) ); + data.insert( "/network/workstations/douglas/os", new QString( "Windows 2000" ) ); + data.insert( "/network/workstations/douglas/cpu", new QString( "2 x Intel Pentium III 800" ) ); + data.insert( "/network/workstations/douglas/memory", new QString( "256 MB" ) ); + data.insert( "/network/printers/overbitt/type", new QString( "Lexmark Optra S 1255 PS" ) ); + data.insert( "/network/printers/overbitt/jobs/job1", + new QString( "Qt manual\n" "A4 size\n" "3000 pages" ) ); + data.insert( "/network/printers/overbitt/jobs/job2", + new QString( "Monthly report\n" "Letter size\n" "24 pages\n" "8 copies" ) ); + data.insert( "/network/printers/kroksleiven/type", new QString( "HP C LaserJet 4500-PS" ) ); + data.insert( "/network/fax/last_number", new QString( "22 22 22 22" ) ); +} + +QStringList InfoData::list( QString path, bool *found ) const +{ + if ( !path.endsWith( "/" ) ) + path += "/"; + if ( !path.startsWith( "/" ) ) + path = "/" + path; + QStringList *list = nodes[ path ]; + if ( list ) { + *found = TRUE; + return *list; + } else { + *found = FALSE; + QStringList empty; + return empty; + } +} + +QString InfoData::get( QString path, bool *found ) const +{ + if ( !path.startsWith( "/" ) ) + path = "/" + path; + QString *file = data[ path ]; + if ( file ) { + *found = TRUE; + return *file; + } else { + *found = FALSE; + QString empty; + return empty; + } +} diff --git a/examples/network/infoprotocol/infoserver/infodata.h b/examples/network/infoprotocol/infoserver/infodata.h new file mode 100644 index 0000000..0189332 --- /dev/null +++ b/examples/network/infoprotocol/infoserver/infodata.h @@ -0,0 +1,31 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef INFODATA_H +#define INFODATA_H + +#include <qdict.h> +#include <qstringlist.h> + + +// The InfoData class manages data, organized in tree structure. +class InfoData +{ +public: + InfoData(); + QStringList list( QString path, bool *found ) const; + QString get( QString path, bool *found ) const; + +private: + QDict< QStringList > nodes; + QDict< QString > data; +}; + +#endif // INFODATA_H + diff --git a/examples/network/infoprotocol/infoserver/infoserver.pro b/examples/network/infoprotocol/infoserver/infoserver.pro new file mode 100644 index 0000000..3d79aef --- /dev/null +++ b/examples/network/infoprotocol/infoserver/infoserver.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = infoserver + +CONFIG += qt warn_on release + +REQUIRES = network full-config nocrosscompiler + +HEADERS = server.h \ + infodata.h +SOURCES = main.cpp \ + server.cpp \ + infodata.cpp +INTERFACES = serverbase.ui diff --git a/examples/network/infoprotocol/infoserver/main.cpp b/examples/network/infoprotocol/infoserver/main.cpp new file mode 100644 index 0000000..fd0e8e3 --- /dev/null +++ b/examples/network/infoprotocol/infoserver/main.cpp @@ -0,0 +1,22 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include <qapplication.h> + +#include "server.h" + +int main( int argc, char** argv ) +{ + QApplication app( argc, argv ); + Q_UINT16 port = ( argc > 1 ) ? QString( argv[ 1 ] ).toInt() : infoPort; + ServerInfo info( port, 0, "server info" ); + app.setMainWidget( &info ); + info.show(); + return app.exec(); +} diff --git a/examples/network/infoprotocol/infoserver/server.cpp b/examples/network/infoprotocol/infoserver/server.cpp new file mode 100644 index 0000000..f3815ae --- /dev/null +++ b/examples/network/infoprotocol/infoserver/server.cpp @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include <qtextview.h> +#include <qpushbutton.h> +#include <qtextstream.h> +#include <qapplication.h> +#include <qmessagebox.h> +#include <stdlib.h> + +#include "server.h" + + + +ServerInfo::ServerInfo( Q_UINT16 port, QWidget *parent, const char *name ) : + ServerInfoBase( parent, name ) +{ + SimpleServer *server = new SimpleServer( port, this, "simple server" ); + connect( server, SIGNAL(newConnect()), SLOT(newConnect()) ); + connect( btnQuit, SIGNAL(clicked()), qApp, SLOT(quit()) ); +} + +void ServerInfo::newConnect() +{ + infoText->append( tr( "New connection\n" ) ); +} + + +SimpleServer::SimpleServer( Q_UINT16 port, QObject* parent, const char *name ) : + QServerSocket( port, 1, parent, name ) +{ + if ( !ok() ) { + QMessageBox::critical( 0, tr( "Error" ), tr( "Failed to bind to port %1" ).arg( port ) ); + exit(1); + } +} + +void SimpleServer::newConnection( int socket ) +{ + (void)new ClientSocket( socket, &info, this, "client socket" ); + emit newConnect(); +} + + +ClientSocket::ClientSocket( int sock, InfoData *i, QObject *parent, const char *name ) : + QSocket( parent, name ), info( i ) +{ + connect( this, SIGNAL(readyRead()), SLOT(readClient()) ); + connect( this, SIGNAL(connectionClosed()), SLOT(connectionClosed()) ); + setSocket( sock ); +} + +void ClientSocket::readClient() +{ + QTextStream stream( this ); + QStringList answer; + while ( canReadLine() ) { + stream << processCommand( stream.readLine() ); + } +} + +QString ClientSocket::processCommand( const QString& command ) +{ + QString answer; + QString com = command.simplifyWhiteSpace (); + if ( com.startsWith( "LIST" ) ) { + bool ok; + QStringList nodes = info->list( com.mid( 5 ), &ok ); + if ( ok ) { + for ( QStringList::Iterator it = nodes.begin(); it != nodes.end(); ++it ) + answer += "212+" + *it + "\r\n"; + answer += "212 \r\n"; + } else + answer += "550 Invalid path\r\n"; + } else if ( com.startsWith( "GET " ) ) { + bool ok; + QStringList data = QStringList::split( '\n', info->get( com.mid( 4 ), &ok ), TRUE ); + if ( ok ) { + for ( QStringList::Iterator it = data.begin(); it != data.end(); ++it ) + answer += "213+" + *it + "\r\n"; + answer += "213 \r\n"; + } else + answer += "550 Info not found\r\n"; + } else + answer += "500 Syntax error\r\n"; + + return answer; +} + +void ClientSocket::connectionClosed() +{ + delete this; +} diff --git a/examples/network/infoprotocol/infoserver/server.h b/examples/network/infoprotocol/infoserver/server.h new file mode 100644 index 0000000..fa07b93 --- /dev/null +++ b/examples/network/infoprotocol/infoserver/server.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef SERVER_H +#define SERVER_H + +#include <qsocket.h> +#include <qserversocket.h> + +#include "infodata.h" +#include "serverbase.h" + +static const Q_UINT16 infoPort = 42417; + + +/* + The ServerInfo class provides a small GUI for the server. It also creates the + SimpleServer and as a result the server. +*/ +class ServerInfo : public ServerInfoBase +{ + Q_OBJECT +public: + ServerInfo( Q_UINT16 port = infoPort, QWidget *parent = 0, const char *name = 0 ); + +private slots: + void newConnect(); +}; + + +class SimpleServer : public QServerSocket +{ + Q_OBJECT +public: + SimpleServer( Q_UINT16 port = infoPort, QObject* parent = 0, const char *name = 0 ); + void newConnection( int socket ); + +signals: + void newConnect(); + +private: + InfoData info; +}; + + +class ClientSocket : public QSocket +{ + Q_OBJECT +public: + ClientSocket( int sock, InfoData *i, QObject *parent = 0, const char *name = 0 ); + +private slots: + void readClient(); + void connectionClosed(); + +private: + QString processCommand( const QString& command ); + InfoData *info; +}; + + +#endif //SERVER_H + diff --git a/examples/network/infoprotocol/infoserver/serverbase.ui b/examples/network/infoprotocol/infoserver/serverbase.ui new file mode 100644 index 0000000..12998da --- /dev/null +++ b/examples/network/infoprotocol/infoserver/serverbase.ui @@ -0,0 +1,117 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>ServerInfoBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ServerInfoBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>272</width> + <height>282</height> + </rect> + </property> + <property name="caption"> + <string>Info Server</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>This is a small Information Server. +Accepting client requests...</string> + </property> + <property name="alignment"> + <set>AlignCenter</set> + </property> + </widget> + <widget class="QTextEdit"> + <property name="name"> + <cstring>infoText</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name" stdset="0"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>btnQuit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Quit</string> + </property> + </widget> + <spacer> + <property name="name" stdset="0"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </vbox> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/examples/network/infoprotocol/infourlclient/client.cpp b/examples/network/infoprotocol/infourlclient/client.cpp new file mode 100644 index 0000000..712090f --- /dev/null +++ b/examples/network/infoprotocol/infourlclient/client.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include <qapplication.h> +#include <qtextedit.h> +#include <qpushbutton.h> +#include <qfiledialog.h> + +#include "qip.h" +#include "client.h" + + + + +ClientInfo::ClientInfo( QWidget *parent, const char *name ) : + ClientInfoBase( parent, name ) +{ + connect( btnOpen, SIGNAL(clicked()), SLOT(downloadFile()) ); + connect( btnQuit, SIGNAL(clicked()), qApp, SLOT(quit()) ); + connect( &op, SIGNAL( data( const QByteArray &, QNetworkOperation * ) ), + this, SLOT( newData( const QByteArray & ) ) ); +} + +void ClientInfo::downloadFile() +{ + // under Windows you must not use the native file dialog + QString file = getOpenFileName(); + if ( !file.isEmpty() ) { + infoText->clear(); + // download the data + op = file; + op.get(); + } +} + +QString ClientInfo::getOpenFileName() +{ + static QString workingDirectory( "qip://localhost/" ); + + QFileDialog dlg( workingDirectory, QString::null, 0, 0, TRUE ); + dlg.setCaption( QFileDialog::tr( "Open" ) ); + dlg.setMode( QFileDialog::ExistingFile ); + QString result; + if ( dlg.exec() == QDialog::Accepted ) { + result = dlg.selectedFile(); + workingDirectory = dlg.url(); + } + return result; +} + +void ClientInfo::newData( const QByteArray &ba ) +{ + infoText->append( QString::fromUtf8( ba ) ); +} diff --git a/examples/network/infoprotocol/infourlclient/client.h b/examples/network/infoprotocol/infourlclient/client.h new file mode 100644 index 0000000..ca8340b --- /dev/null +++ b/examples/network/infoprotocol/infourlclient/client.h @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef CLIENT_H +#define CLIENT_H + +#include <qurloperator.h> + +#include "clientbase.h" + + +class ClientInfo : public ClientInfoBase +{ + Q_OBJECT + +public: + ClientInfo( QWidget *parent = 0, const char *name = 0 ); + +private slots: + void downloadFile(); + void newData( const QByteArray &ba ); + +private: + QUrlOperator op; + QString getOpenFileName(); +}; + +#endif // CLIENT_H + diff --git a/examples/network/infoprotocol/infourlclient/clientbase.ui b/examples/network/infoprotocol/infourlclient/clientbase.ui new file mode 100644 index 0000000..e18b9a3 --- /dev/null +++ b/examples/network/infoprotocol/infourlclient/clientbase.ui @@ -0,0 +1,118 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>ClientInfoBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ClientInfoBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>325</width> + <height>279</height> + </rect> + </property> + <property name="caption"> + <string>Info Client Protocol</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>btnOpen</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Open</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>open data</string> + </property> + </widget> + <spacer> + <property name="name" stdset="0"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>btnQuit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Quit</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>Data:</string> + </property> + </widget> + <widget class="QTextEdit"> + <property name="name"> + <cstring>infoText</cstring> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> + </vbox> +</widget> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/examples/network/infoprotocol/infourlclient/infourlclient.pro b/examples/network/infoprotocol/infourlclient/infourlclient.pro new file mode 100644 index 0000000..219083d --- /dev/null +++ b/examples/network/infoprotocol/infourlclient/infourlclient.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = infourlclient + +CONFIG += qt warn_on release + +REQUIRES = network full-config nocrosscompiler + +HEADERS = client.h \ + qip.h +SOURCES = main.cpp \ + client.cpp \ + qip.cpp +INTERFACES = clientbase.ui diff --git a/examples/network/infoprotocol/infourlclient/main.cpp b/examples/network/infoprotocol/infourlclient/main.cpp new file mode 100644 index 0000000..677f8a1 --- /dev/null +++ b/examples/network/infoprotocol/infourlclient/main.cpp @@ -0,0 +1,23 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include <qapplication.h> + +#include "qip.h" +#include "client.h" + +int main( int argc, char** argv ) +{ + QApplication app( argc, argv ); + QNetworkProtocol::registerNetworkProtocol( "qip", new QNetworkProtocolFactory< Qip > ); + ClientInfo info; + app.setMainWidget( &info ); + info.show(); + return app.exec(); +} diff --git a/examples/network/infoprotocol/infourlclient/qip.cpp b/examples/network/infoprotocol/infourlclient/qip.cpp new file mode 100644 index 0000000..ef71ea3 --- /dev/null +++ b/examples/network/infoprotocol/infourlclient/qip.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#include <qsocket.h> +#include <qurlinfo.h> +#include <qurloperator.h> +#include <qtextstream.h> + +#include "qip.h" + + +Qip::Qip() +{ + state = Start; + socket = new QSocket( this ); + connect( socket, SIGNAL(connected()), SLOT(socketConnected()) ); + connect( socket, SIGNAL(connectionClosed()), SLOT(socketConnectionClosed()) ); + connect( socket, SIGNAL(readyRead()), SLOT(socketReadyRead()) ); + connect( socket, SIGNAL(error(int)), SLOT(socketError(int)) ); +} + +int Qip::supportedOperations() const +{ + return OpListChildren | OpGet; +} + +bool Qip::checkConnection( QNetworkOperation * ) +{ + if ( socket->isOpen() ) + return TRUE; + + // don't call connectToHost() if we are already trying to connect + if ( socket->state() == QSocket::Connecting ) + return FALSE; + + socket->connectToHost( url()->host(), url()->port() != -1 ? url()->port() : infoPort ); + return FALSE; +} + +void Qip::operationListChildren( QNetworkOperation * ) +{ + QTextStream os(socket); + os << "LIST " + url()->path() + "\r\n"; + operationInProgress()->setState( StInProgress ); +} + +void Qip::operationGet( QNetworkOperation * ) +{ + QTextStream os(socket); + os << "GET " + url()->path() + "\r\n"; + operationInProgress()->setState( StInProgress ); +} + +void Qip::socketConnected() +{ + if ( url() ) + emit connectionStateChanged( ConConnected, tr( "Connected to host %1" ).arg( url()->host() ) ); + else + emit connectionStateChanged( ConConnected, tr ("Connected to host" ) ); +} + +void Qip::socketConnectionClosed() +{ + if ( url() ) + emit connectionStateChanged( ConClosed, tr( "Connection to %1 closed" ).arg( url()->host() ) ); + else + emit connectionStateChanged( ConClosed, tr ("Connection closed" ) ); +} + +void Qip::socketError( int code ) +{ + if ( code == QSocket::ErrHostNotFound || + code == QSocket::ErrConnectionRefused ) { + error( ErrHostNotFound, tr( "Host not found or couldn't connect to: %1\n" ).arg( url()->host() ) ); + } else + error( ErrUnsupported, tr( "Error" ) ); +} + +void Qip::socketReadyRead() +{ + // read from the server + QTextStream stream( socket ); + QString line; + while ( socket->canReadLine() ) { + line = stream.readLine(); + if ( line.startsWith( "500" ) ) { + error( ErrValid, line.mid( 4 ) ); + } else if ( line.startsWith( "550" ) ) { + error( ErrFileNotExisting, line.mid( 4 ) ); + } else if ( line.startsWith( "212+" ) ) { + if ( state != List ) { + state = List; + emit start( operationInProgress() ); + } + QUrlInfo inf; + inf.setName( line.mid( 6 ) + QString( ( line[ 4 ] == 'D' ) ? "/" : "" ) ); + inf.setDir( line[ 4 ] == 'D' ); + inf.setSymLink( FALSE ); + inf.setFile( line[ 4 ] == 'F' ); + inf.setWritable( FALSE ); + inf.setReadable( TRUE ); + emit newChild( inf, operationInProgress() ); + } else if ( line.startsWith( "213+" ) ) { + state = Data; + emit data( line.mid( 4 ).utf8(), operationInProgress() ); + } + if( line[3] == ' ' && state != Start) { + state = Start; + operationInProgress()->setState( StDone ); + emit finished( operationInProgress() ); + } + } +} + +void Qip::error( int code, const QString& msg ) +{ + if ( operationInProgress() ) { + operationInProgress()->setState( StFailed ); + operationInProgress()->setErrorCode( code ); + operationInProgress()->setProtocolDetail( msg ); + clearOperationQueue(); + emit finished( operationInProgress() ); + } + state = Start; +} + diff --git a/examples/network/infoprotocol/infourlclient/qip.h b/examples/network/infoprotocol/infourlclient/qip.h new file mode 100644 index 0000000..339e46b --- /dev/null +++ b/examples/network/infoprotocol/infourlclient/qip.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of an example program for Qt. This example +** program may be used, distributed and modified without limitation. +** +*****************************************************************************/ + +#ifndef QIP_H +#define QIP_H + +#include <qnetworkprotocol.h> + +class QSocket; + +static const Q_UINT16 infoPort = 42417; + + +class Qip : public QNetworkProtocol +{ + Q_OBJECT + +public: + Qip(); + virtual int supportedOperations() const; + +protected: + virtual void operationListChildren( QNetworkOperation *op ); + virtual void operationGet( QNetworkOperation *op ); + virtual bool checkConnection( QNetworkOperation *op ); + +private slots: + void socketConnected(); + void socketReadyRead(); + void socketConnectionClosed(); + void socketError( int code ); + +private: + QSocket *socket; + enum State { Start, List, Data } state; + void error( int code, const QString& msg ); +}; + + + +#endif // QIP_H + |