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.
654 lines
22 KiB
654 lines
22 KiB
/***************************************************************************
|
|
* Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> *
|
|
* Copyright (C) 2003 Alain Gibaud <alain.gibaud@free.fr> *
|
|
* *
|
|
* 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 "project_manager.h"
|
|
|
|
#include <tqdragobject.h>
|
|
#include <tqpainter.h>
|
|
#include <tqstyle.h>
|
|
#include <tqtimer.h>
|
|
#include <tqheader.h>
|
|
|
|
#include <tdelocale.h>
|
|
#include <kiconloader.h>
|
|
#include <tdeaction.h>
|
|
#include <tdeapplication.h>
|
|
|
|
#include "project.h"
|
|
#include "project_wizard.h"
|
|
#include "project_editor.h"
|
|
#include "toplevel.h"
|
|
#include "editor_manager.h"
|
|
#include "object_view.h"
|
|
#include "devices/list/device_list.h"
|
|
#include "tools/list/compile_config.h"
|
|
#include "register_view.h"
|
|
#include "hex_editor.h"
|
|
#include "main_global.h"
|
|
#include "common/gui/purl_gui.h"
|
|
#include "device_gui.h"
|
|
|
|
//----------------------------------------------------------------------------
|
|
ProjectManager::View::View(TQWidget *parent)
|
|
: ListView(parent, "project_manager"), _project(0), _modified(false)
|
|
{
|
|
connect(this, TQ_SIGNAL(mouseButtonClicked(int, TQListViewItem *, const TQPoint &, int)),
|
|
TQ_SLOT(clicked(int, TQListViewItem *, const TQPoint &, int)));
|
|
connect(this, TQ_SIGNAL(contextMenuRequested(TQListViewItem *, const TQPoint &, int)),
|
|
TQ_SLOT(contextMenu(TQListViewItem *, const TQPoint &, int)));
|
|
connect(this, TQ_SIGNAL(itemRenamed(TQListViewItem *, int, const TQString &)),
|
|
TQ_SLOT(renamed(TQListViewItem *, int, const TQString &)));
|
|
connect(this, TQ_SIGNAL(moved()), TQ_SLOT(filesReordered()));
|
|
|
|
header()->hide();
|
|
setSorting(-1);
|
|
addColumn(TQString(), 170);
|
|
setFullWidth(true);
|
|
setRootIsDecorated(false);
|
|
setAcceptDrops(true);
|
|
setDragEnabled(true);
|
|
setDropVisualizer(true);
|
|
TQTimer::singleShot(0, this, TQ_SLOT(init()));;
|
|
}
|
|
|
|
ProjectManager::View::~View()
|
|
{
|
|
delete _project;
|
|
}
|
|
|
|
void ProjectManager::View::init()
|
|
{
|
|
clear();
|
|
_rootItem = new RootItem(this);
|
|
setCurrentItem(_rootItem);
|
|
TDEListViewItem *item = new RegisterItem(headerItem(DeviceGroup));
|
|
ensureItemVisible(item);
|
|
_deviceItem = new DeviceItem(headerItem(DeviceGroup));
|
|
ensureItemVisible(_deviceItem);
|
|
_linkerScriptItem = 0;
|
|
(void)headerItem(SourceGroup);
|
|
}
|
|
|
|
ProjectManager::HeaderItem *ProjectManager::View::findHeaderItem(Group group) const
|
|
{
|
|
TQListViewItemIterator it(const_cast<View *>(this));
|
|
for(; it.current(); ++it) {
|
|
if ( it.current()->rtti()!=HeaderRtti ) continue;
|
|
HeaderItem *hi = static_cast<HeaderItem *>(it.current());
|
|
if ( hi->group()==group ) return hi;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
ProjectManager::HeaderItem *ProjectManager::View::headerItem(Group group)
|
|
{
|
|
HeaderItem *item = findHeaderItem(group);
|
|
if (item) return item;
|
|
item = new HeaderItem(_rootItem, group);
|
|
// reorder groups...
|
|
HeaderItem *items[Nb_Groups];
|
|
for (uint i=0; i<Nb_Groups; i++) {
|
|
items[i] = findHeaderItem(Group(i));
|
|
if (items[i]) _rootItem->takeItem(items[i]);
|
|
}
|
|
for (int i=Nb_Groups-1; i>=0; i--) {
|
|
if ( items[i]==0 ) continue;
|
|
_rootItem->insertItem(items[i]);
|
|
}
|
|
return item;
|
|
}
|
|
|
|
ProjectManager::FileItem *ProjectManager::View::findFileItem(const PURL::Url &url) const
|
|
{
|
|
TQListViewItemIterator it(const_cast<View *>(this));
|
|
for(; it.current(); ++it) {
|
|
if ( it.current()->rtti()!=FileRtti ) continue;
|
|
FileItem *fi = static_cast<FileItem *>(it.current());
|
|
if ( fi->url()==url ) return fi;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
ProjectManager::FileItem *ProjectManager::View::findFileItem(PURL::FileType type) const
|
|
{
|
|
TQListViewItemIterator it(const_cast<View *>(this));
|
|
for(; it.current(); ++it) {
|
|
if ( it.current()->rtti()!=FileRtti ) continue;
|
|
FileItem *fi = static_cast<FileItem *>(it.current());
|
|
if ( fi->ftype()==type ) return fi;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
TQListViewItem *ProjectManager::View::findItem(const TQString &tag) const
|
|
{
|
|
TQListViewItemIterator it(const_cast<View *>(this));
|
|
for(; it.current(); ++it) {
|
|
switch (Rtti(it.current()->rtti())) {
|
|
case RootRtti:
|
|
case FileRtti:
|
|
case LinkerScriptRtti:
|
|
case DeviceRtti: continue;
|
|
case HeaderRtti:
|
|
case RegisterRtti: break;
|
|
}
|
|
if ( it.current()->text(0)==tag ) return it.current();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void ProjectManager::View::select(const Editor *e)
|
|
{
|
|
TQListViewItem *item = 0;
|
|
if ( e->url().isEmpty() ) item = findItem(e->tag());
|
|
else item = findFileItem(e->url());
|
|
if (item) setSelected(item, true);
|
|
else clearSelection();
|
|
}
|
|
|
|
void ProjectManager::View::contextMenu(TQListViewItem *item, const TQPoint &p, int)
|
|
{
|
|
if ( item==0 ) return;
|
|
|
|
PopupMenu pop;
|
|
Group group = Nb_Groups;
|
|
if ( item->rtti()==HeaderRtti) group = static_cast<const HeaderItem *>(item)->group();
|
|
|
|
if ( item->rtti()==LinkerScriptRtti || group==LinkerScriptGroup ) {
|
|
if ( _project==0 || Main::toolGroup().linkerScriptType()==PURL::Nb_FileTypes ) return;
|
|
pop.insertTitle(i18n("Linker Script"));
|
|
pop.insertItem("piklab_addfile", i18n("Set Custom..."));
|
|
if ( !_project->customLinkerScript().isEmpty() ) pop.insertItem("edit-delete", i18n("Set Default"));
|
|
switch( pop.exec(p) ) {
|
|
case 1: {
|
|
PURL::Url url = PURL::getOpenUrl(":custom_linker_script", PURL::filter(Main::toolGroup().linkerScriptType()), this, i18n("Select Linker Script"));
|
|
if ( !url.isEmpty() ) _project->setCustomLinkerScript(url);
|
|
break;
|
|
}
|
|
case 2: _project->setCustomLinkerScript(PURL::Url()); break;
|
|
}
|
|
_linkerScriptItem->init();
|
|
} else if ( item->rtti()==RootRtti ) {
|
|
RootItem *ri = static_cast<RootItem *>(item);
|
|
if ( _project==0 ) {
|
|
if ( ri->url().isEmpty() ) {
|
|
pop.insertItem("piklab_createproject", i18n("New Project..."), &Main::toplevel(), TQ_SLOT(newProject()));
|
|
pop.insertItem("piklab_openproject", i18n("Open Project..."), &Main::toplevel(), TQ_SLOT(openProject()));
|
|
pop.exec(p);
|
|
} else {
|
|
pop.insertTitle(i18n("Standalone File"));
|
|
pop.insertItem("configure", i18n("Configure..."));
|
|
if ( pop.exec(p)==1 ) Main::toplevel().configure(ConfigCenter::Standalone);
|
|
}
|
|
} else {
|
|
pop.insertTitle(i18n("Project"));
|
|
pop.insertItem("configure", i18n("Options..."), &Main::toplevel(), TQ_SLOT(configureProject()));
|
|
pop.insertItem("edit-find", i18n("Find Files..."), &Main::toplevel(), TQ_SLOT(runKfind()));
|
|
pop.insertSeparator();
|
|
pop.insertItem("piklab_compile", i18n("Build Project"), &Main::toplevel(), TQ_SLOT(buildProject()));
|
|
pop.insertItem("trashcan_empty", i18n("Clean Project"), &Main::toplevel(), TQ_SLOT(cleanBuild()));
|
|
pop.insertSeparator();
|
|
pop.insertItem("document-new", i18n("New Source File..."), &Main::toplevel(), TQ_SLOT(newSourceFile()));
|
|
pop.insertItem("piklab_addfile", i18n("Add Source Files..."), this, TQ_SLOT(insertSourceFiles()));
|
|
pop.insertItem("piklab_addfile", i18n("Add Object Files..."), this, TQ_SLOT(insertObjectFiles()));
|
|
if ( Main::currentEditor() ) pop.insertItem("piklab_addcurrentfile", i18n("Add Current File"), this, TQ_SLOT(insertCurrentFile()));
|
|
pop.exec(p);
|
|
}
|
|
} else if ( item->rtti()==FileRtti ) {
|
|
if ( _project==0 ) return;
|
|
FileItem *fi = static_cast<FileItem *>(item);
|
|
if ( isExternalFile(fi->url()) ) return;
|
|
pop.insertTitle(item->text(0));
|
|
pop.insertItem("edit-delete", i18n("Remove From Project"));
|
|
if ( pop.exec(p)==1 ) removeFile(fi->url());
|
|
} else if ( item->rtti()==HeaderRtti ) {
|
|
if ( _project==0 ) return;
|
|
if ( group==LinkerObjectGroup ) {
|
|
pop.insertTitle(i18n("Objects"));
|
|
pop.insertItem("piklab_addfile", i18n("Add Object Files..."), this, TQ_SLOT(insertObjectFiles()));
|
|
pop.exec(p);
|
|
} else if ( group==SourceGroup || group==HeaderGroup ) {
|
|
pop.insertTitle(i18n("Sources"));
|
|
pop.insertItem("document-new", i18n("New File..."), &Main::toplevel(), TQ_SLOT(newSourceFile()));
|
|
pop.insertItem("piklab_addfile", i18n("Add Source Files..."), this, TQ_SLOT(insertSourceFiles()));
|
|
pop.exec(p);
|
|
} else if ( group==DeviceGroup ) {
|
|
pop.insertItem("document-new", i18n("Select Device..."), &Main::toplevel(), TQ_SLOT(showDeviceInfo()));
|
|
pop.exec(p);
|
|
}
|
|
}
|
|
}
|
|
|
|
void ProjectManager::View::closeProject()
|
|
{
|
|
if ( _project==0 && projectUrl().isEmpty() ) return;
|
|
if (_project) {
|
|
// save opened files
|
|
PURL::UrlList files = Main::editorManager().files();
|
|
PURL::UrlList::const_iterator it = files.begin();
|
|
PURL::UrlList opened;
|
|
for (; it!=files.end(); ++it) {
|
|
if ( !isExternalFile(*it) ) opened += *it;
|
|
Main::editorManager().closeEditor(*it);
|
|
}
|
|
_project->setOpenedFiles(opened);
|
|
// save watched registers
|
|
_project->setWatchedRegisters(Register::list().watched());
|
|
TQString error;
|
|
if ( !_project->save(error) )
|
|
MessageBox::detailedSorry(i18n("Could not save project file \"%1\".").arg(_project->url().pretty()), error, Log::Show);
|
|
delete _project;
|
|
_project = 0;
|
|
}
|
|
_modified = false;
|
|
init();
|
|
}
|
|
|
|
void ProjectManager::View::addExternalFiles()
|
|
{
|
|
const TQMap<PURL::Url, FileOrigin> &ext = projectData().externals;
|
|
TQMap<PURL::Url, FileOrigin>::const_iterator it;
|
|
for (it=ext.begin(); it!=ext.end(); ++it) {
|
|
if ( !it.key().exists() ) continue;
|
|
addFile(it.key(), it.key().fileType(), it.data());
|
|
}
|
|
}
|
|
|
|
void ProjectManager::View::setStandalone(const PURL::Url &url, PURL::FileType type)
|
|
{
|
|
if ( projectUrl()==url ) return;
|
|
closeProject();
|
|
_rootItem->set(url, true);
|
|
addFile(url, type, Intrinsic);
|
|
_standaloneData[url].type = type;
|
|
addExternalFiles();
|
|
}
|
|
|
|
PURL::Url ProjectManager::View::standaloneGenerator(const PURL::Url &url, PURL::FileType &type) const
|
|
{
|
|
TQMap<PURL::Url, ProjectData>::const_iterator it;
|
|
for (it=_standaloneData.begin(); it!=_standaloneData.end(); ++it) {
|
|
if ( !it.data().externals.contains(url) ) continue;
|
|
if ( !it.key().exists() ) continue;
|
|
type = it.data().type;
|
|
return it.key();
|
|
}
|
|
type = PURL::Nb_FileTypes;
|
|
return url;
|
|
}
|
|
|
|
void ProjectManager::View::insertSourceFiles()
|
|
{
|
|
Q_ASSERT(_project);
|
|
PURL::UrlList list = PURL::getOpenUrls(":<sources>", PURL::sourceFilter(PURL::CompleteFilter), this, i18n("Select Source File"));
|
|
if ( list.isEmpty() ) return;
|
|
PURL::UrlList::const_iterator it;
|
|
for (it=list.begin(); it!=list.end(); ++it) insertFile(*it);
|
|
}
|
|
|
|
void ProjectManager::View::insertObjectFiles()
|
|
{
|
|
Q_ASSERT(_project);
|
|
PURL::UrlList list = PURL::getOpenUrls(":<objects>", PURL::objectFilter(PURL::CompleteFilter), this, i18n("Select Object File"));
|
|
if ( list.isEmpty() ) return;
|
|
PURL::UrlList::const_iterator it;
|
|
for (it=list.begin(); it!=list.end(); ++it) insertFile(*it);
|
|
}
|
|
|
|
void ProjectManager::View::insertFile(const PURL::Url &url)
|
|
{
|
|
if ( !url.exists() ) {
|
|
MessageBox::detailedSorry(i18n("Could not find file."), i18n("File: %1").arg(url.pretty()), Log::Show);
|
|
return;
|
|
}
|
|
PURL::Url purl = url;
|
|
MessageBox::Result copy = MessageBox::No;
|
|
if ( !url.isInto(_project->directory()) ) {
|
|
copy = MessageBox::questionYesNoCancel(i18n("File \"%1\" is not inside the project directory. Do you want to copy the file to your project directory?").arg(url.pretty()),
|
|
i18n("Copy and Add"), i18n("Add only"));
|
|
if ( copy==MessageBox::Cancel ) return;
|
|
if ( copy==MessageBox::Yes ) purl = PURL::Url(_project->directory(), url.filename());
|
|
}
|
|
if ( _project->absoluteFiles().contains(purl) ) {
|
|
MessageBox::detailedSorry(i18n("File is already in the project."), i18n("File: %1").arg(purl.pretty()), Log::Show);
|
|
return;
|
|
}
|
|
if ( copy==MessageBox::Yes ) {
|
|
Log::StringView sview;
|
|
if ( !url.copyTo(purl, sview) ) {
|
|
MessageBox::detailedSorry(i18n("Copying file to project directory failed."), i18n("File: %1\n").arg(url.pretty()) + sview.string(), Log::Show);
|
|
return;
|
|
}
|
|
}
|
|
_project->addFile(purl);
|
|
addFile(purl, purl.fileType(), Intrinsic);
|
|
}
|
|
|
|
bool ProjectManager::View::openProject()
|
|
{
|
|
PURL::Url url = PURL::getOpenUrl(":open_project", PURL::projectFilter(PURL::CompleteFilter), this, i18n("Select Project file"));
|
|
return openProject(url);
|
|
}
|
|
|
|
void ProjectManager::View::addExternalFile(const PURL::Url &url, FileOrigin origin)
|
|
{
|
|
Q_ASSERT( origin!=Intrinsic );
|
|
addFile(url, url.fileType(), origin);
|
|
}
|
|
|
|
const ProjectManager::View::ProjectData &ProjectManager::View::projectData() const
|
|
{
|
|
if ( _project==0 ) return _standaloneData[projectUrl()];
|
|
return _projectData;
|
|
}
|
|
|
|
ProjectManager::View::ProjectData &ProjectManager::View::projectData()
|
|
{
|
|
if ( _project==0 ) return _standaloneData[projectUrl()];
|
|
return _projectData;
|
|
}
|
|
|
|
void ProjectManager::View::addFile(const PURL::Url &url, PURL::FileType type, FileOrigin origin)
|
|
{
|
|
if ( contains(url) ) return;
|
|
TQMap<PURL::Url, FileOrigin> &ext = projectData().externals;
|
|
if ( type.data().group==PURL::LinkerScript && _linkerScriptItem ) {
|
|
_linkerScriptItem->set(url);
|
|
ext[url] = Included;
|
|
return;
|
|
}
|
|
PURL::FileProperties properties = type.data().properties;
|
|
Group grp = Nb_Groups;
|
|
switch (origin) {
|
|
case Intrinsic: grp = group(type); break;
|
|
case Generated: grp = GeneratedGroup; break;
|
|
case Included: grp = IncludedGroup; break;
|
|
}
|
|
HeaderItem *hitem = headerItem(grp);
|
|
TQListViewItem *item = new FileItem(hitem, type, url, origin!=Intrinsic);
|
|
item->moveItem(hitem->lastChild());
|
|
ensureItemVisible(item);
|
|
if ( origin!=Intrinsic ) ext[url] = origin;
|
|
if ( type==PURL::Hex && _project==0 ) {
|
|
TQString extension = PURL::extension(PURL::AsmGPAsm);
|
|
PURL::Url durl = PURL::Url::fromPathOrUrl("<" + (url.isEmpty() ? i18n("Disassembly") : url.appendExtension(extension).filename()) + ">");
|
|
if ( findFileItem(durl)==0 ) {
|
|
(void)new FileItem(headerItem(ViewGroup), PURL::Coff, durl, true);
|
|
ext[durl] = Generated;
|
|
}
|
|
}
|
|
if ( _project && origin==Intrinsic ) _modified = true;
|
|
}
|
|
|
|
void ProjectManager::View::removeExternalFiles()
|
|
{
|
|
TQMap<PURL::Url, FileOrigin> &ext = projectData().externals;
|
|
TQMap<PURL::Url, FileOrigin>::const_iterator it;
|
|
for (it=ext.begin(); it!=ext.end(); ++it) {
|
|
Main::editorManager().closeEditor(it.key());
|
|
removeFile(it.key());
|
|
}
|
|
ext.clear();
|
|
if (_linkerScriptItem) _linkerScriptItem->init();
|
|
}
|
|
|
|
void ProjectManager::View::removeFile(const PURL::Url &url)
|
|
{
|
|
if ( _project && !isExternalFile(url) ) _project->removeFile(url);
|
|
FileItem *item = findFileItem(url);
|
|
if ( item==0 ) return;
|
|
HeaderItem *group = static_cast<HeaderItem *>(item->parent());
|
|
delete item;
|
|
if ( group->childCount()==0 ) delete group;
|
|
_modified = true;
|
|
emit guiChanged();
|
|
}
|
|
|
|
void ProjectManager::View::clicked(int button, TQListViewItem *item, const TQPoint &, int)
|
|
{
|
|
if ( item==0 ) return;
|
|
if ( button!=TQt::LeftButton ) return;
|
|
const Device::Data *data = Main::deviceData();
|
|
Rtti rtti = Rtti(item->rtti());
|
|
if ( data==0 && rtti!=DeviceRtti && rtti!=RootRtti ) {
|
|
MessageBox::sorry(i18n("Cannot open without device specified."), Log::Show);
|
|
return;
|
|
}
|
|
Editor *e = 0;
|
|
::PBusyCursor bc;
|
|
switch (rtti) {
|
|
case RootRtti:
|
|
Main::toplevel().configureProject();
|
|
break;
|
|
case HeaderRtti: {
|
|
if ( static_cast<HeaderItem *>(item)->group()!=DeviceGroup ) break;
|
|
e = Main::editorManager().openEditor(EditorManager::DeviceEditor);
|
|
break;
|
|
}
|
|
case RegisterRtti:
|
|
e = Main::editorManager().openEditor(EditorManager::RegisterEditor);
|
|
break;
|
|
case DeviceRtti: return;
|
|
case LinkerScriptRtti: {
|
|
PURL::Url url = Main::projectManager().linkerScriptUrl();
|
|
if ( url.isEmpty() ) break;
|
|
e = Main::editorManager().findEditor(url);
|
|
if ( e==0 ) {
|
|
e = Main::editorManager().createEditor(url.fileType(), url);
|
|
if ( !e->open(url) ) {
|
|
delete e;
|
|
break;
|
|
}
|
|
if ( e && isExternalFile(url) ) e->setReadOnly(true);
|
|
Main::editorManager().addEditor(e);
|
|
} else Main::editorManager().showEditor(e);
|
|
break;
|
|
}
|
|
case FileRtti: {
|
|
FileItem *fi = static_cast<FileItem *>(item);
|
|
if ( !(fi->ftype().data().properties & PURL::Editable) ) break;
|
|
e = Main::editorManager().findEditor(fi->url());
|
|
if ( e==0 ) {
|
|
if ( fi->ftype()==PURL::Coff && _project==0 && !fi->url().exists() ) {
|
|
PURL::Url url = findFileItem(PURL::Hex)->url();
|
|
if ( url.isEmpty() ) {
|
|
HexEditor *he = ::tqt_cast<HexEditor *>(Main::currentEditor());
|
|
if ( he==0 ) break;
|
|
e = new DisassemblyEditor(*he, *data, this);
|
|
} else e = new DisassemblyEditor(url, *data, this);
|
|
addExternalFile(fi->url(), Generated);
|
|
} else e = Main::editorManager().createEditor(fi->url().fileType(), fi->url());
|
|
if ( e==0 ) break;
|
|
if ( !e->open(fi->url()) ) {
|
|
delete e;
|
|
break;
|
|
}
|
|
if ( isExternalFile(fi->url()) ) e->setReadOnly(true);
|
|
Main::editorManager().addEditor(e);
|
|
} else Main::editorManager().showEditor(e);
|
|
break;
|
|
}
|
|
}
|
|
cancelRenaming();
|
|
emit guiChanged();
|
|
}
|
|
|
|
void ProjectManager::View::insertCurrentFile()
|
|
{
|
|
insertFile(Main::editorManager().currentEditor()->url());
|
|
}
|
|
|
|
bool ProjectManager::View::editProject()
|
|
{
|
|
ProjectEditor dialog(*_project, this);
|
|
if ( dialog.exec()!=TQDialog::Accepted ) return false;
|
|
_modified = true;
|
|
if (_linkerScriptItem) _linkerScriptItem->init();
|
|
return true;
|
|
}
|
|
|
|
bool ProjectManager::View::newProject()
|
|
{
|
|
ProjectWizard wizard(this);
|
|
if ( wizard.exec()==TQDialog::Rejected ) return false;
|
|
closeProject();
|
|
TQString error;
|
|
if ( !wizard.project()->save(error) ) {
|
|
MessageBox::detailedSorry(i18n("Failed to create new project file"), error, Log::Show);
|
|
return false;
|
|
}
|
|
openProject(wizard.url());
|
|
return true;
|
|
}
|
|
|
|
void ProjectManager::View::setProject(Project *project)
|
|
{
|
|
closeProject();
|
|
Main::editorManager().closeAllEditors();
|
|
_project = project;
|
|
_rootItem->set(project->url(), false);
|
|
if ( project && Main::toolGroup().linkerScriptType()!=PURL::Nb_FileTypes ) {
|
|
_linkerScriptItem = new LinkerScriptItem(headerItem(LinkerScriptGroup));
|
|
ensureItemVisible(_linkerScriptItem);
|
|
}
|
|
}
|
|
|
|
bool ProjectManager::View::openProject(const PURL::Url &url)
|
|
{
|
|
if ( url.isEmpty() ) return false;
|
|
bool reload = ( _project && _project->url()==url );
|
|
if ( reload && !MessageBox::askContinue(i18n("Project already loaded. Reload?"), i18n("Reload")) ) return false;
|
|
static_cast< TDERecentFilesAction *>(Main::action("project_open_recent"))->removeURL(url.kurl());
|
|
Project *p = new Project(url);
|
|
TQString error;
|
|
if ( !p->load(error) ) {
|
|
MessageBox::detailedSorry(i18n("Could not open project file."), error, Log::Show);
|
|
delete p;
|
|
return false;
|
|
}
|
|
setProject(p);
|
|
PURL::UrlList files = _project->absoluteFiles();
|
|
PURL::UrlList::const_iterator it;
|
|
for(it=files.begin(); it!=files.end(); ++it) addFile(*it, (*it).fileType(), Intrinsic);
|
|
_projectData.type = PURL::Project;
|
|
_projectData.externals.clear();
|
|
static_cast<TDERecentFilesAction *>(Main::action("project_open_recent"))->addURL(url.kurl());
|
|
files = _project->openedFiles();
|
|
for(it = files.begin(); it!=files.end(); ++it) Main::editorManager().openFile(*it);
|
|
Register::list().init();
|
|
TQValueList<Register::TypeData> watched = _project->watchedRegisters();
|
|
TQValueList<Register::TypeData>::const_iterator wit;
|
|
for (wit=watched.begin(); wit!=watched.end(); ++wit) Register::list().setWatched(*wit, true);
|
|
return true;
|
|
}
|
|
|
|
bool ProjectManager::View::isExternalFile(const PURL::Url &url) const
|
|
{
|
|
if ( projectUrl().isEmpty() ) return false;
|
|
return projectData().externals.contains(url);
|
|
}
|
|
|
|
void ProjectManager::View::modified(const PURL::Url &url)
|
|
{
|
|
FileItem *item = findFileItem(url);
|
|
if ( item && !isExternalFile(url) ) _modified = true;
|
|
}
|
|
|
|
void ProjectManager::View::renamed(TQListViewItem *item, int, const TQString &text)
|
|
{
|
|
Q_ASSERT ( item->rtti()==DeviceRtti );
|
|
Main::toplevel().setDevice(text);
|
|
}
|
|
|
|
void ProjectManager::View::updateGUI()
|
|
{
|
|
_deviceItem->updateText();
|
|
}
|
|
|
|
TQDragObject *ProjectManager::View::dragObject()
|
|
{
|
|
if ( currentItem()==0 || currentItem()->rtti()!=FileRtti ) return 0;
|
|
const FileItem *item = static_cast<const FileItem *>(currentItem());
|
|
const HeaderItem *hitem = static_cast<const HeaderItem *>(item->parent());
|
|
if ( hitem->group()!=SourceGroup ) return 0;
|
|
TQStrList uris;
|
|
uris.append(TQUriDrag::localFileToUri(item->url().filepath()));
|
|
return new TQUriDrag(uris, viewport());
|
|
}
|
|
|
|
bool ProjectManager::View::acceptDrag(TQDropEvent* e) const
|
|
{
|
|
if ( e->source()!=viewport() ) return false;
|
|
const TQListViewItem *item = itemAt(e->pos());
|
|
if ( item==0 || item->rtti()!=FileRtti ) return false;
|
|
const HeaderItem *hitem = static_cast<const HeaderItem *>(item->parent());
|
|
return ( hitem->group()==SourceGroup );
|
|
}
|
|
|
|
void ProjectManager::View::filesReordered()
|
|
{
|
|
if ( _project==0 ) return;
|
|
_project->clearFiles();
|
|
TQListViewItem *item = headerItem(SourceGroup)->firstChild();
|
|
for (;item; item=item->nextSibling())
|
|
_project->addFile(static_cast<FileItem *>(item)->url());
|
|
}
|
|
|
|
TQString ProjectManager::View::tooltip(TQListViewItem *item, int) const
|
|
{
|
|
switch (Rtti(item->rtti())) {
|
|
case RootRtti:
|
|
case FileRtti:
|
|
case LinkerScriptRtti: return static_cast<const UrlItem *>(item)->url().filepath();
|
|
case DeviceRtti:
|
|
case RegisterRtti:
|
|
case HeaderRtti: break;
|
|
}
|
|
return TQString();
|
|
}
|
|
|
|
PURL::Url ProjectManager::View::linkerScriptUrl() const
|
|
{
|
|
TQListViewItemIterator it(const_cast<View *>(this));
|
|
for(; it.current(); ++it) {
|
|
if ( it.current()->rtti()!=LinkerScriptRtti ) continue;
|
|
return static_cast<LinkerScriptItem *>(it.current())->url();
|
|
}
|
|
return PURL::Url();
|
|
}
|
|
|
|
bool ProjectManager::View::needsRecompile() const
|
|
{
|
|
// ### this could be perfected...
|
|
PURL::Url output = projectUrl().toFileType(PURL::Hex);
|
|
TQDateTime outputLastModified;
|
|
if ( !output.exists(&outputLastModified) ) return true;
|
|
PURL::UrlList files;
|
|
if ( Main::project() ) files = Main::project()->absoluteFiles();
|
|
else files.append(projectUrl());
|
|
PURL::UrlList::const_iterator it;
|
|
for (it=files.begin(); it!=files.end(); ++it) {
|
|
TQDateTime lastModified;
|
|
if ( !(*it).exists(&lastModified) ) continue;
|
|
if ( lastModified>outputLastModified ) return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
PURL::Url ProjectManager::View::selectedUrl() const
|
|
{
|
|
TQListViewItem *item = currentItem();
|
|
if ( item==0 ) return PURL::Url();
|
|
Rtti rtti = Rtti(item->rtti());
|
|
if ( rtti!=FileRtti ) return PURL::Url();
|
|
return static_cast<FileItem *>(item)->url();
|
|
}
|
|
|
|
#include "project_manager.moc"
|