summaryrefslogtreecommitdiffstats
path: root/kmrml/kmrml/mrml_part.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmrml/kmrml/mrml_part.cpp')
-rw-r--r--kmrml/kmrml/mrml_part.cpp857
1 files changed, 857 insertions, 0 deletions
diff --git a/kmrml/kmrml/mrml_part.cpp b/kmrml/kmrml/mrml_part.cpp
new file mode 100644
index 00000000..4d3f65e6
--- /dev/null
+++ b/kmrml/kmrml/mrml_part.cpp
@@ -0,0 +1,857 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001,2002 Carsten Pfeiffer <pfeiffer@kde.org>
+
+ 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, version 2.
+
+ 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., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <qcheckbox.h>
+#include <qcursor.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <qgrid.h>
+#include <qhgroupbox.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qtooltip.h>
+#include <qvbox.h>
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kcombobox.h>
+#include <kconfig.h>
+#include <kdatastream.h>
+#include <kdebug.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kinstance.h>
+#include <kio/job.h>
+#include <kio/jobclasses.h>
+#include <kmessagebox.h>
+#include <knuminput.h>
+#include <kprotocolinfo.h>
+#include <kparts/genericfactory.h>
+#include <ktempfile.h>
+
+#include <mrml_utils.h>
+
+#include "algorithmdialog.h"
+#include "browser.h"
+#include "collectioncombo.h"
+#include "mrml_creator.h"
+#include "mrml_elements.h"
+#include "mrml_shared.h"
+#include "mrml_view.h"
+#include "mrml_part.h"
+#include "version.h"
+
+using namespace KMrml;
+
+extern "C"
+{
+ void * init_libkmrmlpart() {
+ return new KMrml::PartFactory();
+ }
+}
+
+KInstance * PartFactory::s_instance = 0L;
+
+PartFactory::PartFactory()
+ : KParts::Factory()
+{
+ MrmlShared::ref();
+}
+
+PartFactory::~PartFactory()
+{
+ MrmlShared::deref();
+ delete s_instance;
+ s_instance = 0L;
+}
+
+KInstance * PartFactory::instance()
+{
+ if ( !s_instance ) {
+ s_instance = new KInstance( "kmrml" );
+ KGlobal::locale()->insertCatalogue( "kmrml" );
+ }
+ return s_instance;
+}
+
+KParts::Part * PartFactory::createPartObject( QWidget *parentWidget,
+ const char *widgetName,
+ QObject *parent,
+ const char *name,
+ const char *,
+ const QStringList& args )
+{
+ return new MrmlPart( parentWidget, widgetName, parent, name, args );
+}
+
+
+// can't use this due to MrmlShared ref-counting
+// typedef KParts::GenericFactory<KMrml::MrmlPart> PartFactory;
+// K_EXPORT_COMPONENT_FACTORY( mrmlpart, PartFactory )
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+
+
+uint MrmlPart::s_sessionId = 0;
+
+MrmlPart::MrmlPart( QWidget *parentWidget, const char * /* widgetName */,
+ QObject *parent, const char *name,
+ const QStringList& /* args */ )
+ : KParts::ReadOnlyPart( parent, name ),
+ m_job( 0L ),
+ m_status( NeedCollection )
+{
+ m_sessionId = QString::number( s_sessionId++ ).prepend("kmrml_");
+
+ setName( "MRML Part" );
+ m_browser = new Browser( this, "mrml browserextension");
+ setInstance( PartFactory::instance(), true ); // do load plugins :)
+ KConfig *config = PartFactory::instance()->config();
+ config->setGroup("MRML Settings");
+
+ QVBox *box = new QVBox( parentWidget, "main mrml box" );
+ m_view = new MrmlView( box, "MrmlView" );
+ connect( m_view, SIGNAL( activated( const KURL&, ButtonState )),
+ this, SLOT( slotActivated( const KURL&, ButtonState )));
+ connect( m_view, SIGNAL( onItem( const KURL& )),
+ this, SLOT( slotSetStatusBar( const KURL& )));
+
+ m_panel = new QHGroupBox( box, "buttons box" );
+
+ QGrid *comboGrid = new QGrid( 2, m_panel, "combo grid" );
+ comboGrid->setSpacing( KDialog::spacingHint() );
+
+ (void) new QLabel( i18n("Server to query:"), comboGrid );
+
+ m_hostCombo = new KComboBox( false, comboGrid, "host combo" );
+ initHostCombo();
+ connect( m_hostCombo, SIGNAL( activated( const QString& ) ),
+ SLOT( slotHostComboActivated( const QString& )));
+
+ (void) new QLabel( i18n("Search in collection:"), comboGrid );
+ m_collectionCombo = new CollectionCombo( comboGrid, "collection-combo" );
+ // will be re-set in initCollections(), but we need to set it here to
+ // prevent crashes when the connection to the server fails
+ m_collectionCombo->setCollections( &m_collections );
+
+ m_algoButton = new QPushButton( QString::null, m_panel );
+ m_algoButton->setPixmap( SmallIcon("configure") );
+ m_algoButton->setFixedSize( m_algoButton->sizeHint() );
+ connect( m_algoButton, SIGNAL( clicked() ),
+ SLOT( slotConfigureAlgorithm() ));
+ QToolTip::add( m_algoButton, i18n("Configure algorithm") );
+
+ QWidget *spacer = new QWidget( m_panel );
+ spacer->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding,
+ QSizePolicy::Minimum ) );
+
+ int resultSize = config->readNumEntry( "Result-size", 20 );
+ m_resultSizeInput = new KIntNumInput( resultSize, m_panel );
+ m_resultSizeInput->setRange( 1, 100 );
+ m_resultSizeInput->setLabel( i18n("Maximum result images:") );
+
+ QVBox *tmp = new QVBox( m_panel );
+ m_random = new QCheckBox( i18n("Random search"), tmp );
+
+ m_startButton = new QPushButton( QString::null, tmp );
+ connect( m_startButton, SIGNAL( clicked() ), SLOT( slotStartClicked() ));
+ setStatus( NeedCollection );
+
+ setWidget( box );
+
+ // setXMLFile( "mrml_part.rc" );
+
+ slotSetStatusBar( QString::null );
+
+ enableServerDependentWidgets( false );
+}
+
+MrmlPart::~MrmlPart()
+{
+ closeURL();
+}
+
+void MrmlPart::enableServerDependentWidgets( bool enable )
+{
+ m_collectionCombo->setEnabled( enable );
+ m_algoButton->setEnabled( enable && false ); // ### re-enable!!!
+}
+
+void MrmlPart::initCollections( const QDomElement& elem )
+{
+ m_collections.initFromDOM( elem );
+
+ m_collectionCombo->setCollections( &m_collections );
+ enableServerDependentWidgets( m_collectionCombo->count() > 0 );
+
+ if ( m_collectionCombo->count() == 0 )
+ {
+ KMessageBox::information( widget(),
+ i18n("There is no image collection available\n"
+ "at %1.\n"), i18n("No Image Collection"));
+ setStatus( NeedCollection );
+ }
+ else
+ m_collectionCombo->updateGeometry(); // adjust the entire grid
+}
+
+void MrmlPart::initAlgorithms( const QDomElement& elem )
+{
+ m_algorithms.initFromDOM( elem );
+}
+
+// this is where we start!
+bool MrmlPart::openURL( const KURL& url )
+{
+ closeURL();
+
+ if ( url.protocol() != "mrml" || !url.isValid() ) {
+ qWarning("MrmlPart::openURL: cannot handle url: %s", url.prettyURL().latin1());
+ return false; // what to do with that?
+ }
+
+ m_url = url;
+ QString host = url.host().isEmpty() ?
+ QString::fromLatin1("localhost") : url.host();
+
+ m_hostCombo->setCurrentItem( host );
+
+ // urls we need to download before starting the query
+ KURL::List downloadList;
+
+ m_queryList.clear();
+ QString param = url.queryItem( "relevant" );
+ QStringList list = QStringList::split( ';', param );
+
+ // we can only search by example on localhost
+ if ( host != "localhost" )
+ {
+ if ( !list.isEmpty() )
+ KMessageBox::sorry( m_view,
+ i18n("You can only search by example images "
+ "on a local indexing server."),
+ i18n("Only Local Servers Possible") );
+ }
+
+ else // localhost query
+ {
+ for( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ KURL u;
+ if ( (*it).at(0) == '/' )
+ u.setPath( *it );
+ else
+ u = *it;
+
+ if ( u.isValid() )
+ {
+ if ( u.isLocalFile() )
+ m_queryList.append( u );
+ else
+ downloadList.append( u );
+ }
+ }
+
+
+ // ### we need a real solution for this!
+ // gift refuses to start when no config file is available.
+ if ( !QFile::exists( m_config.mrmldDataDir() + "/gift-config.mrml" ) )
+ {
+ if ( KMessageBox::questionYesNo(0L,
+ i18n("There are no indexable folders "
+ "specified. Do you want to configure them "
+ "now?"),
+ i18n("Configuration Missing"),
+ i18n("Configure"),
+ i18n("Do Not Configure"),
+ "kmrml_ask_configure_gift" )
+ == KMessageBox::Yes )
+ {
+ KApplication::kdeinitExec( "kcmshell",
+ QString::fromLatin1("kcmkmrml"));
+ setStatus( NeedCollection );
+ return false;
+ }
+ }
+ }
+
+
+ if ( !downloadList.isEmpty() )
+ downloadReferenceFiles( downloadList );
+ else
+ contactServer( m_url );
+
+ return true;
+}
+
+void MrmlPart::contactServer( const KURL& url )
+{
+ m_job = transferJob( url );
+
+ m_job->addMetaData( MrmlShared::kio_task(), MrmlShared::kio_initialize() );
+
+ QString host = url.host().isEmpty() ?
+ QString::fromLatin1("localhost") : url.host();
+
+ slotSetStatusBar( i18n("Connecting to indexing server at %1...").arg( host ));
+}
+
+//
+// schedules a download all urls of downloadList (all remote and wellformed)
+// No other downloads are running (closeURL() has been called before)
+//
+void MrmlPart::downloadReferenceFiles( const KURL::List& downloadList )
+{
+ assert( m_downloadJobs.isEmpty() );
+
+ KURL::List::ConstIterator it = downloadList.begin();
+ for ( ; it != downloadList.end(); it++ )
+ {
+ QString extension;
+ int index = (*it).fileName().findRev( '.' );
+ if ( index != -1 )
+ extension = (*it).fileName().mid( index );
+
+ KTempFile tmpFile( QString::null, extension );
+ if ( tmpFile.status() != 0 )
+ {
+ kdWarning() << "Can't create temporary file, skipping: " << *it << endl;
+
+ continue;
+ }
+
+ m_tempFiles.append( tmpFile.name() );
+ KURL destURL;
+ destURL.setPath( tmpFile.name() );
+
+ KIO::FileCopyJob *job = KIO::file_copy( *it, destURL, -1,
+ true /* overwrite tmpfile */ );
+ connect( job, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotDownloadResult( KIO::Job * ) ));
+ m_downloadJobs.append( job );
+ // ### should this be only called for one job?
+ emit started( job );
+ }
+
+ if ( !m_downloadJobs.isEmpty() )
+ slotSetStatusBar( i18n("Downloading reference files...") );
+ else // probably never happens
+ contactServer( m_url );
+}
+
+bool MrmlPart::closeURL()
+{
+ m_view->stopDownloads();
+ m_view->clear();
+
+ QPtrListIterator<KIO::FileCopyJob> it( m_downloadJobs );
+ for ( ; it.current(); ++it )
+ it.current()->kill();
+ m_downloadJobs.clear();
+
+ QStringList::Iterator tit = m_tempFiles.begin();
+ for ( ; tit != m_tempFiles.end(); ++tit )
+ QFile::remove( *tit );
+ m_tempFiles.clear();
+
+ if ( m_job ) {
+ m_job->kill();
+ m_job = 0L;
+ }
+
+ setStatus( NeedCollection );
+
+ return true;
+}
+
+KIO::TransferJob * MrmlPart::transferJob( const KURL& url )
+{
+ KIO::TransferJob *job = KIO::get( url, true, false ); // reload, no gui
+ job->setAutoErrorHandlingEnabled( true, m_view );
+ connect( job, SIGNAL( result( KIO::Job * )),
+ SLOT( slotResult( KIO::Job * )));
+ connect( job, SIGNAL( data( KIO::Job *, const QByteArray& )),
+ SLOT( slotData( KIO::Job *, const QByteArray& )));
+
+// ###
+// connect( job, SIGNAL( infoMessage( KIO::Job *, const QString& )),
+// SLOT( slotResult( KIO::Job *, const QString& )));
+
+ job->setWindow( widget() );
+ if ( !m_sessionId.isEmpty() )
+ job->addMetaData( MrmlShared::sessionId(), m_sessionId );
+
+ emit started( job );
+ emit setWindowCaption( url.prettyURL() );
+ setStatus( InProgress );
+
+ return job;
+}
+
+void MrmlPart::slotResult( KIO::Job *job )
+{
+ if ( job == m_job )
+ m_job = 0L;
+
+ slotSetStatusBar( QString::null );
+
+ if ( !job->error() )
+ emit completed();
+ else {
+ emit canceled( job->errorString() );
+// qDebug("*** canceled: error: %s", job->errorString().latin1());
+ }
+
+
+ bool auto_random = m_view->isEmpty() && m_queryList.isEmpty();
+ m_random->setChecked( auto_random );
+ m_random->setEnabled( !auto_random );
+ setStatus( job->error() ? NeedCollection : CanSearch );
+
+ if ( !job->error() && !m_queryList.isEmpty() ) {
+ // we have a connection and we got a list of relevant URLs to query for
+ // (via the URL)
+
+ createQuery( &m_queryList );
+ m_queryList.clear();
+ }
+}
+
+// ### when user cancels download, we crash :(
+void MrmlPart::slotDownloadResult( KIO::Job *job )
+{
+ assert( job->inherits( "KIO::FileCopyJob" ) );
+ KIO::FileCopyJob *copyJob = static_cast<KIO::FileCopyJob*>( job );
+
+ if ( !copyJob->error() )
+ m_queryList.append( copyJob->destURL() );
+
+ m_downloadJobs.removeRef( copyJob );
+
+ if ( m_downloadJobs.isEmpty() ) // finally, we can start the query!
+ {
+ if ( m_queryList.isEmpty() ) // rather unlikely, but could happen ;)
+ {
+ kdWarning() << "Couldn't download the reference files. Will start a random search now" << endl;
+ }
+
+ contactServer( m_url );
+ }
+}
+
+// mrml-document in the bytearray
+void MrmlPart::slotData( KIO::Job *, const QByteArray& data )
+{
+ if ( data.isEmpty() )
+ return;
+
+ QDomDocument doc;
+ doc.setContent( data );
+
+ if ( !doc.isNull() )
+ parseMrml( doc );
+}
+
+void MrmlPart::parseMrml( QDomDocument& doc )
+{
+ QDomNode mrml = doc.documentElement(); // root element
+ if ( !mrml.isNull() ) {
+ QDomNode child = mrml.firstChild();
+ for ( ; !child.isNull(); child = child.nextSibling() ) {
+// qDebug("**** HERE %s", child.nodeName().latin1());
+ if ( child.isElement() ) {
+ QDomElement elem = child.toElement();
+
+ QString tagName = elem.tagName();
+
+ if ( tagName == "acknowledge-session-op" )
+ m_sessionId = elem.attribute( MrmlShared::sessionId() );
+
+ else if ( tagName == MrmlShared::algorithmList() ) {
+ initAlgorithms( elem );
+ }
+
+ else if ( tagName == MrmlShared::collectionList() ) {
+ initCollections( elem );
+ }
+
+ else if ( tagName == "error" ) {
+ KMessageBox::information( widget(),
+ i18n("Server returned error:\n%1\n")
+ .arg( elem.attribute( "message" )),
+ i18n("Server Error") );
+ }
+
+ else if ( tagName == "query-result" ) {
+ m_view->clear();
+ parseQueryResult( elem );
+ }
+
+
+ } // child.isElement()
+ }
+ } // !mrml.isNull()
+}
+
+void MrmlPart::parseQueryResult( QDomElement& queryResult )
+{
+ QDomNode child = queryResult.firstChild();
+ for ( ; !child.isNull(); child = child.nextSibling() ) {
+ if ( child.isElement() ) {
+ QDomElement elem = child.toElement();
+ QString tagName = elem.tagName();
+
+ if ( tagName == "query-result-element-list" ) {
+ QValueList<QDomElement> list =
+ KMrml::directChildElements( elem, "query-result-element" );
+
+ QValueListConstIterator<QDomElement> it = list.begin();
+ for ( ; it != list.end(); ++it )
+ {
+ QDomNamedNodeMap a = (*it).attributes();
+ m_view->addItem( KURL( (*it).attribute("image-location" ) ),
+ KURL( (*it).attribute("thumbnail-location" ) ),
+ (*it).attribute("calculated-similarity"));
+
+ }
+ }
+
+ else if ( tagName == "query-result" )
+ parseQueryResult( elem );
+ }
+ }
+}
+
+// creates/stops the query when the Start/Stop button was pressed
+void MrmlPart::slotStartClicked()
+{
+ if ( m_status == InProgress )
+ {
+ closeURL();
+ m_startButton->setText( i18n("&Search" ) );
+ return;
+ }
+
+ // we need to reconnect, if the initial openURL() didn't work due to
+ // the gift not being available.
+ if ( m_status == NeedCollection )
+ {
+ openURL( m_url );
+ return;
+ }
+
+ // cut off an eventual query and reference from the url, when the user
+ // performs a real query (otherwise restoreState() would restore and
+ // re-do the query from the URL
+ m_url.setRef( QString::null );
+ m_url.setQuery( QString::null );
+
+ createQuery();
+ m_browser->openURLNotify();
+}
+
+//
+// relevantItems is 0L when called from slotStartClicked() and set to a
+// non-empty list when called initially, from the commandline.
+//
+void MrmlPart::createQuery( const KURL::List * relevantItems )
+{
+ if ( relevantItems && relevantItems->isEmpty() )
+ return;
+
+ QDomDocument doc( "mrml" );
+ QDomElement mrml = MrmlCreator::createMrml( doc,
+ sessionId(),
+ transactionId() );
+
+ Collection coll = currentCollection();
+// qDebug("** collection: name: %s, id: %s, valid: %i", coll.name().latin1(), coll.id().latin1(), coll.isValid());
+ Algorithm algo = firstAlgorithmForCollection( coll );
+// qDebug("** algorithm: name: %s, id: %s, valid: %i, collection-id: %s", algo.name().latin1(), algo.id().latin1(), algo.isValid(), algo.collectionId().latin1());
+
+ if ( algo.isValid() )
+ {
+ MrmlCreator::configureSession( mrml, algo, sessionId() );
+ }
+
+ QDomElement query = MrmlCreator::addQuery( mrml,
+ m_resultSizeInput->value() );
+ if ( algo.isValid() )
+ query.setAttribute( MrmlShared::algorithmId(), algo.id() );
+
+ // ### result-cutoff, query-type?
+
+ // start-up with/without urls on the commandline via mrmlsearch
+ if ( relevantItems )
+ {
+ QDomElement elem = MrmlCreator::addRelevanceList( query );
+ KURL::List::ConstIterator it = relevantItems->begin();
+ for ( ; it != relevantItems->end(); ++it )
+ MrmlCreator::createRelevanceElement( doc, elem, (*it).url(),
+ MrmlCreator::Relevant );
+ }
+
+ // get relevant items from the view? Only do this when relevantItems is 0L
+ else if ( !m_random->isChecked() )
+ {
+ QDomElement relevants = MrmlCreator::addRelevanceList( query );
+ m_view->addRelevanceToQuery( doc, relevants );
+ }
+
+ performQuery( doc );
+}
+
+Collection MrmlPart::currentCollection() const
+{
+ return m_collectionCombo->current();
+}
+
+Algorithm MrmlPart::firstAlgorithmForCollection( const Collection& coll ) const
+{
+ if ( !m_algorithms.isEmpty() )
+ {
+ AlgorithmList::ConstIterator it = m_algorithms.begin();
+ for ( ; it != m_algorithms.end(); ++it )
+ {
+ Algorithm algo = *it;
+ if ( algo.paradigms().matches( coll.paradigms() ) )
+ {
+ algo.setCollectionId( coll.id() );
+ return algo;
+ }
+ }
+ }
+
+ qDebug("#################### -> ADEFAULT!");
+ Algorithm algo = Algorithm::defaultAlgorithm();
+ algo.setCollectionId( coll.id() );
+ return algo;
+}
+
+// emits the given QDomDocument for eventual plugins, checks after that
+// if there are any relevance elements. If there are none, random search is
+// implied and performed.
+// finally, the search is actually started
+void MrmlPart::performQuery( QDomDocument& doc )
+{
+ QDomElement mrml = doc.documentElement();
+
+ emit aboutToStartQuery( doc ); // let plugins play with it :)
+
+ // no items available? All "neutral"? -> random search
+
+ QDomElement queryStep = KMrml::firstChildElement( mrml, "query-step" );
+ bool randomSearch = false;
+
+ if ( !queryStep.isNull() )
+ {
+ QDomElement relevanceList =
+ KMrml::firstChildElement(queryStep, "user-relevance-element-list");
+ QValueList<QDomElement> relevanceElements =
+ KMrml::directChildElements( relevanceList,
+ "user-relevance-element" );
+
+ randomSearch = relevanceElements.isEmpty();
+
+ if ( randomSearch )
+ {
+ m_random->setChecked( true );
+ m_random->setEnabled( false );
+ queryStep.setAttribute("query-type", "at-random");
+
+ // remove user-relevance-element-list element for random search
+ relevanceList.parentNode().removeChild( relevanceList );
+ }
+ }
+ else
+ {
+ KMessageBox::error( m_view, i18n("Error formulating the query. The "
+ "\"query-step\" element is missing."),
+ i18n("Query Error") );
+ }
+
+ m_job = transferJob( url() );
+ slotSetStatusBar( randomSearch ? i18n("Random search...") :
+ i18n("Searching...") );
+ m_job->addMetaData( MrmlShared::kio_task(), MrmlShared::kio_startQuery() );
+ qDebug("\n\nSending XML:\n%s", doc.toString().latin1());
+ m_job->addMetaData( MrmlShared::mrml_data(), doc.toString() );
+}
+
+void MrmlPart::slotSetStatusBar( const QString& text )
+{
+ if ( text.isEmpty() )
+ emit setStatusBarText( i18n("Ready.") );
+ else
+ emit setStatusBarText( text );
+}
+
+void MrmlPart::slotActivated( const KURL& url, ButtonState button )
+{
+ if ( button == LeftButton )
+ emit m_browser->openURLRequest( url );
+ else if ( button == MidButton )
+ emit m_browser->createNewWindow( url );
+ else if ( button == RightButton ) {
+ // enableExtensionActions( url, true ); // for now
+ emit m_browser->popupMenu( QCursor::pos(), url, QString::null );
+ // enableExtensionActions( url, false );
+ }
+}
+
+void MrmlPart::enableExtensionActions( const KURL& url, bool enable )
+{
+ bool del = KProtocolInfo::supportsDeleting( url );
+ emit m_browser->enableAction( "copy", enable );
+ emit m_browser->enableAction( "trash", del );
+ emit m_browser->enableAction( "del", del );
+ emit m_browser->enableAction( "shred", url.isLocalFile() );
+ emit m_browser->enableAction( "properties", enable );
+ // emit m_browser->enableAction( "print", enable ); // ### later
+}
+
+
+// only implemented because it's abstract in the baseclass
+bool MrmlPart::openFile()
+{
+ return false;
+}
+
+void MrmlPart::slotConfigureAlgorithm()
+{
+ m_algoButton->setEnabled( false );
+
+ m_algoConfig = new AlgorithmDialog( m_algorithms, m_collections,
+ currentCollection(),
+ m_view, "algorithm configuration" );
+ connect( m_algoConfig, SIGNAL( applyClicked() ),
+ SLOT( slotApplyAlgoConfig() ));
+ connect( m_algoConfig, SIGNAL( finished() ),
+ SLOT( slotAlgoConfigFinished() ));
+
+ m_algoConfig->show();
+}
+
+void MrmlPart::slotApplyAlgoConfig()
+{
+ // ###
+}
+
+void MrmlPart::slotAlgoConfigFinished()
+{
+ if ( m_algoConfig->result() == QDialog::Accepted )
+ slotApplyAlgoConfig();
+
+ m_algoButton->setEnabled( true );
+ m_algoConfig->deleteLater();
+ m_algoConfig = 0L;
+}
+
+void MrmlPart::initHostCombo()
+{
+ m_hostCombo->clear();
+ m_hostCombo->insertStringList( m_config.hosts() );
+}
+
+void MrmlPart::slotHostComboActivated( const QString& host )
+{
+ ServerSettings settings = m_config.settingsForHost( host );
+ openURL( settings.getUrl() );
+}
+
+void MrmlPart::setStatus( Status status )
+{
+ switch ( status )
+ {
+ case NeedCollection:
+ m_startButton->setText( i18n("&Connect") );
+ break;
+ case CanSearch:
+ m_startButton->setText( i18n("&Search") );
+ break;
+ case InProgress:
+ m_startButton->setText( i18n("Sto&p") );
+ break;
+ };
+
+ m_status = status;
+}
+
+
+void MrmlPart::saveState( QDataStream& stream )
+{
+ stream << url();
+ stream << m_sessionId;
+ stream << m_queryList;
+// stream << m_algorithms;
+// stream << m_collections;
+
+ stream << m_resultSizeInput->value();
+ stream << *m_collectionCombo;
+
+ m_view->saveState( stream );
+}
+
+void MrmlPart::restoreState( QDataStream& stream )
+{
+ KURL url;
+ stream >> url;
+
+ stream >> m_sessionId;
+ stream >> m_queryList;
+// stream >> m_algorithms;
+// stream >> m_collections;
+
+ int resultSize;
+ stream >> resultSize;
+ m_resultSizeInput->setValue( resultSize );
+ stream >> *m_collectionCombo;
+
+ m_view->restoreState( stream );
+
+// openURL( url );
+ m_url = url;
+}
+
+KAboutData * MrmlPart::createAboutData()
+{
+ KAboutData *data = new KAboutData(
+ "kmrml",
+ I18N_NOOP("MRML Client for KDE"),
+ KMRML_VERSION,
+ I18N_NOOP("A tool to search for images by their content"),
+ KAboutData::License_GPL,
+ I18N_NOOP("(c) 2001-2002, Carsten Pfeiffer"),
+ 0,
+ I18N_NOOP("http://devel-home.kde.org/~pfeiffer/kmrml/") );
+
+ data->addAuthor( "Carsten Pfeiffer",
+ I18N_NOOP("Developer, Maintainer"),
+ "pfeiffer@kde.org" );
+ data->addCredit( "Wolfgang Mller",
+ I18N_NOOP("Developer of the GIFT, Helping Hand") );
+
+ return data;
+}
+
+///////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////
+
+#include "mrml_part.moc"