• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdelibs API Reference
  • KDE Home
  • Contact Us
 

kjsembed

  • sources
  • kde-4.12
  • kdelibs
  • kjsembed
  • kjsembed
variant_binding.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE libraries
2  Copyright (C) 2005, 2006 Ian Reinhart Geiser <geiseri@kde.org>
3  Copyright (C) 2005, 2006 Matt Broadstone <mbroadst@gmail.com>
4  Copyright (C) 2005, 2006 Richard J. Moore <rich@kde.org>
5  Copyright (C) 2005, 2006 Erik L. Bunce <kde@bunce.us>
6  Copyright (C) 2007, 2008 Sebastian Sauer <mail@dipe.org>
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Library General Public
10  License as published by the Free Software Foundation; either
11  version 2 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Library General Public License for more details.
17 
18  You should have received a copy of the GNU Library General Public License
19  along with this library; see the file COPYING.LIB. If not, write to
20  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  Boston, MA 02110-1301, USA.
22 */
23 
24 #include "variant_binding.h"
25 
26 #include <stdlib.h>
27 
28 #include <kjs/PropertyNameArray.h>
29 #include <kjs/array_instance.h>
30 
31 #include <QtCore/QBitRef>
32 #include <QtCore/QByteRef>
33 #include <QtCore/QDebug>
34 #include <QtCore/QObject>
35 #include <QtGui/QWidget>
36 
37 #include "kjseglobal.h"
38 #include "static_binding.h"
39 #include "qobject_binding.h"
40 
41 //#define KJSEMBED_VARIANT_DEBUG
42 
43 using namespace KJSEmbed;
44 
45 const KJS::ClassInfo VariantBinding::info = { "VariantBinding", 0, 0, 0 };
46 
47 VariantBinding::VariantBinding( KJS::ExecState *exec, const QVariant &value )
48  : ProxyBinding(exec), m_value(value)
49 {
50  StaticBinding::publish( exec, this, VariantFactory::methods() );
51 }
52 
53 void *VariantBinding::pointer()
54 {
55  return m_value.data();
56 }
57 
58 KJS::UString VariantBinding::toString(KJS::ExecState *) const
59 {
60  return toUString(m_value.toString());
61 }
62 
63 KJS::UString VariantBinding::className() const
64 {
65  return m_value.typeName();
66 }
67 
68 QVariant VariantBinding::variant() const
69 {
70  return m_value;
71 }
72 
73 void VariantBinding::setValue( const QVariant &val )
74 {
75  m_value = val;
76 }
77 
78 QGenericArgument VariantBinding::arg(const char *type) const
79 {
80  const void *p = m_value.constData();
81  //qDebug("Ptr %0x", p );
82  //qDebug() << p;
83  return QGenericArgument( type, p );
84 }
85 
86 KJS::JSValue *callName( KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args )
87 {
88  Q_UNUSED( args );
89  KJSEmbed::VariantBinding *imp = KJSEmbed::extractBindingImp<KJSEmbed::VariantBinding>(exec, self);
90  return imp ? KJS::jsString( imp->variant().typeName() ) : KJS::jsNull();
91 }
92 
93 KJS::JSValue *callCast( KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args )
94 {
95  KJSEmbed::VariantBinding *imp = KJSEmbed::extractBindingImp<KJSEmbed::VariantBinding>(exec, self );
96  if( imp )
97  {
98  QVariant val = imp->variant();
99  QVariant::Type type = QVariant::nameToType( args[0]->toString(exec).ascii() );
100  KJS::JSValue *returnValue = KJS::jsBoolean(val.convert(type));
101  imp->setValue(val);
102  return returnValue;
103  }
104  return KJS::jsNull();
105 }
106 
107 KJS::JSValue *callToString( KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args )
108 {
109  Q_UNUSED( args );
110  KJSEmbed::VariantBinding *imp = KJSEmbed::extractBindingImp<KJSEmbed::VariantBinding>(exec, self );
111  if( imp )
112  {
113  //qDebug("Call value to string");
114  QVariant val = imp->variant();
115  QString stringVal = val.toString();
116  if( !stringVal.isEmpty() )
117  return KJS::jsString( val.toString() );
118  return KJS::jsString( val.typeName() );
119  }
120  return KJS::jsNull();
121 }
122 
123 const Method VariantFactory::VariantMethods[] =
124 {
125  {"cast", 1, KJS::DontDelete|KJS::ReadOnly|KJS::DontEnum, &callCast },
126  {"toString", 0, KJS::DontDelete|KJS::ReadOnly|KJS::DontEnum, &callToString },
127  {0, 0, 0, 0 }
128 };
129 
130 enum JavaScriptArrayType { None, List, Map };
131 
132 JavaScriptArrayType checkArray( KJS::ExecState *exec, KJS::JSValue *val )
133 {
134  KJS::JSObject *obj = val->toObject( exec );
135  if ( toQString(obj->className()) == "Array" )
136  {
137  if( !obj->hasProperty(exec, KJS::Identifier("length")) )
138  return Map;
139  KJS::JSValue *jslen = obj->get(exec, KJS::Identifier("length"));
140  const int len = jslen->toNumber(exec);
141  if ( len > 0 ) {
142  QByteArray buff;
143  buff.setNum(len-1);
144  if( !obj->hasProperty(exec, KJS::Identifier( buff.data() ) ) )
145  return Map;
146  }
147  return List;
148  }
149  else
150  return None;
151 }
152 
153 QMap<QString, QVariant> KJSEmbed::convertArrayToMap( KJS::ExecState *exec, KJS::JSValue *value )
154 {
155  QMap<QString, QVariant> returnMap;
156  KJS::JSObject *obj = value->toObject(exec);
157  KJS::PropertyNameArray lst;
158  obj->getPropertyNames(exec, lst);
159  KJS::PropertyNameArrayIterator idx = lst.begin();
160  for( ; idx != lst.end(); idx++ )
161  {
162  KJS::Identifier id = *idx;
163  KJS::JSValue *val = obj->get(exec, id);
164  returnMap[toQString(id)] = convertToVariant(exec,val);
165  }
166  return returnMap;
167 }
168 
169 QList<QVariant> KJSEmbed::convertArrayToList( KJS::ExecState *exec, KJS::JSValue *value )
170 {
171  QList<QVariant> returnList;
172  /*
173  KJS::JSObject *obj = value->toObject( exec );
174  if ( toQString(obj->className() == "Array" )
175  {
176  int length = int(obj->get( exec, KJS::Identifier( "length" ) )->toInteger( exec ) );
177  for ( int index = 0; index < length; ++index )
178  {
179  QByteArray buff;
180  buff.setNum(index);
181  KJS::JSValue *val = obj->get(exec, KJS::Identifier( buff.data() ) );
182  if( val )
183  returnList += convertToVariant(exec, val );
184  else
185  returnList += QVariant();
186  }
187  }
188  */
189  KJS::ArrayInstance* arrayImp = extractBindingImp<KJS::ArrayInstance>(exec, value);
190  if(arrayImp)
191  {
192  const unsigned numItems = arrayImp->getLength();
193  for ( unsigned i = 0; i < numItems; ++i )
194  returnList.append( convertToVariant(exec, arrayImp->getItem(i)) );
195  }
196  return returnList;
197 }
198 
199 QStringList KJSEmbed::convertArrayToStringList( KJS::ExecState *exec, KJS::JSValue *value )
200 {
201  QStringList returnList;
202  /*
203  KJS::JSObject *obj = value->toObject( exec );
204  if ( toQString(obj->className()) == "Array" )
205  {
206  int length = int( obj->get( exec, KJS::Identifier( "length" ) )->toInteger( exec ) );
207  for ( int index = 0; index < length; ++index )
208  {
209  QByteArray buff;
210  buff.setNum(index);
211  KJS::JSValue *val = obj->get(exec, KJS::Identifier( buff.data() ) );
212  if( val )
213  returnList += convertToVariant(exec, val ).value<QString>();
214  else
215  returnList += QString();
216  }
217  }
218  */
219  KJS::ArrayInstance* arrayImp = extractBindingImp<KJS::ArrayInstance>(exec, value);
220  if(arrayImp)
221  {
222  const unsigned numItems = arrayImp->getLength();
223  for ( unsigned i = 0; i < numItems; ++i )
224  returnList.append( convertToVariant(exec, arrayImp->getItem(i)).toString() );
225  }
226  return returnList;
227 }
228 
229 QDateTime convertDateToDateTime( KJS::ExecState *exec, KJS::JSValue *value )
230 {
231  KJS::List args;
232  QDateTime returnDateTime;
233  KJS::JSObject *obj = value->toObject( exec );
234  if ( toQString(obj->className()) == "Date" )
235  {
236  int seconds = int( obj->get( exec, KJS::Identifier( "getSeconds" ) )->toObject( exec )->call( exec, obj, args )->toInteger( exec ) );
237  int minutes = int( obj->get( exec, KJS::Identifier( "getMinutes" ) )->toObject( exec )->call( exec, obj, args )->toInteger( exec ) );
238  int hours = int( obj->get( exec, KJS::Identifier( "getHours" ) )->toObject( exec )->call( exec, obj, args )->toInteger( exec ) );
239  int month = int( obj->get( exec, KJS::Identifier( "getMonth" ) )->toObject( exec )->call( exec, obj, args )->toInteger( exec ) );
240  int day = int( obj->get( exec, KJS::Identifier( "getDate" ) )->toObject( exec )->call( exec, obj, args )->toInteger( exec ) );
241  int year = int( obj->get( exec, KJS::Identifier( "getFullYear" ) )->toObject( exec )->call( exec, obj, args )->toInteger( exec ) );
242  returnDateTime.setDate( QDate( year, month + 1, day ) );
243  returnDateTime.setTime( QTime( hours, minutes, seconds ) );
244  }
245  else
246  {
247  // Throw error
248  }
249 
250  return returnDateTime;
251 }
252 
253 QVariant KJSEmbed::convertToVariant( KJS::ExecState *exec, KJS::JSValue *value )
254 {
255 #ifdef KJSEMBED_VARIANT_DEBUG
256  qDebug()<<"KJSEmbed::convertToVariant";
257 #endif
258 
259  QVariant returnValue;
260  switch( value->type() )
261  {
262  case KJS::UndefinedType:
263  case KJS::NullType:
264  break;
265  case KJS::StringType:
266  returnValue = toQString(value->toString(exec));
267  break;
268  case KJS::NumberType:
269  returnValue = value->toNumber(exec);
270  break;
271  case KJS::BooleanType:
272  returnValue = value->toBoolean(exec);
273  break;
274  case KJS::ObjectType:
275  {
276  KJS::JSObject *obj = value->toObject(exec);
277  //qDebug() << "Object type: " << toQString(obj->className());
278  if ( toQString(obj->className()) == "Array" ) {
279  if (checkArray(exec, value) == List)
280  returnValue = convertArrayToList(exec, value);
281  else
282  returnValue = convertArrayToMap(exec, value);
283  }
284  else if ( toQString(obj->className()) == "Date" )
285  returnValue = convertDateToDateTime( exec, value );
286  else
287  returnValue = extractVariant(exec,value);
288  //if( returnValue.isNull() ) returnValue = toQString(value->toString(exec));
289  } break;
290  default:
291  returnValue = extractVariant(exec,value);
292  //if( returnValue.isNull() ) returnValue = toQString(value->toString(exec));
293  break;
294  }
295  return returnValue;
296 }
297 
298 KJS::JSValue *KJSEmbed::convertToValue( KJS::ExecState *exec, const QVariant &value )
299 {
300 #ifdef KJSEMBED_VARIANT_DEBUG
301  qDebug()<<"KJSEmbed::convertToValue typeid="<<value.type()<<"typename="<<value.typeName()<<"toString="<<value.toString();
302 #endif
303 
304  KJS::JSValue *returnValue;
305  switch( value.type() )
306  {
307  case QVariant::Invalid:
308  returnValue = KJS::jsNull();
309  break;
310  case QVariant::Int:
311  returnValue = KJS::jsNumber( value.value<int>() );
312  break;
313  case QVariant::UInt:
314  returnValue = KJS::jsNumber( value.value<unsigned int>() );
315  break;
316  case QVariant::LongLong:
317  returnValue = KJS::jsNumber( value.value<qlonglong>() );
318  break;
319  case QVariant::ULongLong:
320  returnValue = KJS::jsNumber( value.value<qulonglong>() );
321  break;
322  case QVariant::Double:
323  returnValue = KJS::jsNumber( value.value<double>() );
324  break;
325  case QVariant::Bool:
326  returnValue = KJS::jsBoolean( value.value<bool>() );
327  break;
328  case QVariant::ByteArray:
329  returnValue = KJS::jsString( QString(value.value<QByteArray>()) );
330  break;
331  case QVariant::String:
332  returnValue = KJS::jsString( value.value<QString>() );
333  break;
334  case QVariant::StringList:
335  {
336  KJS::List items;
337  QStringList lst = value.value<QStringList>();
338  QStringList::Iterator idx = lst.begin();
339  for ( ; idx != lst.end(); ++idx )
340  items.append( KJS::jsString( ( *idx ) ) );
341  returnValue = exec->lexicalInterpreter()->builtinArray()->construct( exec, items );
342  break;
343  }
344  case QVariant::Date: // fall through
345  case QVariant::DateTime: // fall through
346  case QVariant::Time:
347  {
348  QDateTime dt = QDateTime::currentDateTime();
349  if ( value.type() == QVariant::Date )
350  dt.setDate( value.toDate() );
351  else if ( value.type() == QVariant::Time )
352  dt.setTime( value.toTime() );
353  else
354  dt = value.toDateTime();
355 
356  KJS::List items;
357  items.append( KJS::jsNumber( dt.date().year() ) );
358  items.append( KJS::jsNumber( dt.date().month() - 1 ) );
359  items.append( KJS::jsNumber( dt.date().day() ) );
360  items.append( KJS::jsNumber( dt.time().hour() ) );
361  items.append( KJS::jsNumber( dt.time().minute() ) );
362  items.append( KJS::jsNumber( dt.time().second() ) );
363  items.append( KJS::jsNumber( dt.time().msec() ) );
364  returnValue = exec->lexicalInterpreter()->builtinDate()->construct( exec, items );
365  break;
366  }
367  case QVariant::List:
368  {
369  KJS::List items;
370  QList<QVariant> lst = value.toList();
371  foreach( const QVariant &item, lst)
372  items.append( convertToValue( exec, item ) );
373  returnValue = exec->lexicalInterpreter()->builtinArray()->construct( exec, items );
374  break;
375  }
376  case QVariant::Map:
377  {
378  QMap<QString,QVariant> map = value.toMap();
379  QMap<QString,QVariant>::Iterator idx = map.begin();
380  KJS::JSObject *obj = exec->lexicalInterpreter()->builtinObject()->construct( exec, KJS::List() );
381  for ( ; idx != map.end(); ++idx )
382  obj->put(exec, KJS::Identifier( toUString(idx.key()) ), convertToValue( exec, idx.value() ) );
383  returnValue = obj;
384  break;
385  }
386  default:
387  {
388  if( qVariantCanConvert< QWidget* >(value) ) {
389  QWidget* widget = qvariant_cast< QWidget* >(value);
390  returnValue = widget ? createQObject(exec, widget, KJSEmbed::ObjectBinding::CPPOwned) : KJS::jsNull();
391  }
392  else if( qVariantCanConvert< QObject* >(value) ) {
393  QObject* object = qvariant_cast< QObject* >(value);
394  returnValue = object ? createQObject(exec, object, KJSEmbed::ObjectBinding::CPPOwned) : KJS::jsNull();
395  }
396  else {
397  returnValue = createVariant(exec, value.typeName(), value );
398  if( returnValue->isNull() )
399  returnValue = KJS::jsString( value.value<QString>() );
400  }
401  break;
402  }
403  }
404  return returnValue;
405 }
406 
407 QVariant KJSEmbed::extractVariant( KJS::ExecState *exec, KJS::JSValue *value )
408 {
409 #ifdef KJSEMBED_VARIANT_DEBUG
410  qDebug()<<"KJSEmbed::extractVariant";
411 #endif
412 
413  KJSEmbed::VariantBinding *imp = KJSEmbed::extractBindingImp<KJSEmbed::VariantBinding>(exec, value );
414  if( imp )
415  return imp->variant();
416  if( value->type() == KJS::StringType)
417  return QVariant(toQString(value->toString(exec)));
418  if( value->type() == KJS::NumberType)
419  return QVariant(value->toNumber(exec));
420  if( value->type() == KJS::BooleanType)
421  return QVariant(value->toBoolean(exec));
422 
423  KJS::JSObject *obj = value->toObject( exec );
424  if ( obj ) {
425  if(QObjectBinding *objImp = KJSEmbed::extractBindingImp<QObjectBinding>(exec, value)) {
426  QVariant v;
427  if( QObject* qobj = objImp->qobject<QObject>() )
428  v.setValue(qobj);
429  return v;
430  }
431  if( toQString(obj->className()) == "Array" )
432  return convertArrayToList( exec, value );
433  }
434  return QVariant();
435 }
436 
437 //kate: indent-spaces on; indent-width 4; replace-tabs on; indent-mode cstyle;
KJSEmbed::convertToVariant
QVariant KJSEMBED_EXPORT convertToVariant(KJS::ExecState *exec, KJS::JSValue *value)
Convert a KJS::JSValue into a QVariant object.
Definition: variant_binding.cpp:253
KJSEmbed::VariantBinding::VariantBinding
VariantBinding(KJS::ExecState *exec, const QVariant &value)
Create a new binding implementation with a QVariant to wrap.
Definition: variant_binding.cpp:47
KJSEmbed::QObjectBinding
Definition: qobject_binding.h:79
KJSEmbed::VariantBinding::info
static const KJS::ClassInfo info
Definition: variant_binding.h:123
KJSEmbed::VariantBinding::className
KJS::UString className() const
Definition: variant_binding.cpp:63
None
Definition: variant_binding.cpp:130
KJSEmbed::convertArrayToStringList
QStringList KJSEMBED_EXPORT convertArrayToStringList(KJS::ExecState *exec, KJS::JSValue *value)
Convert a KJS::JSValue inot a QStringList.
Definition: variant_binding.cpp:199
KJSEmbed::StaticBinding::publish
static void publish(KJS::ExecState *exec, KJS::JSObject *object, const Method *methods)
Publishes an array of Methods to an object.
Definition: static_binding.cpp:60
KJSEmbed::VariantBinding
QVariant based binding.
Definition: variant_binding.h:88
KJSEmbed::convertArrayToMap
QMap< QString, QVariant > KJSEMBED_EXPORT convertArrayToMap(KJS::ExecState *exec, KJS::JSValue *value)
Convert a KJS::JSValue that contains an associative array into a QMap.
Definition: variant_binding.cpp:153
KJSEmbed::ProxyBinding
Definition: binding_support.h:247
KJSEmbed::createVariant
KJS::JSValue * createVariant(KJS::ExecState *exec, const KJS::UString &className, const T &value)
Can create any known KJSEmbed::VariantBinding object and set the value.
Definition: variant_binding.h:185
KJSEmbed::VariantBinding::toString
KJS::UString toString(KJS::ExecState *) const
Definition: variant_binding.cpp:58
QWidget
KJSEmbed::VariantFactory::VariantMethods
static const Method VariantMethods[]
Definition: variant_binding.h:250
DomElementNS::val
QString val
Definition: dom.cpp:529
widget
END_METHOD_LUT QSvgWidget * widget
Definition: svg_binding.cpp:106
checkArray
JavaScriptArrayType checkArray(KJS::ExecState *exec, KJS::JSValue *val)
Definition: variant_binding.cpp:132
KJSEmbed::VariantBinding::pointer
void * pointer()
Definition: variant_binding.cpp:53
QObject
DomNodeNS::map
END_VALUE_METHOD QDomNamedNodeMap map
Definition: dom.cpp:57
KJSEmbed::Method
Method structure.
Definition: binding_support.h:294
callCast
KJS::JSValue * callCast(KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args)
Definition: variant_binding.cpp:93
KJSEmbed::createQObject
KJSEMBED_EXPORT KJS::JSObject * createQObject(KJS::ExecState *exec, QObject *value, KJSEmbed::ObjectBinding::Ownership owner=KJSEmbed::ObjectBinding::JSOwned)
Returns a binding object for the specified QObject.
Definition: qobject_binding.cpp:735
convertDateToDateTime
QDateTime convertDateToDateTime(KJS::ExecState *exec, KJS::JSValue *value)
Definition: variant_binding.cpp:229
KJSEmbed::convertArrayToList
QList< QVariant > KJSEMBED_EXPORT convertArrayToList(KJS::ExecState *exec, KJS::JSValue *value)
Convert a KJS::JSValue into a QList.
Definition: variant_binding.cpp:169
KJSEmbed::ObjectBinding::CPPOwned
Definition: object_binding.h:91
JavaScriptArrayType
JavaScriptArrayType
Definition: variant_binding.cpp:130
KJSEmbed::VariantBinding::setValue
void setValue(const QVariant &val)
Set the internal value of the QVariant.
Definition: variant_binding.cpp:73
NodeListNS::idx
END_VALUE_METHOD int idx
Definition: dom.cpp:691
KJSEmbed::VariantFactory::methods
static const Method * methods()
Definition: variant_binding.h:251
kjseglobal.h
KJSEmbed::VariantBinding::variant
QVariant variant() const
Return the wrapped QVariant.
Definition: variant_binding.cpp:68
KJS::jsString
KJS::JSCell * jsString(const QString &s)
Definition: kjseglobal.h:73
List
Definition: variant_binding.cpp:130
static_binding.h
callName
KJS::JSValue * callName(KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args)
Definition: variant_binding.cpp:86
KJSEmbed::toUString
KJS::UString toUString(const QString &qs)
Definition: kjseglobal.h:66
KJSEmbed::convertToValue
KJSEMBED_EXPORT KJS::JSValue * convertToValue(KJS::ExecState *exec, const QVariant &value)
Convert a QVariant to a KJS::JSValue.
Definition: variant_binding.cpp:298
Map
Definition: variant_binding.cpp:130
KJSEmbed::VariantBinding::arg
QGenericArgument arg(const char *type) const
Constructs a QGenericArgument that is used with QMetaObject::invokeMember.
Definition: variant_binding.cpp:78
qobject_binding.h
variant_binding.h
value
QVariant value
Definition: settings.cpp:35
callToString
KJS::JSValue * callToString(KJS::ExecState *exec, KJS::JSObject *self, const KJS::List &args)
Definition: variant_binding.cpp:107
KJSEmbed::extractVariant
QVariant KJSEMBED_EXPORT extractVariant(KJS::ExecState *exec, KJS::JSValue *value)
Extracts a QVariant from a KJS::JSValue if the conversion fails a QVariant::Null is returned...
Definition: variant_binding.cpp:407
KJSEmbed::toQString
QString toQString(const KJS::UString &u)
Definition: kjseglobal.h:58
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:47:53 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kjsembed

Skip menu "kjsembed"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdelibs API Reference

Skip menu "kdelibs API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  • kjsembed
  •   WTF
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Nepomuk-Core
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal