KDevelop API Documentation

parts/filecreate/filecreate_part.cpp

Go to the documentation of this file.
00001 /*************************************************************************** 00002 * Copyright (C) 2003 by Julian Rockey * 00003 * linux@jrockey.com * 00004 * * 00005 * This program is free software; you can redistribute it and/or modify * 00006 * it under the terms of the GNU General Public License as published by * 00007 * the Free Software Foundation; either version 2 of the License, or * 00008 * (at your option) any later version. * 00009 ***************************************************************************/ 00010 00011 #include <qwhatsthis.h> 00012 #include <qdom.h> 00013 #include <qdir.h> 00014 #include <qfileinfo.h> 00015 #include <qvbox.h> 00016 #include <qtimer.h> 00017 00018 #include <kdeversion.h> 00019 #include <kiconloader.h> 00020 #include <klocale.h> 00021 #include <kdevgenericfactory.h> 00022 #include <kfiledialog.h> 00023 #include <kdebug.h> 00024 #include <kstandarddirs.h> 00025 #include <kstdaction.h> 00026 #include <kaction.h> 00027 #include <kapplication.h> 00028 00029 #include "kdevcore.h" 00030 #include "kdevmainwindow.h" 00031 #include "kdevproject.h" 00032 #include "kdevpartcontroller.h" 00033 #include "configwidgetproxy.h" 00034 00035 #include "filetemplate.h" 00036 #include "domutil.h" 00037 #include "urlutil.h" 00038 00039 #include "filecreate_widget2.h" 00040 #include "filecreate_widget3.h" 00041 #include "filecreate_part.h" 00042 #include "filecreate_filetype.h" 00043 #include "filecreate_filedialog.h" 00044 #include "filecreate_newfile.h" 00045 #include "fcconfigwidget.h" 00046 00047 #define PROJECTSETTINGSPAGE 1 00048 #define GLOBALSETTINGSPAGE 2 00049 00050 static const KAboutData data("kdevfilecreate", I18N_NOOP("New File Wizard"), "1.0"); 00051 00052 typedef KDevGenericFactory<FileCreatePart> FileCreateFactory; 00053 K_EXPORT_COMPONENT_FACTORY( libkdevfilecreate, FileCreateFactory( &data ) ) 00054 00055 using namespace FileCreate; 00056 00057 FileCreatePart::FileCreatePart(QObject *parent, const char *name, const QStringList & ) 00058 : KDevCreateFile("FileCreate", "filecreate", parent, name ? name : "FileCreatePart"), m_selectedWidget(-1), m_useSideTab(true) 00059 { 00060 setInstance(FileCreateFactory::instance()); 00061 setXMLFile("kdevpart_filecreate.rc"); 00062 00063 connect( core(), SIGNAL(projectOpened()), this, SLOT(slotProjectOpened()) ); 00064 00065 _configProxy = new ConfigWidgetProxy( core() ); 00066 _configProxy->createProjectConfigPage( i18n("New File Wizard"), PROJECTSETTINGSPAGE ); 00067 _configProxy->createGlobalConfigPage( i18n("New File Wizard"), GLOBALSETTINGSPAGE ); 00068 connect( _configProxy, SIGNAL(insertConfigWidget(const KDialogBase*, QWidget*, unsigned int )), 00069 this, SLOT(insertConfigWidget(const KDialogBase*, QWidget*, unsigned int )) ); 00070 00071 00072 KAction * newAction = KStdAction::openNew(this, SLOT(slotNewFile()), actionCollection(), "file_new"); 00073 newAction->setWhatsThis( i18n("<b>New file</b><p>Creates a new file. Also adds it the project if the <b>Add to project</b> checkbox is turned on.") ); 00074 newAction->setToolTip( i18n("Create a new file") ); 00075 00076 m_filetypes.setAutoDelete(true); 00077 00078 m_availableWidgets[0] = new FriendlyWidget(this); 00079 m_availableWidgets[1] = new ListWidget(this); 00080 m_numWidgets = 2; 00081 00085 selectWidget(1); 00086 } 00087 00088 00089 FileCreatePart::~FileCreatePart() 00090 { 00091 for(int c=0;c<m_numWidgets;c++){ 00092 if (TypeChooser* chooser = m_availableWidgets[c]) { 00093 00094 if( QWidget* as_widget = dynamic_cast<QWidget*>(chooser) ) 00095 mainWindow()->removeView( as_widget ); 00096 00097 delete chooser; 00098 } 00099 } 00100 delete _configProxy; 00101 } 00102 00103 void FileCreatePart::insertConfigWidget( const KDialogBase * dlg, QWidget * page, unsigned int pagenumber ) 00104 { 00105 kdDebug() << k_funcinfo << endl; 00106 00107 switch( pagenumber ) 00108 { 00109 case PROJECTSETTINGSPAGE: 00110 { 00111 FCConfigWidget* w = new FCConfigWidget( this, false, page, "filecreate config widget" ); 00112 connect( dlg, SIGNAL( okClicked( ) ), w, SLOT( accept( ) ) ); 00113 } 00114 break; 00115 00116 case GLOBALSETTINGSPAGE: 00117 { 00118 FCConfigWidget *w = new FCConfigWidget( this, true, page, "filecreate config widget" ); 00119 connect(dlg, SIGNAL(okClicked()), w, SLOT(accept())); 00120 } 00121 break; 00122 } 00123 } 00124 00125 void FileCreatePart::selectWidget(int widgetNumber) { 00126 if (m_selectedWidget==widgetNumber) return; 00127 if (widgetNumber<-1 || widgetNumber>=m_numWidgets) return; 00128 if (setWidget(widgetNumber==-1 ? NULL : m_availableWidgets[widgetNumber])) 00129 m_selectedWidget = widgetNumber; 00130 } 00131 00132 00133 bool FileCreatePart::setWidget(TypeChooser * widg) { 00134 00135 QWidget *as_widget = widg ? dynamic_cast<QWidget*>(widg) : NULL; 00136 00137 // remove the existing widget 00138 TypeChooser *tc = typeChooserWidget(); 00139 if (tc) { 00140 disconnect( tc->signaller(), SIGNAL(filetypeSelected(const FileType *)), this, SLOT(slotFiletypeSelected(const FileType *)) ); 00141 QWidget *as_widget2 = dynamic_cast<QWidget*>(tc); 00142 if (as_widget2) { 00143 kdDebug(9034) << "filecreate_part: Removing as_widget2" << endl; 00144 mainWindow()->removeView(as_widget2); 00145 } else 00146 kdWarning(9034) << "WARNING: could not cast to as_widget2" << endl; 00147 00148 } 00149 00150 if (widg && as_widget) { 00151 connect( widg->signaller(), SIGNAL(filetypeSelected(const FileType *)), this, SLOT(slotFiletypeSelected(const FileType *)) ); 00152 mainWindow()->embedSelectView(as_widget, i18n("New File"), i18n("File creation")); 00153 } 00154 00155 return true; 00156 } 00157 00158 void FileCreatePart::refresh() { 00159 if (typeChooserWidget()) typeChooserWidget()->refresh(); 00160 } 00161 00162 void FileCreatePart::slotNewFile() { 00163 KDevCreateFile::CreatedFile createdFile = createNewFile(); 00164 openCreatedFile(createdFile); 00165 } 00166 00167 void FileCreatePart::slotProjectOpened() { 00168 QTimer::singleShot( 0, this, SLOT(slotInitialize()) ); 00169 } 00170 00171 void FileCreatePart::addFileType(const QString & filename) { 00172 FileType * filetype = getType(filename); 00173 if (!filetype) { 00174 filetype = new FileType; 00175 filetype->setName( filename + " files" ); 00176 filetype->setExt( filename ); 00177 filetype->setCreateMethod("template"); 00178 m_filetypes.append(filetype); 00179 } 00180 filetype->setEnabled(true); 00181 } 00182 00183 void FileCreatePart::slotProjectClosed() { 00184 m_filetypes.clear(); 00185 refresh(); 00186 } 00187 00188 void FileCreatePart::slotFiletypeSelected(const FileType * filetype) { 00189 00190 KDevCreateFile::CreatedFile createdFile = createNewFile(filetype->ext(), 00191 QString::null, 00192 QString::null, 00193 filetype->subtypeRef()); 00194 00195 openCreatedFile(createdFile); 00196 00197 mainWindow()->lowerView( typeChooserWidgetAsQWidget() ); 00198 } 00199 00200 void FileCreatePart::openCreatedFile(const KDevCreateFile::CreatedFile & createdFile) { 00201 if (createdFile.status == KDevCreateFile::CreatedFile::STATUS_OK) { 00202 KURL uu(project()->projectDirectory() + createdFile.dir + "/" + createdFile.filename ); 00203 partController()->editDocument ( uu ); 00204 } 00205 } 00206 00207 int FileCreatePart::readTypes(const QDomDocument & dom, QPtrList<FileType> &m_filetypes, bool enable) { 00208 int numRead = 0; 00209 QDomElement fileTypes = DomUtil::elementByPath(dom,"/kdevfilecreate/filetypes"); 00210 if (!fileTypes.isNull()) { 00211 for(QDomNode node = fileTypes.firstChild();!node.isNull();node=node.nextSibling()) { 00212 // kapp->processEvents(); 00213 00214 if (node.isElement() && node.nodeName()=="type") { 00215 QDomElement element = node.toElement(); 00216 FileType * filetype = new FileType; 00217 filetype->setName( element.attribute("name") ); 00218 filetype->setExt( element.attribute("ext") ); 00219 filetype->setCreateMethod( element.attribute("create") ); 00220 00221 filetype->setIcon( element.attribute("icon") ); 00222 filetype->setDescr( (DomUtil::namedChildElement(element, "descr")).text() ); 00223 filetype->setEnabled(enable || (filetype->ext()=="")); 00224 m_filetypes.append(filetype); 00225 numRead++; 00226 00227 kdDebug(9034) << "node: " << filetype->name().latin1() << endl; 00228 00229 if (node.hasChildNodes()) { 00230 for(QDomNode subnode = node.firstChild();!subnode.isNull();subnode=subnode.nextSibling()) { 00231 kdDebug(9034) << "subnode: " << subnode.nodeName().latin1() << endl; 00232 // kapp->processEvents(); 00233 if (subnode.isElement() && subnode.nodeName()=="subtype") { 00234 QDomElement subelement = subnode.toElement(); 00235 FileType * subtype = new FileType; 00236 subtype->setExt( filetype->ext() ); 00237 subtype->setCreateMethod( filetype->createMethod() ); 00238 subtype->setSubtypeRef( subelement.attribute("ref") ); 00239 subtype->setIcon( subelement.attribute("icon") ); 00240 subtype->setName( subelement.attribute("name") ); 00241 subtype->setDescr( (DomUtil::namedChildElement(subelement, "descr")).text() ); 00242 subtype->setEnabled(enable); 00243 filetype->addSubtype(subtype); 00244 } 00245 } 00246 } 00247 } 00248 } 00249 } 00250 return numRead; 00251 } 00252 00253 FileType * FileCreatePart::getType(const QString & ex, const QString subtRef) { 00254 00255 QString subtypeRef = subtRef; 00256 QString ext = ex; 00257 int dashPos = ext.find('-'); 00258 if (dashPos>-1 && subtRef.isNull()) { 00259 ext = ex.left(dashPos); 00260 subtypeRef = ex.mid(dashPos+1); 00261 } 00262 00263 QPtrList<FileType> filetypes = getFileTypes(); 00264 for(FileType * filetype = filetypes.first(); 00265 filetype; 00266 filetype=filetypes.next()) { 00267 if (filetype->ext()==ext) { 00268 if (subtypeRef.isNull()) return filetype; 00269 QPtrList<FileType> subtypes = filetype->subtypes(); 00270 for(FileType * subtype = subtypes.first(); 00271 subtype; 00272 subtype=subtypes.next()) { 00273 if (subtypeRef==subtype->subtypeRef()) return subtype; 00274 } 00275 } 00276 } 00277 return NULL; 00278 } 00279 00280 FileType * FileCreatePart::getEnabledType(const QString & ex, const QString subtRef) { 00281 00282 QString subtypeRef = subtRef; 00283 QString ext = ex; 00284 int dashPos = ext.find('-'); 00285 if (dashPos>-1 && subtRef.isNull()) { 00286 ext = ex.left(dashPos); 00287 subtypeRef = ex.mid(dashPos+1); 00288 } 00289 00290 QPtrList<FileType> filetypes = getFileTypes(); 00291 for(FileType * filetype = filetypes.first(); 00292 filetype; 00293 filetype=filetypes.next()) { 00294 if (filetype->ext()==ext) { 00295 if ( (subtypeRef.isNull()) && (filetype->enabled()) ) return filetype; 00296 QPtrList<FileType> subtypes = filetype->subtypes(); 00297 for(FileType * subtype = subtypes.first(); 00298 subtype; 00299 subtype=subtypes.next()) { 00300 if ( (subtypeRef==subtype->subtypeRef()) && (filetype->enabled()) ) return subtype; 00301 } 00302 } 00303 } 00304 return NULL; 00305 } 00306 00307 // KDevFileCreate interface 00308 00309 KDevCreateFile::CreatedFile FileCreatePart::createNewFile(QString ext, QString dir, QString name, QString subtype) 00310 { 00311 KDevCreateFile::CreatedFile result; 00312 KURL projectURL( project()->projectDirectory() ); 00313 KURL selectedURL; 00314 00315 NewFileChooser dialog; 00316 dialog.setFileTypes(m_filetypes); 00317 const FileType *filetype = getEnabledType(ext,subtype); 00318 kdDebug(9034) << "Looking for filetype pointer for " << ext << "/" << subtype << endl; 00319 if (filetype) { 00320 kdDebug(9034) << "found filetype" << endl; 00321 } else { 00322 kdDebug(9034) << "could not find filetype" << endl; 00323 } 00324 00325 if (!dir.isNull()) 00326 dialog.setDirectory(dir); 00327 else 00328 { 00329 QString activeDir = project()->activeDirectory(); 00330 dialog.setDirectory( project()->projectDirectory() + 00331 ( activeDir[0] == '/' ? "" : "/" ) 00332 + activeDir ); 00333 } 00334 if (!name.isNull()) dialog.setName(name); 00335 if (filetype) dialog.setCurrent(filetype); 00336 00337 int dialogResult = dialog.exec(); 00338 00339 if (dialogResult == KDialogBase::Rejected) { 00340 result.status = KDevCreateFile::CreatedFile::STATUS_NOTCREATED; 00341 return result; 00342 } 00343 00344 // OK was pressed 00345 00346 result.addToProject = dialog.addToProject(); 00347 selectedURL = dialog.url(); 00348 const FileType *selectedFileType = dialog.selectedType(); 00349 00350 if (dialog.addToProject() && !projectURL.isParentOf(selectedURL)) { 00351 result.status = KDevCreateFile::CreatedFile::STATUS_NOTWITHINPROJECT; 00352 return result; 00353 } 00354 00355 if (selectedFileType) { 00356 ext = selectedFileType->ext(); 00357 subtype = selectedFileType->subtypeRef(); 00358 } 00359 00360 if (dialog.addToProject()) 00361 { 00362 // work out the path relative to the project directory 00363 QString relToProj = URLUtil::relativePath(projectURL, selectedURL, URLUtil::SLASH_PREFIX ); 00364 00365 // add appropriate extension, if not already there 00366 if (!ext.isNull() & ext!="" & !relToProj.endsWith("." + ext)) relToProj+="." + ext; 00367 00368 QString filename = URLUtil::filename(relToProj); 00369 00370 kdDebug(9034) << "relative to proj dir = " << relToProj << endl; 00371 kdDebug(9034) << "filename = " << filename << endl; 00372 00373 // add in subtype, if specified 00374 if (!subtype.isEmpty()) 00375 ext += "-" + subtype; 00376 00377 // create file from template, and add it to the project 00378 if (!FileTemplate::exists(this, ext) || 00379 !FileTemplate::copy(this, ext, project()->projectDirectory() + relToProj) ) { 00380 // no template, create a blank file instead 00381 QFile f(project()->projectDirectory() + relToProj); 00382 f.open( IO_WriteOnly ); 00383 f.close(); 00384 } 00385 00386 project()->addFile(relToProj.mid(1)); 00387 00388 // tell the caller what we did 00389 result.filename = filename; 00390 result.dir = URLUtil::directory(relToProj); 00391 result.status = KDevCreateFile::CreatedFile::STATUS_OK; 00392 } 00393 else //this is for non-project files 00394 { 00395 QString fullPath = selectedURL.path(); 00396 // add appropriate extension, if not already there 00397 if (!ext.isNull() & ext!="" & !fullPath.endsWith("." + ext)) fullPath+="." + ext; 00398 00399 QString filename = URLUtil::filename(fullPath); 00400 00401 kdDebug(9034) << "full path = " << fullPath << endl; 00402 kdDebug(9034) << "filename = " << filename << endl; 00403 00404 // add in subtype, if specified 00405 if (!subtype.isEmpty()) 00406 ext += "-" + subtype; 00407 00408 // create file from template, and add it to the project 00409 if (!FileTemplate::exists(this, ext) || 00410 !FileTemplate::copy(this, ext, fullPath) ) { 00411 // no template, create a blank file instead 00412 QFile f(fullPath); 00413 f.open( IO_WriteOnly ); 00414 f.close(); 00415 } 00416 KURL url; 00417 url.setPath(fullPath); 00418 partController()->editDocument(url); 00419 result.filename = filename; 00420 result.dir = URLUtil::directory(fullPath); 00421 result.status = KDevCreateFile::CreatedFile::STATUS_OK; 00422 } 00423 00424 return result; 00425 } 00426 00427 void FileCreatePart::setShowSideTab(bool on) { 00428 selectWidget(on ? 1 : -1 ); 00429 } 00430 00431 void FileCreatePart::slotNoteFiletype(const FileType * filetype) { 00432 kdDebug(9034) << "Noting file type: " << (filetype ? filetype->ext() : QString::fromLatin1("Null") ) << endl; 00433 m_filedialogFiletype = filetype; 00434 } 00435 00436 void FileCreatePart::slotInitialize( ) 00437 { 00438 // read in global template information 00439 QString globalXMLFile = ::locate("data", "kdevfilecreate/template-info.xml"); 00440 kdDebug(9034) << "Found global template info info " << globalXMLFile << endl; 00441 QDomDocument globalDom; 00442 if (!globalXMLFile.isNull() && 00443 DomUtil::openDOMFile(globalDom,globalXMLFile)) { 00444 kdDebug(9034) << "Reading global template info..." << endl; 00445 // kapp->processEvents(); 00446 readTypes(globalDom, m_filetypes, false); 00447 00448 // use side tab or not? 00450 QDomElement useSideTab = DomUtil::elementByPath(globalDom,"/kdevfilecreate/sidetab"); 00451 if (!useSideTab.isNull() && useSideTab.attribute("active")=="no") { 00452 m_useSideTab = false; 00453 } 00454 } 00455 00456 00457 // read in which global templates are to be used for this project 00458 QDomElement useGlobalTypes = 00459 DomUtil::elementByPath(*projectDom(),"/kdevfilecreate/useglobaltypes"); 00460 for(QDomNode node = useGlobalTypes.firstChild(); 00461 !node.isNull();node=node.nextSibling()) { 00462 00463 // kapp->processEvents(); 00464 00465 if (node.isElement() && node.nodeName()=="type") { 00466 QDomElement element = node.toElement(); 00467 QString ext = element.attribute("ext"); 00468 QString subtyperef = element.attribute("subtyperef"); 00469 // if an extension has been specified as enabled, ensure it 00470 // and all its subtypes are enabled 00471 if (subtyperef.isNull()) { 00472 FileType * filetype = getType(ext); 00473 if (filetype) { 00474 filetype->setEnabled(true); 00475 if (filetype->subtypes().count()) 00476 filetype->setSubtypesEnabled(true); 00477 } 00478 } else { 00479 // if an extension + subtype have been specified, enable 00480 // the subtype and the extension (the 'parent') 00481 FileType * filetype = getType(ext); 00482 FileType * subtype = getType(ext,subtyperef); 00483 if (filetype && subtype) { 00484 filetype->setEnabled(true); 00485 subtype->setEnabled(true); 00486 } 00487 } 00488 } 00489 } 00490 00491 // read in the list of file types for this project 00492 if ( readTypes( *projectDom(), m_filetypes, true )==0 ) { 00493 // default by scanning the templates directory if no template info 00494 // found in project file 00495 QDir templDir( project()->projectDirectory() + "/templates/" ); 00496 if (templDir.exists()) { 00497 templDir.setFilter( QDir::Files ); 00498 const QFileInfoList * list = templDir.entryInfoList(); 00499 if( list ){ 00500 QFileInfoListIterator it( *list ); 00501 QFileInfo *fi; 00502 while ( (fi = it.current()) != 0 ) { 00503 addFileType(fi->fileName()); 00504 ++it; 00505 } 00506 } 00507 } 00508 /* else { // it was probably an imported project 00509 // KLUDGE: we need a better way to determine file types 00510 // the current method looks a bit too restrictive 00511 addFileType( "cpp" ); 00512 addFileType( "h" ); 00513 }*/ 00514 } 00515 00516 setShowSideTab(m_useSideTab); 00517 00518 // refresh view 00519 refresh(); 00520 } 00521 00522 #include "filecreate_part.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Oct 6 17:39:11 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003