2 #include <tqfileinfo.h> 5 #include <tqstringlist.h> 13 #include <tdemessagebox.h> 15 #include <tdelocale.h> 18 #include <tdefiledialog.h> 19 #include <tdemainwindow.h> 20 #include <tdeparts/componentfactory.h> 21 #include <tdeaction.h> 22 #include <tdeapplication.h> 23 #include <tdecmdlineargs.h> 25 #include <tdeglobal.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" 45 #include "codemodel.h" 47 #include "languageselectwidget.h" 48 #include "generalinfowidget.h" 49 #include "projectsession.h" 53 #include "projectmanager.h" 55 TQString ProjectInfo::sessionFile()
const 57 TQString sf = m_projectURL.path(-1);
58 sf.truncate(sf.length() - 8);
63 TQString ProjectManager::projectDirectory(
const TQString& path,
bool absolute ) {
66 KURL url(ProjectManager::getInstance()->projectFile(), path);
73 ProjectManager::ProjectManager()
79 ProjectManager::~ProjectManager()
81 delete m_pProjectSession;
92 void ProjectManager::createActions( TDEActionCollection* ac )
96 action =
new TDEAction(i18n(
"&Open Project..."),
"project_open", 0,
97 this, TQT_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, TQT_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,
112 this, TQT_SLOT(closeProject()),
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, TQT_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);
126 void 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 );
146 void 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 ) );
154 connect (&dlg, TQT_SIGNAL(okClicked()), g, TQT_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() );
173 void ProjectManager::loadSettings()
177 void 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");
190 void 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));
202 bool 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 );
231 if( projectLoaded() && !closeProject() )
233 m_openRecentProjectAction->setCurrentItem( -1 );
235 kapp->restoreOverrideCursor();
239 m_info =
new ProjectInfo;
240 m_info->m_projectURL = url;
242 TQTimer::singleShot( 0,
this, TQT_SLOT(slotLoadProject()) );
248 void 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 #if KDE_IS_VERSION(3,5,0) 294 m_openRecentProjectAction->addURL(projectFile(), projectName());
296 m_openRecentProjectAction->addURL(projectFile());
298 m_closeProjectAction->setEnabled(
true);
299 m_projectOptionsAction->setEnabled(
true);
301 Core::getInstance()->doEmitProjectOpened();
304 kapp->restoreOverrideCursor();
314 if( !projectLoaded() )
318 if (m_info->m_projectURL.isLocalFile())
320 m_pProjectSession->saveToFile(m_info->sessionFile(), PluginController::getInstance()->loadedPlugins() );
323 if ( !PartController::getInstance()->querySaveFiles() )
326 Core::getInstance()->doEmitProjectClosed();
328 PluginController::getInstance()->unloadProjectPlugins();
329 PluginController::getInstance()->changeProfile(m_oldProfileName);
330 unloadLanguageSupport();
336 API::getInstance()->setProjectDom(0);
337 API::getInstance()->codeModel()->wipeout();
342 m_closeProjectAction->setEnabled(
false);
343 m_projectOptionsAction->setEnabled(
false);
347 PartController::getInstance()->slotCloseAllWindows();
353 bool ProjectManager::loadProjectFile()
356 if (!TDEIO::NetAccess::download(m_info->m_projectURL, path, 0)) {
358 i18n(
"Could not read project file: %1").arg(m_info->m_projectURL.prettyURL()));
363 if (!fin.open(IO_ReadOnly))
366 i18n(
"Could not read project file: %1").arg(m_info->m_projectURL.prettyURL()));
370 int errorLine, errorCol;
372 if (!m_info->m_document.setContent(&fin, &errorMsg, &errorLine, &errorCol))
375 i18n(
"This is not a valid project file.\n" 376 "XML error in line %1, column %2:\n%3")
377 .arg(errorLine).arg(errorCol).arg(errorMsg));
379 TDEIO::NetAccess::removeTempFile(path);
382 if (m_info->m_document.documentElement().nodeName() !=
"kdevelop")
385 i18n(
"This is not a valid project file."));
387 TDEIO::NetAccess::removeTempFile(path);
392 TDEIO::NetAccess::removeTempFile(path);
394 API::getInstance()->setProjectDom(&m_info->m_document);
399 bool ProjectManager::saveProjectFile()
401 Q_ASSERT( API::getInstance()->projectDom() );
403 if (m_info->m_projectURL.isLocalFile()) {
404 TQFile fout(m_info->m_projectURL.path());
405 if( !fout.open(IO_WriteOnly) ) {
410 TQTextStream stream(&fout);
411 API::getInstance()->projectDom()->save(stream, 2);
414 KTempFile fout(TQString::fromLatin1(
"kdevelop3"));
415 fout.setAutoDelete(
true);
416 if (fout.status() != 0) {
420 API::getInstance()->projectDom()->save(*(fout.textStream()), 2);
422 TDEIO::NetAccess::upload(fout.name(), m_info->m_projectURL, 0);
428 static TQString getAttribute(TQDomElement elem, TQString attr)
430 TQDomElement el = elem.namedItem(attr).toElement();
431 return el.firstChild().toText().data();
434 static void getAttributeList(TQDomElement elem, TQString attr, TQString tag, TQStringList &list)
438 TQDomElement el = elem.namedItem(attr).toElement();
439 TQDomElement item = el.firstChild().toElement();
440 while (!item.isNull())
442 if (item.tagName() == tag)
443 list << item.firstChild().toText().data();
444 item = item.nextSibling().toElement();
448 void ProjectManager::getGeneralInfo()
450 TQDomElement docEl = m_info->m_document.documentElement();
451 TQDomElement generalEl = docEl.namedItem(
"general").toElement();
453 m_info->m_projectPlugin = getAttribute(generalEl,
"projectmanagement");
454 m_info->m_vcsPlugin = getAttribute(generalEl,
"versioncontrol");
455 m_info->m_language = getAttribute(generalEl,
"primarylanguage");
456 m_info->m_projectName = getAttribute(generalEl,
"projectname");
457 if( m_info->m_projectName.isEmpty() )
459 m_info->m_projectName = m_info->m_projectURL.filename();
460 m_info->m_projectName = m_info->m_projectName.left(m_info->m_projectName.length()-TQString(
".kdevelop").length());
461 TQDomElement prjname = m_info->m_document.createElement(
"projectname");
462 prjname.appendChild( m_info->m_document.createTextNode( m_info->m_projectName) );
463 generalEl.appendChild( prjname );
466 getAttributeList(generalEl,
"ignoreparts",
"part", m_info->m_ignoreParts);
467 getAttributeList(generalEl,
"keywords",
"keyword", m_info->m_keywords);
471 TQDomElement el = generalEl.namedItem(
"profile").toElement();
474 m_info->m_profileName = Settings::profileByAttributes(m_info->m_language, m_info->m_keywords);
476 m_info->m_profileName = el.firstChild().toText().data();
479 bool ProjectManager::loadProjectPart()
481 KService::Ptr projectService = KService::serviceByDesktopName(m_info->m_projectPlugin);
482 if (!projectService) {
484 projectService = KService::serviceByDesktopName(m_info->m_projectPlugin.lower());
486 if (!projectService) {
488 i18n(
"No project management plugin %1 found.")
489 .arg(m_info->m_projectPlugin));
493 KDevProject *projectPart = KParts::ComponentFactory
494 ::createInstanceFromService< KDevProject >( projectService, API::getInstance(), 0,
495 PluginController::argumentsFromService( projectService ) );
496 if ( !projectPart ) {
498 i18n(
"Could not create project management plugin %1.")
499 .arg(m_info->m_projectPlugin));
503 API::getInstance()->setProject( projectPart );
505 TQDomDocument& dom = *API::getInstance()->projectDom();
506 TQString path = DomUtil::readEntry(dom,
"/general/projectdirectory",
".");
507 bool absolute = DomUtil::readBoolEntry(dom,
"/general/absoluteprojectpath",
false);
508 TQString projectDir = projectDirectory( path, absolute );
509 kdDebug(9000) <<
"projectDir: " << projectDir <<
" projectName: " << m_info->m_projectName << endl;
511 projectPart->openProject(projectDir, m_info->m_projectName);
513 PluginController::getInstance()->integratePart( projectPart );
518 void ProjectManager::unloadProjectPart()
520 KDevProject *projectPart = API::getInstance()->project();
521 if( !projectPart )
return;
522 PluginController::getInstance()->removePart( projectPart );
523 projectPart->closeProject();
525 API::getInstance()->setProject(0);
528 bool ProjectManager::loadLanguageSupport(
const TQString& lang)
530 kdDebug(9000) <<
"Looking for language support for " << lang << endl;
532 if (lang == m_info->m_activeLanguage)
534 kdDebug(9000) <<
"Language support already loaded" << endl;
538 TDETrader::OfferList languageSupportOffers =
539 TDETrader::self()->query(TQString::fromLatin1(
"TDevelop/LanguageSupport"),
540 TQString::fromLatin1(
"[X-TDevelop-Language] == '%1' and [X-TDevelop-Version] == %2").arg(lang).arg(TDEVELOP_PLUGIN_VERSION));
542 if (languageSupportOffers.isEmpty()) {
544 i18n(
"No language plugin for %1 found.")
549 KService::Ptr languageSupportService = *languageSupportOffers.begin();
550 KDevLanguageSupport *langSupport = KParts::ComponentFactory
551 ::createInstanceFromService<KDevLanguageSupport>( languageSupportService,
554 PluginController::argumentsFromService( languageSupportService ) );
556 if ( !langSupport ) {
558 i18n(
"Could not create language plugin for %1.")
563 API::getInstance()->setLanguageSupport( langSupport );
564 PluginController::getInstance()->integratePart( langSupport );
565 m_info->m_activeLanguage = lang;
566 kdDebug(9000) <<
"Language support for " << lang <<
" successfully loaded." << endl;
570 void ProjectManager::unloadLanguageSupport()
572 KDevLanguageSupport *langSupport = API::getInstance()->languageSupport();
573 if( !langSupport )
return;
574 kdDebug(9000) <<
"Language support for " << langSupport->name() <<
" unloading..." << endl;
575 PluginController::getInstance()->removePart( langSupport );
577 API::getInstance()->setLanguageSupport(0);
580 void ProjectManager::loadLocalParts()
585 PluginController::getInstance()->unloadPlugins( m_info->m_ignoreParts );
586 PluginController::getInstance()->loadProjectPlugins( m_info->m_ignoreParts );
587 PluginController::getInstance()->loadGlobalPlugins( m_info->m_ignoreParts );
590 KURL ProjectManager::projectFile()
const 594 return m_info->m_projectURL;
597 TQString ProjectManager::projectName()
const 599 if (!m_info)
return TQString();
601 return m_info->m_projectName;
604 bool ProjectManager::projectLoaded()
const 611 return m_pProjectSession;
614 bool ProjectManager::loadKDevelop2Project(
const KURL & url )
616 if( !url.isValid() || !url.isLocalFile() ){
617 KMessageBox::sorry(0, i18n(
"Invalid URL."));
621 TQString cmd = TDEGlobal::dirs()->findExe(
"kdevprj2kdevelop" );
623 KMessageBox::sorry(0, i18n(
"You do not have 'kdevprj2kdevelop' installed."));
627 TQFileInfo fileInfo( url.path() );
629 KShellProcess proc(
"/bin/sh" );
630 proc.setWorkingDirectory( fileInfo.dirPath(
true) );
631 proc <<
"perl" << cmd << KShellProcess::quote( url.path() );
632 proc.start( TDEProcess::Block );
634 TQString projectFile = fileInfo.dirPath(
true ) +
"/" + fileInfo.baseName() +
".kdevelop";
635 return loadProject( KURL(projectFile) );
668 #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.