Logo Search packages:      
Sourcecode: kaffeine version File versions

scandialog.cpp

/***************************************************************************
                          scandialog.cpp  -  description
                             -------------------
    begin                : Mon Mar 22 2004
    copyright            : (C) 2004-2005 by Christophe Thommeret
    email                : hftom@free.fr
    last modified        : $Date: 2005/02/02 10:08:25 $ by $Author: juergenk $
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <qlayout.h>
#include <qdir.h>
#include <qlistbox.h>
#include <qpushbutton.h>
#include <qcheckbox.h>
#include <qcombobox.h>
#include <qgroupbox.h>
#include <qlistview.h>
#include <qpopmenu.h>
#include <qcursor.h>
#include <qwhatsthis.h>
#include <qapp.h>
#include <qaccel.h>

#include <klocale.h>
#include <kiconloader.h>
#include <kmessagebox.h>

#include "scandialog.h"
#include "channeleditor.h"
#include "dvbsi.h"



ScanDialog::ScanDialog( DvbStream *d, QPtrList<ChannelDesc> *ch, QSize size, QString src )
{
      QString s;
      
      KIconLoader *icon = new KIconLoader();
      tvPix = icon->loadIcon( "kdvbtv", KIcon::Small );
      tvcPix = icon->loadIcon( "kdvbtvc", KIcon::Small );
      raPix = icon->loadIcon( "kdvbra", KIcon::Small );
      racPix = icon->loadIcon( "kdvbrac", KIcon::Small );

      chandesc = ch;
      dvbsi = 0;
      dvb = d;
      sourcesPath = src;
      
      searchComb->insertStringList( dvb->getSources() );
      
      dvbType = dvb->dvbType;

      setCaption( i18n("Channels") );
      
      transponders.setAutoDelete( true );

      QGridLayout *statLayout = new QGridLayout( statusFrame, 1, 1, 11, 6 );

      QLabel *lab = new QLabel( i18n("Signal :"), statusFrame );
      statLayout->addWidget( lab, 0, 0 );
      signal = new KGradProgress( statusFrame );
      statLayout->addWidget( signal, 0, 1 );
      lab = new QLabel( i18n("SNR :"), statusFrame );
      statLayout->addWidget( lab, 1, 0 );
      snr = new KGradProgress( statusFrame );
      statLayout->addWidget( snr, 1, 1 );
      lab = new QLabel( i18n("Lock :"), statusFrame );
      statLayout->addWidget( lab, 2, 0 );
      lock = new KLed( statusFrame, "lockLed" );
      lock->setState( KLed::Off );
      lock->setDarkFactor( 500 );
      statLayout->addWidget( lock, 2, 1 );
      progress = new QProgressBar( 100, statusFrame );
      progress->setIndicatorFollowsStyle( false );
      progress->setProgress( 0 );
      statLayout->addMultiCellWidget( progress, 3, 3, 0, 1 );
      progressLab = new QLabel( statusFrame );
      statLayout->addMultiCellWidget( progressLab, 4, 4, 0, 1 );

      channelsList->clear();
      foundList->clear();
      foundList->setSelectionMode( QListBox::Extended );
      channelsList->setSorting( 0 );

      ChannelDesc *chan;
      QListViewItem *it;
      for ( int i=0; i<(int)chandesc->count(); i++ ) {
            chan = chandesc->at(i);
            it = new QListViewItem( channelsList, chan->name );
            if ( chan->type==1 ) {
                  if ( chan->fta ) it->setPixmap( 0, tvcPix );
                  else it->setPixmap( 0, tvPix );
            }
            else {
                  if ( chan->fta ) it->setPixmap( 0, racPix );
                  else it->setPixmap( 0, raPix );
            }
      }           

      bool ok=true;

      if ( dvb ) {
            dvbsi = new DVBsi( &ok, dvb->dvbCard, dvb );
            if ( !ok ) {
                  delete dvbsi;
                  dvbsi = 0;
            }
      }

      if ( dvbsi ) {
            dvb->setScanning( true );
            startBtn->setPaletteForegroundColor( QColor(255,0,0) );
            connect( &checkTimer, SIGNAL( timeout() ), this, SLOT( checkNewChannel() ) );
            connect( &progressTimer, SIGNAL( timeout() ), this, SLOT( setProgress() ) );
            connect( startBtn, SIGNAL(toggled(bool)), this, SLOT(scan(bool)) );
            connect( dvb, SIGNAL(snrStatus(int)), snr, SLOT(setProgress(int)) );
            connect( dvb, SIGNAL(signalStatus(int)), signal, SLOT(setProgress(int)) );
            connect( dvb, SIGNAL(lockStatus(bool)), this, SLOT(setLock(bool)) );
            connect( dvbsi, SIGNAL(end(bool)), this, SLOT(siEnded(bool)) );
            connect( addfilteredBtn, SIGNAL(clicked()), this, SLOT(addFiltered()) );
            connect( addselectedBtn, SIGNAL(clicked()), this, SLOT(addSelected()) );
      }

      connect( channelsList, SIGNAL(contextMenuRequested(QListViewItem*,const QPoint&,int)), this, SLOT(pop(QListViewItem*,const QPoint&,int)) );
      connect( newBtn, SIGNAL(clicked()), this, SLOT(newChannel()) );
      connect( delBtn, SIGNAL(clicked()), this, SLOT(deleteAll()) );

      QAccel *ac = new QAccel( channelsList );
      ac->insertItem( Key_Delete, 100 );
      ac->connectItem( 100, this, SLOT(deleteChannel()) );

      resize( size );
}



void ScanDialog::pop( QListViewItem *it, const QPoint &pos, int col )
{
      QPoint p=pos;
      
      if ( !it ) return;
      
      int i=col;
      QPixmap pix;
      QString s = it->text(0);

      QPopupMenu *pop = new QPopupMenu();
      pop->insertItem( i18n("Edit ..."), 1 );
      pop->insertItem( i18n("Delete"), 2 );
      i = 0;
      i = pop->exec( QCursor::pos() );
      switch ( i ) {
            case 0 :
                  break;
            case 1 : 
                  if ( edit( s, pix ) ) {
                        it->setText( 0, s );
                        it->setPixmap( 0, pix );
                  }
                  break;
            case 2 :
                  deleteChannel( it->text(0) );
                  break;
      }
      delete pop;
}



void ScanDialog::deleteChannel()
{
      QListViewItem *it = channelsList->currentItem();
      if ( it ) deleteChannel( it->text(0) );
}



void ScanDialog::deleteChannel( QString name )
{
      int j, i;
      QListViewItem *it;
      
      for ( j=0; j<(int)chandesc->count(); j++ ) {
            if ( chandesc->at(j)->name==name ) {
                  for ( i=0; i<(int)chandesc->count(); i++ ) {
                        if ( chandesc->at(i)->num==chandesc->count() ) {
                              chandesc->at(i)->num = chandesc->at(j)->num;
                              break;
                        }
                  }
                  dvbsi->channels.append( new ChannelDesc( *chandesc->at(j) ) );
                  addFound( chandesc->at(j), false );
                  chandesc->remove(j);
                  it = channelsList->firstChild();
                  while ( it!=0 ) {
                        if ( name==it->text(0) ) {
                              channelsList->removeItem( it );
                              break;
                        }
                        it = it->nextSibling();
                  }
                  break;
            }
      }
}



void ScanDialog::newChannel()
{
      ChannelDesc chan;
      QStringList list;
      int i;
      
      for ( i=0; i<(int)searchComb->count(); i++ ) list.append( searchComb->text(i) );

      chandesc->append( new ChannelDesc( chan ) );
      chan.tp.type = dvbType;
      chan.num = chandesc->count();
      
      ChannelEditor dlg( list, false, &chan, chandesc, this );

      int ret = dlg.exec();
      chandesc->remove();
      if ( ret==ChannelEditor::Accepted ) {
            chandesc->append( new ChannelDesc( chan ) );
            QListViewItem *it = new QListViewItem( channelsList, chan.name );
            if ( chan.type==1 ) {
                  if ( chan.fta ) it->setPixmap( 0, tvcPix );
                  else it->setPixmap( 0, tvPix );
            }
            else {
                  if ( chan.fta ) it->setPixmap( 0, racPix );
                  else it->setPixmap( 0, raPix );
            }
      }
}



void ScanDialog::deleteAll()
{
      int i, ret;

      ret = KMessageBox::questionYesNo( this, i18n("Do you really want to delete all channels ?") );
      if ( ret!=KMessageBox::Yes ) return;
      for ( i=0; i<(int)chandesc->count(); i++ ) {
            dvbsi->channels.append( new ChannelDesc( *chandesc->at(i) ) );
            addFound( chandesc->at(i), false );
      }
      channelsList->clear();
      chandesc->clear();
}



bool ScanDialog::edit( QString &name, QPixmap &pix )
{
      int j;
      ChannelDesc *chan=0;
      QStringList list;
      int i;
      
      for ( i=0; i<(int)searchComb->count(); i++ ) list.append( searchComb->text(i) );
      
      for ( j=0; j<(int)chandesc->count(); j++ ) {
            chan = chandesc->at(j);
            if ( chan->name==name ) {
                  j = -1;
                  break;
            }
      }
      if ( j==-1 ) {
            ChannelEditor dlg( list, false, chan, chandesc, this );
            int ret = dlg.exec();
            if ( ret==ChannelEditor::Accepted ) {
                  name = chan->name;
                  if ( chan->type==1 ) {
                        if ( chan->fta ) pix = tvcPix;
                        else pix = tvPix;
                  }
                  else {
                        if ( chan->fta ) pix = racPix;
                        else pix = raPix;
                  }
                  return true;
            }
      }
      return false;
}



void ScanDialog::parseTp( QString s, fe_type_t type, QString src )
{
      Transponder *trans;
      QString t;
      int pos;
      
      s = s.stripWhiteSpace();
      trans = new Transponder();
      pos = s.find(" ");
      if ( s.left(pos)=="T" ) trans->type=FE_OFDM;
      else if ( s.left(pos)=="C" ) trans->type=FE_QAM;
      else trans->type=FE_QPSK;
      if ( trans->type!=type ) {
            delete trans;
            return;
      }
      trans->source = src;
      s = s.right( s.length()-pos-1 );
      s = s.stripWhiteSpace();
      pos = s.find(" ");
      trans->freq = s.left(pos).toULong()/1000;
      s = s.right( s.length()-pos-1 );
      s = s.stripWhiteSpace();
      pos = s.find(" ");
      if ( trans->type==FE_QPSK ) {
            trans->pol =  s.left(pos).lower()[0].latin1();
            s = s.right( s.length()-pos-1 );
            s = s.stripWhiteSpace();
            pos = s.find(" ");
      }
      if ( trans->type!=FE_OFDM ) {
            trans->sr = s.left(pos).toULong()/1000;
      }
      else {
            if ( s.left(pos)=="8MHz" ) trans->bandwidth = BANDWIDTH_8_MHZ;
            else if ( s.left(pos)=="7MHz" ) trans->bandwidth = BANDWIDTH_7_MHZ;
            else if ( s.left(pos)=="6MHz" ) trans->bandwidth = BANDWIDTH_6_MHZ;
            else trans->bandwidth = BANDWIDTH_AUTO;
      }
      s = s.right( s.length()-pos-1 );
      s = s.stripWhiteSpace();
      pos = s.find(" ");
      if ( s.left(pos)=="1/2" ) trans->coderateH = FEC_1_2;
      else if ( s.left(pos)=="2/3" ) trans->coderateH = FEC_2_3;
      else if ( s.left(pos)=="3/4" ) trans->coderateH = FEC_3_4;
      else if ( s.left(pos)=="4/5" ) trans->coderateH = FEC_4_5;
      else if ( s.left(pos)=="5/6" ) trans->coderateH = FEC_5_6;
      else if ( s.left(pos)=="6/7" ) trans->coderateH = FEC_6_7;
      else if ( s.left(pos)=="7/8" ) trans->coderateH = FEC_7_8;
      else if ( s.left(pos)=="8/9" ) trans->coderateH = FEC_8_9;
      else if ( s.left(pos)=="NONE" ) trans->coderateH = FEC_NONE;
      else trans->coderateH = FEC_AUTO;
      s = s.right( s.length()-pos-1 );
      s = s.stripWhiteSpace();
      pos = s.find(" ");
      if ( trans->type==FE_OFDM ) {
            if ( s.left(pos)=="1/2" ) trans->coderateL = FEC_1_2;
            else if ( s.left(pos)=="2/3" ) trans->coderateL = FEC_2_3;
            else if ( s.left(pos)=="3/4" ) trans->coderateL = FEC_3_4;
            else if ( s.left(pos)=="4/5" ) trans->coderateL = FEC_4_5;
            else if ( s.left(pos)=="5/6" ) trans->coderateL = FEC_5_6;
            else if ( s.left(pos)=="6/7" ) trans->coderateL = FEC_6_7;
            else if ( s.left(pos)=="7/8" ) trans->coderateL = FEC_7_8;
            else if ( s.left(pos)=="8/9" ) trans->coderateL = FEC_8_9;
            else if ( s.left(pos)=="NONE" ) trans->coderateL = FEC_NONE;
            else trans->coderateL = FEC_AUTO;
            s = s.right( s.length()-pos-1 );
            s = s.stripWhiteSpace();
            pos = s.find(" ");
      }
      if ( trans->type!=FE_QPSK ) {
            if ( s.left(pos)=="QPSK" ) trans->modulation = QPSK;
            else if ( s.left(pos)=="QAM16" ) trans->modulation = QAM_16;
            else if ( s.left(pos)=="QAM32" ) trans->modulation = QAM_32;
            else if ( s.left(pos)=="QAM64" ) trans->modulation = QAM_64;
            else if ( s.left(pos)=="QAM128" ) trans->modulation = QAM_128;
            else if ( s.left(pos)=="QAM256" ) trans->modulation = QAM_256;
            else trans->modulation = QAM_AUTO;
      }
      if ( trans->type==FE_OFDM ) {
            s = s.right( s.length()-pos-1 );
            s = s.stripWhiteSpace();
            pos = s.find(" ");
            if ( s.left(pos)=="8k" ) trans->transmission = TRANSMISSION_MODE_8K;
            else if ( s.left(pos)=="2k" ) trans->transmission = TRANSMISSION_MODE_2K;
            else trans->transmission = TRANSMISSION_MODE_AUTO;

            s = s.right( s.length()-pos-1 );
            s = s.stripWhiteSpace();
            pos = s.find(" ");
            if ( s.left(pos)=="1/32" ) trans->guard = GUARD_INTERVAL_1_32;
            else if ( s.left(pos)=="1/16" ) trans->guard = GUARD_INTERVAL_1_16;
            else if ( s.left(pos)=="1/8" ) trans->guard = GUARD_INTERVAL_1_8;
            else if ( s.left(pos)=="1/4" ) trans->guard = GUARD_INTERVAL_1_4;
            else trans->guard = GUARD_INTERVAL_AUTO;

            s = s.right( s.length()-pos-1 );
            s = s.stripWhiteSpace();
            pos = s.find(" ");
            if ( s.left(pos)=="1" ) trans->hierarchy = HIERARCHY_1;
            else if ( s.left(pos)=="2" ) trans->hierarchy = HIERARCHY_2;
            else if ( s.left(pos)=="4" ) trans->hierarchy = HIERARCHY_4;
            else if ( s.left(pos)=="NONE" ) trans->hierarchy = HIERARCHY_NONE;
            else  trans->hierarchy = HIERARCHY_AUTO;
      }
      transponders.append( trans );
}



bool ScanDialog::getTransData()
{
      QString s=sourcesPath;
      
      transponders.clear();
      switch (dvbType) {
            case FE_QPSK : s += "dvb-s/"; break;
            case FE_QAM : s += "dvb-c/"; break;
            case FE_OFDM : s += "dvb-t/";
      }
      s += searchComb->currentText();
      QFile f( s );
      if ( f.open(IO_ReadOnly) ) {
            QTextStream tt( &f );
            while ( !tt.eof() ) {
                  s = tt.readLine();
                  if ( s.startsWith("#") ) continue;
                  if ( s.length()==0 ) continue;
                  parseTp( s, dvbType, searchComb->currentText() );
            }
            f.close();
            return true;
      }
      else return false;
}



void ScanDialog::addSelected()
{
      ChannelDesc *chan;
      QListViewItem *it;
      int i, j, r;
      int n = foundList->currentItem();

      if ( n<0 ) return;

      for ( i=0; i<(int)foundList->count(); i++ ) {
            chan = 0;
            r = 0;
            if ( !foundList->isSelected( i ) ) continue;
            for ( j=0; j<(int)dvbsi->channels.count(); j++ ) {
                  if ( dvbsi->channels.at(j)->name==foundList->text(i) ) {
                        chan = dvbsi->channels.at(j);
                        break;
                  }
            }
            if ( !chan ) continue;
            for ( n=0; n<(int)chandesc->count(); n++ ) {
                  if ( chan->name==chandesc->at(n)->name ) {
                        KMessageBox::sorry( this, i18n("This channel already exists : ")+chan->name );
                        r++;
                        break;
                  }
            }
            if ( r ) continue;
            chan->num = chandesc->count()+1;
            chandesc->append( new ChannelDesc( *chan ) );
            it = new QListViewItem( channelsList, chan->name );
            if ( chan->type==1 ) {
                  if ( chan->fta ) it->setPixmap( 0, tvcPix );
                  else it->setPixmap( 0, tvPix );
            }
            else {
                  if ( chan->fta ) it->setPixmap( 0, racPix );
                  else it->setPixmap( 0, raPix );
            }
            foundList->removeItem(i);
            dvbsi->channels.remove(j);
            i--;
      }
}



void ScanDialog::working( bool b )
{
      addfilteredBtn->setEnabled( !b );
      addselectedBtn->setEnabled( !b );
      //if ( !isTuned ) searchGroup->setEnabled( !b );
      newBtn->setEnabled( !b );
      delBtn->setEnabled( !b );
}



void ScanDialog::addFiltered()
{
      int i, j;
      ChannelDesc *chan;
      QListViewItem *it;
      int m = dvbsi->channels.count();
      int t=0;

      working( true );
      startBtn->setEnabled( false );
      progress->setProgress(0);
      qApp->processEvents();
      
      for ( i=0; i<(int)dvbsi->channels.count(); i++ ) {
            t++;
            progress->setProgress( t*100/m );
            chan = dvbsi->channels.at(i);
            if ( !chan->completed ) continue;
            if ( chan->name =="" ) continue;
            if ( chan->type<1 ) continue;
            if ( chan->type>2 ) continue;
            if ( chan->type==1 && chan->vpid==0 ) continue;
            if ( chan->type==1 && chan->napid==0 ) continue;
            if ( chan->type==2 && chan->napid==0 ) continue;
            if ( chan->type==2 && chan->vpid!=0 ) continue;
            if ( ftaCb->isChecked() && chan->fta ) continue;
            if ( !tvCb->isChecked() && chan->type==1 ) continue;
            if ( !radioCb->isChecked() && chan->type==2 ) continue;
            if ( providerCb->isChecked() && chan->provider!=providerComb->currentText() ) continue;
            j = 0;
            it = channelsList->firstChild();
            while ( it!=0 ) {
                  if ( chan->name==it->text(0) ) {
                        j++;
                        break;
                  }
                  it = it->nextSibling();
            }
            if ( j ) continue;
            chan->num = chandesc->count()+1;
            chandesc->append( new ChannelDesc( *chan ) );
            it = new QListViewItem( channelsList, chan->name );
            if ( chan->type==1 ) {
                  if ( chan->fta ) it->setPixmap( 0, tvcPix );
                  else it->setPixmap( 0, tvPix );
            }
            else {
                  if ( chan->fta ) it->setPixmap( 0, racPix );
                  else it->setPixmap( 0, raPix );
            }
            for ( j=0; j<(int)foundList->count(); j++ ) {
                  if ( chan->name==foundList->text(j) ) {
                        foundList->removeItem(j);
                        break;
                  }
            }
            for ( j=0; j<(int)dvbsi->channels.count(); j++ ) {
                  if ( chan->name==dvbsi->channels.at(j)->name ) {
                        dvbsi->channels.remove(j);
                        i--;
                        break;
                  }
            }
      }
      progress->setProgress(0);
      startBtn->setEnabled( true );
      working( false );
}
            


void ScanDialog::siEnded( bool b )
{
      checkTimer.stop();
      progressTimer.stop();
      checkNewChannel();
      snr->setProgress( 0 );
      signal->setProgress( 0 );
      setLock( false );
      progress->setProgress( 0 );
      startBtn->setOn( !b );
      working( false );
      startBtn->setText( i18n("START scan") );
      startBtn->setPaletteForegroundColor( QColor(255,0,0) );
}



void ScanDialog::scan( bool b )
{
      if ( b ) {
            if ( checkTimer.isActive() ) checkTimer.stop();
            foundList->clear();
            nChannels = 0;
            ntv = nradio = 0;
            if ( dvb->isTuned() ) dvbsi->go( transponders, 2 );
            else {
                  if ( !getTransData() ) return;
                  dvbsi->go( transponders );
            }
            checkTimer.start( 100 );
            progressTimer.start( 1000 );
            working( true );
            startBtn->setText( i18n("STOP scan") );
            startBtn->setPaletteForegroundColor( QColor(0,255,0) );
      }
      else {
            //setCursor(QCursor(Qt::WaitCursor));
            startBtn->setText( i18n("Stopping ...") );
            startBtn->setEnabled( false );
            qApp->processEvents();
            dvbsi->stop();
            checkTimer.stop();
            progressTimer.stop();
            checkNewChannel();
            snr->setProgress( 0 );
            signal->setProgress( 0 );
            setLock( false );
            progress->setProgress( 0 );
            working( false );
            //setCursor(QCursor(Qt::ArrowCursor));
            startBtn->setText( i18n("START scan") );
            startBtn->setEnabled( true );
            startBtn->setPaletteForegroundColor( QColor(255,0,0) );
      }
}



void ScanDialog::setProgress()
{
      if ( !dvbsi->transponders.count() ) return;
      progress->setProgress( dvbsi->progressTransponder*100/dvbsi->transponders.count() );
}



void ScanDialog::setLock( bool on )
{
      if ( on ) lock->on();
      else lock->off();
}



void ScanDialog::checkNewChannel()
{
      ChannelDesc *chan;
      int j;
      
      for ( j=nChannels; j<(int)dvbsi->channels.count(); j++ ) {
            chan = dvbsi->channels.at(j);
            if ( chan->completed==0 ) break;
            nChannels++;
            if ( chan->name =="" ) continue;
            if ( chan->type<1 ) continue;
            if ( chan->type>2 ) continue;
            if ( chan->type==1 && chan->vpid==0 ) continue;
            if ( chan->type==1 && chan->napid==0 ) continue;
            if ( chan->type==2 && chan->napid==0 ) continue;
            if ( chan->type==2 && chan->vpid!=0 ) continue;
            addFound( chan, true );
      }
}



void ScanDialog::addFound( ChannelDesc *chan, bool scan )
{
      int i;
      
      if ( chan->type==1 ) {
            if ( scan ) ntv++;
            if ( chan->fta ) foundList->insertItem( tvcPix, chan->name );
            else foundList->insertItem( tvPix, chan->name );
      }
      else {
            if ( scan ) nradio++;
            if ( chan->fta ) foundList->insertItem( racPix, chan->name );
            else foundList->insertItem( raPix, chan->name );
      }
      if ( scan ) progressLab->setText( QString( i18n("Found : %1 TV - %2 radio") ).arg(ntv).arg(nradio) );
      if ( chan->provider=="" ) return;
      for ( i=0; i<providerComb->count(); i++ ) {
            if ( chan->provider==providerComb->text(i) ) {
                  i = -1;
                  break;
            }
      }
      if ( i>-1 ) providerComb->insertItem( chan->provider );
}



ScanDialog::~ScanDialog()
{
      if ( checkTimer.isActive() ) checkTimer.stop();
      if ( progressTimer.isActive() ) progressTimer.stop();
      if ( dvbsi ) delete dvbsi;
      dvb->setScanning( false );
      transponders.clear();
}

Generated by  Doxygen 1.6.0   Back to index