00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00101 return;
00102 }
00103
00104 int line, column;
00105 klass->getEndPosition( &line, &column );
00106
00107
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];
00144 }
00145
00146 editIface->insertText( pt.first + insertedLine + 1, 0 , 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
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
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
00305
00306
00307
00308
00309
00310
00311
00312 QString impl = m_implementations[formName]->fileName();
00313 impl.replace(".h", ".cpp");
00314
00315
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
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"