/*************************************************************************** * Copyright (C) 2003 by Julian Rockey * * linux@jrockey.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "filecreate_part.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kdevcore.h" #include "kdevmainwindow.h" #include "kdevproject.h" #include "kdevpartcontroller.h" #include "configwidgetproxy.h" #include "filetemplate.h" #include "domutil.h" #include "urlutil.h" #include "filecreate_widget2.h" #include "filecreate_widget3.h" #include "filecreate_filetype.h" #include "filecreate_filedialog.h" #include "filecreate_newfile.h" #include "fcconfigwidget.h" #define PROJECTSETTINGSPAGE 1 #define GLOBALSETTINGSPAGE 2 #include "kdevplugininfo.h" #include "config.h" static const KDevPluginInfo data("kdevfilecreate"); typedef KDevGenericFactory FileCreateFactory; K_EXPORT_COMPONENT_FACTORY( libkdevfilecreate, FileCreateFactory( data ) ) using namespace FileCreate; FileCreatePart::FileCreatePart(TQObject *parent, const char *name, const TQStringList & ) // : KDevCreateFile(&data, parent, name ? name : "FileCreatePart"), m_selectedWidget(-1), m_useSideTab(true), m_subPopups(0) : KDevCreateFile(&data, parent, name ? name : "FileCreatePart"), m_subPopups(0) { setInstance(FileCreateFactory::instance()); setXMLFile("kdevpart_filecreate.rc"); connect( core(), TQT_SIGNAL(projectOpened()), this, TQT_SLOT(slotProjectOpened()) ); connect( core(), TQT_SIGNAL(projectClosed()), this, TQT_SLOT(slotProjectClosed()) ); _configProxy = new ConfigWidgetProxy( core() ); _configProxy->createProjectConfigPage( i18n("File Templates"), PROJECTSETTINGSPAGE, info()->icon() ); _configProxy->createGlobalConfigPage( i18n("File Templates"), GLOBALSETTINGSPAGE, info()->icon() ); connect( _configProxy, TQT_SIGNAL(insertConfigWidget(const KDialogBase*, TQWidget*, unsigned int )), this, TQT_SLOT(insertConfigWidget(const KDialogBase*, TQWidget*, unsigned int )) ); TDEToolBarPopupAction * newAction = new TDEToolBarPopupAction( i18n("&New"), "document-new", CTRL+TQt::Key_N, this, TQT_SLOT(slotNewFile()), actionCollection(), "file_new"); newAction->setWhatsThis( i18n("New file

Creates a new file. Also adds it the project if the Add to project checkbox is turned on.") ); newAction->setToolTip( i18n("Create a new file") ); m_newPopupMenu = newAction->popupMenu(); connect(m_newPopupMenu, TQT_SIGNAL(aboutToShow()), this, TQT_SLOT(slotAboutToShowNewPopupMenu())); TQTimer::singleShot( 0, this, TQT_SLOT(slotGlobalInitialize()) ); } FileCreatePart::~FileCreatePart() { delete _configProxy; m_newPopupMenu->clear(); delete m_subPopups; } void FileCreatePart::insertConfigWidget( const KDialogBase * dlg, TQWidget * page, unsigned int pagenumber ) { kdDebug() << k_funcinfo << endl; switch( pagenumber ) { case PROJECTSETTINGSPAGE: { FCConfigWidget* w = new FCConfigWidget( this, false, page, "filecreate config widget" ); connect( dlg, TQT_SIGNAL( okClicked( ) ), w, TQT_SLOT( accept( ) ) ); } break; case GLOBALSETTINGSPAGE: { FCConfigWidget *w = new FCConfigWidget( this, true, page, "filecreate config widget" ); connect(dlg, TQT_SIGNAL(okClicked()), w, TQT_SLOT(accept())); } break; } } void FileCreatePart::slotAboutToShowNewPopupMenu() { TDEIconLoader * m_iconLoader = TDEGlobal::iconLoader(); m_newPopupMenu->clear(); delete m_subPopups; m_subPopups = NULL; int id = 0; FileType * filetype = m_filetypes.first(); for(; filetype; filetype=m_filetypes.next()) { if (filetype->enabled()) { if (filetype->subtypes().count()==0) { TQPixmap iconPix = m_iconLoader->loadIcon( filetype->icon(), TDEIcon::Desktop, TDEIcon::SizeSmall, TDEIcon::DefaultState, NULL, true); m_newPopupMenu->insertItem(iconPix, filetype->name(), this, TQT_SLOT(slotNewFilePopup(int)), 0, ++id ); m_newPopupMenu->setItemParameter( id, (long)filetype ); } else { TDEPopupMenu* subMenu = NULL; TQPtrList subtypes = filetype->subtypes(); for(FileType * subtype = subtypes.first(); subtype; subtype=subtypes.next()) { if (subtype->enabled()){ if( !subMenu ) subMenu = new TDEPopupMenu(0,0); TQPixmap iconPix = m_iconLoader->loadIcon( subtype->icon(), TDEIcon::Desktop, TDEIcon::SizeSmall, TDEIcon::DefaultState, NULL, true); subMenu->insertItem(iconPix, subtype->name(), this, TQT_SLOT(slotNewFilePopup(int)), 0, ++id ); subMenu->setItemParameter( id, (long)subtype ); } } if( subMenu ) { if( !m_subPopups ) { m_subPopups = new TQPtrList; m_subPopups->setAutoDelete(true); } m_subPopups->append( subMenu ); m_newPopupMenu->insertItem( filetype->name(), subMenu ); } } } } } void FileCreatePart::slotNewFilePopup( int pFileType ) { const FileType* filetype = (const FileType*) pFileType; slotFiletypeSelected( filetype ); } void FileCreatePart::slotNewFile() { KDevCreateFile::CreatedFile createdFile = createNewFile(); if (createdFile.status == KDevCreateFile::CreatedFile::STATUS_NOTCREATED) KMessageBox::error(0, i18n("Cannot create file. Check whether the directory and filename are valid.")); else if (createdFile.status != KDevCreateFile::CreatedFile::STATUS_CANCELED) openCreatedFile(createdFile); } void FileCreatePart::slotProjectOpened() { TQTimer::singleShot( 0, this, TQT_SLOT(slotInitialize()) ); } void FileCreatePart::addFileType(const TQString & filename) { FileType * filetype = getType(filename); if (!filetype) { filetype = new FileType; filetype->setName( filename + " files" ); filetype->setExt( filename ); filetype->setCreateMethod("template"); m_filetypes.append(filetype); } filetype->setEnabled(true); } void FileCreatePart::slotProjectClosed() { m_filetypes.clear(); TQTimer::singleShot( 0, this, TQT_SLOT(slotGlobalInitialize()) ); } void FileCreatePart::slotFiletypeSelected(const FileType * filetype) { KDevCreateFile::CreatedFile createdFile = createNewFile(filetype->ext(), TQString(), TQString(), filetype->subtypeRef()); openCreatedFile(createdFile); } void FileCreatePart::openCreatedFile(const KDevCreateFile::CreatedFile & createdFile) { if ( createdFile.status == KDevCreateFile::CreatedFile::STATUS_OK ) { KURL uu( createdFile.dir + "/" + createdFile.filename ); partController()->editDocument ( uu ); } } int FileCreatePart::readTypes(const TQDomDocument & dom, TQPtrList &m_filetypes, bool enable) { int numRead = 0; TQDomElement fileTypes = DomUtil::elementByPath(dom,"/kdevfilecreate/filetypes"); if (!fileTypes.isNull()) { for(TQDomNode node = fileTypes.firstChild();!node.isNull();node=node.nextSibling()) { if (node.isElement() && node.nodeName()=="type") { TQDomElement element = node.toElement(); FileType * filetype = new FileType; filetype->setName( element.attribute("name") ); filetype->setExt( element.attribute("ext") ); filetype->setCreateMethod( element.attribute("create") ); filetype->setIcon( element.attribute("icon") ); filetype->setDescr( (DomUtil::namedChildElement(element, "descr")).text() ); filetype->setEnabled(enable || (filetype->ext()=="")); m_filetypes.append(filetype); numRead++; kdDebug(9034) << "node: " << filetype->name().latin1() << endl; if (node.hasChildNodes()) { for(TQDomNode subnode = node.firstChild();!subnode.isNull();subnode=subnode.nextSibling()) { kdDebug(9034) << "subnode: " << subnode.nodeName().latin1() << endl; if (subnode.isElement() && subnode.nodeName()=="subtype") { TQDomElement subelement = subnode.toElement(); FileType * subtype = new FileType; subtype->setExt( filetype->ext() ); subtype->setCreateMethod( filetype->createMethod() ); subtype->setSubtypeRef( subelement.attribute("ref") ); subtype->setIcon( subelement.attribute("icon") ); subtype->setName( subelement.attribute("name") ); subtype->setDescr( (DomUtil::namedChildElement(subelement, "descr")).text() ); subtype->setEnabled(enable); filetype->addSubtype(subtype); } } } } } } return numRead; } FileType * FileCreatePart::getType(const TQString & ex, const TQString subtRef) { TQString subtypeRef = subtRef; TQString ext = ex; int dashPos = ext.find('-'); if (dashPos>-1 && subtRef.isNull()) { ext = ex.left(dashPos); subtypeRef = ex.mid(dashPos+1); } TQPtrList filetypes = getFileTypes(); for(FileType * filetype = filetypes.first(); filetype; filetype=filetypes.next()) { if (filetype->ext()==ext) { if (subtypeRef.isNull()) return filetype; TQPtrList subtypes = filetype->subtypes(); for(FileType * subtype = subtypes.first(); subtype; subtype=subtypes.next()) { if (subtypeRef==subtype->subtypeRef()) return subtype; } } } return NULL; } FileType * FileCreatePart::getEnabledType(const TQString & ex, const TQString subtRef) { TQString subtypeRef = subtRef; TQString ext = ex; int dashPos = ext.find('-'); if (dashPos>-1 && subtRef.isNull()) { ext = ex.left(dashPos); subtypeRef = ex.mid(dashPos+1); } TQPtrList filetypes = getFileTypes(); for(FileType * filetype = filetypes.first(); filetype; filetype=filetypes.next()) { if (filetype->ext()==ext) { if ( (subtypeRef.isNull()) && (filetype->enabled()) ) return filetype; TQPtrList subtypes = filetype->subtypes(); for(FileType * subtype = subtypes.first(); subtype; subtype=subtypes.next()) { if ( (subtypeRef==subtype->subtypeRef()) && (filetype->enabled()) ) return subtype; } } } return NULL; } // KDevFileCreate interface KDevCreateFile::CreatedFile FileCreatePart::createNewFile(TQString ext, TQString dir, TQString name, TQString subtype) { KDevCreateFile::CreatedFile result; KURL projectURL; if ( !project() ) { //result.status = KDevCreateFile::CreatedFile::STATUS_NOTCREATED; //return result; } else { projectURL = project()->projectDirectory(); } KURL selectedURL; NewFileChooser dialog; dialog.setFileTypes(m_filetypes); const FileType *filetype = getEnabledType(ext,subtype); kdDebug(9034) << "Looking for filetype pointer for " << ext << "/" << subtype << endl; if (filetype) { kdDebug(9034) << "found filetype" << endl; } else { kdDebug(9034) << "could not find filetype" << endl; } if (!project()) dialog.setInProjectMode(false); if (!dir.isNull()) dialog.setDirectory(dir); else if (!project()) dialog.setDirectory(TQDir::currentDirPath()); else { TQString activeDir = project()->activeDirectory(); dialog.setDirectory( project()->projectDirectory() + ( activeDir[0] == '/' ? "" : "/" ) + activeDir ); } if (!name.isNull()) dialog.setName(name); if (filetype) dialog.setCurrent(filetype); dialog.setInitialSize(TQSize(500, 200)); int dialogResult = dialog.exec(); if (dialogResult == KDialogBase::Rejected) { result.status = KDevCreateFile::CreatedFile::STATUS_CANCELED; return result; } // OK was pressed result.addToProject = dialog.addToProject(); selectedURL = dialog.url(); const FileType *selectedFileType = dialog.selectedType(); if (dialog.addToProject() && !projectURL.isParentOf(selectedURL) && !(project()->options() & KDevProject::UsesTQMakeBuildSystem) ) { result.status = KDevCreateFile::CreatedFile::STATUS_NOTWITHINPROJECT; return result; } if (selectedFileType) { ext = selectedFileType->ext(); subtype = selectedFileType->subtypeRef(); } TQString fullPath = selectedURL.path(); // add appropriate extension, if not already there if ( !ext.isEmpty() && !fullPath.endsWith("." + ext)) fullPath+="." + ext; TQString filename = URLUtil::filename(fullPath); kdDebug(9034) << "full path = " << fullPath << endl; // add in subtype, if specified if (!subtype.isEmpty()) ext += "-" + subtype; // create file from template bool created = false; if (FileTemplate::exists(this, ext)) created = FileTemplate::copy(this, ext, fullPath); else { // no template, create a blank file instead TQFile f(fullPath); created = f.open( IO_WriteOnly ); f.close(); } if (!created) { result.status = KDevCreateFile::CreatedFile::STATUS_NOTCREATED; return result; } if (dialog.addToProject()) { // work out the path relative to the project directory // TQString relToProj = URLUtil::relativePath(projectURL, selectedURL, URLUtil::SLASH_PREFIX ); TQString relToProj; if( project()->options() & KDevProject::UsesTQMakeBuildSystem ) { relToProj = URLUtil::relativePathToFile( project()->projectDirectory(), fullPath ); project()->addFile(relToProj); }else { relToProj = URLUtil::relativePath(projectURL.path(), fullPath, URLUtil::SLASH_PREFIX ); project()->addFile(relToProj.mid(1)); } } KURL url; url.setPath(fullPath); partController()->editDocument(url); TQString fileName = URLUtil::filename(fullPath); kdDebug(9034) << "file name = " << filename << endl; result.filename = fileName; result.dir = URLUtil::directory(fullPath); result.status = KDevCreateFile::CreatedFile::STATUS_OK; return result; } void FileCreatePart::slotNoteFiletype(const FileType * filetype) { kdDebug(9034) << "Noting file type: " << (filetype ? filetype->ext() : TQString::fromLatin1("Null") ) << endl; m_filedialogFiletype = filetype; } void FileCreatePart::slotInitialize( ) { m_filetypes.clear(); //read global configuration slotGlobalInitialize(); // read in which global templates are to be used for this project TQDomElement useGlobalTypes = DomUtil::elementByPath(*projectDom(),"/kdevfilecreate/useglobaltypes"); for(TQDomNode node = useGlobalTypes.firstChild(); !node.isNull();node=node.nextSibling()) { if (node.isElement() && node.nodeName()=="type") { TQDomElement element = node.toElement(); TQString ext = element.attribute("ext"); TQString subtyperef = element.attribute("subtyperef"); // if an extension has been specified as enabled, ensure it // and all its subtypes are enabled if (subtyperef.isNull()) { FileType * filetype = getType(ext); if (filetype) { filetype->setEnabled(true); if (filetype->subtypes().count()) filetype->setSubtypesEnabled(true); } } else { // if an extension + subtype have been specified, enable // the subtype and the extension (the 'parent') FileType * filetype = getType(ext); FileType * subtype = getType(ext,subtyperef); if (filetype && subtype) { filetype->setEnabled(true); subtype->setEnabled(true); } } } } // read in the list of file types for this project if ( project() && readTypes( *projectDom(), m_filetypes, true )==0 ) { // default by scanning the templates directory if no template info // found in project file TQDir templDir( project()->projectDirectory() + "/templates/" ); if (templDir.exists()) { templDir.setFilter( TQDir::Files ); const TQFileInfoList * list = templDir.entryInfoList(); if( list ){ TQFileInfoListIterator it( *list ); TQFileInfo *fi; while ( (fi = it.current()) != 0 ) { addFileType(fi->fileName()); ++it; } } } /* else { // it was probably an imported project // KLUDGE: we need a better way to determine file types // the current method looks a bit too restrictive addFileType( "cpp" ); addFileType( "h" ); }*/ } } TQString FileCreatePart::findGlobalXMLFile() const { int version = 0; TQString filename; TQStringList filenames = TDEGlobal::instance()->dirs()->findAllResources("data", "kdevfilecreate/template-info.xml"); for( TQStringList::const_iterator it = filenames.begin(); it != filenames.end(); ++it ) { TQDomDocument globalDom; DomUtil::openDOMFile(globalDom,*it); TQDomElement e = globalDom.documentElement(); if( !e.hasAttribute( "version" ) && e.attribute( "version" ).toInt() < version ) { continue; }else { version = e.attribute( "version" ).toInt(); filename = *it; } } return filename; } void FileCreatePart::slotGlobalInitialize( ) { // read in global template information TQString globalXMLFile = findGlobalXMLFile(); kdDebug(9034) << "Found global template info info " << globalXMLFile << endl; TQDomDocument globalDom; if (!globalXMLFile.isNull() && DomUtil::openDOMFile(globalDom,globalXMLFile)) { kdDebug(9034) << "Reading global template info..." << endl; readTypes(globalDom, m_filetypes, false); } } #include "filecreate_part.moc" // kate: indent-width 2; replace-tabs on; tab-width 4; space-indent on;