summaryrefslogtreecommitdiffstats
path: root/parts/filecreate/filecreate_part.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'parts/filecreate/filecreate_part.cpp')
-rw-r--r--parts/filecreate/filecreate_part.cpp562
1 files changed, 562 insertions, 0 deletions
diff --git a/parts/filecreate/filecreate_part.cpp b/parts/filecreate/filecreate_part.cpp
new file mode 100644
index 00000000..3733753a
--- /dev/null
+++ b/parts/filecreate/filecreate_part.cpp
@@ -0,0 +1,562 @@
+/***************************************************************************
+ * Copyright (C) 2003 by Julian Rockey *
+ * *
+ * 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 <qwhatsthis.h>
+#include <qdom.h>
+#include <qdir.h>
+#include <qfileinfo.h>
+#include <qvbox.h>
+#include <qtimer.h>
+
+#include <kdeversion.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kdevgenericfactory.h>
+#include <kfiledialog.h>
+#include <kdebug.h>
+#include <kstandarddirs.h>
+#include <kstdaction.h>
+#include <kaction.h>
+#include <kapplication.h>
+#include <kactionclasses.h>
+#include <kpopupmenu.h>
+#include <kmessagebox.h>
+
+#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<FileCreatePart> FileCreateFactory;
+K_EXPORT_COMPONENT_FACTORY( libkdevfilecreate, FileCreateFactory( data ) )
+
+using namespace FileCreate;
+
+FileCreatePart::FileCreatePart(QObject *parent, const char *name, const QStringList & )
+// : 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(), SIGNAL(projectOpened()), this, SLOT(slotProjectOpened()) );
+ connect( core(), SIGNAL(projectClosed()), this, SLOT(slotProjectClosed()) );
+
+ _configProxy = new ConfigWidgetProxy( core() );
+ _configProxy->createProjectConfigPage( i18n("File Templates"), PROJECTSETTINGSPAGE, info()->icon() );
+ _configProxy->createGlobalConfigPage( i18n("File Templates"), GLOBALSETTINGSPAGE, info()->icon() );
+ connect( _configProxy, SIGNAL(insertConfigWidget(const KDialogBase*, QWidget*, unsigned int )),
+ this, SLOT(insertConfigWidget(const KDialogBase*, QWidget*, unsigned int )) );
+
+
+ KToolBarPopupAction * newAction = new KToolBarPopupAction( i18n("&New"), "filenew", CTRL+Qt::Key_N, this, SLOT(slotNewFile()), actionCollection(), "file_new");
+ 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.") );
+ newAction->setToolTip( i18n("Create a new file") );
+ m_newPopupMenu = newAction->popupMenu();
+ connect(m_newPopupMenu, SIGNAL(aboutToShow()), this, SLOT(slotAboutToShowNewPopupMenu()));
+
+ QTimer::singleShot( 0, this, SLOT(slotGlobalInitialize()) );
+}
+
+
+FileCreatePart::~FileCreatePart()
+{
+ delete _configProxy;
+
+ m_newPopupMenu->clear();
+ delete m_subPopups;
+}
+
+void FileCreatePart::insertConfigWidget( const KDialogBase * dlg, QWidget * page, unsigned int pagenumber )
+{
+ kdDebug() << k_funcinfo << endl;
+
+ switch( pagenumber )
+ {
+ case PROJECTSETTINGSPAGE:
+ {
+ FCConfigWidget* w = new FCConfigWidget( this, false, page, "filecreate config widget" );
+ connect( dlg, SIGNAL( okClicked( ) ), w, SLOT( accept( ) ) );
+ }
+ break;
+
+ case GLOBALSETTINGSPAGE:
+ {
+ FCConfigWidget *w = new FCConfigWidget( this, true, page, "filecreate config widget" );
+ connect(dlg, SIGNAL(okClicked()), w, SLOT(accept()));
+ }
+ break;
+ }
+}
+
+void FileCreatePart::slotAboutToShowNewPopupMenu()
+{
+ KIconLoader * m_iconLoader = KGlobal::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)
+ {
+ QPixmap iconPix = m_iconLoader->loadIcon(
+ filetype->icon(), KIcon::Desktop, KIcon::SizeSmall,
+ KIcon::DefaultState, NULL, true);
+ m_newPopupMenu->insertItem(iconPix, filetype->name(), this,
+ SLOT(slotNewFilePopup(int)), 0, ++id );
+ m_newPopupMenu->setItemParameter( id, (long)filetype );
+ } else
+ {
+ KPopupMenu* subMenu = NULL;
+ QPtrList<FileType> subtypes = filetype->subtypes();
+ for(FileType * subtype = subtypes.first(); subtype; subtype=subtypes.next())
+ {
+ if (subtype->enabled()){
+ if( !subMenu )
+ subMenu = new KPopupMenu(0,0);
+ QPixmap iconPix = m_iconLoader->loadIcon(
+ subtype->icon(), KIcon::Desktop, KIcon::SizeSmall,
+ KIcon::DefaultState, NULL, true);
+ subMenu->insertItem(iconPix, subtype->name(), this,
+ SLOT(slotNewFilePopup(int)), 0, ++id );
+ subMenu->setItemParameter( id, (long)subtype );
+ }
+ }
+ if( subMenu )
+ {
+ if( !m_subPopups )
+ {
+ m_subPopups = new QPtrList<KPopupMenu>;
+ 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() {
+ QTimer::singleShot( 0, this, SLOT(slotInitialize()) );
+}
+
+void FileCreatePart::addFileType(const QString & 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();
+ QTimer::singleShot( 0, this, SLOT(slotGlobalInitialize()) );
+}
+
+void FileCreatePart::slotFiletypeSelected(const FileType * filetype) {
+
+ KDevCreateFile::CreatedFile createdFile = createNewFile(filetype->ext(),
+ QString::null,
+ QString::null,
+ 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 QDomDocument & dom, QPtrList<FileType> &m_filetypes, bool enable) {
+ int numRead = 0;
+ QDomElement fileTypes = DomUtil::elementByPath(dom,"/kdevfilecreate/filetypes");
+ if (!fileTypes.isNull()) {
+ for(QDomNode node = fileTypes.firstChild();!node.isNull();node=node.nextSibling()) {
+
+ if (node.isElement() && node.nodeName()=="type") {
+ QDomElement 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(QDomNode subnode = node.firstChild();!subnode.isNull();subnode=subnode.nextSibling()) {
+ kdDebug(9034) << "subnode: " << subnode.nodeName().latin1() << endl;
+ if (subnode.isElement() && subnode.nodeName()=="subtype") {
+ QDomElement 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 QString & ex, const QString subtRef) {
+
+ QString subtypeRef = subtRef;
+ QString ext = ex;
+ int dashPos = ext.find('-');
+ if (dashPos>-1 && subtRef.isNull()) {
+ ext = ex.left(dashPos);
+ subtypeRef = ex.mid(dashPos+1);
+ }
+
+ QPtrList<FileType> filetypes = getFileTypes();
+ for(FileType * filetype = filetypes.first();
+ filetype;
+ filetype=filetypes.next()) {
+ if (filetype->ext()==ext) {
+ if (subtypeRef.isNull()) return filetype;
+ QPtrList<FileType> subtypes = filetype->subtypes();
+ for(FileType * subtype = subtypes.first();
+ subtype;
+ subtype=subtypes.next()) {
+ if (subtypeRef==subtype->subtypeRef()) return subtype;
+ }
+ }
+ }
+ return NULL;
+}
+
+FileType * FileCreatePart::getEnabledType(const QString & ex, const QString subtRef) {
+
+ QString subtypeRef = subtRef;
+ QString ext = ex;
+ int dashPos = ext.find('-');
+ if (dashPos>-1 && subtRef.isNull()) {
+ ext = ex.left(dashPos);
+ subtypeRef = ex.mid(dashPos+1);
+ }
+
+ QPtrList<FileType> filetypes = getFileTypes();
+ for(FileType * filetype = filetypes.first();
+ filetype;
+ filetype=filetypes.next()) {
+ if (filetype->ext()==ext) {
+ if ( (subtypeRef.isNull()) && (filetype->enabled()) ) return filetype;
+ QPtrList<FileType> 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(QString ext, QString dir, QString name, QString 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(QDir::currentDirPath());
+ else
+ {
+ QString activeDir = project()->activeDirectory();
+ dialog.setDirectory( project()->projectDirectory() +
+ ( activeDir[0] == '/' ? "" : "/" )
+ + activeDir );
+ }
+ if (!name.isNull()) dialog.setName(name);
+ if (filetype) dialog.setCurrent(filetype);
+
+ dialog.setInitialSize(QSize(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::UsesQMakeBuildSystem) ) {
+ result.status = KDevCreateFile::CreatedFile::STATUS_NOTWITHINPROJECT;
+ return result;
+ }
+
+ if (selectedFileType) {
+ ext = selectedFileType->ext();
+ subtype = selectedFileType->subtypeRef();
+ }
+
+ QString fullPath = selectedURL.path();
+ // add appropriate extension, if not already there
+ if ( !ext.isEmpty() && !fullPath.endsWith("." + ext)) fullPath+="." + ext;
+
+ QString 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
+ QFile 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
+// QString relToProj = URLUtil::relativePath(projectURL, selectedURL, URLUtil::SLASH_PREFIX );
+ QString relToProj;
+ if( project()->options() & KDevProject::UsesQMakeBuildSystem )
+ {
+ 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);
+
+ QString 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() : QString::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
+ QDomElement useGlobalTypes =
+ DomUtil::elementByPath(*projectDom(),"/kdevfilecreate/useglobaltypes");
+ for(QDomNode node = useGlobalTypes.firstChild();
+ !node.isNull();node=node.nextSibling()) {
+
+ if (node.isElement() && node.nodeName()=="type") {
+ QDomElement element = node.toElement();
+ QString ext = element.attribute("ext");
+ QString 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
+ QDir templDir( project()->projectDirectory() + "/templates/" );
+ if (templDir.exists()) {
+ templDir.setFilter( QDir::Files );
+ const QFileInfoList * list = templDir.entryInfoList();
+ if( list ){
+ QFileInfoListIterator it( *list );
+ QFileInfo *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" );
+ }*/
+ }
+}
+
+QString FileCreatePart::findGlobalXMLFile() const
+{
+ int version = 0;
+ QString filename;
+ QStringList filenames = KGlobal::instance()->dirs()->findAllResources("data", "kdevfilecreate/template-info.xml");
+ for( QStringList::const_iterator it = filenames.begin(); it != filenames.end(); ++it )
+ {
+ QDomDocument globalDom;
+ DomUtil::openDOMFile(globalDom,*it);
+ QDomElement 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
+ QString globalXMLFile = findGlobalXMLFile();
+ kdDebug(9034) << "Found global template info info " << globalXMLFile << endl;
+ QDomDocument 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;