/* This file is part of the KDE project Copyright (C) 2002-2003 Tim Jansen Copyright (C) 2003-2004 Nadeem Hasan 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; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include #include #include #include "hostpreferences.h" #include "maindialogwidget.h" static const QString DEFAULT_SCOPE = "default"; class UrlListViewItem : public KListViewItem { public: UrlListViewItem( QListView *v, const QString &url, const QString &host, const QString &protocol, const QString &type, const QString &userid, const QString &fullname, const QString &desc, const QString &serviceid ) : KListViewItem( v, host, i18n( "unknown" ), host, protocol ), m_url( url ), m_serviceid( serviceid ) { if ( !type.isNull() ) { //User connects to somebody else's desktop, used for krfb if ( type.lower() == "shared" ) setText( 1, i18n( "Shared Desktop" ) ); //User connects to desktop that exists only on the network else if ( type.lower() == "private" ) setText( 1, i18n( "Standalone Desktop" ) ); } if ( !desc.isNull() ) setText( 0, desc ); if ( ( !userid.isEmpty() ) && ( !fullname.isEmpty() ) ) setText( 0, QString( "%1 (%2)" ).arg( fullname ).arg( userid ) ); else if ( !userid.isNull() ) setText( 0, userid ); else if ( !fullname.isNull() ) setText( 0, fullname ); } QString url() { return m_url; } const QString& serviceid() const { return m_serviceid; } protected: QString m_url; QString m_serviceid; }; MainDialogWidget::MainDialogWidget( QWidget *parent, const char *name ) : MainDialogBase( parent, name ), m_scanning( false ) { HostPreferences *hp = HostPreferences::instance(); QStringList list; list = hp->serverCompletions(); m_serverInput->completionObject()->setItems( list ); list = hp->serverHistory(); m_serverInput->setHistoryItems( list ); m_searchInput->setTrapReturnKey( true ); connect( m_browsingView, SIGNAL( selectionChanged( QListViewItem * ) ), SLOT( itemSelected( QListViewItem * ) ) ); connect( m_browsingView, SIGNAL( doubleClicked( QListViewItem *, const QPoint &, int ) ), SLOT( itemDoubleClicked( QListViewItem * ) ) ); connect( m_scopeCombo, SIGNAL( activated( const QString & ) ), SLOT( scopeSelected( const QString & ) ) ); connect( m_serverInput, SIGNAL( returnPressed( const QString & ) ), SLOT( rescan() ) ); bool showBrowse = hp->showBrowsingPanel(); enableBrowsingArea( showBrowse ); m_locator_dnssd = new DNSSD::ServiceBrowser(QStringList::split(',',"_rfb._tcp,_rdp._tcp"),0,DNSSD::ServiceBrowser::AutoResolve); connect(m_locator_dnssd,SIGNAL(serviceAdded(DNSSD::RemoteService::Ptr)), SLOT(addedService(DNSSD::RemoteService::Ptr))); connect(m_locator_dnssd,SIGNAL(serviceRemoved(DNSSD::RemoteService::Ptr)), SLOT(removedService(DNSSD::RemoteService::Ptr))); m_locator_dnssd->startBrowse(); adjustSize(); } MainDialogWidget::~MainDialogWidget() { delete m_locator_dnssd; } void MainDialogWidget::save() { HostPreferences *hp = HostPreferences::instance(); QStringList list; m_serverInput->addToHistory( m_serverInput->currentText() ); list = m_serverInput->completionObject()->items(); hp->setServerCompletions( list ); list = m_serverInput->historyItems(); hp->setServerHistory( list ); hp->setShowBrowsingPanel( m_browsingPanel->isVisible() ); } void MainDialogWidget::setRemoteHost( const QString &host ) { m_serverInput->setEditText( host ); } QString MainDialogWidget::remoteHost() { return m_serverInput->currentText(); } void MainDialogWidget::hostChanged( const QString &text ) { emit hostValid(text.contains(QRegExp(":[0-9]+$")) || text.contains(QRegExp("^vnc:/.+")) || text.contains(QRegExp("^rdp:/.+"))); } void MainDialogWidget::toggleBrowsingArea() { enableBrowsingArea(!m_browsingPanel->isVisible()); } void MainDialogWidget::enableBrowsingArea( bool enable ) { int hOffset = 0; if (enable) { m_browsingPanel->show(); m_browsingPanel->setMaximumSize(1000, 1000); m_browsingPanel->setEnabled(true); m_browseButton->setText(m_browseButton->text().replace(">>", "<<")); } else { hOffset = m_browsingPanel->height(); m_browsingPanel->hide(); m_browsingPanel->setMaximumSize(0, 0); m_browsingPanel->setEnabled(false); m_browseButton->setText(m_browseButton->text().replace("<<", ">>")); int h = minimumSize().height()-hOffset; setMinimumSize(minimumSize().width(), (h > 0) ? h : 0); resize(width(), height()-hOffset); QTimer::singleShot( 0, parentWidget(), SLOT( adjustSize() ) ); } if (enable) rescan(); } void MainDialogWidget::itemSelected( QListViewItem *item ) { UrlListViewItem *u = ( UrlListViewItem* ) item; QRegExp rx( "^service:remotedesktop\\.kde:([^;]*)" ); if ( rx.search( u->url() ) < 0 ) m_serverInput->setCurrentText( u->url()); else m_serverInput->setCurrentText( rx.cap( 1 ) ); } void MainDialogWidget::itemDoubleClicked( QListViewItem *item ) { itemSelected( item ); emit accept(); } void MainDialogWidget::scopeSelected( const QString &scope ) { QString s = scope; if ( s == i18n( "default" ) ) s = DEFAULT_SCOPE; if ( m_scope == s ) return; m_scope = s; rescan(); } void MainDialogWidget::rescan() { QStringList scopeList; if ( m_scanning ) return; m_scanning = true; m_rescanButton->setEnabled( false ); m_scopeCombo->setEnabled( false ); if ( !ensureLocatorOpen() ) return; m_browsingView->clear(); QString filter; if ( !m_searchInput->text().stripWhiteSpace().isEmpty() ) { QString ef = KServiceLocator::escapeFilter( m_searchInput->text().stripWhiteSpace() ); filter = "(|(|(description=*"+ef+"*)(username=*"+ef+"*))(fullname=*"+ef+"*))"; } if ( !m_locator->findServices( "service:remotedesktop.kde", filter, m_scope ) ) { kdWarning() << "Failure in findServices()" << endl; errorScanning(); return; } } bool MainDialogWidget::ensureLocatorOpen() { if ( m_locator ) return true; m_locator = new KServiceLocator(); if ( !m_locator->available() ) { #ifdef HAVE_SLP KMessageBox::error( 0, i18n( "Browsing the network is not possible. You probably " "did not install SLP support correctly." ), i18n( "Browsing Not Possible" ), false ); #endif return false; } connect( m_locator, SIGNAL( foundService( QString,int ) ), SLOT( foundService( QString,int ) ) ); connect( m_locator, SIGNAL( lastServiceSignal( bool ) ), SLOT( lastSignalServices( bool ) ) ); connect( m_locator, SIGNAL( foundScopes( QStringList ) ), SLOT( foundScopes( QStringList ) ) ); return true; } void MainDialogWidget::errorScanning() { KMessageBox::error( 0, i18n( "An error occurred while scanning the network." ), i18n( "Error While Scanning" ), false ); finishScanning(); } void MainDialogWidget::finishScanning() { m_rescanButton->setEnabled( true ); m_scopeCombo->setEnabled( true ); m_scanning = false; } void MainDialogWidget::foundService( QString url, int ) { QRegExp rx( "^service:remotedesktop\\.kde:(\\w+)://([^;]+);(.*)$" ); if ( rx.search( url ) < 0 ) { rx = QRegExp( "^service:remotedesktop\\.kde:(\\w+)://(.*)$" ); if ( rx.search( url ) < 0 ) return; } QMap map; KServiceLocator::parseAttributeList( rx.cap( 3 ), map ); new UrlListViewItem( m_browsingView, url, rx.cap( 2 ), rx.cap( 1 ), KServiceLocator::decodeAttributeValue( map[ "type" ] ), KServiceLocator::decodeAttributeValue( map[ "username" ] ), KServiceLocator::decodeAttributeValue( map[ "fullname" ] ), KServiceLocator::decodeAttributeValue( map[ "description" ] ), KServiceLocator::decodeAttributeValue( map[ "serviceid" ] ) ); } void MainDialogWidget::addedService( DNSSD::RemoteService::Ptr service ) { QString type = service->type().mid(1,3); if (type == "rfb") type = "vnc"; QString url = type+"://"+service->hostName()+":"+QString::number(service->port()); new UrlListViewItem( m_browsingView, url, service->serviceName(), type.upper(),service->textData()["type"], service->textData()["u"],service->textData()["fullname"], service->textData()["description"],service->serviceName()+service->domain()); } void MainDialogWidget::removedService( DNSSD::RemoteService::Ptr service ) { QListViewItemIterator it( m_browsingView ); while ( it.current() ) { if ( ((UrlListViewItem*)it.current())->serviceid() == service->serviceName()+service->domain() ) delete it.current(); else ++it; } } void MainDialogWidget::lastSignalServices( bool success ) { if ( !success ) { errorScanning(); return; } if ( !m_locator->findScopes() ) { kdWarning() << "Failure in findScopes()" << endl; errorScanning(); } } void MainDialogWidget::foundScopes( QStringList scopeList ) { int di = scopeList.findIndex( DEFAULT_SCOPE ); if ( di >= 0 ) scopeList[ di ] = i18n( "default" ); int ct = scopeList.findIndex( m_scopeCombo->currentText() ); m_scopeCombo->clear(); m_scopeCombo->insertStringList( scopeList ); if ( ct >= 0 ) m_scopeCombo->setCurrentItem( ct ); finishScanning(); } #include "maindialogwidget.moc"