5#include <tqstringlist.h>
13#include <tdemessagebox.h>
18#include <tdefiledialog.h>
19#include <tdemainwindow.h>
20#include <tdeparts/componentfactory.h>
22#include <tdeapplication.h>
23#include <tdecmdlineargs.h>
26#include <kstandarddirs.h>
27#include <tdeio/netaccess.h>
28#include <tdetempfile.h>
29#include <tdemenubar.h>
30#include <kstatusbar.h>
31#include <kiconloader.h>
33#include "kdevproject.h"
34#include "kdevlanguagesupport.h"
35#include "kdevplugin.h"
36#include "kdevcreatefile.h"
37#include "kdevversioncontrol.h"
43#include "plugincontroller.h"
44#include "partcontroller.h"
47#include "languageselectwidget.h"
48#include "generalinfowidget.h"
49#include "projectsession.h"
53#include "projectmanager.h"
55TQString ProjectInfo::sessionFile()
const
57 TQString sf = m_projectURL.path(-1);
58 sf.truncate(sf.length() - 8);
63TQString ProjectManager::projectDirectory(
const TQString& path,
bool absolute ) {
66 KURL url(ProjectManager::getInstance()->projectFile(), path);
73ProjectManager::ProjectManager()
79ProjectManager::~ProjectManager()
81 delete m_pProjectSession;
88 s_instance =
new ProjectManager;
92void ProjectManager::createActions( TDEActionCollection* ac )
96 action =
new TDEAction(i18n(
"&Open Project..."),
"project_open", 0,
97 this, TQ_SLOT(slotOpenProject()),
99 action->setToolTip( i18n(
"Open project"));
100 action->setWhatsThis(i18n(
"<b>Open project</b><p>Opens a KDevelop3 or KDevelop2 project."));
102 m_openRecentProjectAction =
103 new TDERecentFilesAction(i18n(
"Open &Recent Project"), 0,
104 this, TQ_SLOT(loadProject(
const KURL &)),
105 ac,
"project_open_recent");
106 m_openRecentProjectAction->setToolTip(i18n(
"Open recent project"));
107 m_openRecentProjectAction->setWhatsThis(i18n(
"<b>Open recent project</b><p>Opens recently opened project."));
108 m_openRecentProjectAction->loadEntries(kapp->config(),
"RecentProjects");
110 m_closeProjectAction =
111 new TDEAction(i18n(
"C&lose Project"),
"window-close",0,
113 ac,
"project_close");
114 m_closeProjectAction->setEnabled(
false);
115 m_closeProjectAction->setToolTip(i18n(
"Close project"));
116 m_closeProjectAction->setWhatsThis(i18n(
"<b>Close project</b><p>Closes the current project."));
118 m_projectOptionsAction =
new TDEAction(i18n(
"Project &Options"),
"configure", 0,
119 this, TQ_SLOT(slotProjectOptions()),
120 ac,
"project_options" );
121 m_projectOptionsAction->setToolTip(i18n(
"Project options"));
122 m_projectOptionsAction->setWhatsThis(i18n(
"<b>Project options</b><p>Lets you customize project options."));
123 m_projectOptionsAction->setEnabled(
false);
126void ProjectManager::slotOpenProject()
128 TDEConfig *config = kapp->config();
129 config->setGroup(
"General Options");
130 TQString defaultProjectsDir = config->readPathEntry(
"DefaultProjectsDir", TQDir::homeDirPath()+
"/");
132 KURL url = KFileDialog::getOpenURL(defaultProjectsDir,
133 i18n(
"*.kdevelop|KDevelop 3 Project Files\n"
134 "*.kdevprj|KDevelop 2 Project Files"),
140 if (url.path().endsWith(
"kdevprj"))
141 loadKDevelop2Project( url );
146void ProjectManager::slotProjectOptions()
148 KDialogBase dlg(KDialogBase::IconList, i18n(
"Project Options"),
150 "project options dialog");
152 TQVBox *box = dlg.addVBoxPage( i18n(
"General"), i18n(
"General"), BarIcon(
"tdevelop", TDEIcon::SizeMedium ) );
153 GeneralInfoWidget *g =
new GeneralInfoWidget(*API::getInstance()->projectDom(), box,
"general informations widget");
154 connect (&dlg, TQ_SIGNAL(okClicked()), g, TQ_SLOT(accept()));
156 TDEConfig *config = kapp->config();
157 config->setGroup(
"Project Settings Dialog");
158 int height = config->readNumEntry(
"Height", 600 );
159 int width = config->readNumEntry(
"Width", 800 );
161 dlg.resize( width, height );
163 Core::getInstance()->doEmitProjectConfigWidget(&dlg);
168 config->setGroup(
"Project Settings Dialog");
169 config->writeEntry(
"Height", dlg.size().height() );
170 config->writeEntry(
"Width", dlg.size().width() );
173void ProjectManager::loadSettings()
177void ProjectManager::saveSettings()
179 TDEConfig *config = kapp->config();
183 config->setGroup(
"General Options");
184 config->writePathEntry(
"Last Project", ProjectManager::getInstance()->projectFile().url());
187 m_openRecentProjectAction->saveEntries(config,
"RecentProjects");
190void ProjectManager::loadDefaultProject()
192 TDEConfig *config = kapp->config();
193 config->setGroup(
"General Options");
194 TQString project = config->readPathEntry(
"Last Project");
195 bool readProject = config->readBoolEntry(
"Read Last Project On Startup",
true);
196 if (!project.isEmpty() && readProject)
198 loadProject(KURL(project));
202bool ProjectManager::loadProject(
const KURL &projectURL)
204 KURL url = projectURL;
209 if (url.isLocalFile())
211 TQDir dir(url.path());
212 TQString can_path = dir.canonicalPath();
214 if(can_path.isNull())
217 url.setPath(can_path);
221 if( projectLoaded() && url.path() == projectFile().path() )
224 i18n(
"Are you sure you want to reopen the current project?"), TQString(), i18n(
"Reopen"), i18n(
"Do Not Reopen")) == KMessageBox::No)
229 kapp->setOverrideCursor( waitCursor );
233 m_openRecentProjectAction->setCurrentItem( -1 );
235 kapp->restoreOverrideCursor();
239 m_info =
new ProjectInfo;
240 m_info->m_projectURL = url;
242 TQTimer::singleShot( 0,
this, TQ_SLOT(slotLoadProject()) );
248void ProjectManager::slotLoadProject( )
250 if( !loadProjectFile() )
252 m_openRecentProjectAction->removeURL(m_info->m_projectURL);
253 delete m_info; m_info = 0;
256 kapp->restoreOverrideCursor();
262 if( !loadLanguageSupport(m_info->m_language) ) {
263 delete m_info; m_info = 0;
265 kapp->restoreOverrideCursor();
269 if( !loadProjectPart() ) {
270 unloadLanguageSupport();
271 delete m_info; m_info = 0;
272 API::getInstance()->setProjectDom( 0 );
274 kapp->restoreOverrideCursor();
279 m_oldProfileName = PluginController::getInstance()->changeProfile(m_info->m_profileName);
285 if (m_info->m_projectURL.isLocalFile())
288 if (!m_pProjectSession->restoreFromFile(m_info->sessionFile(), PluginController::getInstance()->loadedPlugins() ))
290 kdWarning() << i18n(
"error during restoring of the TDevelop session !") << endl;
293 m_openRecentProjectAction->addURL(projectFile(), projectName());
294 m_closeProjectAction->setEnabled(
true);
295 m_projectOptionsAction->setEnabled(
true);
297 Core::getInstance()->doEmitProjectOpened();
300 kapp->restoreOverrideCursor();
310 if( !projectLoaded() )
314 if (m_info->m_projectURL.isLocalFile())
316 m_pProjectSession->saveToFile(m_info->sessionFile(), PluginController::getInstance()->loadedPlugins() );
319 if ( !PartController::getInstance()->querySaveFiles() )
322 Core::getInstance()->doEmitProjectClosed();
324 PluginController::getInstance()->unloadProjectPlugins();
325 PluginController::getInstance()->changeProfile(m_oldProfileName);
326 unloadLanguageSupport();
332 API::getInstance()->setProjectDom(0);
333 API::getInstance()->codeModel()->wipeout();
338 m_closeProjectAction->setEnabled(
false);
339 m_projectOptionsAction->setEnabled(
false);
343 PartController::getInstance()->slotCloseAllWindows();
349bool ProjectManager::loadProjectFile()
352 if (!TDEIO::NetAccess::download(m_info->m_projectURL, path, 0)) {
354 i18n(
"Could not read project file: %1").arg(m_info->m_projectURL.prettyURL()));
359 if (!fin.open(IO_ReadOnly))
362 i18n(
"Could not read project file: %1").arg(m_info->m_projectURL.prettyURL()));
366 int errorLine, errorCol;
368 if (!m_info->m_document.setContent(&fin, &errorMsg, &errorLine, &errorCol))
371 i18n(
"This is not a valid project file.\n"
372 "XML error in line %1, column %2:\n%3")
373 .arg(errorLine).arg(errorCol).arg(errorMsg));
375 TDEIO::NetAccess::removeTempFile(path);
378 if (m_info->m_document.documentElement().nodeName() !=
"kdevelop")
381 i18n(
"This is not a valid project file."));
383 TDEIO::NetAccess::removeTempFile(path);
388 TDEIO::NetAccess::removeTempFile(path);
390 API::getInstance()->setProjectDom(&m_info->m_document);
395bool ProjectManager::saveProjectFile()
397 Q_ASSERT( API::getInstance()->projectDom() );
399 if (m_info->m_projectURL.isLocalFile()) {
400 TQFile fout(m_info->m_projectURL.path());
401 if( !fout.open(IO_WriteOnly) ) {
406 TQTextStream stream(&fout);
407 API::getInstance()->projectDom()->save(stream, 2);
410 KTempFile fout(TQString::fromLatin1(
"kdevelop3"));
411 fout.setAutoDelete(
true);
412 if (fout.status() != 0) {
416 API::getInstance()->projectDom()->save(*(fout.textStream()), 2);
418 TDEIO::NetAccess::upload(fout.name(), m_info->m_projectURL, 0);
424static TQString getAttribute(TQDomElement elem, TQString attr)
426 TQDomElement el = elem.namedItem(attr).toElement();
427 return el.firstChild().toText().data();
430static void getAttributeList(TQDomElement elem, TQString attr, TQString tag, TQStringList &list)
434 TQDomElement el = elem.namedItem(attr).toElement();
435 TQDomElement item = el.firstChild().toElement();
436 while (!item.isNull())
438 if (item.tagName() == tag)
439 list << item.firstChild().toText().data();
440 item = item.nextSibling().toElement();
444void ProjectManager::getGeneralInfo()
446 TQDomElement docEl = m_info->m_document.documentElement();
447 TQDomElement generalEl = docEl.namedItem(
"general").toElement();
449 m_info->m_projectPlugin = getAttribute(generalEl,
"projectmanagement");
450 m_info->m_vcsPlugin = getAttribute(generalEl,
"versioncontrol");
451 m_info->m_language = getAttribute(generalEl,
"primarylanguage");
452 m_info->m_projectName = getAttribute(generalEl,
"projectname");
453 if( m_info->m_projectName.isEmpty() )
455 m_info->m_projectName = m_info->m_projectURL.filename();
456 m_info->m_projectName = m_info->m_projectName.left(m_info->m_projectName.length()-TQString(
".kdevelop").length());
457 TQDomElement prjname = m_info->m_document.createElement(
"projectname");
458 prjname.appendChild( m_info->m_document.createTextNode( m_info->m_projectName) );
459 generalEl.appendChild( prjname );
462 getAttributeList(generalEl,
"ignoreparts",
"part", m_info->m_ignoreParts);
463 getAttributeList(generalEl,
"keywords",
"keyword", m_info->m_keywords);
467 TQDomElement el = generalEl.namedItem(
"profile").toElement();
470 m_info->m_profileName = Settings::profileByAttributes(m_info->m_language, m_info->m_keywords);
472 m_info->m_profileName = el.firstChild().toText().data();
475bool ProjectManager::loadProjectPart()
477 KService::Ptr projectService = KService::serviceByDesktopName(m_info->m_projectPlugin);
478 if (!projectService) {
480 projectService = KService::serviceByDesktopName(m_info->m_projectPlugin.lower());
482 if (!projectService) {
484 i18n(
"No project management plugin %1 found.")
485 .arg(m_info->m_projectPlugin));
489 KDevProject *projectPart = KParts::ComponentFactory
490 ::createInstanceFromService< KDevProject >( projectService, API::getInstance(), 0,
491 PluginController::argumentsFromService( projectService ) );
492 if ( !projectPart ) {
494 i18n(
"Could not create project management plugin %1.")
495 .arg(m_info->m_projectPlugin));
499 API::getInstance()->setProject( projectPart );
501 TQDomDocument& dom = *API::getInstance()->projectDom();
502 TQString path = DomUtil::readEntry(dom,
"/general/projectdirectory",
".");
503 bool absolute = DomUtil::readBoolEntry(dom,
"/general/absoluteprojectpath",
false);
504 TQString projectDir = projectDirectory( path, absolute );
505 kdDebug(9000) <<
"projectDir: " << projectDir <<
" projectName: " << m_info->m_projectName << endl;
507 projectPart->openProject(projectDir, m_info->m_projectName);
509 PluginController::getInstance()->integratePart( projectPart );
514void ProjectManager::unloadProjectPart()
516 KDevProject *projectPart = API::getInstance()->project();
517 if( !projectPart )
return;
518 PluginController::getInstance()->removePart( projectPart );
519 projectPart->closeProject();
521 API::getInstance()->setProject(0);
524bool ProjectManager::loadLanguageSupport(
const TQString& lang)
526 kdDebug(9000) <<
"Looking for language support for " << lang << endl;
528 if (lang == m_info->m_activeLanguage)
530 kdDebug(9000) <<
"Language support already loaded" << endl;
534 TDETrader::OfferList languageSupportOffers =
535 TDETrader::self()->query(TQString::fromLatin1(
"TDevelop/LanguageSupport"),
536 TQString::fromLatin1(
"[X-TDevelop-Language] == '%1' and [X-TDevelop-Version] == %2").arg(lang).arg(TDEVELOP_PLUGIN_VERSION));
538 if (languageSupportOffers.isEmpty()) {
540 i18n(
"No language plugin for %1 found.")
545 KService::Ptr languageSupportService = *languageSupportOffers.begin();
546 KDevLanguageSupport *langSupport = KParts::ComponentFactory
547 ::createInstanceFromService<KDevLanguageSupport>( languageSupportService,
550 PluginController::argumentsFromService( languageSupportService ) );
552 if ( !langSupport ) {
554 i18n(
"Could not create language plugin for %1.")
559 API::getInstance()->setLanguageSupport( langSupport );
560 PluginController::getInstance()->integratePart( langSupport );
561 m_info->m_activeLanguage = lang;
562 kdDebug(9000) <<
"Language support for " << lang <<
" successfully loaded." << endl;
566void ProjectManager::unloadLanguageSupport()
568 KDevLanguageSupport *langSupport = API::getInstance()->languageSupport();
569 if( !langSupport )
return;
570 kdDebug(9000) <<
"Language support for " << langSupport->name() <<
" unloading..." << endl;
571 PluginController::getInstance()->removePart( langSupport );
573 API::getInstance()->setLanguageSupport(0);
576void ProjectManager::loadLocalParts()
581 PluginController::getInstance()->unloadPlugins( m_info->m_ignoreParts );
582 PluginController::getInstance()->loadProjectPlugins( m_info->m_ignoreParts );
583 PluginController::getInstance()->loadGlobalPlugins( m_info->m_ignoreParts );
586KURL ProjectManager::projectFile()
const
590 return m_info->m_projectURL;
593TQString ProjectManager::projectName()
const
595 if (!m_info)
return TQString();
597 return m_info->m_projectName;
600bool ProjectManager::projectLoaded()
const
607 return m_pProjectSession;
610bool ProjectManager::loadKDevelop2Project(
const KURL & url )
612 if( !url.isValid() || !url.isLocalFile() ){
613 KMessageBox::sorry(0, i18n(
"Invalid URL."));
617 TQString cmd = TDEGlobal::dirs()->findExe(
"kdevprj2kdevelop" );
619 KMessageBox::sorry(0, i18n(
"You do not have 'kdevprj2kdevelop' installed."));
623 TQFileInfo fileInfo( url.path() );
625 KShellProcess proc(
"/bin/sh" );
626 proc.setWorkingDirectory( fileInfo.dirPath(
true) );
627 proc <<
"perl" << cmd << KShellProcess::quote( url.path() );
628 proc.start( TDEProcess::Block );
630 TQString projectFile = fileInfo.dirPath(
true ) +
"/" + fileInfo.baseName() +
".kdevelop";
631 return loadProject( KURL(projectFile) );
664#include "projectmanager.moc"
bool closeProject(bool exiting=false)
This class stores and restores the last situation before the certain project was closed.
static KDevMainWindow * getInstance()
Get a pointer to the single KDevTopLevel object.