diff options
Diffstat (limited to 'quanta/project/projectprivate.cpp')
-rw-r--r-- | quanta/project/projectprivate.cpp | 1675 |
1 files changed, 1675 insertions, 0 deletions
diff --git a/quanta/project/projectprivate.cpp b/quanta/project/projectprivate.cpp new file mode 100644 index 00000000..c74b1dc9 --- /dev/null +++ b/quanta/project/projectprivate.cpp @@ -0,0 +1,1675 @@ +/*************************************************************************** + projectprivate.cpp - description + ------------------- + begin : Mon Oct 4 20:49:39 2004 + copyright : (C) 2000 by Yacovlev Alexander & Dmitry Poplavsky <pdima@mail.univ.kiev.ua> + (C) 2001-2004 by Andras Mantia <amantia@kde.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 "projectprivate.h" + +//qt includes +#include <qcheckbox.h> +#include <qdir.h> +#include <qfile.h> +#include <qradiobutton.h> +#include <qwidgetstack.h> +#include <qwizard.h> +#include <qeventloop.h> + +//kde includes +#include <kaction.h> +#include <kapplication.h> +#include <kcharsets.h> +#include <kconfig.h> +#include <kdirwatch.h> +#include <kfiledialog.h> +#include <kinputdialog.h> +#include <kio/netaccess.h> +#include <klineedit.h> +#include <klocale.h> +#include <kmainwindow.h> +#include <kmessagebox.h> +#include <kparts/componentfactory.h> +#include <kprogress.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kurl.h> +#include <kurlrequester.h> +#include <kurlrequesterdlg.h> + +//app includes +#include "copyto.h" +#include "debuggerclient.h" +#include "dtds.h" +#include "project.h" +#include "projectnewgeneral.h" +#include "projectnewlocal.h" +#include "projectnewweb.h" +#include "projectnewfinal.h" +#include "qpevents.h" +#include "quantacommon.h" +#include "resource.h" +#include "uploadprofiles.h" +#include "viewmanager.h" + +ProjectPrivate::ProjectPrivate(Project *p) + : QObject(), config(0L), m_dirWatch(0L), tempFile(0L), sessionTempFile(0L) +{ + parent = p; + m_projectFiles.setAutoDelete(true); + m_showUploadTreeviews = true; + m_eventsEnabled = true; + m_events = new EventActions(); + init(); + m_wizTitle = i18n("<b>Insert Files in Project</b>"); +} + +ProjectPrivate::~ProjectPrivate() +{ + delete m_events; +} + +/** setup of the actions */ +void ProjectPrivate::initActions(KActionCollection *ac) +{ + (void) new KAction( i18n( "&New Project..." ), "window_new", 0, + this, SLOT( slotNewProject() ), + ac, "project_new" ); + + (void) new KAction( i18n( "&Open Project..." ), "project_open", 0, + this, SLOT( slotOpenProject() ), + ac, "project_open" ); + m_projectRecent = + KStdAction::openRecent(parent, SLOT(slotOpenProject(const KURL&)), + ac, "project_open_recent"); + m_projectRecent->setText(i18n("Open Recent Project")); + m_projectRecent->setIcon("project_open"); + m_projectRecent->setToolTip(i18n("Open/Open recent project")); + connect(m_projectRecent, SIGNAL(activated()), this, SLOT(slotOpenProject())); + + closeprjAction = new KAction( i18n( "&Close Project" ), "fileclose", 0, + this, SLOT( slotCloseProject() ), + ac, "project_close" ); + + + openPrjViewAction = new KSelectAction( i18n( "Open Project &View..." ), 0, + ac, "project_view_open" ); + connect(openPrjViewAction, SIGNAL(activated(const QString &)), + this, SLOT(slotOpenProjectView(const QString &))); + openPrjViewAction->setToolTip(i18n("Open project view")); + + savePrjViewAction = new KAction( i18n( "&Save Project View" ), "filesave", 0, + this, SLOT( slotSaveProjectView() ), + ac, "project_view_save" ); + saveAsPrjViewAction = new KAction( i18n( "Save Project View &As..." ), "filesaveas", 0, + this, SLOT( slotSaveAsProjectView() ), + ac, "project_view_save_as" ); + deletePrjViewAction = new KSelectAction( i18n( "&Delete Project View" ), "editdelete", 0, + ac, "project_view_delete" ); + connect(deletePrjViewAction, SIGNAL(activated(const QString &)), + this, SLOT(slotDeleteProjectView(const QString &))); + deletePrjViewAction->setToolTip(i18n("Close project view")); + + + + insertFileAction = new KAction( i18n( "&Insert Files..." ), 0, + this, SLOT( slotAddFiles() ), + ac, "project_insert_file" ); + + insertDirAction = new KAction( i18n( "Inser&t Folder..." ), 0, + this, SLOT( slotAddDirectory() ), + ac, "project_insert_directory" ); + + rescanPrjDirAction = new KAction( i18n( "&Rescan Project Folder..." ), "reload", 0, + parent, SLOT( slotRescanPrjDir() ), + ac, "project_rescan" ); + + uploadProjectAction = new KAction( i18n( "&Upload Project..." ), "up", Key_F8, + parent, SLOT( slotUpload() ), + ac, "project_upload" ); + + projectOptionAction = new KAction( i18n( "&Project Properties" ), "configure", SHIFT + Key_F7, + parent, SLOT( slotOptions() ), + ac, "project_options" ); + + saveAsProjectTemplateAction = + new KAction( i18n( "Save as Project Template..." ), 0, + m_mainWindow, SLOT( slotFileSaveAsProjectTemplate() ), + ac, "save_project_template" ); + + saveSelectionAsProjectTemplateAction = + new KAction( i18n( "Save Selection to Project Template File..." ), 0, + m_mainWindow, SLOT( slotFileSaveSelectionAsProjectTemplate() ), + ac, "save_selection_project_template" ); + adjustActions(); +} + + +void ProjectPrivate::adjustActions() +{ + bool projectExists = parent->hasProject(); + closeprjAction->setEnabled(projectExists); + openPrjViewAction->setEnabled(projectExists); + savePrjViewAction->setEnabled(projectExists); + saveAsPrjViewAction->setEnabled(projectExists); + deletePrjViewAction->setEnabled(projectExists); + + insertFileAction->setEnabled(projectExists); + insertDirAction->setEnabled(projectExists); + rescanPrjDirAction->setEnabled(projectExists); + uploadProjectAction->setEnabled(projectExists); + projectOptionAction->setEnabled(projectExists); + saveAsProjectTemplateAction->setEnabled(projectExists); + saveSelectionAsProjectTemplateAction->setEnabled(projectExists); + + adjustViewActions(); + parent->slotShowProjectToolbar(projectExists); +} + + +void ProjectPrivate::adjustViewActions() +{ + QStringList viewList = projectViewList(); + QString oldItem = openPrjViewAction->currentText(); + openPrjViewAction->clear(); + openPrjViewAction->setItems(viewList); + int i = viewList.findIndex(oldItem); + if (i > -1) + openPrjViewAction->setCurrentItem(i); + deletePrjViewAction->clear(); + deletePrjViewAction->setItems(viewList); + bool hasView = !currentProjectView.isEmpty(); + savePrjViewAction->setEnabled(hasView); +} + + +QStringList ProjectPrivate::projectViewList() +{ + QStringList list; + QDomNodeList nl = dom.elementsByTagName("projectview"); + QDomElement el; + for (uint i = 0; i < nl.count(); i++) + { + el = nl.item(i).cloneNode().toElement(); + list += el.attribute("name"); + } + list.sort(); + return list; +} + +void ProjectPrivate::init() +{ + projectURL = KURL(); + templateURL = KURL(); + projectName = QString::null; + m_modified = false; + m_defaultDTD = qConfig.defaultDocType; + excludeRx.setPattern(".*~$"); + excludeList.clear(); + excludeList.append("*~"); + usePreviewPrefix = false; + previewPrefix = KURL(); + m_persistentBookmarks = false; + m_debuggerPersistentBreakpoints = false; + m_debuggerPersistentWatches = false; + m_excludeCvsignore = false; + currentProjectView = QString::null; + m_projectFiles.clear(); + m_mailingList = QString::null; + m_teamLeader.name = QString::null; + m_teamLeader.email = QString::null; + m_taskLeaders.clear(); + m_subprojectLeaders.clear(); + m_subprojects.clear(); + m_simpleMembers.clear(); + UploadProfiles::ref()->clear(); +} + + +void ProjectPrivate::openCurrentView() +{ + if (currentProjectView.isEmpty()) + return; + KURL::List urlsToOpen, urlsInView; + QDomNodeList nl = dom.elementsByTagName("projectview"); + QDomElement el; + for (uint i = 0; i < nl.count(); i++) + { + el = nl.item(i).cloneNode().toElement(); + if (el.attribute("name") == currentProjectView) + { + QDomNodeList itemNodes = el.childNodes(); + for (uint j = 0; j < itemNodes.count(); j++) + { + QDomElement el2 = itemNodes.item(j).cloneNode().toElement(); + KURL url = baseURL; + QuantaCommon::setUrl(url,el2.attribute("url")); + url = QExtFileInfo::toAbsolute(url, baseURL); + if (el2.nodeName() == "viewitem") + { + urlsInView.append(url); + if (!ViewManager::ref()->isOpened(url) && QExtFileInfo::exists(url, true, m_mainWindow)) + urlsToOpen.append(url); + } else { + if (el2.nodeName() == "viewtoolbar") + { + parent->loadToolbarFile(url); + } + } + } + // first we open what we want, might be that a wanted file is already open! + parent->openFiles(urlsToOpen, m_defaultEncoding); + // second we close what we don't want + KURL::List openURLs = ViewManager::ref()->openedFiles(true); // get open urls + KURL::List::Iterator it; + for ( it = openURLs.begin(); it != openURLs.end(); ++it ) + { + if (urlsInView.findIndex( *it ) == -1) + parent->closeFile (*it); + } + break; + } + } + QStringList viewList = projectViewList(); + int i = viewList.findIndex(currentProjectView); + if (i > -1) + openPrjViewAction->setCurrentItem(i); + adjustViewActions(); +} + +/** Opens a project view (toolbars & files). */ +void ProjectPrivate::slotOpenProjectView(const QString &view) +{ + currentProjectView = view; + openCurrentView(); +} + +/** insert files */ +void ProjectPrivate::insertFiles( KURL::List files ) +{ + QDomElement el; + QDomNodeList nl = dom.elementsByTagName("item"); + parent->statusMsg( i18n("Adding files to the project...") ); + progressBar->setTotalSteps(2 * files.count() - 2); + progressBar->setValue(0); + progressBar->setTextEnabled(true); + + KURL::List::Iterator it; + for ( it = files.begin(); it != files.end(); ++it ) + { + if (m_projectFiles.contains(*it)) + { + it = files.erase(it); + --it; + } + progressBar->advance(1); + } + for ( it = files.begin(); it != files.end(); ++it ) + { + if (! (*it).isEmpty()) + { + KURL url = *it; + url.setPath(url.directory(false)); + while ( baseURL.isParentOf(url) ) + { + if (!m_projectFiles.contains(url)) + { + el = dom.createElement("item"); + el.setAttribute("url", QuantaCommon::qUrl(QExtFileInfo::toRelative(url, baseURL, false))); + dom.firstChild().firstChild().appendChild(el); + m_projectFiles.insert( new ProjectURL(url, "", 1, false, el) ); + emit eventHappened("after_project_add", url.url(), QString::null); + m_modified = true; + } + url.setPath(url.directory(false)); + } + el = dom.createElement("item"); + url = *it; + if (!excludeRx.exactMatch(url.path())) + { + el.setAttribute("url", QuantaCommon::qUrl(QExtFileInfo::toRelative(url, baseURL, false))); + dom.firstChild().firstChild().appendChild(el); + m_projectFiles.insert( new ProjectURL(url, "", 1, false, el) ); + emit eventHappened("after_project_add", url.url(), QString::null); + m_modified = true; + } + } + progressBar->advance(1); + } + progressBar->setTotalSteps(1); + progressBar->setValue(0); + progressBar->setTextEnabled(false); + + parent->reloadTree(&(m_projectFiles), false, QStringList()); + parent->newStatus(); + parent->statusMsg(QString::null); +} + + +/** insert files from dir recursive */ +void ProjectPrivate::insertFiles(const KURL& pathURL, const QString& mask ) +{ + KURL::List list; + + list.append(pathURL); + list += QExtFileInfo::allFiles(pathURL, mask, m_mainWindow); + insertFiles(list); +} + + +void ProjectPrivate::loadProjectXML() +{ +//TODO: Optimize reading. For example iterate through all the nodes and handle them +//according to the found node type + parent->statusMsg( i18n("Reading the project file...") ); + QDomNode no; + QDomElement el; + KURL url; + QDomNode projectNode = dom.firstChild().firstChild(); + projectName = projectNode.toElement().attribute("name"); + + if ( projectNode.isNull() || projectName.isEmpty() ) + { + parent->hideSplash(); + KMessageBox::sorry(m_mainWindow, i18n("Invalid project file.") ); + adjustActions(); + return; + } + + m_modified = false; + QString tmpString; + QDomNode sessionNode; + + if (!m_createSessionDom) + { + sessionNode = m_sessionDom.firstChild().firstChild(); + tmpString = sessionNode.toElement().attribute("previewPrefix"); + if ( !tmpString.isEmpty()) + { + previewPrefix = KURL::fromPathOrURL(tmpString); + } + usePreviewPrefix = ( sessionNode.toElement().attribute("usePreviewPrefix") == "1"); + m_persistentBookmarks = (sessionNode.toElement().attribute("usePersistentBookmarks") == "1"); + } else //TODO: Remove when upgrade from 3.4 is not supported + { + tmpString = projectNode.toElement().attribute("previewPrefix"); + if ( !tmpString.isEmpty()) + { + previewPrefix = KURL::fromPathOrURL(tmpString); + } + usePreviewPrefix = ( projectNode.toElement().attribute("usePreviewPrefix") == "1"); + m_persistentBookmarks = (projectNode.toElement().attribute("usePersistentBookmarks") == "1"); + + sessionNode = m_sessionDom.firstChild().firstChild(); + sessionNode.toElement().setAttribute("usePreviewPrefix", usePreviewPrefix ? "1" : "0"); + sessionNode.toElement().setAttribute("previewPrefix", previewPrefix.url()); + sessionNode.toElement().setAttribute("usePersistentBookmarks", m_persistentBookmarks ? "1" : "0"); + } + no = sessionNode.namedItem("itemcursorpositions"); + if (no.isNull()) + { + el = m_sessionDom.createElement("itemcursorpositions"); + sessionNode.appendChild(el); + } + m_eventsEnabled = projectNode.toElement().attribute("enableEvents", "true") == "true"; + m_defaultEncoding = projectNode.toElement().attribute("encoding"); + if (m_defaultEncoding.isEmpty()) + { + m_defaultEncoding = qConfig.defaultEncoding; + } + no = projectNode.namedItem("author"); + author = no.firstChild().nodeValue(); + no = projectNode.namedItem("email"); + email = no.firstChild().nodeValue(); + no = projectNode.namedItem("defaultDTD"); + m_defaultDTD = no.firstChild().nodeValue(); + if (m_defaultDTD.isEmpty()) m_defaultDTD = qConfig.defaultDocType; + + no = projectNode.namedItem("autoload"); + currentProjectView = no.toElement().attribute("projectview"); + if (currentProjectView.isEmpty()) + { + QStringList list = projectViewList(); + if (list.count() > 0) + currentProjectView = list[0]; + } + // Debugger + no = projectNode.namedItem("debuggerclient"); + debuggerClient = no.firstChild().nodeValue(); + m_debuggerPersistentBreakpoints = (no.toElement().attribute("persistentBreakpoints") == "1"); + m_debuggerPersistentWatches = (no.toElement().attribute("persistentWatches") == "1"); + + no = projectNode.namedItem("templates"); + tmpString = no.firstChild().nodeValue(); + templateURL = baseURL; + if(no.isNull()) // compatability + { + templateURL.setPath("templates/"); + m_modified = true; + } + else + { + QuantaCommon::setUrl(templateURL, tmpString); + } + if (tmpString != QuantaCommon::qUrl(templateURL) ) + { + el = no.toElement(); + url = QExtFileInfo::toRelative(templateURL, baseURL); + if(el.isNull()) + { + el = dom.createElement("templates"); + dom.firstChild().firstChild().appendChild(el); + el.appendChild(dom.createTextNode(QuantaCommon::qUrl(url))); + } + else + { + el.firstChild().setNodeValue(QuantaCommon::qUrl(url)); + } + } + templateURL = QExtFileInfo::toAbsolute(templateURL, baseURL); + + no = projectNode.namedItem("toolbars"); + toolbarURL = baseURL; + if (no.isNull()) // compatability + { + toolbarURL.setPath(baseURL.path(1) + "toolbars/"); + m_modified = true; + } + else + { + QuantaCommon::setUrl(toolbarURL,no.firstChild().nodeValue()); + } + if (tmpString != QuantaCommon::qUrl(toolbarURL)) + { + el = no.toElement(); + url = QExtFileInfo::toRelative(toolbarURL, baseURL); + if(el.isNull()) + { + el = dom.createElement("toolbars"); + dom.firstChild().firstChild().appendChild(el); + el.appendChild(dom.createTextNode(QuantaCommon::qUrl(url))); + } + else + { + el.firstChild().setNodeValue(QuantaCommon::qUrl(url)); + } + } + toolbarURL = QExtFileInfo::toAbsolute(toolbarURL, baseURL); + + no = projectNode.namedItem("exclude"); + m_excludeCvsignore = (no.toElement().attribute("cvsignore", "false") == "true"); + QString excludeStr = no.firstChild().nodeValue(); + QString regExpStr = ""; + excludeList = QStringList::split(';', excludeStr); + for (uint i = 0; i < excludeList.count(); i++) + { + excludeStr = excludeList[i].stripWhiteSpace(); + QString str = excludeStr; + if (!excludeStr.startsWith("*")) + { + if (!excludeStr.endsWith("*")) + str += "|^" + excludeStr + "/*|*/" + excludeStr + "/*|*/" + excludeStr + "$"; + else + str += "|^" + excludeStr + "|*/" + excludeStr + "$"; + } else + if (!excludeStr.endsWith("*")) + str = excludeStr + "/*|"+ excludeStr + "$"; + str.replace(".","\\."); + str.replace("*",".*"); + str.replace("?","."); + regExpStr.append(str); + if (i+1 < excludeList.count()) + regExpStr.append("|"); + } + QDomNodeList nl = dom.firstChild().firstChild().childNodes(); + if (m_excludeCvsignore && projectURL.isLocalFile()) + { + QStringList cvsIgnoreList; + uint nlCount = nl.count(); + for ( uint i = 0; i < nlCount; i++ ) + { + el = nl.item(i).toElement(); + tmpString = el.attribute("url"); + if (!tmpString.endsWith("/")) continue; + cvsIgnoreList.append(tmpString); + } + cvsIgnoreList.append(""); + for (QStringList::ConstIterator it = cvsIgnoreList.constBegin(); it != cvsIgnoreList.constEnd(); ++it) + { + tmpString = *it; + QString rxStr; + KURL cvsIgnoreURL; + cvsIgnoreURL.setPath(baseURL.path(1) + tmpString + ".cvsignore"); + QFile f(cvsIgnoreURL.path()); + if (f.open(IO_ReadOnly)) + { + QTextStream stream(&f); + stream.setEncoding(QTextStream::UnicodeUTF8); + QString line; + while (!stream.atEnd()) + { + line = stream.readLine().stripWhiteSpace(); + line.prepend(tmpString); + if (!line.endsWith("*")) + line = line + "/*|"+ line + "$"; + if (!line.startsWith("*")) + line.prepend("^"); + line.replace(".","\\."); + line.replace("*",".*"); + line.replace("?","."); + rxStr += line + "|"; + } + regExpStr.prepend(rxStr); + f.close(); + } + } + } + excludeRx.setPattern(regExpStr); + + m_events->clear(); + nl = projectNode.toElement().elementsByTagName("event"); + uint nlCount = nl.count(); + for ( uint i = 0; i < nlCount; i++ ) + { + el = nl.item(i).toElement(); + EventAction ev; + if (el.attribute("type", "internal") == "internal") + ev.type = EventAction::Internal; + else + ev.type = EventAction::External; + ev.action = el.attribute("action"); + QDomNodeList nl2 = el.elementsByTagName("argument"); + for (uint j = 0; j < nl2.count(); j++) + { + QString s = nl2.item(j).toElement().text(); + if (s != "--not set--" && !s.isEmpty()) + ev.arguments << s; + } + if (m_events->contains(el.attribute("name"))) + { + (*m_events)[el.attribute("name")].append(ev); + } else + { + QValueList<EventAction> evList; + evList.append(ev); + m_events->insert(el.attribute("name"), evList); + } + } + + QDomNode teamNode = projectNode.namedItem("teamdata"); + no = teamNode.namedItem("leader"); + if (!no.isNull()) + { + m_teamLeader.name = no.namedItem("name").toElement().text(); + m_teamLeader.nickName = no.namedItem("nickName").toElement().text(); + m_teamLeader.email = no.namedItem("email").toElement().text(); + } + + m_subprojects.clear(); + m_subprojectLeaders.clear(); + no = teamNode.namedItem("subprojectleaders"); + nl = no.toElement().elementsByTagName("subproject"); + for (uint i = 0; i < nl.count(); i++) + { + el = nl.item(i).toElement(); + QDomElement el2 = el.namedItem("subprojectleader").toElement(); + TeamMember member; + member.name = el2.attribute("name"); + member.nickName = el2.attribute("nickName"); + member.email = el2.attribute("email"); + SubProject subproject; + subproject.name = el.attribute("name"); + subproject.location = el.attribute("location"); + m_subprojects.append(subproject); + m_subprojectLeaders[subproject.name] = member; + } + + m_taskLeaders.clear(); + no = teamNode.namedItem("taskleaders"); + nl = no.toElement().elementsByTagName("projecttask"); + for (uint i = 0; i < nl.count(); i++) + { + el = nl.item(i).toElement(); + TeamMember member; + member.name = el.attribute("tasklead"); + member.nickName = el.attribute("nickName"); + member.email = el.attribute("email"); + m_taskLeaders[el.attribute("task")] = member; + } + + m_simpleMembers.clear(); + nl = teamNode.toElement().elementsByTagName("member"); + for (uint i = 0; i < nl.count(); i++) + { + el = nl.item(i).toElement(); + TeamMember member; + member.name = el.namedItem("name").toElement().text(); + member.nickName = el.namedItem("nickName").toElement().text(); + member.email = el.namedItem("email").toElement().text(); + member.task = el.attribute("task"); + m_simpleMembers.append(member); + } + + no = teamNode.namedItem("mailinglist"); + m_mailingList = no.toElement().attribute("address"); + teamNode = m_sessionDom.firstChild().namedItem("teamdata"); + m_yourself = teamNode.toElement().attribute("yourself"); + + if (m_projectFiles.readFromXML(dom, baseURL, templateURL, excludeRx)) + m_modified = true; + QDomNode uploadNode; + if (!m_createSessionDom) + { + uploadNode = sessionNode.namedItem("uploadprofiles"); + } else + { + uploadNode = projectNode.namedItem("uploadprofiles").cloneNode(true); + sessionNode.appendChild(uploadNode); + } + + QDomElement uploadEl = uploadNode.toElement(); + m_showUploadTreeviews = uploadEl.attribute("showtreeviews", "true") == "true"; + if (m_showUploadTreeviews) + { + // read the profiles and create treeviews for them + UploadProfiles::ref()->readFromXML(m_sessionDom); + } else + UploadProfiles::ref()->clear(); + + if (m_createSessionDom) + { + QDomNode node; + node = projectNode.namedItem("treestatus").cloneNode(true); + sessionNode.appendChild(node); + node = projectNode.namedItem("debuggers").cloneNode(true); + sessionNode.appendChild(node); + } + + + parent->statusMsg(QString::null); + parent->newProjectLoaded(projectName, baseURL, templateURL); + parent->reloadTree(&(m_projectFiles), true, treeStatusFromXML()); + parent->newStatus(); + adjustActions(); +} + +void ProjectPrivate::slotAcceptCreateProject() +{ + bool errorOccured = false; + + projectName = png->linePrjName->text(); + QString basePath = png->linePrjDir ->text(); + + KURL oldBaseURL = baseURL; + baseURL = KURL::fromPathOrURL(basePath); + if (baseURL.isLocalFile()) + { + QString path = QDir(baseURL.path()).canonicalPath(); + if (baseURL.path().endsWith("/")) + path.append("/"); + if (!path.isEmpty()) + baseURL.setPath(path); + } + /* + it is important to set the fields only if there is some input + otherwise you set them to an empty string and the treeview will + not recognize it as parent url because: + QString::Null != "" + */ + if (!png->lineHost->text().isEmpty()) + baseURL.setHost(png->lineHost->text()); + if (!png->lineUser->text().isEmpty()) + baseURL.setUser(png->lineUser->text()); + if (!png->linePasswd->text().isEmpty()) + baseURL.setPass(png->linePasswd->text()); + if (!png->linePort->text().isEmpty()) + baseURL.setPort(png->linePort->text().toInt()); + if (!png->comboProtocol->currentText().isEmpty()) + baseURL.setProtocol(png->comboProtocol->currentText()); + if (baseURL.protocol() == i18n("Local")) baseURL.setProtocol("file"); + baseURL.adjustPath(1); + if (!baseURL.path().startsWith("/")) baseURL.setPath("/"+ baseURL.path()); + if (!QExtFileInfo::createDir(baseURL, m_mainWindow)) + { + QuantaCommon::dirCreationError(m_mainWindow, baseURL); + baseURL = oldBaseURL; + } else + { + projectURL = baseURL; + projectURL.setPath(baseURL.path(1) + png->linePrjFile->text()); + + errorOccured = !createEmptyDom(); + if (!errorOccured) + { + email = pnf->lineEmail->text(); + author = pnf->lineAuthor->text(); + m_defaultDTD = DTDs::ref()->getDTDNameFromNickName(pnf->dtdCombo->currentText()); + m_defaultEncoding = pnf->encodingCombo->currentText(); + + previewPrefix = KURL::fromPathOrURL( pnf->linePrefix->text() ); + usePreviewPrefix = pnf->checkPrefix->isChecked(); + + QDomElement el; + KURL url; + + el = dom.firstChild().firstChild().toElement(); + el.setAttribute("type", png->type()); + el.setAttribute("name", projectName ); + el.setAttribute("encoding", m_defaultEncoding); + + el = m_sessionDom.firstChild().firstChild().toElement(); + el.setAttribute("previewPrefix", previewPrefix.url() ); + el.setAttribute("usePreviewPrefix",usePreviewPrefix); + + el = dom.createElement("author"); + dom.firstChild().firstChild().appendChild( el ); + el.appendChild( dom.createTextNode( author ) ); + + el = dom.createElement("email"); + dom.firstChild().firstChild().appendChild( el ); + el.appendChild( dom.createTextNode( email ) ); + + el = dom.createElement("defaultDTD"); + dom.firstChild().firstChild().appendChild(el); + el.appendChild(dom.createTextNode(m_defaultDTD)); + + KURL::List list; + if ( png->type() == "Local" ) list = pnl->files(); + if ( png->type() == "Web" ) list = pnw->files(); + + for ( KURL::List::Iterator it = list.begin(); it != list.end(); ++it ) + { + url = *it;//QExtFileInfo::toRelative(*it, baseURL ); + el = dom.createElement("item"); + el.setAttribute("url",QuantaCommon::qUrl(url)); + dom.firstChild().firstChild().appendChild( el ); + } + + // el = dom.createElement("item"); + // el.setAttribute("url","templates/"); + // dom.firstChild().firstChild().appendChild(el); + + //setup the templates directory + templateURL = baseURL; + bool createTemplateDir = true; + if (pnf->insertGlobalTemplates->isChecked()) + { + KURL url; + QuantaCommon::setUrl(url, qConfig.globalDataDir + resourceDir + "templates/"); + parent->slotAddDirectory(url, false); + QuantaCommon::setUrl(templateURL, "templates/"); + createTemplateDir = false; + } + if (pnf->insertLocalTemplates->isChecked()) + { + KURL url; + QuantaCommon::setUrl(url, locateLocal("data", resourceDir + "templates/")); + parent->slotAddDirectory(url, false); + QuantaCommon::setUrl(templateURL, "templates/"); + createTemplateDir = false; + } + + if (createTemplateDir) + { + QuantaCommon::setUrl(templateURL, png->linePrjTmpl->text()); + templateURL.adjustPath(1); + templateURL = QExtFileInfo::toAbsolute(templateURL, baseURL); + if (!QExtFileInfo::createDir(templateURL, m_mainWindow)) + { + QuantaCommon::dirCreationError(m_mainWindow, templateURL); + } + } + //the nodes are already created in loadProjectXML() called from createEmptyDom() + el = dom.firstChild().firstChild().namedItem("templates").toElement(); + url = QExtFileInfo::toRelative(templateURL, baseURL); + el.firstChild().setNodeValue(QuantaCommon::qUrl(url)); + + //setup the toolbars directory + toolbarURL = baseURL; + QuantaCommon::setUrl(toolbarURL,png->linePrjToolbar->text()); + toolbarURL.adjustPath(1); + toolbarURL = QExtFileInfo::toAbsolute(toolbarURL, baseURL); + if (!QExtFileInfo::createDir(toolbarURL, m_mainWindow)) + { + QuantaCommon::dirCreationError(m_mainWindow, toolbarURL); + } + el = dom.firstChild().firstChild().namedItem("toolbars").toElement(); + url = QExtFileInfo::toRelative(toolbarURL, baseURL); + el.firstChild().setNodeValue(QuantaCommon::qUrl(url)); + +#if KDE_IS_VERSION(3,4,89) + m_projectRecent->addURL(projectURL, projectName); +#else + m_projectRecent->addURL(projectURL); +#endif + m_projectRecent->setCurrentItem(0); + // remember the project in config + writeConfig(); + +//workaround to load the newly created project items in the treeview + KURL u = projectURL; + slotCloseProject(); + loadProject(u); + } +} +if (errorOccured) +{ + slotCloseProject(); +} +} + + +/** Saves a project view (group of files & toolbars) without asking for a name. */ +void ProjectPrivate::slotSaveProjectView() +{ + slotSaveAsProjectView(currentProjectView.isEmpty()); +} + + +/** Deletes a project view */ +void ProjectPrivate::slotDeleteProjectView(const QString &view) +{ + QDomNodeList nl = dom.elementsByTagName("projectview"); + QDomElement el; + for (uint i = 0; i < nl.count(); i++) + { + QDomNode node = nl.item(i); + el = node.cloneNode().toElement(); + if (el.attribute("name") == view) + { + node.parentNode().removeChild(node); + if (currentProjectView == view) + currentProjectView = ""; + parent->setModified(); + adjustViewActions(); + break; + } + } +} + +/** Saves a project view (group of files & toolbars) asking for a name. */ +void ProjectPrivate::slotSaveAsProjectView(bool askForName) +{ + if (askForName) + { + bool ok; + QString newProjectView = KInputDialog::getText(i18n("Save Project View As"), + i18n("Enter the name of the view:"), "", &ok, m_mainWindow).lower(); + if (!ok) + return; + currentProjectView = newProjectView; + } + QDomNodeList nl = dom.elementsByTagName("projectview"); + for (uint i = 0 ;i < nl.count(); i++) + { + QDomNode node = nl.item(i); + if (node.toElement().attribute("name") == currentProjectView) + { + if (!askForName || + KMessageBox::warningContinueCancel(m_mainWindow, i18n("<qt>A project view named <b>%1</b> already exists.<br>Do you want to overwrite it?</qt>") + .arg(currentProjectView), QString::null, i18n("Overwrite")) == KMessageBox::Continue) + { + node.parentNode().removeChild(node); + break; + } else + { + return; + } + } + } + + QDomElement el = dom.createElement("projectview"); + el.setAttribute("name", currentProjectView); + QDomElement item; + KURL::List openURLs = ViewManager::ref()->openedFiles(true); // get open urls + KURL::List::Iterator it; + for ( it = openURLs.begin(); it != openURLs.end(); ++it ) + { + KURL url = (*it); + if (m_projectFiles.contains(url)) + { + item = dom.createElement("viewitem"); + item.setAttribute("url", QuantaCommon::qUrl(QExtFileInfo::toRelative(url, baseURL)) ); + el.appendChild(item); + } + } + + KURL::List toolbarList; + parent->getUserToolbarFiles(&toolbarList); + for (uint i =0 ; i < toolbarList.count(); i++) + { + item = dom.createElement("viewtoolbar"); + KURL url = toolbarList[i]; + url = QExtFileInfo::toRelative(url, baseURL); + item.setAttribute("url", QuantaCommon::qUrl(url) ); + el.appendChild(item); + } + + dom.firstChild().firstChild().appendChild( el ); + parent->setModified(); + adjustViewActions(); +} + + +void ProjectPrivate::slotSelectProjectType(const QString &title) +{ + if ( png->radioLocal->isChecked() ) stack->raiseWidget( 0 ); + if ( png->radioWeb ->isChecked() ) stack->raiseWidget( 1 ); + if ( title == m_wizTitle ) + emit setLocalFiles( pnl->checkInsert->isChecked() ); +} + + +bool ProjectPrivate::createEmptyDom() +{ + QString str; + QTextStream stream(&str, IO_WriteOnly); + stream.setEncoding(QTextStream::UnicodeUTF8); + + stream << "<!DOCTYPE webproject ><webproject>" << endl; + stream << "\t<project name=\"" << projectName << "\">" << endl; + stream << "\t\t<upload />" << endl; + stream << "\t</project>" << endl; + stream << "</webproject>" << endl; + + QString sessionStr; + QTextStream sessionStream(&sessionStr, IO_WriteOnly); + sessionStream.setEncoding(QTextStream::UnicodeUTF8); + + sessionStream << "<!DOCTYPE webprojectsession ><webprojectsession>" << endl; + sessionStream << "\t<session>" << endl; + sessionStream << "\t</session>" << endl; + sessionStream << "</webprojectsession>" << endl; + + KURL sessionURL = projectURL; + QString fileName = projectURL.fileName(); + if (fileName.endsWith(".webprj")) + fileName.replace(".webprj", ".session"); + else + fileName += ".session"; + sessionURL.setFileName(fileName); + + bool result = true; + + if (!projectURL.isLocalFile()) + { + tempFile = new KTempFile(tmpDir); // tempFile will get deleted in slotProjectClose() + tempFile->setAutoDelete(true); + tempFile->textStream()->setEncoding(QTextStream::UnicodeUTF8); + *(tempFile->textStream()) << str; + tempFile->close(); + result = QExtFileInfo::createDir(baseURL, m_mainWindow); + if (result) + result = KIO::NetAccess::upload(tempFile->name(), projectURL, m_mainWindow); + if (result) + m_tmpProjectFile = tempFile->name(); + + sessionTempFile = new KTempFile(tmpDir); // sessionTempFile will get deleted in slotProjectClose() + sessionTempFile->setAutoDelete(true); + sessionTempFile->textStream()->setEncoding(QTextStream::UnicodeUTF8); + *(sessionTempFile->textStream()) << sessionStr; + sessionTempFile->close(); + result = KIO::NetAccess::upload(sessionTempFile->name(), sessionURL, m_mainWindow); + if (result) + m_tmpSessionFile= sessionTempFile->name(); + } else + { + QFile f(projectURL.path()); + if (f.open( IO_WriteOnly )) + { + QTextStream fstream(&f); + fstream.setEncoding(QTextStream::UnicodeUTF8); + fstream << str; + m_tmpProjectFile = projectURL.path(); // we are local: the temp file and the projectURL are the same + } else + { + result = false; + } + f.close(); + if (result) + { + f.setName(sessionURL.path()); + if (f.open(IO_WriteOnly)) + { + QTextStream fstream(&f); + fstream.setEncoding(QTextStream::UnicodeUTF8); + fstream << sessionStr; + m_tmpSessionFile = sessionURL.path(); // we are local: the temp file and the projectURL are the same + } else + { + result = false; + } + f.close(); + } + } + + if (!result) + { + parent->hideSplash(); + KMessageBox::sorry(m_mainWindow, i18n("<qt>Cannot open file <b>%1</b> for writing.</qt>").arg(projectURL.prettyURL(0, KURL::StripFileProtocol))); + delete tempFile; + tempFile = 0L; + delete sessionTempFile; + sessionTempFile = 0L; + return false; + } + + dom.setContent(str); + m_sessionDom.setContent(sessionStr); + m_projectFiles.clear(); + return true; +} + + +QStringList ProjectPrivate::treeStatusFromXML() +{ + QStringList folderList; + QDomNodeList nl = m_sessionDom.elementsByTagName("treestatus"); + if (nl.count() > 0) { + nl = nl.item(0).childNodes(); + for ( unsigned int i = 0; i < nl.count(); i++ ) + { + QString urlString = nl.item(i).toElement().attribute("url"); + folderList.append( baseURL.url(1) + urlString); + } + } + return folderList; +} + + +void ProjectPrivate::getStatusFromTree() +{ + // remove old status + QDomNodeList nl = m_sessionDom.elementsByTagName("treestatus"); + QDomElement el; + for ( unsigned int i = 0; i < nl.count(); i++ ) + { + el = nl.item(i).toElement(); + el.parentNode().removeChild( el ); + i--; + } + QStringList folderList; + parent->getTreeStatus( &folderList ); + // toplevel folder is always open in a project and QExtFileInfo::toRelative + // creates strange output -> we remove the toplevel folder + if (folderList.count() > 0) + folderList.remove(folderList.begin()); + if (folderList.count() > 0) { + // create the root element + QDomElement root = m_sessionDom.createElement("treestatus"); + m_sessionDom.firstChild().firstChild().appendChild(root); + for (QStringList::Iterator it = folderList.begin(); it != folderList.end(); ++it) { + el = m_sessionDom.createElement("openfolder"); + el.setAttribute("url", QuantaCommon::qUrl( QExtFileInfo::toRelative(KURL(*it), baseURL) ) ); + root.appendChild( el ); + } + } +} + + +/** create new project */ +void ProjectPrivate::slotNewProject() +{ + QWizard *wiz = new QWizard(m_mainWindow, "new", true); + wiz->setCaption(i18n("New Project Wizard")); + wiz->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); + + png = new ProjectNewGeneral(0L); + + stack = new QWidgetStack(0L); + + pnl = new ProjectNewLocal(stack); + pnw = new ProjectNewWeb(stack); + pnf = new ProjectNewFinal(0L); + + stack->addWidget( pnl, 0); + stack->addWidget( pnw, 1 ); + + wiz->addPage( png, i18n("<b>General Project Settings</b>")); + wiz->addPage( stack, m_wizTitle ); + wiz->addPage( pnf, i18n("<b>More Project Settings</b>")); + + wiz->setNextEnabled ( png, false ); + wiz->setBackEnabled ( stack, true ); + wiz->setNextEnabled ( stack, true ); + wiz->setNextEnabled ( pnf, false ); + wiz->setFinishEnabled( pnf, true ); + + connect( png, SIGNAL(enableNextButton(QWidget *,bool)), + wiz, SLOT(setNextEnabled(QWidget*,bool))); + connect( png, SIGNAL(setBaseURL(const KURL&)), + pnl, SLOT( setBaseURL(const KURL&))); + connect( png, SIGNAL(setBaseURL(const KURL&)), + pnw, SLOT( setBaseURL(const KURL&))); + connect( this,SIGNAL(setLocalFiles(bool)), + pnl, SLOT(slotSetFiles(bool))); + + connect(wiz, SIGNAL(selected(const QString &)), + this, SLOT (slotSelectProjectType(const QString &))); + connect(wiz, SIGNAL(helpClicked()), SLOT(slotNewProjectHelpClicked())); + + connect( pnw, SIGNAL(enableMessagesWidget()), + parent, SIGNAL(enableMessageWidget())); + connect( pnw, SIGNAL(messages(const QString&)), + parent, SLOT (slotGetMessages(const QString&))); + connect( pnw, SIGNAL(enableNextButton(QWidget *,bool)), + wiz, SLOT(setNextEnabled(QWidget*,bool))); + connect( pnw, SIGNAL(enableNextButton(QWidget *,bool)), + wiz, SLOT(setBackEnabled(QWidget*,bool))); + + QStringList lst = DTDs::ref()->nickNameList(true); + pnf->dtdCombo->insertStringList(lst); + QString defaultDTDName = DTDs::ref()->getDTDNickNameFromName(qConfig.defaultDocType.lower()); + int pos = lst.findIndex(defaultDTDName); + if (pos >= 0) + pnf->dtdCombo->setCurrentItem(pos); + + QStringList availableEncodingNames(KGlobal::charsets()->availableEncodingNames()); + pnf->encodingCombo->insertStringList( availableEncodingNames ); + QStringList::ConstIterator iter; + int iIndex = -1; + for (iter = availableEncodingNames.begin(); iter != availableEncodingNames.end(); ++iter) + { + ++iIndex; + if ((*iter).lower() == qConfig.defaultEncoding.lower()) + { + pnf->encodingCombo->setCurrentItem(iIndex); + break; + } + } + + png->linePrjName->setFocus(); + if (wiz->exec()) + { + slotCloseProject(); + slotAcceptCreateProject(); + } + delete wiz; + + adjustActions(); + parent->newStatus(); +} + +/** close project and edited files */ +void ProjectPrivate::slotCloseProject() +{ + if (!parent->hasProject()) return; + connect(ViewManager::ref(), SIGNAL(filesClosed(bool)), this, SLOT(slotProceedWithCloseProject(bool))); + parent->closeFiles(); +} + +void ProjectPrivate::slotProceedWithCloseProject(bool success) +{ + disconnect(ViewManager::ref(), SIGNAL(filesClosed(bool)), this, SLOT(slotProceedWithCloseProject(bool))); + if (!success) return; + emit eventHappened("before_project_close", baseURL.url(), QString::null); + if (!uploadProjectFile()) + { + if (KMessageBox::warningContinueCancel(m_mainWindow, i18n("Saving of project failed. Do you want to continue with closing (might cause data loss)?"), i18n("Project Saving Error"), KStdGuiItem::close()) == KMessageBox::Cancel) + return; + } + emit eventHappened("after_project_close", baseURL.url(), QString::null); + // empty dom tree + dom.clear(); + m_sessionDom.clear(); + m_events->clear(); + config->setGroup("Projects"); + config->writePathEntry("Last Project", QString::null); + init(); + parent->newProjectLoaded(projectName, baseURL, templateURL); + parent->reloadTree( &(m_projectFiles), true, QStringList()); + adjustActions(); + m_projectRecent->setCurrentItem(-1); + parent->newStatus(); + kapp->processEvents(QEventLoop::ExcludeUserInput | QEventLoop::ExcludeSocketNotifiers); +} + + +/** open project file */ +void ProjectPrivate::slotOpenProject() +{ + KURL url = KFileDialog::getOpenURL( QString::null, + "*.wpj *.webprj"+i18n("|Project Files\n*|All Files"), m_mainWindow, + i18n("Open Project")); + + if( !url.isEmpty() ) + { + loadProject ( url ); + } +} + + +/* save project file */ +bool ProjectPrivate::saveProject() +{ + if ( !parent->hasProject() ) return false; + bool result = true; + // remove old opened files + QDomElement el; + QDomNodeList nl = dom.firstChild().firstChild().childNodes(); + + for ( unsigned int i = 0; i < nl.count(); i++ ) + { + el = nl.item(i).toElement(); + if ( el.nodeName() == "openfile" ) + { + el.parentNode().removeChild( el ); + i--; + } + } + getStatusFromTree(); + QFile f(m_tmpProjectFile); + if (f.open(IO_WriteOnly)) + { + QTextStream stream( &f ); + stream.setEncoding(QTextStream::UnicodeUTF8); + dom.save(stream, 2); + f.close(); + f.setName(m_tmpSessionFile); + if (f.open(IO_WriteOnly)) + { + QTextStream stream(&f); + stream.setEncoding(QTextStream::UnicodeUTF8); + m_sessionDom.save(stream, 2); + f.close(); + } + m_modified = false; + parent->statusMsg(i18n( "Wrote project file %1" ).arg(m_tmpProjectFile)); + } else + { + parent->hideSplash(); + KMessageBox::error(m_mainWindow, i18n("<qt>Cannot open the file <b>%1</b> for writing.</qt>").arg(m_tmpProjectFile)); + result = false; + } + return result; +} + + +void ProjectPrivate::loadProjectFromTemp(const KURL &url, const QString &tempFile, const QString &sessionTempFile) +{ + m_createSessionDom = true; + m_tmpProjectFile = tempFile; + if (!sessionTempFile.isEmpty()) + m_tmpSessionFile = sessionTempFile; + projectURL = url; + QFile f(tempFile); + if (f.open(IO_ReadOnly)) + { + baseURL = url; + baseURL.setPath(url.directory(true, true)); + if (baseURL.isLocalFile()) + { + QDir dir(baseURL.path()); + baseURL.setPath(dir.canonicalPath()); + baseURL.adjustPath(-1); + } + dom.setContent(&f); + f.close(); + if (!sessionTempFile.isEmpty()) + { + f.setName(sessionTempFile); + if (f.open(IO_ReadOnly)) + { + m_sessionDom.setContent(&f); + m_createSessionDom = false; + f.close(); + } + } + loadProjectXML(); + openCurrentView(); +#if KDE_IS_VERSION(3,4,89) + kdDebug(24000) << "Add recent project: " << url << " : projectName= " << projectName << endl; + m_projectRecent->addURL(url, projectName); +#else + m_projectRecent->addURL( url ); +#endif + m_projectRecent->setCurrentItem(0); + // remember the project in config + writeConfig(); + } else + { + parent->hideSplash(); + KMessageBox::error(m_mainWindow, i18n("<qt>Cannot open the file <b>%1</b> for reading.</qt>").arg(tempFile)); + } +} + +/** load project from file: url */ +bool ProjectPrivate::loadProject(const KURL &url) +{ + if (projectURL == url) + return true; + if (!url.isValid()) + { + parent->hideSplash(); + KMessageBox::sorry(m_mainWindow, i18n("<qt>Malformed URL: <b>%1</b></qt>").arg(url.prettyURL())); + return false; + } + if ( projectAlreadyOpen(url.url()) ) + { + parent->hideSplash(); + if (KMessageBox::warningContinueCancel(m_mainWindow, i18n("<qt>The project<br><b>%1</b><br> seems to be used by another Quanta instance.<br>You may end up with data loss if you open the same project in two instances, modify and save them in both.<br><br>Do you want to proceed with open?</qt>").arg(url.prettyURL()), QString::null, KStdGuiItem::open()) == KMessageBox::Cancel) + return false; + } + QString projectTmpFile; + QString sessionTmpFile; + + // test if url is writeable and download to local file + if (KIO::NetAccess::exists(url, false, m_mainWindow) && + KIO::NetAccess::download(url, projectTmpFile, m_mainWindow)) + { + if (parent->hasProject()) + { + slotCloseProject(); + } + KURL sessionURL = url; + QString fileName = url.fileName(); + if (fileName.endsWith(".webprj")) + fileName.replace(".webprj", ".session"); + else + fileName += ".session"; + sessionURL.setFileName(fileName); + if (KIO::NetAccess::exists(sessionURL, false, m_mainWindow)) + KIO::NetAccess::download(sessionURL, sessionTmpFile, m_mainWindow); + else + { + QString sessionStr; + QTextStream sessionStream(&sessionStr, IO_WriteOnly); + sessionStream.setEncoding(QTextStream::UnicodeUTF8); + + sessionStream << "<!DOCTYPE webprojectsession ><webprojectsession>" << endl; + sessionStream << "\t<session>" << endl; + sessionStream << "\t</session>" << endl; + sessionStream << "</webprojectsession>" << endl; + if (!sessionURL.isLocalFile()) + { + sessionTempFile = new KTempFile(tmpDir); // sessionTempFile will get deleted in slotProjectClose() + sessionTempFile->setAutoDelete(true); + sessionTempFile->textStream()->setEncoding(QTextStream::UnicodeUTF8); + *(sessionTempFile->textStream()) << sessionStr; + sessionTempFile->close(); + m_tmpSessionFile = sessionTempFile->name(); + } else + { + QFile f(sessionURL.path()); + if (f.open(IO_WriteOnly)) + { + QTextStream fstream(&f); + fstream.setEncoding(QTextStream::UnicodeUTF8); + fstream << sessionStr; + m_tmpSessionFile = sessionURL.path(); // we are local: the temp file and the projectURL are the same + } + f.close(); + } + m_sessionDom.setContent(sessionStr); + } + loadProjectFromTemp(url, projectTmpFile, sessionTmpFile); + } else + { + parent->hideSplash(); + KMessageBox::error(m_mainWindow, i18n("<qt>Cannot access the project file <b>%1</b>.</qt>").arg(url.prettyURL(0, KURL::StripFileProtocol))); + return false; + } + return true; +} + + +/** dialog for add files */ +void ProjectPrivate::slotAddFiles() +{ + KURL::List list = KFileDialog::getOpenURLs( + baseURL.url(), i18n("*"), m_mainWindow, i18n("Insert Files in Project")); + + if ( !list.isEmpty() ) + { + KURL firstURL = list.first(); + firstURL = QExtFileInfo::toRelative( firstURL, baseURL ); + + if ( firstURL.path().startsWith("/") || firstURL.path().startsWith(".")) + { + KURLRequesterDlg *urlRequesterDlg = new KURLRequesterDlg( baseURL.prettyURL(), m_mainWindow, ""); + urlRequesterDlg->setCaption(i18n("Files: Copy to Project")); + urlRequesterDlg->urlRequester()->setMode( KFile::Directory | KFile::ExistingOnly); + urlRequesterDlg->exec(); + KURL destination = urlRequesterDlg->selectedURL(); + delete urlRequesterDlg; + + if ( !destination.isEmpty()) + { + CopyTo *dlg = new CopyTo( baseURL); + connect(dlg, SIGNAL(deleteDialog(CopyTo*)), + SLOT (slotDeleteCopytoDlg(CopyTo*))); + connect(dlg, SIGNAL(addFilesToProject(const KURL::List&)), parent, + SLOT (slotInsertFilesAfterCopying(const KURL::List&))); + list = dlg->copy( list, destination ); + return; + } + else { + return; + } + } + + insertFiles( list ); + //Take care also of the selected dirs + KURL dirURL; + for (uint i = 0; i < list.count(); i++) + { + dirURL = list[i]; + if (dirURL.path().endsWith("/")) + { + insertFiles( dirURL, "*" ); + } + } + + parent->reloadTree( &(m_projectFiles), false, QStringList()); + } +} + + +void ProjectPrivate::slotDeleteCopytoDlg(CopyTo *dlg) +{ +//The CopyTo dlg is deleted only here!! + delete dlg; +} + + +void ProjectPrivate::slotAddDirectory() +{ + KURL url = KURL(); + url = KFileDialog::getExistingURL(baseURL.prettyURL(), m_mainWindow, + i18n("Insert Folder in Project")); + parent->slotAddDirectory(url); +} + + +void ProjectPrivate::slotDebuggerOptions() +{ + // Debuggers Combo + KTrader::OfferList offers = KTrader::self()->query("Quanta/Debugger"); + KTrader::OfferList::ConstIterator iterDbg; + for(iterDbg = offers.begin(); iterDbg != offers.end(); ++iterDbg) + { + KService::Ptr service = *iterDbg; + if(m_debuggerClientEdit == service->name()) + { + DebuggerClient *dbg = 0L; + int errCode = 0; +//Workaround for dynamic_cast not working correctly on SUSE 10, gcc 4.0.2 +//The correct way should be a simple: +// DebuggerClient *dbg = KParts::ComponentFactory::createInstanceFromService<DebuggerClient>(service, this, 0, QStringList(), &errCode); + QObject* obj = KParts::ComponentFactory::createInstanceFromService<QObject>(service, this, 0, QStringList(), &errCode); + if (obj && obj->inherits("DebuggerClient")) + dbg = static_cast<DebuggerClient *>(obj); + if (dbg) + { + QDomNode projectNode = m_sessionDom.firstChild().firstChild(); + QDomNode nodeThisDbg; + QDomNode nodeDbg = projectNode.namedItem("debuggers"); + if(nodeDbg.isNull()) + { + nodeDbg = m_sessionDom.createElement("debuggers"); + projectNode.appendChild(nodeDbg); + } + + nodeThisDbg = nodeDbg.namedItem(service->name()); + if(nodeThisDbg.isNull()) + { + nodeThisDbg = m_sessionDom.createElement(service->name()); + nodeDbg.appendChild(nodeThisDbg); + } + dbg->showConfig(nodeThisDbg); + delete dbg; + } + else + { + parent->hideSplash(); + KMessageBox::error(NULL, i18n("<qt>Unable to load the debugger plugin, error code %1 was returned: <b>%2</b>.</qt>").arg(errCode).arg(KLibLoader::self()->lastErrorMessage()), i18n("Debugger Error")); + } + } + } +} + +void ProjectPrivate::slotDebuggerChanged(const QString &debugger) +{ + m_debuggerClientEdit = debugger; +} + + +void ProjectPrivate::writeConfig() +{ + config->reparseConfiguration(); + config->setGroup("Projects"); + // remember the last project in config + KURL url = projectURL.url(); + url.setPass(""); + config->writePathEntry("Last Project", url.url()); + // add project to list + if (!projectURL.isEmpty()) + { + QStringList projectList = QuantaCommon::readPathListEntry(config, "OpenProjects"); + if (projectList.contains( projectURL.url() ) == 0) + { + projectList.append( projectURL.url() ); + config->writePathEntry("OpenProjects", projectList); + // add the temp file to list + projectList = QuantaCommon::readPathListEntry(config, "ProjectTempFiles"); + projectList.append(KURL::fromPathOrURL(m_tmpProjectFile).url()); + config->writePathEntry("ProjectTempFiles", projectList); + projectList = QuantaCommon::readPathListEntry(config, "ProjectSessionTempFiles"); + projectList.append(KURL::fromPathOrURL(m_tmpSessionFile).url()); + config->writePathEntry("ProjectSessionTempFiles", projectList); + } + } + // save recent projects + config->deleteGroup("RecentProjects"); + m_projectRecent->saveEntries(config, "RecentProjects"); + config->sync(); +} + + +void ProjectPrivate::removeFromConfig(const QString & urlStr) +{ + config->reparseConfiguration(); + config->setGroup("Projects"); + QStringList projectList = QuantaCommon::readPathListEntry(config, "OpenProjects"); + int i = projectList.findIndex( urlStr ); + if ( i > -1) + { + projectList.remove(projectList.at(i)); + config->writePathEntry("OpenProjects", projectList); + // remove the temp file from list + projectList = QuantaCommon::readPathListEntry(config, "ProjectTempFiles"); + projectList.remove(projectList.at(i)); + config->writePathEntry("ProjectTempFiles", projectList); + projectList = QuantaCommon::readPathListEntry(config, "ProjectSessionTempFiles"); + if (projectList.count() > (uint)i) + { + projectList.remove(projectList.at(i)); + config->writePathEntry("ProjectSessionTempFiles", projectList); + } + } + config->sync(); +} + + +bool ProjectPrivate::projectAlreadyOpen(const QString & urlStr) +{ + config->reparseConfiguration(); + config->setGroup("Projects"); + QStringList projectList = QuantaCommon::readPathListEntry(config, "OpenProjects"); + return (projectList.contains(urlStr) != 0); +} + + +/* uploads project file */ +bool ProjectPrivate::uploadProjectFile() +{ + if (m_tmpProjectFile.isNull() || !saveProject()) + return false; + KURL sessionURL = projectURL; + QString fileName = projectURL.fileName(); + if (fileName.endsWith(".webprj")) + fileName.replace(".webprj", ".session"); + else + fileName += ".session"; + sessionURL.setFileName(fileName); + + // no need to upload a local file because it is the same as the tempFile + if (projectURL.isLocalFile()) + { + removeFromConfig( projectURL.url() ); // remove the project from the list of open projects + // delete all temp files we used + delete tempFile; + tempFile = 0L; + delete sessionTempFile; + sessionTempFile = 0L; + m_tmpProjectFile = QString::null; + return true; + } + if (KIO::NetAccess::upload(m_tmpProjectFile, projectURL, m_mainWindow) && KIO::NetAccess::upload(m_tmpSessionFile, sessionURL, m_mainWindow)) + { + removeFromConfig(projectURL.url()); // remove the project from the list of open projects + if (quantaApp) + parent->statusMsg(i18n( "Uploaded project file %1" ).arg( projectURL.prettyURL())); + // delete all temp files we used + // first the one from creating a new project + delete tempFile; + tempFile = 0L; + delete sessionTempFile; + sessionTempFile = 0L; + // second the one from downloading a project + KIO::NetAccess::removeTempFile(m_tmpProjectFile); + KIO::NetAccess::removeTempFile(m_tmpSessionFile); + // third if we recovered after crash + KIO::NetAccess::del(KURL().fromPathOrURL(m_tmpProjectFile), m_mainWindow); + KIO::NetAccess::del(KURL().fromPathOrURL(m_tmpSessionFile), m_mainWindow); + m_tmpProjectFile = ""; + m_tmpSessionFile = ""; + } + else + { + if (quantaApp) + { + parent->statusMsg(QString::null ); + KMessageBox::error(m_mainWindow, KIO::NetAccess::lastErrorString()); + } + return false; + } + return true; +} + +void ProjectPrivate::slotNewProjectHelpClicked() +{ + kapp->invokeHelp("create-new-project-3-2", "quanta"); +} + +#include "projectprivate.moc" |