General ------- KDevelop 2 could be generally divided into the following categories: - The core: Which connects the parts and plug-ins to the user interface - Parts: Which implements various parts of the KDevelop based on Components architecture. - Plug-ins: Which implements some other stuff based on the plug-in architecture. For the difference between Components and plug-ins see bellow. The Core -------- Resided in kdevelop/, sets up the GUI, loads various components (throug the Component Manager - see bellow), communicates with the components to let them talk to the user interface. Components/Component Architecture --------------------------------- Initial functionalities whithin KDevelop are divided into some Parts. These are parts which KDevelop needs to run and function. For instance you can think of the editor, or the class parser. To give the component identities and uniformation, they shold be derived from the class KDevComponent as defined in kdevelop/lib/ComponentManager/kdevcomponent.h. This class defines some minimal functionality needed for instance for communications. Each component can communicate with other components or with the core. KDevComponent defines some virtual methods which could be overrided in each component. To let the components communicate with each other, every component should have some minimum access to the component which it's going to communicate with. That's why the communicating components should be divided into a generalization and a specialization. The Generalization is directly derived from KDevComponent and provides minimum access for other components which may communicate. The Specialization is a derived class from the Generalization, and extends the components and implements it fully. The generalizations are resided in kdevelop/lib/ComponentManger/Components/ and the specializations are defined as Parts in kdevelop/parts. If a component does not need to communicate with other components, or nobody wants to communicate with it, it does not need to have generalization and it could directly derive from KDevComponent. In this case it is called a global component. The Generalizations are identified externally by ServiceTypes of KDE. The Specializations are identified externally by Services. The MUST have these. (See Component Manager) The components can communicate also with the core, or the core may want to communicate with them. This happens through the Component Manager (See bellow). Plug-ins/ Plug-in architecture ------------------------------ Extended specializations of the Parts and also some other functionalities are defined as Plug-ins. Plug-ins are resided in /kdevelop/plugin. Component Manager ----------------- To give a uniform structure to the Core<->Component communications and to organize the loading/unloading the componens and to register them correctly there is Component Manager. Class KDevComponentManager, resided in lib/ComponentManager is responsible for loading the components (using the klibloader and kservice). Everybody (mostly the core) who wants to load a component, loads it using the KDevComponentManager. KDevComponentManager provides the needed methods. When KDevComponentManager loads a module, registers it as well, so it can give the pointer to the rest, if they ask for it. Another aspect of the KDevComponentManager is the Core<->Component communications. It provides some public slots and signals. Send the right signal to it, it distributes the signal over the registerd components. So can the core communicate easily with the components just using the KDevComponentManager to deliver its qt signals. Creating a KDevComponent ------------------------ A new KDevComponent should have the following characters: - It could have a generalization. - It must have a specialization. - The generalization (if exists) must derive from the class KDevComponent. - The specialization must derive from the generalization (if exists, otherwise from the class KDevComponent) - The generalization (if exists) must provide a ServiceType. - The specialization must provide a Service associating with the ServiceType of the generalization (if exists, otherwise the ServiceType of KDevComponent). - The generalization (if exists) must reside in kdevelop/lib/ComponentManager/Components. - The specialization must reside in kdevelop/parts. - It must have a KInstance and should be able to be loaded with klibloader. Note: Not everything should be component. The Component architecture is complex enough and should stay understandable. Take a look, perhaps it is better to make a plug-in out of it. KDevNode -------- A KDevNode (lib/general/kdevnodes.h) is a data structure which holds information for an object in KDevelop. This can be used if components want to exchange information about a specific object. For instance a Projectspace can raise the signal "sigAddedFileToProject(KDevFileNode*)" to inform all other running components that a file was added. The KDevFileNode is a subclass of KDevNode and contains information about Projectspace,Projectname and of course the filenname of this file. KDevNodeAction -------------- KDevNodeAction is a special KAction which stores a KDevNode and raise it if the action was activated. In KDevelop 2 it is possible to extend the the popup menus in the treeviews or similar things at 'runtime' for every object 'indivual'. For this you will need KDevNodeAction (lib/general/kdevactions.h), the following signal and method : void KDevComponent::needKDevNodeActions(KDevNode* pNode, QList*pList) QList*KDevComponent::kdevNodeActions(KDevNode* pNode). An example: (asking for actions) the Projectview need some actions (the user clicked the right mousebutton) for the file "main.cpp" in the project "foobar", projectspace: "foo". The Projectview creates now a KDevFileNode (pNode) with these properties and an empty list (pList). After this it raise the signal KDevComponent::needKDevNodeActions(KDevNode* pNode,QList* pList) The list (pList) will be filled with actions (from running components) for these KDevNode. You can use it with: +++ for(pAction=pList->first();pAction!=0;pAction= pList->next()){ pAction->plug(pPopup,-1);// add all available actions to the popupmenu } +++ An example: (implementing a new action for an KDevNode) An implemention from a ProjectSpace component which add a "Move to" action could look like this: +++ QList* ProjectSpace::kdevNodeActions(KDevNode* pNode){ QList* pList = new QList; KDevNodeAction* pAction=0; if(pNode->inherits("KDevFileNode")){ pList->append(new KActionSeparator()); pAction = new KDevNodeAction(pNode,"Move to..."); // pNode is stored in the Action connect(pAction,SIGNAL(activated(KDevNode*)),this, SLOT(slotMoveFileTo(KDevNode*))); pList->append(pAction); ... return pList; } Coding style rules for KDevelop 2 --------------------------------- - prefix "m_" for class attributes - prefix "p" for pointers but no further type-prefixes - prefix "m_p" for class attributes which are pointers - upper case letters for each single word in a compound word: e.g. KDevViewHandler instead of Kdevviewhandler. - tab space = 4 - tabs replaced by spaces - no prefix "get" at the beginning of a get function. How to help ----------- Please take a look at TODO file (kdevelop/TODO). Perhaps there is something you can do. You can also look for bugs and fix them. You can implement new idea's. You can provide translations. You can add comment and documentations. If you create something, made some pics, provide a patch, etc., you can upload it into our anonymous ftp site. (please visit: http://www.kdevelop.org/index.html?filename=upload.html). And please don't fprget to inform us per email. Is there any question? Is there something unclear? Do you need additional information? Just ask! There will be someone at the mailinglist to answer your question. 28-02-2001 KDevelop Team Omid Givi, omid@kdevelop.org