/* This file is part of libkresources Copyright (c) 2001 Cornelius Schumacher Copyright (c) 2002 Jan-Pascal van Best This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef KRESOURCES_RESOURCE_H #define KRESOURCES_RESOURCE_H //US #ifdef QT_THREAD_SUPPORT #include #endif //QT_THREAD_SUPPORT #include #include #include #include class KConfig; namespace KRES { class ConfigWidget; class SyncWidgetContainer; /** * @internal * @libdoc The KDE Resource library * * NOTE: this library is NOT (YET?) PUBLIC. Do not publish this * interface, it is in constant flux. * * The KDE Resource framework can be used to manage resources of * different types, organized in families. The Resource framework * is currently used for addressbook resources in libkabc and for * calendar resources in libkcal. * * When you want to use the framework for a new family, you need to *
  • Define a name for your resource family
  • *
  • subclass Resource and add the fields and method that are needed * in your application
  • *
  • If needed, override the doOpen() and doClose() methods. *
  • Provide a configuration possibility for resources in your * new family. You can use @ref ResourcesConfigPage to easily create a * KControl applet
  • *
  • In your application, you can use @ref ResourceManager to keep track * of the resources in your family, and you can use @ref ResourceSelectDialog * to let the user select a single resource.
  • *
* * When you want to add a new resource type to an existing resource family, * you need to *
  • Further subclass the family-specific Resource to implement * resource type-specific operation
  • *
  • Subclass ResourceConfigWidget to provide a configuration widget * for your new resource type
  • *
  • Provide a .desktop file so that the new resource type can be found * automatically by the ResourceManager
  • *
* * Example: * resourceexample.h:
#include 
#include 

class ResourceExample : public KRES::ResourceExample
{
public:
  ResourceExample( const KConfig * );
  ~ResourceCalendarExchange();
  void writeConfig( KConfig *config );
private:
  QString mLocation;
  QString mPassword;
}
resourceexample.cpp:
#include 

#include "resourceexample.h"

ResourceExample::ResourceExample( const KConfig *config )
    : Resource( config )
{
  if ( config ) {
    mLocation = config->readEntry( "Location" );
    mPassword = KStringHandler::obscure( config->readEntry( "Password" ) );
  } else {
    mLocation = ""; // Or some sensible default
    mPassword = "";
  }
}

void ResourceExample::writeConfig( KConfig *config )
{
  KRES::Resource::writeConfig( config );
  config->writeEntry( "Location", mLocation );
  config->writeEntry( "Password", KStringHandler::obscure( mPassword ) );
}

extern "C"
{
  KRES::ResourceExample *config_widget( QWidget *parent ) {
    return new ResourceExampleConfig( parent, "Configure Example Resource" );
  }

  KRES::Resource *resource( const KConfig *config ) {
    return new ResourceExample( config );
  }
}
* resourceexampleconfig.h:
#include 
#include 

#include "resourceexample.h"

class ResourceExampleConfig : public KRES::ResourceConfigWidget
{
  Q_OBJECT

public:
  ResourceExampleConfig( QWidget* parent = 0, const char* name = 0 );

public slots:
  virtual void loadSettings( KRES::Resource *resource);
  virtual void saveSettings( KRES::Resource *resource );

private:
  KLineEdit* mLocationEdit;
  KLineEdit* mPasswordEdit;
};
* resourceexampleconfig.cpp:
#include 
#include 
#include "resourceexample.h"
#include "resourceexampleconfig.h"

ResourceExampleConfig::ResourceExampleConfig( QWidget* parent,  const char* name )
    : KRES::ResourceConfigWidget( parent, name )
{
  resize( 245, 115 );
  QGridLayout *mainLayout = new QGridLayout( this, 2, 2 );

  QLabel *label = new QLabel( i18n( "Location:" ), this );
  mHostEdit = new KLineEdit( this );
  mainLayout->addWidget( label, 1, 0 );
  mainLayout->addWidget( mHostEdit, 1, 1 );

  label = new QLabel( i18n( "Password:" ), this );
  mPasswordEdit = new KLineEdit( this );
  mPasswordEdit->setEchoMode( QLineEdit::Password );
  mainLayout->addWidget( label, 2, 0 );
  mainLayout->addWidget( mPasswordEdit, 2, 1 );
}

void ResourceExampleConfig::loadSettings( KRES::Resource *resource )
{
  ResourceExample* res = dynamic_cast( resource );
  if (res) {
    mHostEdit->setText( res->host() );
    mPasswordEdit->setText( res->password() );
  } else
    kdDebug(5700) << "ERROR: ResourceExampleConfig::loadSettings(): no ResourceExample, cast failed" << endl;
}

void ResourceExampleConfig::saveSettings( KRES::Resource *resource )
{
  ResourceExample* res = dynamic_cast( resource );
  if (res) {
    res->setHost(mHostEdit->text());
    res->setPassword(mPasswordEdit->text());
  } else
    kdDebug(5700) << "ERROR: ResourceExampleConfig::saveSettings(): no ResourceExample, cast failed" << endl;
}
* resourceexample.desktop:
[Desktop Entry]
Type=Service

[Misc]
Encoding=UTF-8
Name=Example Resource

[Plugin]
Type=exchange
X-KDE-Library=resourceexample
* Makefile.am
kde_module_LTLIBRARIES = resourceexample.la

resourceexample_la_SOURCES = resourceexample.cpp resourceexampleconfig.cpp
resourceexample_la_LDFLAGS= $(all_libraries) -module $(KDE_PLUGIN)
resourceexample_la_LIBADD= -lkderesources

linkdir= $(kde_datadir)/resources/family
link_DATA= resourceexample.desktop
* * */ /** * A @ref Resource is a ... * * A subclass should reimplement at least the constructor and the * @ref writeConfig method. * */ class Resource : public QObject { Q_OBJECT public: typedef QValueList List; /** * Constructor. Construct resource from config. * @param config Configuration to read persistence information from. * If config==0, create object using default settings. */ Resource( const KConfig* config ); /** * Destructor. */ virtual ~Resource(); /** * Write configuration information for this resource to a configuration * file. If you override this method, remember to call Resource::writeConfig * or Terrible Things(TM) will happen. * @param config Configuration to write persistence information to. */ virtual void writeConfig( KConfig* config ); /** * Open this resource, if it not already open. Increase the open * count of this object, and open the resource by calling @ref doOpen(). * This method may block while another thread is concurrently opening * or closing the resource. * * Returns true if the resource was already opened or if it was opened * successfully; returns false if the resource was not opened successfully. */ bool open(); /** * Decrease the open count of this object, and if the count reaches * zero, close this resource by calling @ref doClose(). * This method may block while another thread is concurrently closing * or opening the resource. */ void close(); /** * Returns whether the resource is open or not. */ bool isOpen() const; /** * Returns a unique identifier. The identifier is unique for this resource. * It is created when the resource is first created, and it is retained * in the resource family configuration file for this resource. * @return This resource's identifier */ QString identifier() const; /** * Returns the type of this resource. */ QString type() const; /** * Mark the resource as read-only. You can override this method, * but also remember to call Resource::setReadOnly(). */ virtual void setReadOnly( bool value ); /** * Returns, if the resource is read-only. */ virtual bool readOnly() const; void setIncludeInSync( bool value ); bool includeInSync() const; /** * Set the name of resource.You can override this method, * but also remember to call Resource::setResourceName(). */ virtual void setResourceName( const QString &name ); /** * Returns the name of resource. */ virtual QString resourceName() const; virtual bool isSyncable() const = 0; /** Sets, if the resource is active. */ void setActive( bool active ); /** Return true, if the resource is active. */ bool isActive() const; friend class Factory; friend class ManagerImpl; /** Print resource information as debug output. */ virtual void dump() const; protected: /** * Open this resource. When called, the resource must be in * a closed state. * * Returns true if the resource was opened successfully; * returns false if the resource was not opened successfully. * * The result of this call can be accessed later by @ref isOpen() */ virtual bool doOpen() { return true; } /** * Close this resource. Pre-condition: resource is open. * Post-condition: resource is closed. */ virtual void doClose() {} void setIdentifier( const QString& identifier ); void setType( const QString& type ); private: class ResourcePrivate; ResourcePrivate *d; }; class PluginFactoryBase : public KLibFactory { public: virtual Resource *resource( const KConfig *config, bool syncable ) = 0; virtual ConfigWidget *configWidget( QWidget *parent ) = 0; virtual SyncWidgetContainer *syncWidgetContainer() = 0; protected: virtual QObject* createObject( QObject*, const char*, const char*, const QStringList & ) { return 0; } }; template class PluginFactory : public PluginFactoryBase { public: Resource *resource( const KConfig *config, bool syncable ) { return new TR( config, syncable ); } ConfigWidget *configWidget( QWidget *parent ) { return new TC( parent ); } SyncWidgetContainer *syncWidgetContainer() { return new TS(); } }; } #endif