You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ktechlab/src/projectmanager.cpp

1257 lines
29 KiB

/***************************************************************************
* 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 <tdefiledialog.h>
#include <kiconloader.h>
#include <tdeio/netaccess.h>
#include <tdelocale.h>
#include <tdemessagebox.h>
#include <kmimetype.h>
#include <kstandarddirs.h>
#include <tqdom.h>
#include <tqpopupmenu.h>
#include <tqwhatsthis.h>
#include <assert.h>
//BEGIN class LinkerOptions
LinkerOptions::LinkerOptions()
{
m_hexFormat = HexFormat::inhx32;
m_bOutputMapFile = false;
}
TQDomElement LinkerOptions::toDomElement( TQDomDocument & doc, const KURL & baseURL ) const
{
TQDomElement 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() );
TQStringList::const_iterator end = m_linkedInternal.end();
for ( TQStringList::const_iterator it = m_linkedInternal.begin(); it != end; ++it )
{
TQDomElement child = doc.createElement("linked-internal");
node.appendChild(child);
child.setAttribute( "url", KURL::relativeURL( baseURL, *it ) );
}
end = m_linkedExternal.end();
for ( TQStringList::const_iterator it = m_linkedExternal.begin(); it != end; ++it )
{
TQDomElement child = doc.createElement("linked-external");
node.appendChild(child);
child.setAttribute( "url", *it );
}
return node;
}
void LinkerOptions::domElementToLinkerOptions( const TQDomElement & element, const KURL & baseURL )
{
setHexFormat( stringToHexFormat( element.attribute( "hex-format", TQString() ) ) );
setOutputMapFile( element.attribute( "output-map-file", "0" ).toInt() );
setLibraryDir( element.attribute( "library-dir", TQString() ) );
setLinkerScript( element.attribute( "linker-script", TQString() ) );
setLinkerOther( element.attribute( "other", TQString() ) );
m_linkedInternal.clear();
m_linkedExternal.clear();
TQDomNode node = element.firstChild();
while ( !node.isNull() )
{
TQDomElement childElement = node.toElement();
if ( !childElement.isNull() )
{
const TQString tagName = childElement.tagName();
if ( tagName == "linked-internal" )
m_linkedInternal << KURL( baseURL, childElement.attribute( "url", TQString() ) ).url();
else if ( tagName == "linked-external" )
m_linkedExternal << childElement.attribute( "url", TQString() );
else
kdError() << k_funcinfo << "Unrecognised element tag name: "<<tagName<<endl;
}
node = node.nextSibling();
}
}
TQString 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 TQString & 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()
{
}
TQDomElement ProcessingOptions::toDomElement( TQDomDocument & doc, const KURL & baseURL ) const
{
TQDomElement node = doc.createElement("processing");
node.setAttribute( "output", KURL::relativeURL( baseURL, outputURL().url() ) );
node.setAttribute( "micro", m_microID );
return node;
}
void ProcessingOptions::domElementToProcessingOptions( const TQDomElement & element, const KURL & baseURL )
{
setOutputURL( KURL( baseURL, element.attribute( "output", TQString() ) ) );
setMicroID( element.attribute("micro", TQString() ) );
}
//END class ProcessingOptions
//BEGIN class ProjectItem
ProjectItem::ProjectItem( ProjectItem * parent, Type type, ProjectManager * projectManager, KTechlab * ktechlab )
: TQObject()
{
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:
{
TQPixmap pm;
pm.load( locate( "appdata", "icons/project_program.png" ) );
m_pILVItem->setPixmap( 0, pm );
break;
}
case LibraryType:
{
TQPixmap 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( TDEIcon::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 TQString & 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...
TQString 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 TQString fileName = url.url();
TQString extension = fileName.right( fileName.length() - fileName.findRev('.') );
setOutputURL( TQString(fileName).replace( extension, newExtension ) );
}
}
updateILVItemPixmap();
}
TQString ProjectItem::microID() const
{
if ( !m_bUseParentMicroID )
return m_microID;
return m_pParent ? m_pParent->microID() : TQString();
}
void ProjectItem::setMicroID( const TQString & 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
TQStringList::iterator send = m_linkedInternal.end();
for ( TQStringList::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
TQStringList 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
TQStringList::iterator lend = m_linkedInternal.end();
for ( TQStringList::iterator it = m_linkedInternal.begin(); it != lend; ++it )
po.m_linkLibraries += projectInfo->directory() + *it;
lend = m_linkedExternal.end();
for ( TQStringList::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(), (TQWidget*)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();
}
TQDomElement ProjectItem::toDomElement( TQDomDocument & doc, const KURL & baseURL ) const
{
TQDomElement 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);
}
TQString ProjectItem::typeToString() const
{
switch (m_type)
{
case ProjectType:
return "Project";
case FileType:
return "File";
case ProgramType:
return "Program";
case LibraryType:
return "Library";
}
return TQString();
}
ProjectItem::Type ProjectItem::stringToType( const TQString & 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 TQDomElement & element, const KURL & baseURL )
{
Type type = stringToType( element.attribute( "type", TQString() ) );
TQString name = element.attribute( "name", TQString() );
KURL url( baseURL, element.attribute( "url", TQString() ) );
ProjectItem * createdItem = new ProjectItem( this, type, m_pProjectManager, p_ktechlab );
createdItem->setName( name );
createdItem->setURL( url );
addChild( createdItem );
TQDomNode node = element.firstChild();
while ( !node.isNull() )
{
TQDomElement childElement = node.toElement();
if ( !childElement.isNull() )
{
const TQString 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 = TQString();
}
ProjectInfo::~ ProjectInfo()
{
}
bool ProjectInfo::open( const KURL & url )
{
TQString target;
if ( !TDEIO::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, TDEIO::NetAccess::lastErrorString() );
return false;
}
TQFile file(target);
if ( !file.open( IO_ReadOnly ) )
{
KMessageBox::sorry( 0l, i18n("Could not open %1 for reading").arg(target) );
return false;
}
m_url = url;
TQString xml;
TQTextStream textStream( &file );
while ( !textStream.eof() )
xml += textStream.readLine() + '\n';
file.close();
TQDomDocument doc( "KTechlab" );
TQString errorMessage;
if ( !doc.setContent( xml, &errorMessage ) )
{
KMessageBox::sorry( 0l, i18n("Couldn't parse xml:\n%1").arg(errorMessage) );
return false;
}
TQDomElement root = doc.documentElement();
TQDomNode node = root.firstChild();
while ( !node.isNull() )
{
TQDomElement element = node.toElement();
if ( !element.isNull() )
{
const TQString 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()
{
TQFile 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;
}
TQDomDocument doc("KTechlab");
TQDomElement 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 ) );
TQTextStream 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)
{
TQWhatsThis::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, TQ_SIGNAL(clicked(TQListViewItem*)), this, TQ_SLOT(slotItemClicked(TQListViewItem*)) );
}
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" );
TQDir 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(TQString(),
"*.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( TQListViewItem * 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( TQListViewItem * item, const TQPoint& pos, int /*col*/ )
{
TQString popupName;
ILVItem * ilvItem = dynamic_cast<ILVItem*>(item);
TDEAction * 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 );
TQPopupMenu *pop = static_cast<TQPopupMenu*>(p_ktechlab->factory()->container( popupName, p_ktechlab ));
if (pop)
pop->popup(pos);
}
//END class ProjectManager
#include "projectmanager.moc"