You are not logged in.
Pages: 1
Hi everyone,
from what I understood, since Pacman 3 there is a library called libalpm that makes it easy to implement, let's say, a GUI for doing the same operations that you could do with pacman. And what I understood is that libalpm is written in C.
My question is: has libalpm been ported to python or are there any plans to do it? Sorry if that ahs already been asked, but by searching around in forums and wiki I haven't found almost anything about this topic.
Thanks a lot
Offline
Read this :
http://bbs.archlinux.org/viewtopic.php?id=34971
However, I am afraid Stiat is still as busy, and that this pyalpm project was pretty dead these last months.
I am not sure if Cx really contributed anything, but I could be wrong.
Anyway, it's never too late for you to wake it up You should probably contact these two guys first though.
pacman roulette : pacman -S $(pacman -Slq | LANG=C sort -R | head -n $((RANDOM % 10)))
Offline
Hi shining,
thanks a lot for answering. Ok, I'll try to get in touch with Stiat, even if I never wrote a wrapper, with some guidance (and since most of the code has already been written), maybe I could help him in some way.
Cheers
Last edited by drf (2008-01-25 16:55:31)
Offline
I've just talked to Stiat, and he doesn't have enough time at the moment to keep it going, and nobody is looking at it now. So, I wonder if anyone is still interested in developing something like this. Stiat did write some code in pyrex, it compiles but it is not complete. So, if anyone knows pyrex or is willing to learn, this could be the right time to bring this project back to life.
Offline
Not just not complete, but also not functional if alpm changed much (hopefully it did).
The alpm design in 3.0 had some flaws, but within me having less time, the pacman developers were working on a better, cleaner design for alpm.
Ability is nothing without opportunity.
Offline
Not just not complete, but also not functional if alpm changed much (hopefully it did).
The alpm design in 3.0 had some flaws, but within me having less time, the pacman developers were working on a better, cleaner design for alpm.
Which flaws exactly are you referring to?
I am afraid that part didn't really improve.
pacman roulette : pacman -S $(pacman -Slq | LANG=C sort -R | head -n $((RANDOM % 10)))
Offline
I had the chance to take a look at pacman's code and libalpm's code and I have to agree with Stiat. I think that, when switching to alpm (I am pretty new to Arch, so I don't know about the past situation), the developers just thought about "splitting" the code, and not about creating a clean, and easily reusable library.
There are also a lot of TODO in pacman's code that are asking for more abstraction, so I think that developers are aware of that and I hope polishing and cleaning of libalpm is one of their priorities.
That said, writing a wrapper for libalpm now it's a consuming task and now I realize why nobody has already done one. gtkPacman has found a very interesting way for interacting with pacman, by reading the database as text files and using pacman itself from command line to perform actions.
I think this is the best way to go now, unless libalpm changes its design, making things easier. And to realize that what I say is true, just take a look at libalpm's amount of code and pacman's itself amount of code. Since pacman should be the most basic and simple implementation of libalpm, it should be just about parsing command line arguments, calling libalpm's function, and printing to the stdout to show progress and to ask for confirmation, but, you see for yourself, it's not like this.
And also, I really appreciate the fact that developers thought about a library approach to pacman, trying to make any implementation different than pacman itself easier, but, let's face it: I've always coded in C/C++, and I'm pretty tired of it. Python and such opened new possibilities and make GUI programming a lot easier and, why not, more enjoyable. So I hope that having a wrapper is in their plans, also because since libalpm is the base of Arch, something mantained upstream will surely be better and more reliable.
My post is not a complaint: I think pacman is the best package manager out there and it puts apt to shame in my opinion, and that's something I never thought I could say. These are just thoughts and some constructive criticism. And about the wrapper, I'm not pretending it, I'm just asking if pacman's developers are interested in porting it to other languages.
Sorry for the long post
Last edited by drf (2008-01-27 15:33:26)
Offline
I had the chance to take a look at pacman's code and libalpm's code and I have to agree with Stiat. I think that, when switching to alpm (I am pretty new to Arch, so I don't know about the past situation), the developers just thought about "splitting" the code, and not about creating a clean, and easily reusable library.
There are also a lot of TODO in pacman's code that are asking for more abstraction, so I think that developers are aware of that and I hope polishing and cleaning of libalpm is one of their priorities.That said, writing a wrapper for libalpm now it's a consuming task and now I realize why nobody has already done one. gtkPacman has found a very interesting way for interacting with pacman, by reading the database as text files and using pacman itself from command line to perform actions.
I think this is the best way to go now, unless libalpm changes its design, making things easier. And to realize that what I say is true, just take a look at libalpm's amount of code and pacman's itself amount of code. Since pacman should be the most basic and simple implementation of libalpm, it should be just about parsing command line arguments, calling libalpm's function, and printing to the stdout to show progress and to ask for confirmation, but, you see for yourself, it's not like this.
Actually, it's more or less what it does. And libalpm IS bigger than pacman :
> cat src/pacman/*.{c,h} | wc -l
4377
> cat lib/libalpm/*.{c,h} | wc -l
12462
But maybe more stuff could be moved to libalpm.
And also, I really appreciate the fact that developers thought about a library approach to pacman, trying to make any implementation different than pacman itself easier, but, let's face it: I've always coded in C/C++, and I'm pretty tired of it. Python and such opened new possibilities and make GUI programming a lot easier and, why not, more enjoyable. So I hope that having a wrapper is in their plans, also because since libalpm is the base of Arch, something mantained upstream will surely be better and more reliable.
My post is not a complaint: I think pacman is the best package manager out there and it puts apt to shame in my opinion, and that's something I never thought I could say. These are just thoughts and some constructive criticism. And about the wrapper, I'm not pretending it, I'm just asking if pacman's developers are interested in porting it to other languages.
The only real interest I saw was from Stiat. I believe current pacman developers and contributors have other priorities.
pacman roulette : pacman -S $(pacman -Slq | LANG=C sort -R | head -n $((RANDOM % 10)))
Offline
Of course, it's bigger. But I think that something else might be moved and something in libalpm polished. Maybe it's just about me, anyway.
You are right anyway: until we stay in the Arch way to KISS, and where pacman should be used from the command line, that's ok, bindings are useless. But, if things are really this way, splitting the code into pacman and libalpm was useless too. So, if the code was splitted to allow a easier process in creating a GUI to pacman, I thought that some bindings could have been planned.
Nevermind, in the worst case I'll stay with the old C/C++
Offline
Ok, I decided to stay with C/C++. One last question, can somebody point me to libalpm's documentation or a libalpm's tutorial (if exists)?
Offline
http://bugs.archlinux.org/task/9237
I all ready made support request for it... unfortunate it's abracadabra for me
Got this reply:
Comment by Dan McGee (toofishes) - Thursday, 17 January 2008, 02:27 GMT+1
Some doxygen docs are available. Download the source tarball and configure with --enable-doxygen, or clone the GIT repo and do the same.
There is also this:
http://code.toofishes.net/pacman/doc/
Think they're quite buzzy at the moment...
I found this too...
http://wiki.archlinux.org/index.php/Use … _interface
This is the doxyfile I found:
# Doxyfile 1.5.2
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = libalpm
PROJECT_NUMBER =
OUTPUT_DIRECTORY = ./
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
ALWAYS_DETAILED_SEC = YES
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
DISTRIBUTE_GROUP_DOC = NO
SUBGROUPING = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = YES
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ../lib/libalpm/
INPUT_ENCODING = UTF-8
FILE_PATTERNS =
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = NO
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = NO
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = YES
MAN_OUTPUT = .
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
SEARCH_INCLUDES = YES
INCLUDE_PATH = ../..
INCLUDE_FILE_PATTERNS = *.h
PREDEFINED = HAVE_CONFIG_H= SYMHIDDEN= SYMEXPORT=
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = NO
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO
And this could come in 'handy' (?!)
Pacman - Contributing
=====================
This file is meant to give you a brief overview of coding style and other
concerns when hacking on pacman. If you are interested in contributing, please
read link:submitting-patches.html[submitting-patches] and
link:translation-help.html[translation-help] as well.
Coding style
------------
1. All code should be indented with tabs. (Ignore the use of only spaces in
this file) By default, source files contain the following VIM modeline:
+
[C]
code~~~~~~~~~~
/* vim: set ts=2 sw=2 noet: */
code~~~~~~~~~~
2. When opening new blocks such as 'while', 'if', or 'for', leave the opening
brace on the same line as the beginning of the codeblock. The closing brace
gets its own line (the only exception being 'else'). Do not use extra
spaces around the parentheses of the block. ALWAYS use opening and closing
braces, even if it's just a one-line block. This reduces future error when
blocks are expanded beyond one line.
+
[C]
code~~~~~~~~~~
for(lp = list; lp; lp = lp->next) {
newlist = _alpm_list_add(newlist, strdup(lp->data));
}
while(it) {
ptr = it->next;
if(fn) {
fn(it->data);
} else {
return(1);
}
free(it);
it = ptr;
}
code~~~~~~~~~~
3. When declaring a new function, put the opening and closing braces on their
own line. Also, when declaring a pointer, do not put a space between the
asterisk and the variable name.
+
[C]
code~~~~~~~~~~
alpm_list_t *alpm_list_add(alpm_list_t *list, void *data)
{
alpm_list_t *ptr, *lp;
ptr = list;
if(ptr == NULL) {
...
}
...
}
code~~~~~~~~~~
4. Comments should be ANSI-C89 compliant. That means no `// Comment` style;
use only `/* Comment */` style.
/* This is a comment */
NOT
// This is a comment
5. Return statements should be written like a function call.
return(0);
NOT
return 0;
6. The sizeof() operator should accept a type, not a value. (TODO: in certain
cases, it may be better- should this be a set guideline? Read "The Practice
of Programming")
sizeof(alpm_list_t);
NOT
sizeof(*mylist);
7. When using strcmp() (or any function that returns 0 on success) in a
conditional statement, use != 0 or == 0 and not the negation (!) operator.
It reads much cleaner for humans (using a negative to check for success is
confusing) and the compiler will treat it correctly anyway.
if(strcmp(a, b) == 0)
NOT
if(!strcmp(a, b))
Other Concerns
--------------
Header Includes
~~~~~~~~~~~~~~~
Currently our #include usage is in messy shape, but this is no reason to
continue down this messy path. When adding an include to a file, follow this
general pattern, including blank lines:
[C]
code~~~~~~~~~~
#include "config.h"
#include <standardheader.h>
#include <another.h>
#include <...>
code~~~~~~~~~~
Follow this with some more headers, depending on whether the file is in libalpm
or pacman proper. For libalpm:
[C]
code~~~~~~~~~~
/* libalpm */
#include "yourfile.h"
#include "alpm_list.h"
#include "anythingelse.h"
code~~~~~~~~~~
For pacman:
[C]
code~~~~~~~~~~
#include <alpm.h>
#include <alpm_list.h>
/* pacman */
#include "yourfile.h"
#include "anythingelse.h"
code~~~~~~~~~~
/////
vim: set ts=2 sw=2 syntax=asciidoc et:
/////
Last edited by ibendiben (2008-01-28 12:33:36)
Offline
I am not sure what that wiki page is, but it is certainly not what you want.
It might be a draft for making libalpm nicer to use, as drf requested earlier. But that is a bit old, I think.
I will ask toofishes for confirmation though.
About using libalpm :
your best bet is to look at pacman as being a "reference"
That's taken a bit out of context, but I think it's still valid :
http://archlinux.org/pipermail/pacman-d … 08512.html
pacman roulette : pacman -S $(pacman -Slq | LANG=C sort -R | head -n $((RANDOM % 10)))
Offline
For the HACKING file, it probably looks better formatted :
http://archlinux.org/pacman/HACKING.html
pacman roulette : pacman -S $(pacman -Slq | LANG=C sort -R | head -n $((RANDOM % 10)))
Offline
ibendiben and shining: thanks for the links, apart from toofish's website I think I'll use pacman's code, also because it does exactly everything that can be done with libalpm. Thanks, now it's just about wishing me good luck
Offline
Offline
I am a bit curious of what you are going to create by using libalpm?
And of course, Good luck!
Offline
Thanks
Well, looks like nobody has still used the power of libalpm to create a GUI... so that's what I'm going to do, with some nice addons... Top Secret by now Anyway, I'll do it in QT, also because GTK guys already have gtkPacman, that works great.
Offline
And to realize that what I say is true, just take a look at libalpm's amount of code and pacman's itself amount of code.
The pacman code is quite big in places, but alot of it due to error checking and handling of different command line arguments. To handle a simple case like 'pacman -S vim', there are only a handful of functions needed.
alpm_db_register_local() // register the local db
alpm_db_register_sync() // register a sync db ('core')
alpm_db_setserver() // add a server for a sync db
alpm_trans_init() // initialize the transaction, obtaining a lock
alpm_trans_addtarget() // add a target to the transaction ('vim')
alpm_trans_prepare() // check for missing dependencies or conflicts
alpm_trans_commit() // download and install
alpm_trans_release() // release the lock
There are probably a few more functions that I'm missing, but it's not too bad.
Good luck
Offline
Design of libalpm isn't as bad as I thought on a second look. I like the way transactions are handled, asynchronously with callbacks. I just can't get the stuff about DBs, basically, a DB is a repository, so if I register core I get an handler to the core repository, in which I can perform some actions. This means i have to group DBs in a list (such as pacman does) and iterate it on performing every action.
So far so good, but I still don't get what alpm_db_register_local() is there for. I've just had a lame glance, so I probably missed something. I'm also missing the difference between a local and a sync DB.
And also, to get available repos (or DBs), do I have to parse pacman.conf or is there a libalpm function for that?
Anyway thanks for the hint
EDIT: I have an important question: pacman.conf is a configuration file for pacman only or also for libalpm?
Last edited by drf (2008-01-28 15:27:42)
Offline
The main difference between the two db_register functions is that the local version sets handle.db_local while the sync version adds the db to the handle.dbs_sync list. handle is basically a global variable for libalpm. You shouldn't need to worry about it unless you start modifying the libalpm code.
pacman.conf serves as configuration for both pacman and libalpm. Look at pacman.c around line 623. Any option that gets set via alpm_option* is a libalpm option, and options that get set using config->* is a pacman option (though be sure to read the comment in the __config_t structure about the path configs).
Probably the best way to configure your client would be to parse pacman.conf for the libalpm options, then have your own .conf file which has options for your client only.
Offline
Ok, then life makes sense Thanks for the clarification on DBs, I'll look into Pacman's code for more details.
Offline
Wah, just some hours passed and so much spam to read .
@shining: The parts we talked about, a year ago. List handling in general in alpm, unified data structures (instead of having 20 similar looking ones), getting rid of non type safe functions and pointers (as far as possible, but i think most void* got replaced by type safe structures before 3.0 already).
Also moving the download handling and similar out of alpm into pacman, since it's most likely not to consider as backend code (even when you can pass by this an elegant - or not so elegant way).
Oh, btw: the error structure (enum) is annoying "1..2..3...4...6... damn, again".
I had implemented installing, uninstalling and dependency checking already. I don't know if the version found it's way into svn before my notebook crashed.
Probably, the database handling changed lately, i remember that there was just one register function back then.
@nj: the problem is, that due to the design of alpm, you've to rebuild most structures manually, and implement the list functions again in pyrex - for every list available, since python / pyrex is quite restrictive about types. Therefore, wrapping different kinds of lists is quite a good choice, just "reading" the alpm list building up a own data structure internally, mapping your structure towards the alpm ones.
Yours,
STi
Last edited by STiAT (2008-01-28 17:16:33)
Ability is nothing without opportunity.
Offline
Stiat: most of *voids are still in. I'm sorry I probably won't continue your project (now), since I think going with C++ is a better way, and not only for libalpm but for some other reasons. Both languages (python and C++) have their downsides, and choosing any of them implies a risk, so let's see how it will come out.
Offline
I also think c++ might be the better choice, also for the reason if you look forward to qt4 and kde4 bindings in the "near" future.
You'll probably have it easier starting out directly with QT4 instead of writing the bindings first. Since kde 4.1 will be released ... uhm .. some day this year (october? don't know, didn't look at the shedule discussions yet, since i'm currently busy discussing the qt4-port of TOra, as well as looking at new qt and kde technology - the new backends/libs look great - but yet unstable. I still got a bunch of library and interface descriptions to read ).
Also, for me, Python is great for developing plugins, scripts, tools and similar as with the new plugin interface for KDE applications. I see no real advantage developing whole projects in Python instead of C++ (most people say it's faster to develop, but I personally disagree on this).
Last edited by STiAT (2008-01-29 08:45:28)
Ability is nothing without opportunity.
Offline
I actually don't know, because I thought to give python a try just for learning it but yes, you've got the point: C++ (talking about Qt4/KDE4 development) is far more mature and reliable now, and since I don't want to wait another year to develop such a thing, C++ is probably the better choice.
KDE4.1 is scheduled for July... but I think October is more realistic New KDE libs seems really great, I didn't get deep but it seems like they're a great step forward compared to KDE3 and make development of some things really a breeze... We'll see.
Cheers
Offline
Pages: 1