diff options
Diffstat (limited to 'src/projectmanager.cpp')
-rw-r--r-- | src/projectmanager.cpp | 1256 |
1 files changed, 1256 insertions, 0 deletions
diff --git a/src/projectmanager.cpp b/src/projectmanager.cpp new file mode 100644 index 0000000..dfef6b3 --- /dev/null +++ b/src/projectmanager.cpp @@ -0,0 +1,1256 @@ +/*************************************************************************** + * Copyright (C) 2003-2005 by David Saxton * + * david@bluehaze.org * + * * + * 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 "core/ktlconfig.h" +#include "docmanager.h" +#include "document.h" +#include "language.h" +#include "languagemanager.h" +#include "ktechlab.h" +#include "microselectwidget.h" +#include "programmerdlg.h" +#include "projectdlgs.h" +#include "projectmanager.h" +#include "recentfilesaction.h" + +#include <kdebug.h> +#include <kfiledialog.h> +#include <kiconloader.h> +#include <kio/netaccess.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kmimetype.h> +#include <kstandarddirs.h> +#include <qdom.h> +#include <qpopupmenu.h> +#include <qwhatsthis.h> + +#include <assert.h> + +//BEGIN class LinkerOptions +LinkerOptions::LinkerOptions() +{ + m_hexFormat = HexFormat::inhx32; + m_bOutputMapFile = false; +} + + +QDomElement LinkerOptions::toDomElement( QDomDocument & doc, const KURL & baseURL ) const +{ + QDomElement node = doc.createElement("linker"); + + node.setAttribute( "hex-format", hexFormatToString(hexFormat()) ); + node.setAttribute( "output-map-file", outputMapFile() ); + node.setAttribute( "library-dir", libraryDir() ); + node.setAttribute( "linker-script", linkerScript() ); + node.setAttribute( "other", linkerOther() ); + + QStringList::const_iterator end = m_linkedInternal.end(); + for ( QStringList::const_iterator it = m_linkedInternal.begin(); it != end; ++it ) + { + QDomElement child = doc.createElement("linked-internal"); + node.appendChild(child); + child.setAttribute( "url", KURL::relativeURL( baseURL, *it ) ); + } + + end = m_linkedExternal.end(); + for ( QStringList::const_iterator it = m_linkedExternal.begin(); it != end; ++it ) + { + QDomElement child = doc.createElement("linked-external"); + node.appendChild(child); + child.setAttribute( "url", *it ); + } + + return node; +} + + +void LinkerOptions::domElementToLinkerOptions( const QDomElement & element, const KURL & baseURL ) +{ + setHexFormat( stringToHexFormat( element.attribute( "hex-format", QString::null ) ) ); + setOutputMapFile( element.attribute( "output-map-file", "0" ).toInt() ); + setLibraryDir( element.attribute( "library-dir", QString::null ) ); + setLinkerScript( element.attribute( "linker-script", QString::null ) ); + setLinkerOther( element.attribute( "other", QString::null ) ); + + m_linkedInternal.clear(); + m_linkedExternal.clear(); + + QDomNode node = element.firstChild(); + while ( !node.isNull() ) + { + QDomElement childElement = node.toElement(); + if ( !childElement.isNull() ) + { + const QString tagName = childElement.tagName(); + + if ( tagName == "linked-internal" ) + m_linkedInternal << KURL( baseURL, childElement.attribute( "url", QString::null ) ).url(); + + else if ( tagName == "linked-external" ) + m_linkedExternal << childElement.attribute( "url", QString::null ); + + else + kdError() << k_funcinfo << "Unrecognised element tag name: "<<tagName<<endl; + } + + node = node.nextSibling(); + } +} + + +QString LinkerOptions::hexFormatToString( HexFormat::type hexFormat ) +{ + switch ( hexFormat ) + { + case HexFormat::inhx32: + return "inhx32"; + + case HexFormat::inhx8m: + return "inhx8m"; + + case HexFormat::inhx8s: + return "inhx8s"; + + case HexFormat::inhx16: + return "inhx16"; + } + + // Default hex format is inhx32 + return "inhx32"; +} + + +LinkerOptions::HexFormat::type LinkerOptions::stringToHexFormat( const QString & hexFormat ) +{ + if ( hexFormat == "inhx8m" ) + return HexFormat::inhx8m; + + if ( hexFormat == "inhx8s" ) + return HexFormat::inhx8s; + + if ( hexFormat == "inhx16" ) + return HexFormat::inhx16; + + return HexFormat::inhx32; +} +//END class LinkerOptions + + + +//BEGIN class ProcessingOptions +ProcessingOptions::ProcessingOptions() +{ + m_bUseParentMicroID = false; + m_microID = "P16F84"; +} + + +ProcessingOptions::~ProcessingOptions() +{ +} + + +QDomElement ProcessingOptions::toDomElement( QDomDocument & doc, const KURL & baseURL ) const +{ + QDomElement node = doc.createElement("processing"); + + node.setAttribute( "output", KURL::relativeURL( baseURL, outputURL().url() ) ); + node.setAttribute( "micro", m_microID ); + + return node; +} + + +void ProcessingOptions::domElementToProcessingOptions( const QDomElement & element, const KURL & baseURL ) +{ + setOutputURL( KURL( baseURL, element.attribute( "output", QString::null ) ) ); + setMicroID( element.attribute("micro", QString::null ) ); +} +//END class ProcessingOptions + + + +//BEGIN class ProjectItem +ProjectItem::ProjectItem( ProjectItem * parent, Type type, ProjectManager * projectManager, KTechlab * ktechlab ) + : QObject() +{ + m_pParent = parent; + m_pILVItem = 0l; + m_pProjectManager = projectManager; + p_ktechlab = ktechlab; + m_type = type; +} + + +ProjectItem::~ProjectItem() +{ + m_children.remove( (ProjectItem*)0l ); + ProjectItemList::iterator end = m_children.end(); + for ( ProjectItemList::iterator it = m_children.begin(); it != end; ++it ) + (*it)->deleteLater(); + m_children.clear(); + + delete m_pILVItem; + m_pILVItem = 0l; +} + + +void ProjectItem::setILVItem( ILVItem * ilvItem ) +{ + m_pILVItem = ilvItem; + ilvItem->setOpen(true); + ilvItem->setText( 0, name() ); + ilvItem->setProjectItem(this); + updateILVItemPixmap(); +} + + +void ProjectItem::updateILVItemPixmap() +{ + if ( !m_pILVItem ) + return; + + switch ( type() ) + { + case ProjectType: + { + // ?! - We shouldn't have an ilvitem for this. + break; + } + + case ProgramType: + { + QPixmap pm; + pm.load( locate( "appdata", "icons/project_program.png" ) ); + m_pILVItem->setPixmap( 0, pm ); + break; + } + + case LibraryType: + { + QPixmap pm; + pm.load( locate( "appdata", "icons/project_library.png" ) ); + m_pILVItem->setPixmap( 0, pm ); + break; + } + + case FileType: + { + KMimeType::Ptr m = KMimeType::findByPath( url().path() ); + m_pILVItem->setPixmap( 0, m->pixmap( KIcon::Small ) ); + break; + } + } +} + + +void ProjectItem::addChild( ProjectItem * child ) +{ + if ( !child || m_children.contains(child) ) + return; + + m_children << child; + + child->setILVItem( m_pILVItem ? + new ILVItem( m_pILVItem, child->name() ) : + new ILVItem( m_pProjectManager, name() ) ); + + updateControlChildMicroIDs(); +} + + +void ProjectItem::updateControlChildMicroIDs() +{ + bool control = false; + switch ( type() ) + { + case ProjectItem::ProjectType: + case ProjectItem::LibraryType: + case ProjectItem::ProgramType: + control = !microID().isEmpty(); + break; + + case ProjectItem::FileType: + control = true; + break; + } + + m_children.remove( (ProjectItem*)0l ); + ProjectItemList::iterator end = m_children.end(); + for ( ProjectItemList::iterator it = m_children.begin(); it != end; ++it ) + (*it)->setUseParentMicroID( control ); +} + + +void ProjectItem::setName( const QString & name ) +{ + m_name = name; + if (m_pILVItem) + m_pILVItem->setText( 0, name ); +} + + +void ProjectItem::setURL( const KURL & url ) +{ + m_url = url; + + if ( m_name.isEmpty() ) + setName( url.fileName() ); + + if ( type() != FileType ) + { + // The output url *is* our url + setOutputURL(url); + } + else if ( outputURL().isEmpty() ) + { + // Try and guess what the output url should be... + QString newExtension; + + switch ( outputType() ) + { + case ProgramOutput: + newExtension = ".hex"; + break; + + case ObjectOutput: + newExtension = ".o"; + break; + + case LibraryOutput: + newExtension = ".o"; + break; + + case UnknownOutput: + break; + } + + if ( !newExtension.isEmpty() ) + { + const QString fileName = url.url(); + QString extension = fileName.right( fileName.length() - fileName.findRev('.') ); + setOutputURL( QString(fileName).replace( extension, newExtension ) ); + } + } + + updateILVItemPixmap(); +} + + +QString ProjectItem::microID() const +{ + if ( !m_bUseParentMicroID ) + return m_microID; + + return m_pParent ? m_pParent->microID() : QString::null; +} + + +void ProjectItem::setMicroID( const QString & id ) +{ + ProcessingOptions::setMicroID(id); + updateControlChildMicroIDs(); +} + + +ProjectItem::OutputType ProjectItem::outputType() const +{ + if ( !m_pParent ) + return UnknownOutput; + + switch ( m_pParent->type() ) + { + case ProjectItem::ProjectType: + { + // We're a top level build target, so look at our own type + switch ( type() ) + { + case ProjectItem::ProjectType: + kdWarning() << k_funcinfo << "Parent item and this item are both project items" << endl; + return UnknownOutput; + + case ProjectItem::FileType: + case ProjectItem::ProgramType: + return ProgramOutput; + + case ProjectItem::LibraryType: + return LibraryOutput; + } + return UnknownOutput; + } + + case ProjectItem::FileType: + { + kdWarning() << k_funcinfo << "Don't know how to handle parent item being a file" << endl; + return UnknownOutput; + } + + case ProjectItem::ProgramType: + case ProjectItem::LibraryType: + return ObjectOutput; + } + + return UnknownOutput; +} + + +bool ProjectItem::build( ProcessOptionsList * pol ) +{ + if ( !pol ) + return false; + + // Check to see that we aren't already in the ProcessOptionstList; + ProcessOptionsList::iterator polEnd = pol->end(); + for ( ProcessOptionsList::iterator it = pol->begin(); it != polEnd; ++it ) + { + if ( (*it).targetFile() == outputURL().path() ) + return true; + } + + ProjectInfo * projectInfo = ProjectManager::self()->currentProject(); + assert(projectInfo); + + if ( outputURL().isEmpty() ) + { + KMessageBox::sorry( 0l, i18n("Don't know how to build \"%1\" (output url is empty).").arg(name()) ); + return false; + } + + // Build all internal libraries that we depend on + QStringList::iterator send = m_linkedInternal.end(); + for ( QStringList::iterator it = m_linkedInternal.begin(); it != send; ++it ) + { + ProjectItem * lib = projectInfo->findItem( projectInfo->directory() + *it ); + if ( !lib ) + { + KMessageBox::sorry( 0l, i18n("Don't know how to build \"%1\" (library does not exist in project).").arg(*it) ); + return false; + } + + if ( !lib->build(pol) ) + return false; + } + + + // Build all children + m_children.remove( (ProjectItem*)0l ); + ProjectItemList::iterator cend = m_children.end(); + for ( ProjectItemList::iterator it = m_children.begin(); it != cend; ++it ) + { + if ( ! (*it)->build(pol) ) + return false; + } + + + // Now build ourself + ProcessOptions po; + po.b_addToProject = false; + po.setTargetFile( outputURL().path() ); + po.m_picID = microID(); + + ProcessOptions::ProcessPath::MediaType typeTo; + + switch ( outputType() ) + { + case UnknownOutput: + KMessageBox::sorry( 0l, i18n("Don't know how to build \"%1\" (unknown output type).").arg(name()) ); + return false; + + case ProgramOutput: + typeTo = ProcessOptions::ProcessPath::Program; + break; + + case ObjectOutput: + typeTo = ProcessOptions::ProcessPath::Object; + break; + + case LibraryOutput: + typeTo = ProcessOptions::ProcessPath::Library; + break; + } + + switch ( type() ) + { + case ProjectType: + // Nothing to do + return true; + + case FileType: + po.setInputFiles( url().path() ); + po.setProcessPath( ProcessOptions::ProcessPath::path( ProcessOptions::guessMediaType( url().url() ), typeTo ) ); + break; + + case ProgramType: + case LibraryType: + // Build up a list of input urls + QStringList inputFiles; + + // Link child objects + m_children.remove( (ProjectItem*)0l ); + ProjectItemList::iterator cend = m_children.end(); + for ( ProjectItemList::iterator it = m_children.begin(); it != cend; ++it ) + inputFiles << (*it)->outputURL().path(); + + po.setInputFiles(inputFiles); + po.setProcessPath( ProcessOptions::ProcessPath::path( ProcessOptions::ProcessPath::Object, typeTo ) ); + break; + } + + po.m_hexFormat = hexFormatToString( hexFormat() ); + po.m_bOutputMapFile = outputMapFile(); + po.m_libraryDir = libraryDir(); + po.m_linkerScript = linkerScript(); + po.m_linkOther = linkerOther(); + + // Link against libraries + QStringList::iterator lend = m_linkedInternal.end(); + for ( QStringList::iterator it = m_linkedInternal.begin(); it != lend; ++it ) + po.m_linkLibraries += projectInfo->directory() + *it; + lend = m_linkedExternal.end(); + for ( QStringList::iterator it = m_linkedExternal.begin(); it != lend; ++it ) + po.m_linkLibraries += *it; + + // Save our working file (if open) and append to the build list + Document * currentDoc = DocManager::self()->findDocument( url() ); + if (currentDoc) + currentDoc->fileSave(); + pol->append(po); + + return true; +} + + +void ProjectItem::upload( ProcessOptionsList * pol ) +{ + build( pol ); + + ProgrammerDlg * dlg = new ProgrammerDlg( microID(), (QWidget*)p_ktechlab, "Programmer Dlg" ); + + dlg->exec(); + if ( !dlg->isAccepted() ) + { + dlg->deleteLater(); + return; + } + + ProcessOptions po; + dlg->initOptions( & po ); + po.b_addToProject = false; + po.setInputFiles( outputURL().path() ); + po.setProcessPath( ProcessOptions::ProcessPath::Program_PIC ); + + pol->append( po ); + + dlg->deleteLater(); +} + + +QDomElement ProjectItem::toDomElement( QDomDocument & doc, const KURL & baseURL ) const +{ + QDomElement node = doc.createElement("item"); + + node.setAttribute( "type", typeToString() ); + node.setAttribute( "name", m_name ); + node.setAttribute( "url", KURL::relativeURL( baseURL, m_url.url() ) ); + + node.appendChild( LinkerOptions::toDomElement( doc, baseURL ) ); + node.appendChild( ProcessingOptions::toDomElement( doc, baseURL ) ); + + + ProjectItemList::const_iterator end = m_children.end(); + for ( ProjectItemList::const_iterator it = m_children.begin(); it != end; ++it ) + { + if (*it) + node.appendChild( (*it)->toDomElement( doc, baseURL ) ); + } + + return node; +} + + +KURL::List ProjectItem::childOutputURLs( unsigned types, unsigned outputTypes ) const +{ + KURL::List urls; + + ProjectItemList::const_iterator end = m_children.end(); + for ( ProjectItemList::const_iterator it = m_children.begin(); it != end; ++it ) + { + if (!*it) + continue; + + if ( ((*it)->type() & types) && ((*it)->outputType() & outputTypes) ) + urls += (*it)->outputURL().prettyURL(); + + urls += (*it)->childOutputURLs(types); + } + + return urls; +} + + +ProjectItem * ProjectItem::findItem( const KURL & url ) +{ + if ( this->url() == url ) + return this; + + ProjectItemList::const_iterator end = m_children.end(); + for ( ProjectItemList::const_iterator it = m_children.begin(); it != end; ++it ) + { + if (!*it) + continue; + + ProjectItem * found = (*it)->findItem(url); + if (found) + return found; + } + + return 0l; +} + + +bool ProjectItem::closeOpenFiles() +{ + Document * doc = DocManager::self()->findDocument(m_url); + if ( doc && !doc->fileClose() ) + return false; + + m_children.remove( (ProjectItem*)0l ); + ProjectItemList::iterator end = m_children.end(); + for ( ProjectItemList::iterator it = m_children.begin(); it != end; ++it ) + { + if ( !(*it)->closeOpenFiles() ) + return false; + } + + return true; +} + + +void ProjectItem::addFiles() +{ + KURL::List urls = p_ktechlab->getFileURLs(); + const KURL::List::iterator end = urls.end(); + for ( KURL::List::iterator it = urls.begin(); it != end; ++ it) + addFile(*it); +} + + +void ProjectItem::addCurrentFile() +{ + Document *document = DocManager::self()->getFocusedDocument(); + if (!document) + return; + + // If the file isn't saved yet, we must do that + // before it is added to the project. + if( document->url().isEmpty() ) + { + document->fileSaveAs(); + // If the user pressed cancel then just give up, + // otherwise the file can now be added. + } + + if( !document->url().isEmpty() ) + addFile( document->url() ); +} + + +void ProjectItem::addFile( const KURL & url ) +{ + if ( url.isEmpty() ) + return; + + m_children.remove( (ProjectItem*)0l ); + ProjectItemList::iterator end = m_children.end(); + for ( ProjectItemList::iterator it = m_children.begin(); it != end; ++it ) + { + if ( (*it)->type() == FileType && (*it)->url() == url ) + return; + } + + ProjectItem * item = new ProjectItem( this, FileType, m_pProjectManager, p_ktechlab ); + item->setURL(url); + addChild(item); +} + + +QString ProjectItem::typeToString() const +{ + switch (m_type) + { + case ProjectType: + return "Project"; + + case FileType: + return "File"; + + case ProgramType: + return "Program"; + + case LibraryType: + return "Library"; + } + return QString::null; +} + + +ProjectItem::Type ProjectItem::stringToType( const QString & type ) +{ + if ( type == "Project" ) + return ProjectType; + + if ( type == "File" ) + return FileType; + + if ( type == "Program" ) + return ProgramType; + + if ( type == "Library" ) + return LibraryType; + + return FileType; +} + + +void ProjectItem::domElementToItem( const QDomElement & element, const KURL & baseURL ) +{ + Type type = stringToType( element.attribute( "type", QString::null ) ); + QString name = element.attribute( "name", QString::null ); + KURL url( baseURL, element.attribute( "url", QString::null ) ); + + ProjectItem * createdItem = new ProjectItem( this, type, m_pProjectManager, p_ktechlab ); + createdItem->setName( name ); + createdItem->setURL( url ); + + addChild( createdItem ); + + QDomNode node = element.firstChild(); + while ( !node.isNull() ) + { + QDomElement childElement = node.toElement(); + if ( !childElement.isNull() ) + { + const QString tagName = childElement.tagName(); + + if ( tagName == "linker" ) + createdItem->domElementToLinkerOptions( childElement, baseURL ); + + else if ( tagName == "processing" ) + createdItem->domElementToProcessingOptions( childElement, baseURL ); + + else if ( tagName == "item" ) + createdItem->domElementToItem( childElement, baseURL ); + + else + kdError() << k_funcinfo << "Unrecognised element tag name: "<<tagName<<endl; + } + + node = node.nextSibling(); + } +} +//END class ProjectItem + + + +//BEGIN class ProjectInfo +ProjectInfo::ProjectInfo( ProjectManager * projectManager, KTechlab * ktechlab ) + : ProjectItem( 0l, ProjectItem::ProjectType, projectManager, ktechlab ) +{ + m_microID = QString::null; +} + + +ProjectInfo::~ ProjectInfo() +{ +} + + +bool ProjectInfo::open( const KURL & url ) +{ + QString target; + if ( !KIO::NetAccess::download( url, target, 0l ) ) + { + // If the file could not be downloaded, for example does not + // exist on disk, NetAccess will tell us what error to use + KMessageBox::error( 0l, KIO::NetAccess::lastErrorString() ); + + return false; + } + + QFile file(target); + if ( !file.open( IO_ReadOnly ) ) + { + KMessageBox::sorry( 0l, i18n("Could not open %1 for reading").arg(target) ); + return false; + } + + m_url = url; + + QString xml; + QTextStream textStream( &file ); + while ( !textStream.eof() ) + xml += textStream.readLine() + '\n'; + + file.close(); + + QDomDocument doc( "KTechlab" ); + QString errorMessage; + if ( !doc.setContent( xml, &errorMessage ) ) + { + KMessageBox::sorry( 0l, i18n("Couldn't parse xml:\n%1").arg(errorMessage) ); + return false; + } + + QDomElement root = doc.documentElement(); + + QDomNode node = root.firstChild(); + while ( !node.isNull() ) + { + QDomElement element = node.toElement(); + if ( !element.isNull() ) + { + const QString tagName = element.tagName(); + + if ( tagName == "linker" ) + domElementToLinkerOptions( element, m_url ); + + else if ( tagName == "processing" ) + domElementToProcessingOptions( element, m_url ); + + else if ( tagName == "file" || tagName == "item" ) + domElementToItem( element, m_url ); + + else + kdWarning() << k_funcinfo << "Unrecognised element tag name: "<<tagName<<endl; + } + + node = node.nextSibling(); + } + + updateControlChildMicroIDs(); + return true; +} + + +bool ProjectInfo::save() +{ + QFile file( m_url.path() ); + if ( file.open(IO_WriteOnly) == false ) + { + KMessageBox::sorry( NULL, i18n("Project could not be saved to \"%1\"").arg(m_url.path()), i18n("Saving Project") ); + return false; + } + + QDomDocument doc("KTechlab"); + + QDomElement root = doc.createElement("project"); + doc.appendChild(root); + +// root.appendChild( LinkerOptions::toDomElement(doc) ); +// root.appendChild( ProcessingOptions::toDomElement(doc) ); + + m_children.remove( (ProjectItem*)0l ); + ProjectItemList::const_iterator end = m_children.end(); + for ( ProjectItemList::const_iterator it = m_children.begin(); it != end; ++it ) + root.appendChild( (*it)->toDomElement( doc, m_url ) ); + + QTextStream stream(&file); + stream << doc.toString(); + file.close(); + + (static_cast<RecentFilesAction*>(p_ktechlab->action("project_open_recent")))->addURL(m_url); + + return true; +} + + +bool ProjectInfo::saveAndClose() +{ + if (!save()) + return false; + + if (!closeOpenFiles()) + return false; + + return true; +} +//END class ProjectInfo + + + +//BEGIN class ProjectManager +ProjectManager * ProjectManager::m_pSelf = 0l; + +ProjectManager * ProjectManager::self( KTechlab * ktl, KateMDI::ToolView * parent ) +{ + if ( !m_pSelf ) + { + assert(ktl); + assert(parent); + m_pSelf = new ProjectManager( ktl, parent ); + } + return m_pSelf; +} + + +ProjectManager::ProjectManager( KTechlab * ktl, KateMDI::ToolView * parent ) + : ItemSelector( parent, "Project Manager" ), + m_pCurrentProject(0l), + p_ktechlab(ktl) +{ + QWhatsThis::add( this, i18n("Displays the list of files in the project.\nTo open or close a project, use the \"Project\" menu. Right click on a file to remove it from the project") ); + + setListCaption( i18n("File") ); + setCaption( i18n("Project Manager") ); + + connect( this, SIGNAL(clicked(QListViewItem*)), this, SLOT(slotItemClicked(QListViewItem*)) ); +} + + +ProjectManager::~ProjectManager() +{ +} + + +void ProjectManager::slotNewProject() +{ + if ( !slotCloseProject() ) + return; + + NewProjectDlg *newProjectDlg = new NewProjectDlg(this); + newProjectDlg->exec(); + + if ( newProjectDlg->accepted() ) + { + m_pCurrentProject = new ProjectInfo( this, p_ktechlab ); + m_pCurrentProject->setName( newProjectDlg->projectName() ); + m_pCurrentProject->setURL( newProjectDlg->location() + m_pCurrentProject->name().lower() + ".ktechlab" ); + + QDir dir; + if ( !dir.mkdir( m_pCurrentProject->directory() ) ) + kdDebug() << "Error in creating directory " << m_pCurrentProject->directory() << endl; + + m_pCurrentProject->save(); + updateActions(); + + emit projectCreated(); + } + + delete newProjectDlg; +} + + +void ProjectManager::slotProjectOptions() +{ +} + + +void ProjectManager::slotOpenProject() +{ + KURL url = KFileDialog::getOpenURL(QString::null, + "*.ktechlab|KTechlab Project(*.ktechlab)\n*|All Files", this, i18n("Open Location")); + + if ( url.isEmpty() ) + return; + + slotOpenProject(url); +} + + +void ProjectManager::slotOpenProject( const KURL & url ) +{ + if ( m_pCurrentProject && m_pCurrentProject->url() == url ) + return; + + if ( !slotCloseProject() ) + return; + + m_pCurrentProject = new ProjectInfo( this, p_ktechlab ); + + if ( !m_pCurrentProject->open(url) ) + { + m_pCurrentProject->deleteLater(); + m_pCurrentProject = 0l; + return; + } + + RecentFilesAction * rfa = static_cast<RecentFilesAction*>(p_ktechlab->action("project_open_recent")); + rfa->addURL( m_pCurrentProject->url() ); + + if ( KTLConfig::raiseItemSelectors() ) + p_ktechlab->showToolView( p_ktechlab->toolView( toolViewIdentifier() ) ); + + updateActions(); + emit projectOpened(); +} + + +bool ProjectManager::slotCloseProject() +{ + if ( !m_pCurrentProject ) + return true; + + if ( !m_pCurrentProject->saveAndClose() ) + return false; + + m_pCurrentProject->deleteLater(); + m_pCurrentProject = 0l; + updateActions(); + emit projectClosed(); + return true; +} + + +void ProjectManager::slotCreateSubproject() +{ + if ( !currentProject() ) + return; + + CreateSubprojectDlg * dlg = new CreateSubprojectDlg(this); + dlg->exec(); + + if ( dlg->accepted() ) + { + ProjectItem::Type type = ProjectItem::ProgramType; + switch ( dlg->type() ) + { + case CreateSubprojectDlg::ProgramType: + type = ProjectItem::ProgramType; + break; + + case CreateSubprojectDlg::LibraryType: + type = ProjectItem::LibraryType; + break; + } + + ProjectItem * subproject = new ProjectItem( currentProject(), type, this, p_ktechlab ); + subproject->setURL( dlg->targetFile() ); + + currentProject()->addChild(subproject); + currentProject()->save(); + + emit subprojectCreated(); + } + + delete dlg; +} + + +void ProjectManager::updateActions() +{ + bool projectIsOpen = m_pCurrentProject; + + p_ktechlab->action("project_create_subproject")->setEnabled( projectIsOpen ); + p_ktechlab->action("project_export_makefile")->setEnabled( projectIsOpen ); + p_ktechlab->action("subproject_add_existing_file")->setEnabled( projectIsOpen ); + p_ktechlab->action("subproject_add_current_file")->setEnabled( projectIsOpen ); +// p_ktechlab->action("project_options")->setEnabled( projectIsOpen ); + p_ktechlab->action("project_close")->setEnabled( projectIsOpen ); + p_ktechlab->action("project_add_existing_file")->setEnabled( projectIsOpen ); + p_ktechlab->action("project_add_current_file")->setEnabled( projectIsOpen ); +} + + +void ProjectManager::slotAddFile() +{ + if ( !currentProject() ) + return; + + currentProject()->addFiles(); + emit filesAdded(); +} + + +void ProjectManager::slotAddCurrentFile() +{ + if ( !currentProject() ) + return; + currentProject()->addCurrentFile(); + emit filesAdded(); +} + + +void ProjectManager::slotSubprojectAddExistingFile() +{ + ILVItem * currentItem = dynamic_cast<ILVItem*>(selectedItem()); + if ( !currentItem || !currentItem->projectItem() ) + return; + + currentItem->projectItem()->addFiles(); + emit filesAdded(); +} + + +void ProjectManager::slotSubprojectAddCurrentFile() +{ + ILVItem * currentItem = dynamic_cast<ILVItem*>(selectedItem()); + if ( !currentItem || !currentItem->projectItem() ) + return; + + currentItem->projectItem()->addCurrentFile(); + emit filesAdded(); +} + + +void ProjectManager::slotItemBuild() +{ + ILVItem * currentItem = dynamic_cast<ILVItem*>(selectedItem()); + if ( !currentItem || !currentItem->projectItem() ) + return; + + ProcessOptionsList pol; + currentItem->projectItem()->build(&pol); + LanguageManager::self()->compile(pol); +} + + +void ProjectManager::slotItemUpload() +{ + ILVItem * currentItem = dynamic_cast<ILVItem*>(selectedItem()); + if ( !currentItem || !currentItem->projectItem() ) + return; + + ProcessOptionsList pol; + currentItem->projectItem()->upload(&pol); + LanguageManager::self()->compile(pol); +} + + +void ProjectManager::slotRemoveSelected() +{ + ILVItem *currentItem = dynamic_cast<ILVItem*>(selectedItem()); + if ( !currentItem ) + return; + + int choice = KMessageBox::questionYesNo( this, i18n("Do you really want to remove \"%1\"?").arg( currentItem->text(0) ), i18n("Remove Project File?"), KGuiItem(i18n("Remove")), KGuiItem(i18n("Cancel")) ); + + if ( choice == KMessageBox::No ) + return; + + currentItem->projectItem()->deleteLater(); + emit filesRemoved(); +} + + +void ProjectManager::slotExportToMakefile() +{ +} + + +void ProjectManager::slotSubprojectLinkerOptions() +{ + ILVItem * currentItem = dynamic_cast<ILVItem*>(selectedItem()); + if ( !currentItem || !currentItem->projectItem() ) + return; + + LinkerOptionsDlg * dlg = new LinkerOptionsDlg( currentItem->projectItem(), this ); + dlg->exec(); + currentProject()->save(); + + // The dialog sets the options for us if it was accepted, so we don't need to do anything + delete dlg; +} + + +void ProjectManager::slotItemProcessingOptions() +{ + ILVItem * currentItem = dynamic_cast<ILVItem*>(selectedItem()); + if ( !currentItem || !currentItem->projectItem() ) + return; + + ProcessingOptionsDlg * dlg = new ProcessingOptionsDlg( currentItem->projectItem(), this ); + dlg->exec(); + currentProject()->save(); + + // The dialog sets the options for us if it was accepted, so we don't need to do anything + delete dlg; +} + + +void ProjectManager::slotItemClicked( QListViewItem * item ) +{ + ILVItem * ilvItem = dynamic_cast<ILVItem*>(item); + if ( !ilvItem ) + return; + + ProjectItem * projectItem = ilvItem->projectItem(); + if ( !projectItem || projectItem->type() != ProjectItem::FileType ) + return; + + DocManager::self()->openURL( projectItem->url() ); +} + + +void ProjectManager::slotContextMenuRequested( QListViewItem * item, const QPoint& pos, int /*col*/ ) +{ + QString popupName; + ILVItem * ilvItem = dynamic_cast<ILVItem*>(item); + KAction * linkerOptionsAct = p_ktechlab->action("project_item_linker_options"); + linkerOptionsAct->setEnabled(false); + + if ( !m_pCurrentProject ) + popupName = "project_none_popup"; + + else if ( !ilvItem ) + popupName = "project_blank_popup"; + + else + { + ProcessOptions::ProcessPath::MediaType mediaType = ProcessOptions::guessMediaType( ilvItem->projectItem()->url().url() ); + + switch ( ilvItem->projectItem()->type() ) + { + case ProjectItem::FileType: + if ( mediaType == ProcessOptions::ProcessPath::Unknown ) + popupName = "project_file_other_popup"; + else + popupName = "project_file_popup"; + break; + + case ProjectItem::ProgramType: + popupName = "project_program_popup"; + break; + + case ProjectItem::LibraryType: + popupName = "project_library_popup"; + break; + + case ProjectItem::ProjectType: + return; + } + switch ( ilvItem->projectItem()->outputType() ) + { + case ProjectItem::ProgramOutput: + linkerOptionsAct->setEnabled(true); + break; + + case ProjectItem::ObjectOutput: + case ProjectItem::LibraryOutput: + case ProjectItem::UnknownOutput: + linkerOptionsAct->setEnabled(false); + break; + } + + // Only have linking options for SDCC files + linkerOptionsAct->setEnabled( mediaType == ProcessOptions::ProcessPath::C ); + } + + bool haveFocusedDocument = DocManager::self()->getFocusedDocument(); + p_ktechlab->action("subproject_add_current_file")->setEnabled( haveFocusedDocument ); + p_ktechlab->action("project_add_current_file")->setEnabled( haveFocusedDocument ); + + QPopupMenu *pop = static_cast<QPopupMenu*>(p_ktechlab->factory()->container( popupName, p_ktechlab )); + if (pop) + pop->popup(pos); +} +//END class ProjectManager + +#include "projectmanager.moc" |