Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

mainwindow.cpp

Go to the documentation of this file.
00001 /**********************************************************************
00002 ** Copyright (C) 2002-2004 Michael 'Mickey' Lauer.  All rights reserved.
00003 **
00004 ** This file is part of Wellenreiter II.
00005 **
00006 ** This file may be distributed and/or modified under the terms of the
00007 ** GNU General Public License version 2 as published by the Free Software
00008 ** Foundation and appearing in the file LICENSE.GPL included in the
00009 ** packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00013 **
00014 **********************************************************************/
00015 
00016 #include "configwindow.h"
00017 #include "gps.h"
00018 #include "logwindow.h"
00019 #include "packetview.h"
00020 #include "mainwindow.h"
00021 #include "wellenreiter.h"
00022 #include "scanlist.h"
00023 
00024 /* OPIE */
00025 #ifdef QWS
00026 #include <opie2/oresource.h>
00027 #include <opie2/odebug.h>
00028 #include <opie2/ofiledialog.h>
00029 #else
00030 #include "resource.h"
00031 #include <qapplication.h>
00032 #include <qfiledialog.h>
00033 #endif
00034 
00035 /* QT */
00036 #include <qcombobox.h>
00037 #include <qdatastream.h>
00038 #include <qfile.h>
00039 #include <qfileinfo.h>
00040 #include <qlabel.h>
00041 #include <qlayout.h>
00042 #include <qlineedit.h>
00043 #include <qiconset.h>
00044 #include <qmenubar.h>
00045 #include <qmessagebox.h>
00046 #include <qpopupmenu.h>
00047 #include <qpushbutton.h>
00048 #include <qstatusbar.h>
00049 #include <qspinbox.h>
00050 #include <qtextstream.h>
00051 #include <qtoolbutton.h>
00052 #include <qwhatsthis.h>
00053 
00054 /* STD */
00055 #include <unistd.h>
00056 
00057 using namespace Opie::Core;
00058 using namespace Opie::Net;
00059 using namespace Opie::Ui;
00060 
00061 WellenreiterMainWindow::WellenreiterMainWindow( QWidget * parent, const char * name, WFlags f )
00062            :QMainWindow( parent, name, f )
00063 {
00064     cw = new WellenreiterConfigWindow( this );
00065     mw = new Wellenreiter( this );
00066     mw->setConfigWindow( cw );
00067     setCentralWidget( mw );
00068 
00069     // setup application icon
00070 
00071     setIcon( Opie::Core::OResource::loadPixmap( "wellenreiter/appicon-trans", Opie::Core::OResource::SmallIcon ) );
00072     #ifndef QWS
00073     setIconText( "Wellenreiter/X11" );
00074     #endif
00075 
00076     // setup tool buttons
00077     bool useBigIcon = qApp->desktop()->size().width() > 330;
00078 
00079     startButton = new QToolButton( 0 );
00080     startButton->setUsesBigPixmap( useBigIcon );
00081     QWhatsThis::add( startButton, tr( "Click here to start scanning." ) );
00082     #ifdef QWS
00083     startButton->setAutoRaise( true );
00084     #endif
00085     startButton->setIconSet( Opie::Core::OResource::loadPixmap( "wellenreiter/SearchIcon", Opie::Core::OResource::SmallIcon ) );
00086     startButton->setEnabled( false );
00087     connect( startButton, SIGNAL( clicked() ), mw, SLOT( startClicked() ) );
00088 
00089     stopButton = new QToolButton( 0 );
00090     stopButton->setUsesBigPixmap( useBigIcon );
00091     QWhatsThis::add( stopButton, tr( "Click here to stop scanning." ) );
00092     #ifdef QWS
00093     stopButton->setAutoRaise( true );
00094     #endif
00095     stopButton->setIconSet( Opie::Core::OResource::loadPixmap( "wellenreiter/CancelIcon", Opie::Core::OResource::SmallIcon ) );
00096     stopButton->setEnabled( false );
00097     connect( stopButton, SIGNAL( clicked() ), mw, SLOT( stopClicked() ) );
00098 
00099     QToolButton* d = new QToolButton( 0 );
00100     d->setUsesBigPixmap( useBigIcon );
00101     QWhatsThis::add( d, tr( "Click here to open the configure dialog." ) ),
00102     #ifdef QWS
00103     d->setAutoRaise( true );
00104     #endif
00105     d->setIconSet( Opie::Core::OResource::loadPixmap( "wellenreiter/SettingsIcon", Opie::Core::OResource::SmallIcon ) );
00106     connect( d, SIGNAL( clicked() ), this, SLOT( showConfigure() ) );
00107 
00108     uploadButton = new QToolButton( 0 );
00109     uploadButton->setUsesBigPixmap( useBigIcon );
00110     QWhatsThis::add( uploadButton, tr( "Click here to upload a capture session." ) );
00111     #ifdef QWS
00112     uploadButton->setAutoRaise( true );
00113     #endif
00114     uploadButton->setIconSet( Opie::Core::OResource::loadPixmap( "up", Opie::Core::OResource::SmallIcon ) );
00115     uploadButton->setEnabled( false );
00116     //uploadButton->setEnabled( true ); // DEBUGGING
00117     connect( uploadButton, SIGNAL( clicked() ), this, SLOT( uploadSession() ) );
00118 
00119     // setup menu bar
00120 
00121     int id;
00122 
00123     QMenuBar* mb = menuBar();
00124 
00125     QPopupMenu* fileSave = new QPopupMenu( mb );
00126     fileSave->insertItem( tr( "&Session..." ), this, SLOT( fileSaveSession() ) );
00127     fileSave->insertItem( tr( "&Text Log..." ), this, SLOT( fileSaveLog() ) );
00128     fileSave->insertItem( tr( "&Hex Log..." ), this, SLOT( fileSaveHex() ) );
00129 
00130     QPopupMenu* fileLoad = new QPopupMenu( mb );
00131     fileLoad->insertItem( tr( "&Session..." ), this, SLOT( fileLoadSession() ) );
00132     //fileLoad->insertItem( "&Log", this, SLOT( fileLoadLog() ) );
00133 
00134     QPopupMenu* file = new QPopupMenu( mb );
00135     file->insertItem( tr( "&New" ), this, SLOT( fileNew() ) );
00136     id = file->insertItem( tr( "&Load" ), fileLoad );
00137     file->insertItem( tr( "&Save" ), fileSave );
00138     file->insertSeparator();
00139     uploadID = file->insertItem( tr( "&Upload Session" ), this, SLOT( uploadSession() ) );
00140     file->insertSeparator();
00141     file->insertItem( tr( "&Exit" ), qApp, SLOT( quit() ) );
00142 
00143     QPopupMenu* sniffer = new QPopupMenu( mb );
00144     sniffer->insertItem( tr( "&Configure..." ), this, SLOT( showConfigure() ) );
00145     sniffer->insertSeparator();
00146     startID = sniffer->insertItem( tr( "&Start" ), mw, SLOT( startClicked() ) );
00147     sniffer->setItemEnabled( startID, false );
00148     stopID = sniffer->insertItem( tr( "Sto&p" ), mw, SLOT( stopClicked() ) );
00149     sniffer->setItemEnabled( stopID, false );
00150 
00151     QPopupMenu* view = new QPopupMenu( mb );
00152     view->insertItem( tr( "&Expand All" ), this, SLOT( viewExpandAll() ) );
00153     view->insertItem( tr( "&Collapse All" ), this, SLOT( viewCollapseAll() ) );
00154 
00155     QPopupMenu* demo = new QPopupMenu( mb );
00156     demo->insertItem( tr( "&Add something" ), this, SLOT( demoAddStations() ) );
00157     //demo->insertItem( tr( "&Read from GPSd" ), this, SLOT( demoReadFromGps() ) );
00158 
00159     id = mb->insertItem( tr( "&File" ), file );
00160 
00161     id = mb->insertItem( tr( "&View" ), view );
00162     //mb->setItemEnabled( id, false );
00163 
00164     id = mb->insertItem( tr( "&Sniffer" ), sniffer );
00165 
00166     id = mb->insertItem( tr( "&Demo" ), demo );
00167     mb->setItemEnabled( id, true );
00168     mb->setItemEnabled( uploadID, false );
00169 
00170     #ifdef QWS
00171     mb->insertItem( startButton );
00172     mb->insertItem( stopButton );
00173     mb->insertItem( uploadButton );
00174     mb->insertItem( d );
00175     #else // Qt3 changed the insertion order. It's now totally random :(
00176     mb->insertItem( d );
00177     mb->insertItem( uploadButton );
00178     mb->insertItem( stopButton );
00179     mb->insertItem( startButton );
00180     #endif
00181 
00182     updateToolButtonState();
00183 
00184     // setup status bar (for now only on X11)
00185 
00186     #ifndef QWS
00187     statusBar()->message( tr( "Ready." ) );
00188     #endif
00189 
00190     connect( mw, SIGNAL( startedSniffing() ), this, SLOT( changedSniffingState() ) );
00191     connect( mw, SIGNAL( stoppedSniffing() ), this, SLOT( changedSniffingState() ) );
00192 };
00193 
00194 
00195 
00196 void WellenreiterMainWindow::showConfigure()
00197 {
00198     odebug << "show configure..." << oendl;
00199     cw->setCaption( tr( "Configure" ) );
00200     int result = QPEApplication::execDialog( cw );
00201 
00202     if ( result ) updateToolButtonState();
00203 }
00204 
00205 
00206 void WellenreiterMainWindow::updateToolButtonState()
00207 {
00208     const QString& interface = cw->interfaceName->currentText();
00209     const int cardtype = cw->driverType();
00210 
00211     if ( ( interface != "<select>" ) && ( cardtype != 0 ) )
00212     {
00213         startButton->setEnabled( true );
00214         menuBar()->setItemEnabled( startID, true );
00215     }
00216     else
00217     {
00218         startButton->setEnabled( false );
00219         menuBar()->setItemEnabled( startID, false );
00220     }
00221 }
00222 
00223 
00224 void WellenreiterMainWindow::changedSniffingState()
00225 {
00226     startButton->setEnabled( !mw->sniffing );
00227     menuBar()->setItemEnabled( startID, !mw->sniffing );
00228     stopButton->setEnabled( mw->sniffing );
00229     menuBar()->setItemEnabled( stopID, mw->sniffing );
00230 
00231     if ( !mw->sniffing && QFile::exists( mw->dumpname ) )
00232     {
00233         menuBar()->setItemEnabled( uploadID, true );
00234         uploadButton->setEnabled( true );
00235     }
00236 }
00237 
00238 
00239 WellenreiterMainWindow::~WellenreiterMainWindow()
00240 {
00241     odebug << "Wellenreiter: bye." << oendl;
00242 };
00243 
00244 
00245 void WellenreiterMainWindow::demoAddStations()
00246 {
00247     //mw = 0; // test SIGSEGV handling
00248 
00249     mw->netView()->addNewItem( "managed", "Vanille", OMacAddress::fromString("00:00:20:EF:A6:43"), true, 6, 80, GpsLocation( 39.8794, -94.0936) );
00250     mw->netView()->addNewItem( "managed", "Vanille", OMacAddress::fromString("00:30:6D:EF:A6:23"), true, 11, 10, GpsLocation( 0.0, 0.0 ) );
00251     mw->netView()->addNewItem( "adhoc", "ELAN", OMacAddress::fromString("00:03:F8:E7:16:22"), false, 3, 10, GpsLocation( 5.5, 2.3 ) );
00252     mw->netView()->addNewItem( "adhoc", "ELAN", OMacAddress::fromString("00:04:01:E7:56:62"), false, 3, 15, GpsLocation( 2.3, 5.5 ) );
00253     mw->netView()->addNewItem( "adhoc", "ELAN", OMacAddress::fromString("00:05:8E:E7:56:E2"), false, 3, 20, GpsLocation( -10.0, -20.5 ) );
00254 }
00255 
00256 
00257 void WellenreiterMainWindow::demoReadFromGps()
00258 {
00259     WellenreiterConfigWindow* configwindow = WellenreiterConfigWindow::instance();
00260     GPS* gps = new GPS( this );
00261     odebug << "Wellenreiter::demoReadFromGps(): url=gps://" << configwindow->gpsdHost->currentText() << ":" << configwindow->gpsdPort->value() << "/" << oendl;
00262     gps->open( configwindow->gpsdHost->currentText(), configwindow->gpsdPort->value() );
00263     GpsLocation loc = gps->position();
00264     QMessageBox::information( this, "Wellenreiter/Opie", tr( "GPS said:\n%1" ).arg( loc.dmsPosition() ) );
00265     delete gps;
00266 }
00267 
00268 
00269 QString WellenreiterMainWindow::getFileName( bool save )
00270 {
00271     QMap<QString, QStringList> map;
00272     map.insert( tr("All"), QStringList() );
00273     QStringList text;
00274     text << "text/*";
00275     map.insert( tr("Text"), text );
00276     text << "*";
00277     map.insert( tr("All"), text );
00278 
00279     QString str;
00280     if ( save )
00281     {
00282         #ifdef QWS
00283         str = OFileDialog::getSaveFileName( 2, "/", QString::null, map );
00284         #else
00285         str = QFileDialog::getSaveFileName();
00286         #endif
00287         if ( str.isEmpty() /*|| QFileInfo(str).isDir()*/ )
00288             return "";
00289     }
00290     else
00291     {
00292         #ifdef QWS
00293         str = OFileDialog::getOpenFileName( 2, "/", QString::null, map );
00294         #else
00295         str = QFileDialog::getOpenFileName();
00296         #endif
00297         if ( str.isEmpty() || !QFile(str).exists() || QFileInfo(str).isDir() )
00298             return "";
00299     }
00300     return str;
00301 }
00302 
00303 
00304 void WellenreiterMainWindow::fileSaveLog()
00305 {
00306     QString fname = getFileName( true );
00307     if ( !fname.isEmpty() )
00308     {
00309         QFile f( fname );
00310         if ( f.open(IO_WriteOnly) )
00311         {
00312             QTextStream t( &f );
00313             t << mw->logWindow()->getLog();
00314             f.close();
00315             odebug << "Saved log to file '" << fname << "'" << oendl;
00316         }
00317         else
00318         {
00319             odebug << "Problem saving log to file '" << fname << "'" << oendl;
00320         }
00321     }
00322 }
00323 
00324 void WellenreiterMainWindow::fileSaveSession()
00325 {
00326     QString fname = getFileName( true );
00327     if ( !fname.isEmpty() )
00328     {
00329 
00330         QFile f( fname );
00331         if ( f.open(IO_WriteOnly) )
00332         {
00333             QDataStream t( &f );
00334             t << *mw->netView();
00335             f.close();
00336             odebug << "Saved session to file '" << fname << "'" << oendl;
00337         }
00338         else
00339         {
00340             odebug << "Problem saving session to file '" << fname << "'" << oendl;
00341         }
00342     }
00343 }
00344 
00345 void WellenreiterMainWindow::fileSaveHex()
00346 {
00347     #warning DOES NOT WORK AT THE MOMENT
00348     /*
00349     QString fname = getFileName( true );
00350     if ( !fname.isEmpty() )
00351     {
00352         QFile f( fname );
00353         if ( f.open(IO_WriteOnly) )
00354         {
00355             QTextStream t( &f );
00356             t << mw->hexWindow()->getLog();
00357             f.close();
00358             odebug << "Saved hex log to file '" << fname << "'" << oendl;
00359         }
00360         else
00361         {
00362             odebug << "Problem saving hex log to file '" << fname << "'" << oendl;
00363         }
00364     }
00365     */
00366 }
00367 
00368 void WellenreiterMainWindow::fileLoadSession()
00369 {
00370     QString fname = getFileName( false );
00371     if ( !fname.isEmpty() )
00372     {
00373         QFile f( fname );
00374         if ( f.open(IO_ReadOnly) )
00375         {
00376             QDataStream t( &f );
00377             t >> *mw->netView();
00378             f.close();
00379             odebug << "Loaded session from file '" << fname << "'" << oendl;
00380         }
00381         else
00382         {
00383             odebug << "Problem loading session from file '" << fname << "'" << oendl;
00384         }
00385     }
00386 }
00387 
00388 
00389 void WellenreiterMainWindow::fileNew()
00390 {
00391     mw->netView()->clear();
00392     mw->logWindow()->clear();
00393     mw->hexWindow()->clear();
00394 }
00395 
00396 
00397 void WellenreiterMainWindow::closeEvent( QCloseEvent* e )
00398 {
00399     if ( mw->isDaemonRunning() )
00400     {
00401         QMessageBox::warning( this, "Wellenreiter/Opie",
00402                               tr( "Sniffing in progress!\nPlease stop sniffing before closing." ) );
00403         e->ignore();
00404     }
00405     else
00406     {
00407         QMainWindow::closeEvent( e );
00408     }
00409 }
00410 
00411 static const char* CAP_hostname = "www.vanille.de";
00412 
00413 #include <netdb.h>
00414 #include <unistd.h>
00415 #include <sys/types.h>
00416 #include <sys/socket.h>
00417 
00418 void WellenreiterMainWindow::uploadSession()
00419 {
00420     QLineEdit* from;
00421     QLineEdit* location;
00422     QLineEdit* comments;
00423     QPushButton* accept;
00424     QPushButton* reject;
00425 
00426     QDialog* d = new QDialog( 0, "session upload", true );
00427     d->setCaption( tr( "Upload Session" ) );
00428     QGridLayout* g = new QGridLayout( d, 4, 2, 3 );
00429     g->addWidget( new QLabel( tr( "From: " ), d ), 0, 0 );
00430     g->addWidget( from = new QLineEdit( d ), 0, 1 );
00431     g->addWidget( new QLabel( tr( "Location: " ), d ), 1, 0 );
00432     g->addWidget( location = new QLineEdit( d ), 1, 1 );
00433     g->addWidget( new QLabel( tr( "Comments: " ), d ), 2, 0 );
00434     g->addWidget( comments = new QLineEdit( d ), 2, 1 );
00435     g->addWidget( accept = new QPushButton( tr( "&Ok" ), d ), 3, 0 );
00436     g->addWidget( reject = new QPushButton( tr( "&Cancel" ), d ), 3, 1 );
00437     accept->setDefault( true );
00438     accept->setAutoDefault( true );
00439     from->setText( "WL II User" );
00440     location->setText( "WL II Location" );
00441     comments->setText( "No Comments." );
00442     connect( accept, SIGNAL( clicked() ), d, SLOT( accept() ) );
00443     connect( reject, SIGNAL( clicked() ), d, SLOT( reject() ) );
00444     int result = d->exec();
00445 
00446     if ( !result )
00447     {
00448         odebug << "Session upload cancelled :(" << oendl;
00449         return;
00450     }
00451 
00452     odebug << "Starting upload..." << oendl;
00453 
00454     struct sockaddr_in raddr;
00455     struct hostent *rhost_info;
00456     int sock = -1;
00457     bool ok = false;
00458 
00459     rhost_info = (struct hostent *) ::gethostbyname( CAP_hostname );
00460     if ( rhost_info )
00461     {
00462 
00463 
00464         if ( !QFile::exists( mw->captureFileName() ) )
00465         {
00466             QMessageBox::warning( 0, tr( "Error" ), tr( "<p>Logfile '%1' doesn't exist</p>").arg( mw->captureFileName() ) );
00467             return;
00468         }
00469 
00470         QFile f( mw->captureFileName() );
00471         if ( !f.open( IO_ReadOnly ) )
00472         {
00473             QMessageBox::warning( 0, tr( "Error" ), tr( "<p>Can't open Logfile '%1'</p>").arg( mw->captureFileName() ) );
00474             return;
00475         }
00476 
00477 //        int content_length = f.size();
00478 
00479         ::memset( &raddr, 0, sizeof (struct sockaddr_in) );
00480         ::memcpy( &raddr. sin_addr, rhost_info-> h_addr, rhost_info-> h_length );
00481         raddr.sin_family = rhost_info-> h_addrtype;
00482         raddr.sin_port = htons ( 80 );
00483 
00484         sock = ::socket( AF_INET, SOCK_STREAM, 0 );
00485 
00486         if ( sock >= 0 )
00487         {
00488             if ( ::connect ( sock, (struct sockaddr *) & raddr, sizeof (struct sockaddr)) >= 0 )
00489             {
00490                 QString header;
00491                 QString content;
00492                 QString preambel;
00493 
00494                 header = ""
00495                 "POST /projects/capturedump.spy HTTP/1.1\r\n"
00496                 "Host: www.vanille.de\r\n"
00497                 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5) Gecko/20031010 Galeon/1.3.10\r\n"
00498                 "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1\r\n"
00499                 "Accept-Language: en\r\n"
00500                 "Accept-Encoding: gzip, deflate, compress;q=0.9\r\n"
00501                 "Accept-Charset: us-ascii,utf-8;q=0.7,*;q=0.7\r\n"
00502                 "Keep-Alive: 300\r\n"
00503                 "Connection: keep-alive\r\n"
00504                 "Referer: http://www.vanille.de/projects/capturedump.spy\r\n"
00505                 "Content-Type: multipart/form-data; boundary=---------------------------97267758015830030481215568065\r\n"
00506                 "Content-Length: %1\r\n"
00507                 "\r\n";
00508 
00509                 content = ""
00510                 "-----------------------------97267758015830030481215568065\r\n"
00511                 "Content-Disposition: form-data; name=\"Name\"\r\n"
00512                 "\r\n"
00513                 "%1\r\n"
00514                 "-----------------------------97267758015830030481215568065\r\n"
00515                 "Content-Disposition: form-data; name=\"Location\"\r\n"
00516                 "\r\n"
00517                 "%2\r\n"
00518                 "-----------------------------97267758015830030481215568065\r\n"
00519                 "Content-Disposition: form-data; name=\"Comments\"\r\n"
00520                 "\r\n"
00521                 "%3\r\n"
00522                 "-----------------------------97267758015830030481215568065\r\n"
00523                 "Content-Disposition: form-data; name=\"upfile\"; filename=\"%4\"\r\n"
00524                 "Content-Type: application/octet-stream\r\n"
00525                 "\r\n";
00526 
00527                 preambel = ""
00528                 "\r\n-----------------------------97267758015830030481215568065--\r\n";
00529 
00530                 content = content.arg( from->text().isEmpty() ? QString( "Anonymous Wellenreiter II User" ) : from->text() );
00531                 content = content.arg( location->text().isEmpty() ? QString( "Anonymous Wellenreiter II Location" ) : location->text() );
00532                 content = content.arg( comments->text().isEmpty() ? QString( "Anonymous Wellenreiter II Comments" ) : comments->text() );
00533                 content = content.arg( mw->captureFileName() );
00534 
00535                 header = header.arg( QString::number( content.length() + f.size() + preambel.length() ) );
00536 
00537                 // write header
00538 
00539                 const char* ascii = header.latin1();
00540                 uint ascii_len = ::strlen( ascii );
00541                 ::write ( sock, ascii, ascii_len );
00542 
00543                 // write fixed content
00544 
00545                 ascii = content.latin1();
00546                 ascii_len = ::strlen( ascii );
00547                 ::write ( sock, ascii, ascii_len );
00548 
00549                 // write variable content
00550 
00551                 char ch;
00552                 while ( !f.atEnd() )
00553                 {
00554                     f.readBlock( &ch, 1 );
00555                     ::write ( sock, &ch, 1 );
00556                 }
00557 
00558                 // write preambel
00559 
00560                 ascii = preambel.latin1();
00561                 ascii_len = ::strlen( ascii );
00562                 ::write ( sock, ascii, ascii_len );
00563 
00564                 // done!
00565 
00566                 ok = true;
00567             }
00568         }
00569         ::close ( sock );
00570     }
00571     if ( ok )
00572     QMessageBox::information( 0, tr( "Success" ),
00573                               QString ( "<p>%1</p>" ).arg( tr( "Capture Dump was uploaded to %1" ) ).arg( CAP_hostname ) );
00574     else
00575     QMessageBox::warning( 0, tr( "Error" ),
00576                           QString ( "<p>%1</p>" ).arg ( tr( "Connection to %1 failed" ) ).arg( CAP_hostname ) );
00577 }
00578 
00579 
00580 void WellenreiterMainWindow::viewExpandAll()
00581 {
00582     mw->netView()->expand();
00583 }
00584 
00585 void WellenreiterMainWindow::viewCollapseAll()
00586 {
00587     mw->netView()->collapse();
00588 }

Generated on Sat Nov 5 16:15:52 2005 for OPIE by  doxygen 1.4.2