KDevelop API Documentation

qtdesignerintegration.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2004 by Alexander Dymo                                  *
00003  *   adymo@mksat.net                                                       *
00004  *   Portions Copyright (C) 2003 Roberto Raggi (roberto@kdevelop.org)      *
00005  *                                                                         *
00006  *   This program is free software; you can redistribute it and/or modify  *
00007  *   it under the terms of the GNU General Public License as published by  *
00008  *   the Free Software Foundation; either version 2 of the License, or     *
00009  *   (at your option) any later version.                                   *
00010  *                                                                         *
00011  *   This program is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU General Public License for more details.                          *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU General Public License     *
00017  *   along with this program; if not, write to the                         *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00020  ***************************************************************************/
00021 #include "qtdesignerintegration.h"
00022 
00023 #include <qpair.h>
00024 #include <qregexp.h>
00025 
00026 #include <klocale.h>
00027 #include <kdebug.h>
00028 #include <kmessagebox.h>
00029 #include <kurl.h>
00030 #include <ktexteditor/editinterface.h>
00031 #include <ktexteditor/view.h>
00032 #include <ktexteditor/viewcursorinterface.h>
00033 
00034 #include <domutil.h>
00035 #include <kdevpartcontroller.h>
00036 #include <kdevcreatefile.h>
00037 
00038 #include "backgroundparser.h"
00039 #include "cppsupportpart.h"
00040 #include "codemodel_utils.h"
00041 #include "implementationwidget.h"
00042 
00043 QtDesignerIntegration::QtDesignerIntegration(CppSupportPart *part, const char* name)
00044     :KDevDesignerIntegration(part, name), m_part(part)
00045 {
00046 }
00047 
00048 QtDesignerIntegration::~QtDesignerIntegration()
00049 {
00050 }
00051 
00052 void QtDesignerIntegration::addFunction(const QString& formName, KInterfaceDesigner::Function function)
00053 {
00054     kdDebug() << "QtDesignerIntegration::addFunction: form: " << formName << ", function: " << function.function << endl;
00055     
00056     if (!m_implementations[formName])
00057         if (!selectImplementation(formName))
00058             return;
00059     
00060     ClassDom klass = m_implementations[formName];
00061     if (!klass)
00062         KMessageBox::error(0, i18n("Cannot find implementation class for form: %1").arg(formName));
00063 
00064     addFunctionToClass(function, klass);
00065 }
00066 
00067 void QtDesignerIntegration::editFunction(const QString& formName, KInterfaceDesigner::Function oldFunction, KInterfaceDesigner::Function function)
00068 {
00069     kdDebug() << "QtDesignerIntegration::editFunction: form: " << formName 
00070         << ", old function: " << oldFunction.function
00071         << ", function: " << function.function << endl;
00072 }
00073 
00074 void QtDesignerIntegration::removeFunction(const QString& formName, KInterfaceDesigner::Function function)
00075 {
00076     kdDebug() << "QtDesignerIntegration::removeFunction: form: " << formName << ", function: " << function.function << endl;
00077 }
00078 
00079 bool QtDesignerIntegration::selectImplementation(const QString &formName)
00080 {
00081     QFileInfo fi(formName);
00082     if (!fi.exists())
00083         return false;
00084     
00085     ImplementationWidget selectImpl(m_part, formName);
00086     if (selectImpl.exec())
00087     {
00088         m_implementations[formName] = selectImpl.selectedClass();
00089         return true;
00090     }
00091     return false;
00092 }
00093 
00094 void QtDesignerIntegration::addFunctionToClass(KInterfaceDesigner::Function function, ClassDom klass)
00095 {
00096     m_part->partController()->editDocument( KURL( klass->fileName() ) );
00097     KTextEditor::EditInterface* editIface = dynamic_cast<KTextEditor::EditInterface*>( m_part->partController()->activePart() );
00098     if( !editIface ){
00100 //        QDialog::accept();
00101         return;
00102     }
00103 
00104     int line, column;
00105     klass->getEndPosition( &line, &column );
00106 
00107     // compute the insertion point map
00108     QMap<QString, QPair<int,int> > points;
00109 
00110     const FunctionList functionList = klass->functionList();
00111     for( FunctionList::ConstIterator it=functionList.begin(); it!=functionList.end(); ++it )
00112     {
00113         int funEndLine, funEndColumn;
00114         (*it)->getEndPosition( &funEndLine, &funEndColumn );
00115         QString access = accessID( *it );
00116         QPair<int, int> funEndPoint = qMakePair( funEndLine, funEndColumn );
00117 
00118         if( !points.contains(access) || points[access] < funEndPoint ){
00119             points[ access ] = funEndPoint;
00120         }
00121     }
00122 
00123     int insertedLine = 0;
00124 
00125     QString access = function.access + ( function.type == KInterfaceDesigner::ftQtSlot ? " slots" : "" );
00126 
00127     QString str = function.returnType + " " + function.function;
00128     if (function.specifier == "virtual")
00129         str = "virtual " + str;
00130     else if (function.specifier == "pure virtual")
00131         str = "virtual " + str + " = 0";
00132     else if (function.specifier == "static")
00133         str = "static " + str;
00134     str += ";\n";
00135     str = "    " + str;
00136 
00137     QPair<int, int> pt;
00138     if( points.contains(access) ) {
00139         pt = points[access];
00140     } else {
00141         str.prepend( access + ":\n" );
00142         points[access] = qMakePair( line-1, 0 );
00143         pt = points[access]; // end of class declaration
00144     }
00145 
00146     editIface->insertText( pt.first + insertedLine + 1, 0 /*pt.second*/, str );
00147     insertedLine += str.contains( QChar('\n') );
00148 
00149     m_part->backgroundParser()->addFile( klass->fileName() );
00150 
00151     if (function.specifier == "pure virtual")
00152         return;
00153 
00154     
00155     //implementation
00156     QString stri = function.returnType + " " + klass->name() + "::" + function.function;
00157     if (function.specifier == "static")
00158         stri = "static " + stri;
00159     stri += "\n{\n}\n";
00160     stri = "\n" + stri;
00161         
00162     QFileInfo fi(klass->fileName());
00163     QString implementationFile = fi.absFilePath();
00164     implementationFile.replace(".h", ".cpp");
00165 
00166     QFileInfo fileInfo( implementationFile );
00167     if( !QFile::exists(fileInfo.absFilePath()) ){
00168         m_part->createFileSupport()->createNewFile( fileInfo.extension(), fileInfo.dirPath(true), fileInfo.fileName() );
00169     }
00170 
00171     m_part->partController()->editDocument( KURL( implementationFile ) );
00172     editIface = dynamic_cast<KTextEditor::EditInterface*>( m_part->partController()->activePart() );
00173     if( !editIface )
00174         return;
00175 
00176     int atLine = 0, atColumn = 0;
00177     TranslationUnitAST *translationUnit = m_part->backgroundParser()->translationUnit(implementationFile);
00178     if (translationUnit){
00179         translationUnit->getEndPosition( &atLine, &atColumn );
00180         kdDebug() << "atLine: " << atLine << endl;
00181         stri = "\n" + stri;
00182     } else {
00183         atLine = editIface->numLines();
00184         line = editIface->numLines();
00185         while (line > 0)
00186         {
00187             if (editIface->textLine(line).isEmpty())
00188             {
00189                 --line;
00190                 continue;
00191             }
00192             else
00193             {
00194                 if (editIface->textLine(line).contains(QRegExp(".*#include .*\\.moc.*")))
00195                     atLine = line;
00196                 break;
00197             }
00198         }
00199         kdDebug() << "atLine (2): " << atLine << endl;
00200         atColumn = 0;
00201     }
00202     
00203 //    editIface->insertLine( atLine + 1, QString::fromLatin1("") );
00204          kdDebug() << "at line in intg: " << atLine  << " atCol: " << atColumn << endl;
00205          kdDebug() << "text: " << stri << endl;
00206     editIface->insertText( atLine, atColumn, stri );
00207     KTextEditor::View *activeView = dynamic_cast<KTextEditor::View*>( m_part->partController()->activePart()->widget() );
00208     if (activeView)
00209     {
00210         KTextEditor::ViewCursorInterface* cursor = dynamic_cast<KTextEditor::ViewCursorInterface*>(activeView );
00211         if (cursor)
00212             cursor->setCursorPositionReal( atLine+3, 1 );
00213     }
00214     
00215     m_part->backgroundParser()->addFile( implementationFile );
00216 }
00217 
00218 QString QtDesignerIntegration::accessID(FunctionDom fun) const
00219 {
00220     if( fun->isSignal() )
00221         return QString::fromLatin1( "signals" );
00222 
00223     switch( fun->access() )
00224     {
00225         case CodeModelItem::Public:
00226             if( fun->isSlot() )
00227                 return QString::fromLatin1( "public slots" );
00228             return QString::fromLatin1( "public" );
00229 
00230         case CodeModelItem::Protected:
00231             if( fun->isSlot() )
00232                 return QString::fromLatin1( "protected slots" );
00233             return QString::fromLatin1( "protected" );
00234 
00235         case CodeModelItem::Private:
00236             if( fun->isSlot() )
00237                 return QString::fromLatin1( "private slots" );
00238             return QString::fromLatin1( "private" );
00239     }
00240 
00241     return QString::null;
00242 }
00243 
00244 void QtDesignerIntegration::loadSettings(QDomDocument dom, QString path)
00245 {
00246     QDomElement el = DomUtil::elementByPath(dom, path + "/qtdesigner");
00247     if (el.isNull())
00248         return;
00249     QDomNodeList impls = el.elementsByTagName("implementation");
00250     for (uint i = 0; i < impls.count(); ++i)
00251     {
00252         QDomElement el = impls.item(i).toElement();
00253         if (el.isNull())
00254             continue;
00255         FileDom file = m_part->codeModel()->fileByName(el.attribute("implementationpath"));
00256         if (!file)
00257             continue;
00258         ClassList cllist = file->classByName(el.attribute("class"));
00259         if (cllist.count() > 0)
00260             m_implementations[el.attribute("path")] = cllist.first();
00261     }
00262 }
00263 
00264 void QtDesignerIntegration::saveSettings(QDomDocument dom, QString path)
00265 {
00266     kdDebug() << "QtDesignerIntegration::saveSettings" << endl;
00267     QDomElement el = DomUtil::createElementByPath(dom, path + "/qtdesigner");
00268     for (QMap<QString, ClassDom>::const_iterator it = m_implementations.begin(); 
00269         it != m_implementations.end(); ++it)
00270     {
00271         QDomElement il = dom.createElement("implementation");
00272         el.appendChild(il);
00273         il.setAttribute("path", it.key());
00274         il.setAttribute("implementationpath", it.data()->fileName());
00275         il.setAttribute("class", it.data()->name());
00276     }
00277 }
00278 
00279 struct MyPred{
00280     MyPred(const QString &functionName): m_functionName(functionName) {}
00281     bool operator () (const FunctionDefinitionDom& fun){
00282         kdDebug() << "    ==: " << fun->name() << " vs " << m_functionName << endl;
00283         if (fun->name() == m_functionName)
00284             return true;
00285         return false;
00286     }
00287     QString m_functionName;
00288 };
00289 
00290 
00291 void QtDesignerIntegration::openFunction(const QString &formName, const QString &functionName)
00292 {
00293     kdDebug() << "QtDesignerIntegration::openFunction, formName = " << formName 
00294         << ", functionName = " << functionName << endl;
00295     QString fn = functionName;
00296     if (fn.find("(") > 0)
00297         fn.remove(fn.find("("), fn.length());
00298     
00299     if (!m_implementations[formName])
00300         return;
00301 
00302     int line = -1, col = -1;
00303     
00304 /*    FunctionDefinitionList list;       
00305     MyPred mypred(fn);
00306     CodeModelUtils::findFunctionDefinitions<MyPred>(mypred, m_implementations[formName], list);
00307     if (list.count() == 0)
00308         return;
00309     
00310     list.first()->getStartPosition(&line, &col);*/
00311 
00312     QString impl = m_implementations[formName]->fileName();
00313     impl.replace(".h", ".cpp");
00314     
00315 //    kdDebug() << "seeking for fn = " << fn << endl;
00316     if (m_part->codeModel()->hasFile(impl))
00317     {
00318         FunctionDefinitionList list = m_part->codeModel()->fileByName(impl)->functionDefinitionList();
00319         for (FunctionDefinitionList::const_iterator it = list.begin(); it != list.end(); ++it)
00320         {
00321 //            kdDebug() << " <<: " << (*it)->name() << endl;
00322             if ((*it)->name() == fn)
00323                 (*it)->getStartPosition(&line, &col);
00324         }
00325     }
00326     
00327     m_part->partController()->editDocument(KURL(impl), line, col);
00328 }
00329 
00330 
00331 #include "qtdesignerintegration.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:30 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003