summaryrefslogtreecommitdiffstats
path: root/quanta/project
diff options
context:
space:
mode:
Diffstat (limited to 'quanta/project')
-rw-r--r--quanta/project/Makefile.am26
-rw-r--r--quanta/project/eventconfigurationdlg.cpp151
-rw-r--r--quanta/project/eventconfigurationdlg.h50
-rw-r--r--quanta/project/eventconfigurationdlgs.ui223
-rw-r--r--quanta/project/eventeditordlg.cpp407
-rw-r--r--quanta/project/eventeditordlg.h57
-rw-r--r--quanta/project/eventeditordlgs.ui236
-rw-r--r--quanta/project/membereditdlg.cpp183
-rw-r--r--quanta/project/membereditdlg.h40
-rw-r--r--quanta/project/membereditdlgs.ui196
-rw-r--r--quanta/project/project.cpp1428
-rw-r--r--quanta/project/project.h220
-rw-r--r--quanta/project/projectlist.cpp187
-rw-r--r--quanta/project/projectlist.h115
-rw-r--r--quanta/project/projectnewfinal.cpp42
-rw-r--r--quanta/project/projectnewfinal.h36
-rw-r--r--quanta/project/projectnewfinals.ui296
-rw-r--r--quanta/project/projectnewgeneral.cpp254
-rw-r--r--quanta/project/projectnewgeneral.h58
-rw-r--r--quanta/project/projectnewgenerals.ui454
-rw-r--r--quanta/project/projectnewlocal.cpp361
-rw-r--r--quanta/project/projectnewlocal.h57
-rw-r--r--quanta/project/projectnewlocals.ui344
-rw-r--r--quanta/project/projectnewweb.cpp245
-rw-r--r--quanta/project/projectnewweb.h75
-rw-r--r--quanta/project/projectnewwebs.ui292
-rw-r--r--quanta/project/projectoptions.ui540
-rw-r--r--quanta/project/projectoptions.ui.h52
-rw-r--r--quanta/project/projectprivate.cpp1675
-rw-r--r--quanta/project/projectprivate.h255
-rw-r--r--quanta/project/projectupload.cpp819
-rw-r--r--quanta/project/projectupload.h118
-rw-r--r--quanta/project/projectuploads.ui497
-rw-r--r--quanta/project/projecturl.h64
-rw-r--r--quanta/project/rescanprj.cpp249
-rw-r--r--quanta/project/rescanprj.h68
-rw-r--r--quanta/project/rescanprjdir.ui255
-rw-r--r--quanta/project/subprojecteditdlgs.ui73
-rw-r--r--quanta/project/teammembersdlg.cpp263
-rw-r--r--quanta/project/teammembersdlg.h52
-rw-r--r--quanta/project/teammembersdlgs.ui249
-rw-r--r--quanta/project/uploadprofiledlgs.ui310
-rw-r--r--quanta/project/uploadprofiles.cpp120
-rw-r--r--quanta/project/uploadprofiles.h108
-rw-r--r--quanta/project/uploadprofilespage.ui125
-rw-r--r--quanta/project/uploadprofilespage.ui.h31
46 files changed, 11956 insertions, 0 deletions
diff --git a/quanta/project/Makefile.am b/quanta/project/Makefile.am
new file mode 100644
index 00000000..f9a4248f
--- /dev/null
+++ b/quanta/project/Makefile.am
@@ -0,0 +1,26 @@
+noinst_LTLIBRARIES = libproject.la
+METASOURCES = AUTO
+
+libproject_la_SOURCES = projectoptions.ui projectnewgenerals.ui \
+ projectnewgeneral.cpp projectnewlocals.ui projectnewlocal.cpp rescanprj.cpp rescanprjdir.ui \
+ projectnewfinals.ui projectuploads.ui projectnewfinal.cpp projectupload.cpp project.cpp \
+ projectnewwebs.ui projectnewweb.cpp uploadprofiledlgs.ui projectlist.cpp \
+ membereditdlgs.ui teammembersdlgs.ui teammembersdlg.cpp membereditdlg.cpp \
+ subprojecteditdlgs.ui eventconfigurationdlgs.ui eventeditordlgs.ui eventconfigurationdlg.cpp \
+ eventeditordlg.cpp uploadprofiles.cpp uploadprofilespage.ui projectprivate.cpp
+
+AM_CPPFLAGS = -I$(top_srcdir)/quanta/utility \
+ -I$(top_srcdir)/quanta/parsers \
+ -I$(top_srcdir)/quanta/dialogs \
+ -I$(top_srcdir)/quanta/dialogs/tagdialogs \
+ -I$(top_srcdir)/quanta/treeviews \
+ -I$(top_srcdir)/quanta/src \
+ -I$(top_srcdir)/quanta/utility \
+ -I$(top_srcdir)/lib \
+ -I$(top_srcdir)/quanta/components/debugger \
+ -I$(top_srcdir)/quanta/components/debugger/interfaces \
+ -I$(top_builddir)/quanta/dialogs \
+ $(KMDI_INCLUDES) $(all_includes)
+
+noinst_HEADERS = teammembersdlg.h membereditdlg.h eventconfigurationdlg.h \
+ eventeditordlg.h
diff --git a/quanta/project/eventconfigurationdlg.cpp b/quanta/project/eventconfigurationdlg.cpp
new file mode 100644
index 00000000..e85ce7f6
--- /dev/null
+++ b/quanta/project/eventconfigurationdlg.cpp
@@ -0,0 +1,151 @@
+/***************************************************************************
+ eventconfigurationdlg.cpp - description
+ -------------------
+ begin : Mon Jul 12 2004
+ copyright : (C) 2004 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+ //qt includes
+#include <qdom.h>
+
+//kde includes
+#include <kcombobox.h>
+#include <kdialogbase.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+//app includes
+#include "eventconfigurationdlg.h"
+#include "eventeditordlg.h"
+#include "qpevents.h"
+
+EventConfigurationDlg::EventConfigurationDlg(KActionCollection *actionCollection, QWidget* parent, const char* name, WFlags fl)
+: EventConfigurationDlgS(parent,name,fl)
+{
+ m_actionCollection = actionCollection;
+}
+
+EventConfigurationDlg::~EventConfigurationDlg()
+{
+}
+
+void EventConfigurationDlg::initEvents(EventActions *events)
+{
+ QListViewItem *item;
+ for (EventActions::ConstIterator it = events->constBegin(); it != events->constEnd(); ++it)
+ {
+ QValueList<EventAction> evList = it.data();
+ for (QValueList<EventAction>::ConstIterator it2 = evList.constBegin(); it2 != evList.constEnd(); ++it2)
+ {
+ EventAction ev = *it2;
+ item = new QListViewItem(eventsListView, QPEvents::ref()->fullEventName(it.key()), QPEvents::ref()->fullActionName(ev.action));
+ int argcount = ev.arguments.count();
+ if (argcount > 0)
+ item->setText(2, ev.arguments[0]);
+ if (argcount > 1)
+ item->setText(3, ev.arguments[1]);
+ if (argcount > 2)
+ item->setText(4, ev.arguments[2]);
+ if (argcount > 3)
+ item->setText(5, ev.arguments[3]);
+ }
+ }
+}
+
+void EventConfigurationDlg::saveEvents(QDomDocument dom)
+{
+ QDomNode projectNode = dom.firstChild().firstChild();
+ QDomNode eventsNode = projectNode.namedItem("events");
+ projectNode.removeChild(eventsNode);
+ eventsNode = dom.createElement("events");
+ projectNode.appendChild(eventsNode);
+ QDomElement node;
+ QListViewItemIterator it(eventsListView);
+ QListViewItem *item;
+ while (it.current())
+ {
+ item = it.current();
+ node = dom.createElement("event");
+ eventsNode.appendChild(node);
+ QDomElement el = node.toElement();
+ el.setAttribute("name", QPEvents::ref()->eventName(item->text(0)));
+ el.setAttribute("action", QPEvents::ref()->actionName(item->text(1)));
+ if (el.attribute("action") == "script" || el.attribute("action") == "action")
+ el.setAttribute("type", "external");
+ else
+ el.setAttribute("type", "internal");
+ for (uint i = 2; i < 6; i++)
+ {
+ QString s = item->text(i);
+ if (s.isEmpty())
+ s = "--not set--";
+ QDomNode argNode = dom.createElement("argument");
+ node.appendChild(argNode);
+ argNode.appendChild(dom.createTextNode(s));
+ }
+ ++it;
+ }
+}
+
+void EventConfigurationDlg::slotAddEvent()
+{
+ KDialogBase editDlg(this, "add_event", true, i18n("New Event"), KDialogBase::Ok | KDialogBase::Cancel);
+ EventEditorDlg eventDlg(m_actionCollection, &editDlg);
+ editDlg.setMainWidget(&eventDlg);
+ if (editDlg.exec())
+ {
+ QListViewItem *item = new QListViewItem(eventsListView);
+ item->setText(0, eventDlg.eventCombo->currentText());
+ item->setText(1, eventDlg.actionCombo->currentText());
+ item->setText(2, eventDlg.argument1());
+ item->setText(3, eventDlg.argument2());
+ item->setText(4, eventDlg.argument3());
+ item->setText(5, eventDlg.argument4());
+ }
+}
+
+void EventConfigurationDlg::slotEditEvent()
+{
+ QListViewItem *item = eventsListView->currentItem();
+ if (!item) return;
+ KDialogBase editDlg(this, "edit_event", true, i18n("Edit Event"), KDialogBase::Ok | KDialogBase::Cancel);
+ EventEditorDlg eventDlg(m_actionCollection, &editDlg);
+ editDlg.setMainWidget(&eventDlg);
+ eventDlg.setEvent(item->text(0));
+ eventDlg.setAction(item->text(1));
+ QStringList arguments;
+ arguments << item->text(2) << item->text(3) << item->text(4) << item->text(5);
+ eventDlg.setArguments(arguments);
+ if (editDlg.exec())
+ {
+ item->setText(0, eventDlg.eventCombo->currentText());
+ item->setText(1, eventDlg.actionCombo->currentText());
+ item->setText(2, eventDlg.argument1());
+ item->setText(3, eventDlg.argument2());
+ item->setText(4, eventDlg.argument3());
+ item->setText(5, eventDlg.argument4());
+ }
+}
+
+void EventConfigurationDlg::slotDeleteEvent()
+{
+ QListViewItem *item = eventsListView->currentItem();
+ if (!item) return;
+ if (KMessageBox::warningContinueCancel(this, i18n("<qt>Are you sure that you want to remove the configuration of the <b>%1</b> event?</qt>").arg(item->text(0)), i18n("Delete Event Configuration"),KStdGuiItem::del()) == KMessageBox::Continue)
+ {
+ delete item;
+ }
+}
+
+#include "eventconfigurationdlg.moc"
+
diff --git a/quanta/project/eventconfigurationdlg.h b/quanta/project/eventconfigurationdlg.h
new file mode 100644
index 00000000..b1e4c14d
--- /dev/null
+++ b/quanta/project/eventconfigurationdlg.h
@@ -0,0 +1,50 @@
+/***************************************************************************
+ eventconfigurationdlg.h - description
+ -------------------
+ begin : Mon Jul 12 2004
+ copyright : (C) 2004 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef EVENTCONFIGURATIONDLG_H
+#define EVENTCONFIGURATIONDLG_H
+
+#include "eventconfigurationdlgs.h"
+
+class QDomDocument;
+class KActionCollection;
+struct EventAction;
+typedef QMap<QString, QValueList<EventAction> > EventActions;
+
+class EventConfigurationDlg : public EventConfigurationDlgS
+{
+ Q_OBJECT
+
+public:
+ EventConfigurationDlg(KActionCollection *actionCollection, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~EventConfigurationDlg();
+ void initEvents(EventActions *events);
+ void saveEvents(QDomDocument dom);
+
+public slots:
+ void slotEditEvent();
+ void slotAddEvent();
+ void slotDeleteEvent();
+
+protected:
+ KActionCollection *m_actionCollection;
+
+protected slots:
+
+};
+
+#endif
+
diff --git a/quanta/project/eventconfigurationdlgs.ui b/quanta/project/eventconfigurationdlgs.ui
new file mode 100644
index 00000000..329791b8
--- /dev/null
+++ b/quanta/project/eventconfigurationdlgs.ui
@@ -0,0 +1,223 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>EventConfigurationDlgS</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>EventConfigurationDlgS</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>enableEventsBox</cstring>
+ </property>
+ <property name="text">
+ <string>Ena&amp;ble the event actions</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Configure Events</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KPushButton" row="1" column="0">
+ <property name="name">
+ <cstring>addButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Add</string>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="1" column="2">
+ <property name="name">
+ <cstring>editButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Edit</string>
+ </property>
+ </widget>
+ <spacer row="1" column="1">
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>172</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KListView" row="0" column="0" rowspan="1" colspan="5">
+ <column>
+ <property name="text">
+ <string>Event</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Action</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Argument 1</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Argument 2</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Argument 3</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Argument 4</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>eventsListView</cstring>
+ </property>
+ </widget>
+ <spacer row="1" column="3">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>150</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton" row="1" column="4">
+ <property name="name">
+ <cstring>deleteButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Delete</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>addButton</sender>
+ <signal>clicked()</signal>
+ <receiver>EventConfigurationDlgS</receiver>
+ <slot>slotAddEvent()</slot>
+ </connection>
+ <connection>
+ <sender>deleteButton</sender>
+ <signal>clicked()</signal>
+ <receiver>EventConfigurationDlgS</receiver>
+ <slot>slotDeleteEvent()</slot>
+ </connection>
+ <connection>
+ <sender>editButton</sender>
+ <signal>clicked()</signal>
+ <receiver>EventConfigurationDlgS</receiver>
+ <slot>slotEditEvent()</slot>
+ </connection>
+ <connection>
+ <sender>eventsListView</sender>
+ <signal>doubleClicked(QListViewItem*)</signal>
+ <receiver>EventConfigurationDlgS</receiver>
+ <slot>slotEditEvent()</slot>
+ </connection>
+ <connection>
+ <sender>enableEventsBox</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>groupBox1</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>eventsListView</tabstop>
+ <tabstop>addButton</tabstop>
+ <tabstop>editButton</tabstop>
+ <tabstop>deleteButton</tabstop>
+</tabstops>
+<slots>
+ <slot>slotEditEvent()</slot>
+ <slot>slotAddEvent()</slot>
+ <slot>slotDeleteEvent()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klistview.h</includehint>
+</includehints>
+</UI>
diff --git a/quanta/project/eventeditordlg.cpp b/quanta/project/eventeditordlg.cpp
new file mode 100644
index 00000000..d67251f0
--- /dev/null
+++ b/quanta/project/eventeditordlg.cpp
@@ -0,0 +1,407 @@
+/***************************************************************************
+ eventeditordlg.cpp - description
+ -------------------
+ begin : Mon Jul 12 2004
+ copyright : (C) 2004 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+//qt includes
+#include <qlabel.h>
+#include <qregexp.h>
+#include <qtooltip.h>
+
+//kde includes
+#include <kaction.h>
+#include <kcombobox.h>
+#include <klocale.h>
+
+ //app includes
+#include "eventeditordlg.h"
+#include "qpevents.h"
+#include "project.h"
+#include "tagaction.h"
+
+extern QString simpleMemberStr;
+extern QString taskLeaderStr;
+extern QString teamLeaderStr;
+extern QString subprojectLeaderStr;
+
+EventEditorDlg::EventEditorDlg(KActionCollection *actionCollection, QWidget* parent, const char* name, WFlags fl)
+: EventEditorDlgS(parent,name,fl)
+{
+ m_actionCollection = actionCollection;
+ eventCombo->insertStringList(QPEvents::ref()->eventNames());
+ actionCombo->insertStringList(QPEvents::ref()->actionNames());
+ slotActionChanged(actionCombo->currentText());
+}
+
+EventEditorDlg::~EventEditorDlg()
+{
+}
+
+void EventEditorDlg::setEvent(const QString &name)
+{
+ for (int i = 0; i < eventCombo->count(); i++)
+ {
+ if (eventCombo->text(i) == name)
+ {
+ eventCombo->setCurrentItem(i);
+ break;
+ }
+ }
+}
+
+void EventEditorDlg::setAction(const QString &name)
+{
+ for (int i = 0; i < actionCombo->count(); i++)
+ {
+ if (actionCombo->text(i) == name)
+ {
+ actionCombo->setCurrentItem(i);
+ slotActionChanged(name);
+ break;
+ }
+ }
+}
+
+QString EventEditorDlg::argument1()
+{
+ if (argument1Combo->isEnabled())
+ {
+ QString s = argument1Combo->currentText();
+ QString actionType = actionCombo->currentText();
+ if (actionType == QPEvents::ref()->fullActionName("email"))
+ {
+ if (s == i18n(teamLeaderStr.utf8()))
+ s = "teamleader";
+ else
+ if (s.startsWith(i18n(taskLeaderStr.utf8()) +" - "))
+ {
+ s.remove(i18n(taskLeaderStr.utf8()) +" - ");
+ s.prepend("taskleader-");
+ } else
+ if (s.startsWith(i18n(subprojectLeaderStr.utf8()) +" - "))
+ {
+ s.remove(i18n(subprojectLeaderStr.utf8()) +" - ");
+ s.prepend("subprojectleader-");
+ }
+ return s;
+ } else
+ if (actionType == QPEvents::ref()->fullActionName("script"))
+ {
+ QString s = argument1Combo->currentText();
+ for (QMap<QString, QString>::ConstIterator it = m_scriptActions.constBegin(); it != m_scriptActions.constEnd(); ++it)
+ {
+ if (it.data() == s)
+ {
+ s = it.key();
+ break;
+ }
+ }
+ return s;
+ } else
+ if (actionType == QPEvents::ref()->fullActionName("action"))
+ {
+ QString s = argument1Combo->currentText();
+ for (QMap<QString, QString>::ConstIterator it = m_otherActions.constBegin(); it != m_otherActions.constEnd(); ++it)
+ {
+ if (it.data() == s)
+ {
+ s = it.key();
+ break;
+ }
+ }
+ return s;
+ } else
+
+ return s;
+ }
+
+ return QString::null;
+}
+
+QString EventEditorDlg::argument2()
+{
+ if (argument2Combo->isEnabled())
+ {
+ QString actionType = actionCombo->currentText();
+ if (actionType == QPEvents::ref()->fullActionName("log"))
+ {
+ int id = argument2Combo->currentItem();
+ if (id == 0)
+ return "full";
+ else
+ return "minimal";
+ } else
+ if (actionType == QPEvents::ref()->fullActionName("script"))
+ {
+ int id = argument2Combo->currentItem();
+ if (id == 0)
+ return "yes";
+ else
+ return "no";
+ }
+ return argument2Combo->currentText();
+ } else
+ return QString::null;
+}
+
+QString EventEditorDlg::argument3()
+{
+ if (argument3Combo->isEnabled())
+ {
+ QString actionType = actionCombo->currentText();
+ if (actionType == QPEvents::ref()->fullActionName("log"))
+ {
+ int id = argument3Combo->currentItem();
+ if (id == 0)
+ return "create_new";
+ else
+ return "append";
+ }
+ return argument3Combo->currentText();
+ } else
+ return QString::null;
+}
+
+QString EventEditorDlg::argument4()
+{
+ if (argument4Combo->isEnabled())
+ {
+ return argument4Combo->currentText();
+ } else
+ return QString::null;
+}
+
+void EventEditorDlg::setArguments(const QStringList& arguments)
+{
+ QString actionType = actionCombo->currentText();
+ if (actionType == QPEvents::ref()->fullActionName("email"))
+ {
+ QString s = arguments[0];
+ if (s == "teamleader")
+ s = i18n(teamLeaderStr.utf8());
+ else
+ if (s.startsWith("taskleader-"))
+ {
+ s.remove("taskleader-");
+ s.prepend(i18n(taskLeaderStr.utf8()) +" - ");
+ } else
+ if (s.startsWith("subprojectleader-"))
+ {
+ s.remove("subprojectleader-");
+ s.prepend(i18n(subprojectLeaderStr.utf8()) +" - ");
+ }
+ if (argument1Combo->contains(s))
+ {
+ for (int i = 0; i < argument1Combo->count(); i++)
+ {
+ if (argument1Combo->text(i) == s)
+ {
+ argument1Combo->setCurrentItem(i);
+ break;
+ }
+ }
+ }
+ else
+ {
+ argument1Combo->insertItem(s, 0);
+ argument1Combo->setCurrentItem(0);
+ }
+ } else
+ if (actionType == QPEvents::ref()->fullActionName("script"))
+ {
+ QString s = arguments[0];
+ if (m_scriptActions.contains(s))
+ s = m_scriptActions[s];
+ if (argument1Combo->contains(s))
+ {
+ for (int i = 0; i < argument1Combo->count(); i++)
+ {
+ if (argument1Combo->text(i) == s)
+ {
+ argument1Combo->setCurrentItem(i);
+ break;
+ }
+ }
+ }
+ else
+ {
+ argument1Combo->insertItem(s, 0);
+ argument1Combo->setCurrentItem(0);
+ }
+ s = arguments[1];
+ if (s == "yes")
+ argument2Combo->setCurrentItem(0);
+ else if (s == "no")
+ argument2Combo->setCurrentItem(1);
+ return; //setup for script arguments completed
+ } else
+ if (actionType == QPEvents::ref()->fullActionName("action"))
+ {
+ QString s = arguments[0];
+ if (m_otherActions.contains(s))
+ s = m_otherActions[s];
+ if (argument1Combo->contains(s))
+ {
+ for (int i = 0; i < argument1Combo->count(); i++)
+ {
+ if (argument1Combo->text(i) == s)
+ {
+ argument1Combo->setCurrentItem(i);
+ break;
+ }
+ }
+ }
+ else
+ {
+ argument1Combo->insertItem(s, 0);
+ argument1Combo->setCurrentItem(0);
+ }
+ } else
+ if (actionType == QPEvents::ref()->fullActionName("log"))
+ {
+ argument1Combo->insertItem(arguments[0], 0);
+ argument1Combo->setCurrentItem(0);
+ QString s = arguments[1];
+ if (s == "full")
+ argument2Combo->setCurrentItem(0);
+ else if (s == "minimal")
+ argument2Combo->setCurrentItem(1);
+ s = arguments[2];
+ if (s == "create_new")
+ argument3Combo->setCurrentItem(0);
+ else if (s == "append")
+ argument3Combo->setCurrentItem(1);
+ return; //setup for log arguments completed
+ } else
+ {
+ argument1Combo->insertItem(arguments[0], 0);
+ argument1Combo->setCurrentItem(0);
+ }
+ argument2Combo->insertItem(arguments[1], 0);
+ argument2Combo->setCurrentItem(0);
+ argument3Combo->insertItem(arguments[2], 0);
+ argument3Combo->setCurrentItem(0);
+ argument4Combo->insertItem(arguments[3], 0);
+ argument4Combo->setCurrentItem(0);
+}
+
+void EventEditorDlg::resetArgumentWidgets(QLabel *label, KComboBox *combo)
+{
+ label->setText(i18n("Argument:"));
+ label->setEnabled(false);
+ combo->setEnabled(false);
+ combo->setEditable(true);
+ combo->clear();
+ QToolTip::remove(combo);
+}
+
+void EventEditorDlg::slotActionChanged(const QString &name)
+{
+ resetArgumentWidgets(argument1Label, argument1Combo);
+ resetArgumentWidgets(argument2Label, argument2Combo);
+ resetArgumentWidgets(argument3Label, argument3Combo);
+ resetArgumentWidgets(argument4Label, argument4Combo);
+ if (name == QPEvents::ref()->fullActionName("email"))
+ {
+ argument1Label->setEnabled(true);
+ argument1Label->setText(i18n("Receiver:"));
+ argument1Combo->setEnabled(true);
+ argument1Combo->insertItem(i18n(teamLeaderStr.utf8()));
+ QValueList<SubProject> *subprojects = Project::ref()->subprojects();
+ for (uint i = 0; i < subprojects->count(); i++)
+ {
+ QString s = (*subprojects)[i].name;
+ if (!Project::ref()->subprojectLeader(s).name.isEmpty())
+ argument1Combo->insertItem(i18n(subprojectLeaderStr.utf8()) + " - " + s);
+ }
+ QStringList tasks = Project::ref()->tasks();
+ for (uint i = 0; i < tasks.count(); i++)
+ {
+ argument1Combo->insertItem(i18n(taskLeaderStr.utf8()) + " - " + tasks[i]);
+ }
+ } else
+ if (name == QPEvents::ref()->fullActionName("log"))
+ {
+ argument1Label->setEnabled(true);
+ argument1Label->setText(i18n("Log file:"));
+ argument1Combo->setEnabled(true);
+ QToolTip::add(argument1Combo, i18n("A relative file to the project folder or a file outside of the project folder in which case the full path must be specified."));
+ argument2Label->setEnabled(true);
+ argument2Label->setText(i18n("Detail:"));
+ argument2Combo->setEnabled(true);
+ argument2Combo->setEditable(false);
+ argument2Combo->insertItem(i18n("Full"), 0);
+ argument2Combo->insertItem(i18n("Minimal"), 1);
+ argument3Label->setEnabled(true);
+ argument3Label->setText(i18n("Behavior:"));
+ argument3Combo->setEnabled(true);
+ argument3Combo->setEditable(false);
+ argument3Combo->insertItem(i18n("Create New Log"), 0);
+ argument3Combo->insertItem(i18n("Append to Existing Log"), 1);
+ } else
+ if (name == QPEvents::ref()->fullActionName("script"))
+ {
+ argument1Label->setEnabled(true);
+ argument1Label->setText(i18n("Action name:"));
+ TagAction *action = 0L;
+ QString s;
+ QStringList items;
+ QRegExp r("\\&(?!\\&)");
+ for (uint i = 0; i < m_actionCollection->count(); i++)
+ {
+ action = dynamic_cast<TagAction*>(m_actionCollection->action(i));
+ if (action && action->type() == "script")
+ {
+ s = action->text().replace(r, "");
+ items.append(s);
+ m_scriptActions[action->name()] = s;
+ }
+ }
+ items.sort();
+ argument1Combo->insertStringList(items);
+ argument1Combo->setEnabled(true);
+ argument2Label->setEnabled(true);
+ argument2Label->setText(i18n("Blocking:"));
+ argument2Combo->setEnabled(true);
+ argument2Combo->setEditable(false);
+ argument2Combo->insertItem(i18n("Yes"), 0);
+ argument2Combo->insertItem(i18n("No"), 1);
+ } else
+ if (name == QPEvents::ref()->fullActionName("action"))
+ {
+ argument1Label->setEnabled(true);
+ argument1Label->setText(i18n("Action name:"));
+ TagAction *action = 0L;
+ QString s;
+ QRegExp r("\\&(?!\\&)");
+ QStringList items;
+ for (uint i = 0; i < m_actionCollection->count(); i++)
+ {
+ KAction *a = m_actionCollection->action(i);
+ action = dynamic_cast<TagAction*>(a);
+ if (!action || action->type() != "script")
+ {
+ s = a->text().replace(r, "");
+ items.append(s);
+ m_otherActions[a->name()] = s;
+ }
+ }
+ items.sort();
+ argument1Combo->insertStringList(items);
+ argument1Combo->setEnabled(true);
+ }
+}
+
+#include "eventeditordlg.moc"
+
diff --git a/quanta/project/eventeditordlg.h b/quanta/project/eventeditordlg.h
new file mode 100644
index 00000000..a8dd6842
--- /dev/null
+++ b/quanta/project/eventeditordlg.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ eventeditordlg.h - description
+ -------------------
+ begin : Mon Jul 12 2004
+ copyright : (C) 2004 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+
+#ifndef EVENTEDITORDLG_H
+#define EVENTEDITORDLG_H
+
+#include "eventeditordlgs.h"
+
+class QLabel;
+class KActionCollection;
+class KComboBox;
+
+class EventEditorDlg : public EventEditorDlgS
+{
+ Q_OBJECT
+
+public:
+ EventEditorDlg(KActionCollection *actionCollection, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~EventEditorDlg();
+ void setEvent(const QString &name);
+ void setAction(const QString &name);
+ void setArguments(const QStringList& arguments);
+ QString argument1();
+ QString argument2();
+ QString argument3();
+ QString argument4();
+
+public slots:
+ void slotActionChanged(const QString &name);
+
+protected:
+ void resetArgumentWidgets(QLabel *label, KComboBox *combo);
+
+ QMap<QString, QString> m_scriptActions;
+ QMap<QString, QString> m_otherActions;
+ KActionCollection *m_actionCollection;
+
+protected slots:
+
+};
+
+#endif
+
diff --git a/quanta/project/eventeditordlgs.ui b/quanta/project/eventeditordlgs.ui
new file mode 100644
index 00000000..a19a35d1
--- /dev/null
+++ b/quanta/project/eventeditordlgs.ui
@@ -0,0 +1,236 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>EventEditorDlgS</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>EventEditorDlgS</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>544</width>
+ <height>206</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>350</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="caption">
+ <string></string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Event:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="0" column="1">
+ <property name="name">
+ <cstring>eventCombo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Action:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="1" column="1">
+ <property name="name">
+ <cstring>actionCombo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>argument1Label</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Argument 1:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="2" column="1">
+ <property name="name">
+ <cstring>argument1Combo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>argument2Label</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Argument 2:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="3" column="1">
+ <property name="name">
+ <cstring>argument2Combo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>argument3Label</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Argument 3:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="0">
+ <property name="name">
+ <cstring>argument4Label</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Argument 4:</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="4" column="1">
+ <property name="name">
+ <cstring>argument3Combo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="5" column="1">
+ <property name="name">
+ <cstring>argument4Combo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>actionCombo</sender>
+ <signal>activated(const QString&amp;)</signal>
+ <receiver>EventEditorDlgS</receiver>
+ <slot>slotActionChanged(const QString&amp;)</slot>
+ </connection>
+</connections>
+<slots>
+ <slot>slotActionChanged(const QString &amp;name)</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/quanta/project/membereditdlg.cpp b/quanta/project/membereditdlg.cpp
new file mode 100644
index 00000000..6e47d044
--- /dev/null
+++ b/quanta/project/membereditdlg.cpp
@@ -0,0 +1,183 @@
+/***************************************************************************
+ membereditdlg.cpp - description
+ -------------------
+ begin : Wed Jul 7 2004
+ copyright : (C) 2004 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+//qt includes
+#include <qcheckbox.h>
+
+//kde includes
+#include <kcombobox.h>
+#include <kdialogbase.h>
+#include <kinputdialog.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kpushbutton.h>
+#include <kabc/stdaddressbook.h>
+
+//app includes
+#include "listdlg.h"
+#include "membereditdlg.h"
+#include "subprojecteditdlgs.h"
+#include "project.h"
+
+QString simpleMemberStr = I18N_NOOP("Simple Member");
+QString taskLeaderStr = I18N_NOOP("Task Leader");
+QString teamLeaderStr = I18N_NOOP("Team Leader");
+QString subprojectLeaderStr = I18N_NOOP("Subproject Leader");
+
+
+MemberEditDlg::MemberEditDlg(QWidget *parent, const char *name)
+ : MemberEditDlgS(parent, name)
+{
+ QValueList<SubProject> *subprojects = Project::ref()->subprojects();
+ for (QValueList<SubProject>::ConstIterator it = subprojects->constBegin(); it != subprojects->constEnd(); ++it)
+ subprojectCombo->insertItem((*it).name);
+ subprojectCombo->setEnabled(false);
+ editSubprojectsButton->setEnabled(false);
+
+ QMap<QString, TeamMember> members = Project::ref()->allMembers();
+ QStringList items;
+ for (QMap<QString, TeamMember>::ConstIterator it = members.constBegin(); it != members.constEnd(); ++it)
+ {
+ nameCombo->insertItem(it.key());
+ }
+ nameCombo->insertItem(QString::null, 0);
+
+ roleCombo->insertItem(i18n(teamLeaderStr.utf8()));
+ roleCombo->insertItem(i18n(subprojectLeaderStr.utf8()));
+ roleCombo->insertItem(i18n(taskLeaderStr.utf8()));
+ roleCombo->insertItem(i18n(simpleMemberStr.utf8()));
+ roleCombo->setCurrentItem(3);
+}
+
+
+MemberEditDlg::~MemberEditDlg()
+{
+}
+
+void MemberEditDlg::slotRoleSelected(const QString &roleName)
+{
+ if (roleName != i18n(subprojectLeaderStr.utf8()))
+ {
+ subprojectCombo->setEnabled(false);
+ editSubprojectsButton->setEnabled(false);
+ } else
+ {
+ subprojectCombo->setEnabled(true);
+ editSubprojectsButton->setEnabled(true);
+ }
+}
+
+void MemberEditDlg::slotEditSubprojects()
+{
+ KDialogBase editDlg(this, "edit_subprojects", true, i18n("Edit Subprojects"), KDialogBase::Ok | KDialogBase::Cancel);
+ SubprojectEditDlgS subprojectDlg(&editDlg);
+ editDlg.setMainWidget(&subprojectDlg);
+ QValueList<SubProject> *subprojects = Project::ref()->subprojects();
+ int idx = 0;
+ SubProject subProject;
+ for (uint i = 0; i < subprojects->count(); i++)
+ {
+ subProject = (*subprojects)[i];
+ if (subprojectCombo->currentText() == subProject.name)
+ {
+ subprojectDlg.nameEdit->setText(subProject.name);
+ subprojectDlg.locationEdit->setText(subProject.location);
+ idx = i;
+ break;
+ }
+ }
+ if (subprojects->count() == 0)
+ subprojectDlg.createNew->setChecked(true);
+ if (editDlg.exec())
+ {
+ QString oldName = subProject.name;
+ subProject.name = subprojectDlg.nameEdit->text();
+ subProject.location = subprojectDlg.locationEdit->text();
+ if (subprojectDlg.createNew->isChecked() && (subProject.name != oldName))
+ {
+ subprojects->append(subProject);
+ subprojectCombo->insertItem(subProject.name);
+ subprojectCombo->setCurrentItem(subprojectCombo->count() - 1);
+ } else
+ {
+ (*subprojects)[idx] = subProject;
+ subprojectCombo->setCurrentText(subProject.name);
+ }
+ }
+}
+
+void MemberEditDlg::slotMemberSelected()
+{
+ QString name = nameCombo->currentText();
+ QMap<QString, TeamMember> members = Project::ref()->allMembers();
+ if (members.contains(name))
+ {
+ emailEdit->setText(members[name].email);
+ }
+}
+
+void MemberEditDlg::selectMember(const QString &name)
+{
+ bool found = false;
+ for (int i = 0; i < nameCombo->count(); i++)
+ {
+ if (nameCombo->text(i) == name)
+ {
+ nameCombo->setCurrentItem(i);
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ nameCombo->insertItem(name, 1);
+ nameCombo->setCurrentItem(1);
+ }
+}
+
+void MemberEditDlg::slotSelectFromAddrBook()
+{
+ QMap<QString, QString> uidMap;
+ QString name;
+ QStringList result;
+ KABC::AddressBook *addressBook = KABC::StdAddressBook::self();
+ KABC::AddressBook::ConstIterator it;
+ KABC::AddressBook::ConstIterator end = addressBook->end();
+ for( it = addressBook->begin(); it != end; ++it )
+ {
+ result.append((*it).assembledName());
+ uidMap.insert((*it).assembledName(), (*it).uid());
+ }
+ result.sort();
+
+ if ( result.count() > 0 )
+ {
+ ListDlg listDlg(result);
+ listDlg.setCaption(i18n("Select Member"));
+ if (!listDlg.exec()) return;
+ name = listDlg.getEntry();
+ KABC::Addressee entry = addressBook->findByUid(uidMap[name]);
+ nameCombo->insertItem(name, 1);
+ nameCombo->setCurrentItem(1);
+ emailEdit->setText(entry.emails()[0]);
+ nicknameEdit->setText(entry.nickName());
+ } else
+ {
+ KMessageBox::error(this,i18n("No entries found in the addressbook."));
+ }
+}
+
+#include "membereditdlg.moc"
diff --git a/quanta/project/membereditdlg.h b/quanta/project/membereditdlg.h
new file mode 100644
index 00000000..33669488
--- /dev/null
+++ b/quanta/project/membereditdlg.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ membereditdlg.h - description
+ -------------------
+ begin : Wed Jul 7 2004
+ copyright : (C) 2004 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef MEMBEREDITDLG_H
+#define MEMBEREDITDLG_H
+
+#include <membereditdlgs.h>
+
+/**
+@author Andras Mantia
+*/
+class MemberEditDlg : public MemberEditDlgS
+{
+Q_OBJECT
+public:
+ MemberEditDlg(QWidget *parent = 0, const char *name = 0);
+ ~MemberEditDlg();
+ void selectMember(const QString &name);
+
+public slots:
+ void slotRoleSelected(const QString& roleName);
+ void slotEditSubprojects();
+ void slotMemberSelected();
+ void slotSelectFromAddrBook();
+};
+
+#endif
diff --git a/quanta/project/membereditdlgs.ui b/quanta/project/membereditdlgs.ui
new file mode 100644
index 00000000..487e20bf
--- /dev/null
+++ b/quanta/project/membereditdlgs.ui
@@ -0,0 +1,196 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>MemberEditDlgS</class>
+<author>(C) 2005 Andras Mantia &lt;[email protected]&gt;</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>MemberEditDlgS</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>553</width>
+ <height>236</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KComboBox" row="0" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>nameCombo</cstring>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="0" column="3">
+ <property name="name">
+ <cstring>selectButton</cstring>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>nameCombo</cstring>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="5" column="2" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>editSubprojectsButton</cstring>
+ </property>
+ <property name="text">
+ <string>E&amp;dit Subprojects</string>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="3" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>roleCombo</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="4" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>taskEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>Tas&amp;k:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>taskEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="0">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="text">
+ <string>Subpro&amp;ject:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>subprojectCombo</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Role:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>roleCombo</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Email:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>emailEdit</cstring>
+ </property>
+ </widget>
+ <widget class="KComboBox" row="5" column="1">
+ <property name="name">
+ <cstring>subprojectCombo</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Nickname:</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="2" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>emailEdit</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="1" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>nicknameEdit</cstring>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>roleCombo</sender>
+ <signal>activated(const QString&amp;)</signal>
+ <receiver>MemberEditDlgS</receiver>
+ <slot>slotRoleSelected(const QString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>editSubprojectsButton</sender>
+ <signal>clicked()</signal>
+ <receiver>MemberEditDlgS</receiver>
+ <slot>slotEditSubprojects()</slot>
+ </connection>
+ <connection>
+ <sender>nameCombo</sender>
+ <signal>activated(const QString&amp;)</signal>
+ <receiver>MemberEditDlgS</receiver>
+ <slot>slotMemberSelected()</slot>
+ </connection>
+ <connection>
+ <sender>selectButton</sender>
+ <signal>clicked()</signal>
+ <receiver>MemberEditDlgS</receiver>
+ <slot>slotSelectFromAddrBook()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>nameCombo</tabstop>
+ <tabstop>selectButton</tabstop>
+ <tabstop>nicknameEdit</tabstop>
+ <tabstop>emailEdit</tabstop>
+ <tabstop>roleCombo</tabstop>
+ <tabstop>taskEdit</tabstop>
+ <tabstop>subprojectCombo</tabstop>
+ <tabstop>editSubprojectsButton</tabstop>
+</tabstops>
+<slots>
+ <slot>slotRoleSelected(const QString&amp; roleName)</slot>
+ <slot>slotEditSubprojects()</slot>
+ <slot>slotMemberSelected()</slot>
+ <slot>slotSelectFromAddrBook()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kcombobox.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>kcombobox.h</includehint>
+ <includehint>klineedit.h</includehint>
+ <includehint>klineedit.h</includehint>
+</includehints>
+</UI>
diff --git a/quanta/project/project.cpp b/quanta/project/project.cpp
new file mode 100644
index 00000000..3601e628
--- /dev/null
+++ b/quanta/project/project.cpp
@@ -0,0 +1,1428 @@
+/***************************************************************************
+ project.cpp - description
+ -------------------
+ begin : Thu Mar 16 2000
+ copyright : (C) 2000 by Yacovlev Alexander & Dmitry Poplavsky <[email protected]>
+ (C) 2001-2005 by Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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.h"
+
+// unix includes
+#include <time.h>
+#include <unistd.h>
+
+// include QT files
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+
+// include files for KDE
+#include <kactionclasses.h>
+#include <kapplication.h>
+#include <kcharsets.h>
+#include <kdirwatch.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 <kstringhandler.h>
+#include <kurlrequester.h>
+#include <kurlrequesterdlg.h>
+
+#include <ktexteditor/markinterface.h>
+#include <ktexteditor/viewcursorinterface.h>
+
+// application headers
+#include "copyto.h"
+#include "document.h"
+#include "dtds.h"
+#include "dtdselectdialog.h"
+#include "eventconfigurationdlg.h"
+#include "qextfileinfo.h"
+#include "quantacommon.h"
+#include "projectprivate.h"
+#include "projectupload.h"
+#include "projectoptions.h"
+#include "rescanprj.h"
+#include "resource.h"
+#include "teammembersdlg.h"
+#include "uploadprofilespage.h"
+#include "viewmanager.h"
+#include "qpevents.h"
+
+extern QString simpleMemberStr;
+extern QString taskLeaderStr;
+extern QString teamLeaderStr;
+extern QString subprojectLeaderStr;
+
+Project::Project(KMainWindow *parent)
+ : QObject()
+{
+ d = new ProjectPrivate(this);
+ connect(d, SIGNAL(eventHappened(const QString&, const QString&, const QString& )), this, SIGNAL(eventHappened(const QString&, const QString&, const QString& )));
+ d->m_mainWindow = parent;
+ d->m_uploadDialog = 0L;
+ keepPasswd = true;
+ d->initActions(parent->actionCollection());
+}
+
+Project::~Project()
+{
+ delete d;
+ d = 0;
+}
+
+
+QStringList Project::fileNameList()
+{
+ QStringList list;
+ ProjectList::Iterator it( d->m_projectFiles );
+ for ( ; it.current(); ++it) {
+ if (! it.current()->fileName(false).isEmpty())
+ list.append(it.current()->url());
+ }
+ list.sort();
+ return list;
+}
+
+KURL::List Project::files()
+{
+ KURL::List list;
+ ProjectList::Iterator it( d->m_projectFiles );
+ for ( ; it.current(); ++it) {
+ if (!it.current()->fileName(false).isEmpty())
+ list.append((*it.current()));
+ }
+ return list;
+}
+
+void Project::insertFile(const KURL& nameURL, bool repaint )
+{
+ if (d->excludeRx.exactMatch(nameURL.path()))
+ return;
+ KURL url = nameURL;
+
+ if ( !d->baseURL.isParentOf(url) )
+ {
+ KURLRequesterDlg *urlRequesterDlg = new KURLRequesterDlg( d->baseURL.prettyURL(), d->m_mainWindow, "");
+ urlRequesterDlg->setCaption(i18n("%1: Copy to Project").arg(nameURL.prettyURL(0, KURL::StripFileProtocol)));
+ urlRequesterDlg->urlRequester()->setMode( KFile::Directory | KFile::ExistingOnly);
+ urlRequesterDlg->exec();
+ KURL destination = urlRequesterDlg->selectedURL();
+ if (destination.isLocalFile())
+ {
+ QDir dir(destination.path());
+ destination.setPath(dir.canonicalPath());
+ }
+ delete urlRequesterDlg;
+ if ( !destination.isEmpty() )
+ {
+ CopyTo *dlg = new CopyTo(d->baseURL);
+ connect(dlg, SIGNAL(deleteDialog(CopyTo*)), d,
+ SLOT(slotDeleteCopytoDlg(CopyTo*)));
+ url = dlg->copy( nameURL, destination );
+ }
+ else // Copy canceled, addition aborted
+ {
+ return;
+ }
+ }
+ QDomElement el;
+ while ( d->baseURL.isParentOf(url) )
+ {
+ if ( !d->m_projectFiles.contains(url) )
+ {
+ el = d->dom.createElement("item");
+ el.setAttribute("url", QuantaCommon::qUrl( QExtFileInfo::toRelative(url, d->baseURL) ));
+ d->dom.firstChild().firstChild().appendChild( el );
+ KURL u = url.upURL();
+ ProjectURL *parentURL = d->m_projectFiles.find(u);
+ int uploadStatus = 1;
+ if (parentURL)
+ uploadStatus = parentURL->uploadStatus;
+ d->m_projectFiles.insert( new ProjectURL(url, "", uploadStatus, false, el) );
+ }
+ url.setPath(url.directory(false));
+ }
+ emit eventHappened("after_project_add", url.url(), QString::null);
+ setModified();
+ if ( repaint )
+ {
+ emit reloadTree( &(d->m_projectFiles), false, QStringList());
+ emit newStatus();
+ }
+}
+
+
+void Project::readConfig(KConfig *config)
+{
+ d->config = config;
+ config->setGroup("General Options");
+ int maxRecentItems = config->readNumEntry("Recent Files Limit", 32);
+ d->m_projectRecent->setMaxItems(maxRecentItems);
+ config->setGroup ("Projects");
+ d->m_projectRecent->loadEntries(config, "RecentProjects");
+}
+
+
+void Project::loadLastProject(bool reload)
+{
+ d->config->setGroup("Projects");
+ QStringList projectList = QuantaCommon::readPathListEntry(d->config, "OpenProjects");
+ QStringList tempList = QuantaCommon::readPathListEntry(d->config, "ProjectTempFiles");
+ QStringList sessionTempList = QuantaCommon::readPathListEntry(d->config, "ProjectSessionTempFiles");
+ // remove all local open projects because project and temp file are the same
+ for (uint i = 0; i < projectList.count(); ++i)
+ {
+ if (KURL::fromPathOrURL( projectList[i] ).isLocalFile())
+ {
+ projectList.remove( projectList.at(i) );
+ QStringList::Iterator it = tempList.at(i);
+ if (it != tempList.end())
+ tempList.remove(it);
+ QStringList::Iterator it2 = sessionTempList.at(i);
+ if (it2 != sessionTempList.end())
+ sessionTempList.remove(it2);
+ --i;
+ }
+ }
+ QString urlPath;
+ KURL url;
+ // have we still a project left ?
+ while (projectList.count() > 0)
+ {
+ urlPath = projectList[0];
+ QuantaCommon::setUrl(url, urlPath);
+ QString tempPath = tempList[0];
+ QString sessionTempPath = sessionTempList[0];
+ // test if the remote project is available
+ if ( KIO::NetAccess::exists(url, false, d->m_mainWindow) )
+ {
+ KURL tempURL = KURL().fromPathOrURL(tempPath);
+ if (KIO::NetAccess::exists(tempURL, false, d->m_mainWindow) &&
+ KMessageBox::questionYesNo(d->m_mainWindow, i18n("<qt>Found a backup for project <b>%1</b>.<br> Do you want to open it?</qt>").arg(url.prettyURL()), i18n("Open Project Backup"), KStdGuiItem::open(), i18n("Do Not Open") )
+ == KMessageBox::Yes)
+ {
+ d->m_tmpProjectFile = tempPath;
+ d->m_tmpSessionFile = sessionTempPath;
+ d->loadProjectFromTemp(url, d->m_tmpProjectFile, d->m_tmpSessionFile);
+ // the lists might have changed
+ d->config->writePathEntry("OpenProjects", projectList);
+ d->config->writePathEntry("ProjectTempFiles", tempList);
+ d->config->writePathEntry("ProjectSessionTempFiles", sessionTempList);
+ d->config->sync();
+ return;
+ }
+ }
+ projectList.remove(projectList.at(0));
+ tempList.remove(tempList.at(0));
+ sessionTempList.remove(sessionTempList.at(0));
+ }
+ // the lists might have changed
+ d->config->writePathEntry("OpenProjects", projectList);
+ d->config->writePathEntry("ProjectTempFiles", tempList);
+ // now we look for the last project
+ urlPath = QuantaCommon::readPathEntry(d->config, "Last Project");
+ QuantaCommon::setUrl(url, urlPath);
+
+ if ( reload && (!urlPath.isEmpty() && url.isValid()))
+ {
+ if (!d->loadProject(url))
+ {
+ d->config->deleteEntry("Last Project");
+ }
+ }
+ d->config->sync();
+}
+
+///////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////
+// SLOTS implementation
+//
+
+void Project::slotOpenProject(const KURL &url)
+{
+ kdDebug(24000) << "Open recent project: " << url <<endl;
+ if ( !url.isEmpty() )
+ {
+ if ( !QExtFileInfo::exists(url, true, d->m_mainWindow) )
+ {
+ emit hideSplash();
+ if (KMessageBox::questionYesNo(d->m_mainWindow,
+ i18n("<qt>The file <b>%1</b> does not exist.<br> Do you want to remove it from the list?</qt>").arg(url.prettyURL(0, KURL::StripFileProtocol)), QString::null, KStdGuiItem::del(), i18n("Keep") )
+ == KMessageBox::Yes)
+ {
+ d->m_projectRecent->removeURL(url);
+ } else
+ d->m_projectRecent->setCurrentItem(0);
+ } else
+ {
+ d->loadProject ( url );
+ emit eventHappened("after_project_open", url.url(), QString::null);
+ }
+ }
+}
+
+
+
+// slot for insert file
+void Project::slotInsertFile( const KURL& url )
+{
+ insertFile( url, true );
+}
+
+
+void Project::slotAddDirectory(const KURL& p_dirURL, bool showDlg)
+{
+ KURL dirURL = p_dirURL;
+ if ( hasProject() && !dirURL.isEmpty() )
+ {
+ dirURL.adjustPath(1);
+ if ( !d->baseURL.isParentOf(dirURL) )
+ {
+ KURL destination = d->baseURL;
+ if (showDlg)
+ {
+ KURLRequesterDlg *urlRequesterDlg = new KURLRequesterDlg( d->baseURL.prettyURL(), d->m_mainWindow, "");
+ urlRequesterDlg->setCaption(i18n("%1: Copy to Project").arg(dirURL.prettyURL(0, KURL::StripFileProtocol)));
+ urlRequesterDlg->urlRequester()->setMode( KFile::Directory | KFile::ExistingOnly);
+ urlRequesterDlg->exec();
+ destination = urlRequesterDlg->selectedURL();
+ delete urlRequesterDlg;
+ }
+ if ( (showDlg == false) ||
+ (!destination.isEmpty()) )
+ {
+ CopyTo *dlg = new CopyTo(d->baseURL);
+ connect(dlg, SIGNAL(addFilesToProject(const KURL::List&)),
+ SLOT (slotInsertFilesAfterCopying(const KURL::List&)));
+ connect(dlg, SIGNAL(deleteDialog(CopyTo *)), d,
+ SLOT (slotDeleteCopytoDlg(CopyTo *)));
+ //if ( rdir.right(1) == "/" ) rdir.remove( rdir.length()-1,1);
+ dirURL = dlg->copy(dirURL, destination);
+ return;
+ }
+ else
+ {
+ return;
+ }
+ }
+ d->insertFiles( dirURL, "*" );
+ //And again, insert now directly the directory name into the project.
+ //It's important if rdir doesn't contain any files or subdirectories.
+ d->insertFiles(dirURL);
+ emit reloadTree( &(d->m_projectFiles), false, QStringList() );
+ }
+}
+
+void Project::slotInsertFilesAfterCopying(const KURL::List& a_urlList)
+{
+ KURL::List::ConstIterator it;
+ KURL url;
+ for (it = a_urlList.begin(); it != a_urlList.end(); ++it)
+ {
+ url = *it;
+ //url.adjustPath(1);
+ d->insertFiles( url, "*" );
+ }
+ emit reloadTree( &(d->m_projectFiles), false, QStringList() );
+}
+
+//rename the elements in the project dom tree
+void Project::slotRenamed(const KURL& oldURL, const KURL& newURL)
+{
+ if ( oldURL == newURL) // just in case
+ return;
+
+ // remove the target if already there
+ // TODO: check if this is correct because it removes a folder but not the content?
+ d->m_projectFiles.removeFromListAndXML(newURL);
+
+ emit statusMsg(i18n("Renaming files..."));
+ progressBar->setTotalSteps(d->m_projectFiles.count());
+ progressBar->setValue(0);
+ progressBar->setTextEnabled(true);
+
+ QDomElement el;
+ bool isFolder = oldURL.fileName(false).isEmpty();
+ ProjectList::Iterator it( d->m_projectFiles );
+ for ( ; it.current(); ++it)
+ {
+ ProjectURL * curUrl = it.current();
+ if ( oldURL == *curUrl || (isFolder && oldURL.isParentOf(*curUrl)) )
+ {
+ curUrl->setPath( curUrl->path().replace(oldURL.path(), newURL.path()) );
+ el = curUrl->domElement;
+ el.setAttribute("url", d->m_projectFiles.toRelative(*curUrl).path());
+// el.setAttribute("upload_time", "");
+ d->m_modified = true;
+ if (! isFolder)
+ break;
+ }
+ progressBar->advance(1);
+ }
+
+ progressBar->setTotalSteps(1);
+ progressBar->setValue(0);
+ progressBar->setTextEnabled(false);
+
+ emit statusMsg(QString::null);
+ if (d->m_modified)
+ setModified(); // there happens more than setting the flag !
+
+ emit reloadTree(&(d->m_projectFiles), false, QStringList());
+ emit newStatus();
+}
+
+
+void Project::slotRemove(const KURL& urlToRemove)
+{
+ emit statusMsg(i18n("Removing files..."));
+ progressBar->setTotalSteps(d->m_projectFiles.count());
+ progressBar->setValue(0);
+ progressBar->setTextEnabled(true);
+
+ KURL url;
+ bool isFolder = d->m_projectFiles.isFolder(urlToRemove);
+ ProjectList projectFiles = d->m_projectFiles;
+ ProjectList::Iterator it(projectFiles);
+ for ( ; it.current(); ++it)
+ {
+ url = *(it.current());
+ if (urlToRemove == url || (isFolder && urlToRemove.isParentOf(url)) )
+ {
+ d->m_projectFiles.removeFromListAndXML(url);
+ d->m_modified = true;
+ emit eventHappened("after_project_remove", url.url(), QString::null);
+ if (!isFolder)
+ break;
+ }
+ progressBar->advance(1);
+ }
+
+ progressBar->setTotalSteps(1);
+ progressBar->setValue(0);
+ progressBar->setTextEnabled(false);
+
+ emit statusMsg(QString::null);
+
+ if (d->m_modified)
+ setModified(); // there happens more than setting the flag !
+ emit reloadTree( &(d->m_projectFiles), false, QStringList() );
+ emit newStatus();
+
+ QString urlPath = QExtFileInfo::toRelative(urlToRemove, d->baseURL).path();
+ QString nice = urlPath;
+ nice = KStringHandler::lsqueeze(nice, 60);
+ if (KMessageBox::warningContinueCancel(d->m_mainWindow, i18n("<qt>Do you want to remove <br><b>%1</b><br> from the server(s) as well?</qt>").arg(nice), i18n("Remove From Server"), KStdGuiItem::remove(), "RemoveFromServer") == KMessageBox::Continue )
+ {
+ QDomNode profilesNode = d->m_sessionDom.firstChild().firstChild().namedItem("uploadprofiles");
+ QDomNodeList profileList = profilesNode.toElement().elementsByTagName("profile");
+ QDomElement e;
+ QString s;
+ for (uint i = 0; i < profileList.count(); i++)
+ {
+ e = profileList.item(i).toElement();
+ QString path = e.attribute("remote_path","");
+ if (!path.startsWith("/"))
+ path.prepend("/");
+ KURL baseUrl;
+ baseUrl.setProtocol(e.attribute("remote_protocol","ftp"));
+ baseUrl.setPort(e.attribute("remote_port","").toInt());
+ baseUrl.setHost(e.attribute("remote_host",""));
+ baseUrl.setPath(path);
+ baseUrl.setUser(e.attribute("user",""));
+ QString passwd = password(e.attribute("remote_protocol") + "://" + e.attribute("user") + "@" + e.attribute("remote_host"));
+ baseUrl.setPass(passwd);
+ baseUrl.addPath(urlPath);
+ KIO::NetAccess::del(baseUrl, d->m_mainWindow);
+ }
+ }
+}
+
+
+
+void Project::slotOptions()
+{
+ KURL url;
+ KDialogBase optionsDlg(KDialogBase::Tabbed, WStyle_DialogBorder, d->m_mainWindow, "project_options", true, i18n("Project Settings"), KDialogBase::Ok | KDialogBase::Cancel);
+ // optionsDlg.setMainWidget(&optionsPage);
+
+ //add the main options page
+ QFrame *page = optionsDlg.addPage(i18n("Options"));
+ ProjectOptions optionsPage(page);
+ QVBoxLayout *topLayout = new QVBoxLayout( page, 0, KDialog::spacingHint() );
+ topLayout->addWidget(&optionsPage);
+
+ optionsPage.linePrjName->setText( d->projectName );
+ url = QExtFileInfo::toRelative(d->templateURL, d->baseURL);
+ optionsPage.linePrjTmpl->setText(QuantaCommon::qUrl(url));
+ url = QExtFileInfo::toRelative(d->toolbarURL, d->baseURL);
+ optionsPage.linePrjToolbar->setText( QuantaCommon::qUrl(url) );
+
+ optionsPage.lineAuthor->setText( d->author );
+ optionsPage.lineEmail->setText( d->email );
+
+ // Signals to handle debugger settings
+ connect(optionsPage.buttonDebuggerOptions, SIGNAL(clicked()),
+ d, SLOT(slotDebuggerOptions()));
+ connect(optionsPage.comboDebuggerClient, SIGNAL(activated(const QString &)),
+ d, SLOT(slotDebuggerChanged(const QString &)));
+
+
+ // Debuggers Combo
+ KTrader::OfferList offers = KTrader::self()->query("Quanta/Debugger");
+ KTrader::OfferList::ConstIterator iterDbg;
+ optionsPage.comboDebuggerClient->clear();
+ optionsPage.comboDebuggerClient->insertItem(i18n("No Debugger"));
+ int idxDbg = 0;
+ d->m_debuggerClientEdit = d->debuggerClient;
+ optionsPage.buttonDebuggerOptions->setEnabled(false);
+ for(iterDbg = offers.begin(); iterDbg != offers.end(); ++iterDbg)
+ {
+ KService::Ptr service = *iterDbg;
+ optionsPage.comboDebuggerClient->insertItem(service->name());
+ idxDbg++;
+ if(d->debuggerClient == service->name())
+ {
+ optionsPage.comboDebuggerClient->setCurrentItem(idxDbg);
+ optionsPage.buttonDebuggerOptions->setEnabled(true);
+ }
+ }
+ optionsPage.checkDebuggerPersistentBreakpoints->setChecked(d->m_debuggerPersistentBreakpoints);
+ optionsPage.checkDebuggerPersistentWatches->setChecked(d->m_debuggerPersistentWatches);
+
+ QString excludeStr;
+ for (uint i = 0; i < d->excludeList.count(); i++)
+ {
+ excludeStr.append(d->excludeList[i]);
+ excludeStr.append(";");
+ }
+ optionsPage.lineExclude->setText(excludeStr);
+ optionsPage.checkCvsignore->setChecked(d->m_excludeCvsignore);
+
+ optionsPage.linePrefix->setText(d->previewPrefix.prettyURL());
+ QStringList lst = DTDs::ref()->nickNameList(true);
+ uint pos = 0;
+ for (uint i = 0; i < lst.count(); i++)
+ {
+ optionsPage.dtdCombo->insertItem(lst[i]);
+ if (lst[i] == DTDs::ref()->getDTDNickNameFromName(d->m_defaultDTD))
+ pos = i;
+ }
+ optionsPage.dtdCombo->setCurrentItem(pos);
+
+
+ QStringList availableEncodingNames(KGlobal::charsets()->availableEncodingNames());
+ optionsPage.encodingCombo->insertStringList( availableEncodingNames );
+ QStringList::ConstIterator iter;
+ int iIndex = -1;
+ for (iter = availableEncodingNames.begin(); iter != availableEncodingNames.end(); ++iter)
+ {
+ ++iIndex;
+ if ((*iter).lower() == d->m_defaultEncoding.lower())
+ {
+ optionsPage.encodingCombo->setCurrentItem(iIndex);
+ break;
+ }
+ }
+
+
+ QStringList list = d->projectViewList();
+ QString defaultView = d->dom.firstChild().firstChild().namedItem("autoload").toElement().attribute("projectview");
+ if (list.count() > 0)
+ {
+ optionsPage.viewCombo->insertStringList(list);
+ for (uint i = 0; i < list.count(); i++)
+ {
+ if (list[i] == defaultView)
+ {
+ optionsPage.viewCombo->setCurrentItem(i);
+ break;
+ }
+ }
+ } else
+ {
+ optionsPage.viewCombo->insertItem(i18n("No view was saved yet."));
+ optionsPage.viewCombo->setEnabled(false);
+ }
+
+ optionsPage.checkPrefix->setChecked(d->usePreviewPrefix);
+ optionsPage.checkPersistentBookmarks->setChecked(d->m_persistentBookmarks);
+
+//add upload profiles page
+ page = optionsDlg.addPage(i18n("Up&load Profiles"));
+ UploadProfilesPage uploadProfilesPage(page);
+ topLayout = new QVBoxLayout( page, 0, KDialog::spacingHint() );
+ topLayout->addWidget(&uploadProfilesPage);
+ QDomElement uploadEl = d->m_sessionDom.firstChild().firstChild().namedItem("uploadprofiles").toElement();
+ uploadProfilesPage.profileLabel->setText(uploadEl.attribute("defaultProfile"));
+ uploadProfilesPage.checkShowUploadTreeviews->setChecked(d->m_showUploadTreeviews);
+
+//add the team members page
+ page = optionsDlg.addPage(i18n("Team Configuration"));
+ TeamMembersDlg membersPage(page);
+ topLayout = new QVBoxLayout( page, 0, KDialog::spacingHint() );
+ topLayout->addWidget(&membersPage);
+
+ QListViewItem *item;
+ if (!teamLeader().name.isEmpty())
+ {
+ TeamMember member = teamLeader();
+ item = new QListViewItem(membersPage.membersListView, member.name, member.nickName, member.email, i18n("Team Leader"), member.task);
+ membersPage.membersListView->insertItem(item);
+ }
+ for (QMap<QString, TeamMember>::ConstIterator it = d->m_subprojectLeaders.constBegin(); it != d->m_subprojectLeaders.constEnd(); ++it)
+ {
+ TeamMember member = it.data();
+ item = new QListViewItem(membersPage.membersListView, member.name, member.nickName, member.email, i18n("Subproject Leader"), member.task, it.key());
+ }
+ for (QMap<QString, TeamMember>::ConstIterator it = d->m_taskLeaders.constBegin(); it != d->m_taskLeaders.constEnd(); ++it)
+ {
+ TeamMember member = it.data();
+ item = new QListViewItem(membersPage.membersListView, member.name, member.nickName, member.email, i18n("Task Leader"), it.key());
+ }
+ for (QValueList<TeamMember>::ConstIterator it = d->m_simpleMembers.constBegin(); it != d->m_simpleMembers.constEnd(); ++it)
+ {
+ TeamMember member = *it;
+ item = new QListViewItem(membersPage.membersListView, member.name, member.nickName, member.email, i18n("Simple Member"), member.task);
+ }
+ membersPage.mailingListEdit->setText(d->m_mailingList);
+ membersPage.setYourself(d->m_yourself);
+
+//add the event configuration page
+ page = optionsDlg.addPage(i18n("Event Configuration"));
+ EventConfigurationDlg eventsPage(d->m_mainWindow->actionCollection(), page);
+ topLayout = new QVBoxLayout( page, 0, KDialog::spacingHint() );
+ topLayout->addWidget(&eventsPage);
+ eventsPage.initEvents(d->m_events);
+ eventsPage.enableEventsBox->setChecked(d->m_eventsEnabled);
+
+ if ( optionsDlg.exec() )
+ {
+ d->projectName = optionsPage.linePrjName->text();
+ d->author = optionsPage.lineAuthor ->text();
+ d->email = optionsPage.lineEmail ->text();
+
+ // Debugger
+ d->debuggerClient = optionsPage.comboDebuggerClient->currentText();
+ d->m_debuggerPersistentBreakpoints = optionsPage.checkDebuggerPersistentBreakpoints->isChecked();
+ d->m_debuggerPersistentWatches = optionsPage.checkDebuggerPersistentWatches->isChecked();
+
+ d->m_defaultDTD = DTDs::ref()->getDTDNameFromNickName(optionsPage.dtdCombo->currentText()).lower();
+ d->m_defaultEncoding = optionsPage.encodingCombo->currentText();
+
+ QuantaCommon::setUrl(d->templateURL, optionsPage.linePrjTmpl->text());
+ d->templateURL.adjustPath(1);
+ d->templateURL = QExtFileInfo::toAbsolute(d->templateURL, d->baseURL);
+ if (!QExtFileInfo::createDir(d->templateURL, d->m_mainWindow))
+ {
+ QuantaCommon::dirCreationError(d->m_mainWindow, d->templateURL);
+ }
+
+ QuantaCommon::setUrl(d->toolbarURL, optionsPage.linePrjToolbar->text());
+ d->toolbarURL.adjustPath(1);
+ d->toolbarURL = QExtFileInfo::toAbsolute(d->toolbarURL, d->baseURL);
+ if (!QExtFileInfo::createDir(d->toolbarURL, d->m_mainWindow))
+ {
+ QuantaCommon::dirCreationError(d->m_mainWindow, d->toolbarURL);
+ }
+
+ d->previewPrefix = KURL::fromPathOrURL( optionsPage.linePrefix->text() );
+ d->usePreviewPrefix = optionsPage.checkPrefix->isChecked();
+ d->m_persistentBookmarks = optionsPage.checkPersistentBookmarks->isChecked();
+
+ QDomNode projectNode = d->dom.firstChild().firstChild();
+ QDomElement el;
+
+ el = projectNode.toElement();
+ el.setAttribute("name",d->projectName);
+ el.setAttribute("encoding", d->m_defaultEncoding);
+ el = d->m_sessionDom.firstChild().firstChild().toElement();
+ el.setAttribute("previewPrefix", d->previewPrefix.url() );
+ el.setAttribute("usePreviewPrefix", d->usePreviewPrefix );
+ el.setAttribute("usePersistentBookmarks", d->m_persistentBookmarks);
+
+ el = projectNode.namedItem("author").toElement();
+ if (!el.isNull())
+ el.parentNode().removeChild(el);
+ el =d->dom.createElement("author");
+ projectNode.appendChild( el );
+ el.appendChild(d->dom.createTextNode( d->author ) );
+
+ el = projectNode.namedItem("email").toElement();
+ if (!el.isNull())
+ el.parentNode().removeChild(el);
+ el =d->dom.createElement("email");
+ projectNode.appendChild( el );
+ el.appendChild(d->dom.createTextNode( d->email ) );
+
+ // Debugger
+ el =projectNode.namedItem("debuggerclient").toElement();
+ if (!el.isNull())
+ el.parentNode().removeChild(el);
+ el =d->dom.createElement("debuggerclient");
+ projectNode.appendChild( el );
+ el.appendChild(d->dom.createTextNode( d->debuggerClient ) );
+ el.setAttribute("persistentBreakpoints", d->m_debuggerPersistentBreakpoints);
+ el.setAttribute("persistentWatches", d->m_debuggerPersistentWatches);
+
+ d->m_excludeCvsignore = optionsPage.checkCvsignore->isChecked();
+ excludeStr = optionsPage.lineExclude->text();
+ el =projectNode.namedItem("exclude").toElement();
+ if (!el.isNull())
+ el.parentNode().removeChild(el);
+ el =d->dom.createElement("exclude");
+ if (d->m_excludeCvsignore)
+ el.setAttribute("cvsignore", "true");
+ else
+ el.setAttribute("cvsignore", "false");
+ projectNode.appendChild( el );
+ el.appendChild(d->dom.createTextNode( excludeStr ) );
+
+ el =projectNode.namedItem("defaultDTD").toElement();
+ if(el.isNull())
+ {
+ el =d->dom.createElement("defaultDTD");
+ projectNode.appendChild(el);
+ el.appendChild(d->dom.createTextNode(d->m_defaultDTD));
+ }
+ else
+ {
+ el.firstChild().setNodeValue(d->m_defaultDTD);
+ }
+
+ el = projectNode.namedItem("templates").toElement();
+ url = QExtFileInfo::toRelative(d->templateURL, d->baseURL);
+ if(el.isNull())
+ {
+ el =d->dom.createElement("templates");
+ projectNode.appendChild(el);
+ el.appendChild(d->dom.createTextNode(QuantaCommon::qUrl(url)));
+ }
+ else
+ {
+ el.firstChild().setNodeValue(QuantaCommon::qUrl(url));
+ }
+
+ url = QExtFileInfo::toRelative(d->toolbarURL, d->baseURL);
+ el = projectNode.namedItem("toolbars").toElement();
+ if(el.isNull())
+ {
+ el =d->dom.createElement("toolbars");
+ projectNode.appendChild(el);
+ el.appendChild(d->dom.createTextNode(QuantaCommon::qUrl(url)));
+ }
+ else
+ {
+ el.firstChild().setNodeValue(QuantaCommon::qUrl(url));
+ }
+
+ if (optionsPage.viewCombo->isEnabled())
+ {
+ defaultView = optionsPage.viewCombo->currentText();
+ el = projectNode.namedItem("autoload").toElement();
+ if (el.isNull())
+ {
+ el =d->dom.createElement("autoload");
+ el.setAttribute("projectview", defaultView);
+ projectNode.appendChild( el );
+ } else
+ {
+ el.setAttribute("projectview", defaultView);
+ }
+ }
+ uploadEl.setAttribute("showtreeviews", uploadProfilesPage.checkShowUploadTreeviews->isChecked() ? "true" : "false");
+
+ QDomNode teamNode = projectNode.namedItem("teamdata");
+ if (!teamNode.isNull())
+ projectNode.removeChild(teamNode);
+ teamNode = d->dom.createElement("teamdata");
+ QDomNode taskLeadersNode = d->dom.createElement("taskleaders");
+ teamNode.appendChild(taskLeadersNode);
+ QDomNode subLeadersNode = d->dom.createElement("subprojectleaders");
+ teamNode.appendChild(subLeadersNode);
+ QListViewItemIterator it(membersPage.membersListView);
+ QListViewItem *item;
+ QStringList savedSubprojects;
+ while (it.current())
+ {
+ item = it.current();
+ QString role = item->text(3);
+ if (role == i18n(teamLeaderStr.utf8()))
+ {
+ QDomElement leaderEl = d->dom.createElement("leader");
+ teamNode.appendChild(leaderEl);
+ el = d->dom.createElement("name");
+ leaderEl.appendChild(el);
+ el.appendChild(d->dom.createTextNode(item->text(0)));
+ el = d->dom.createElement("nickName");
+ leaderEl.appendChild(el);
+ el.appendChild(d->dom.createTextNode(item->text(1)));
+ el = d->dom.createElement("email");
+ leaderEl.appendChild(el);
+ el.appendChild(d->dom.createTextNode(item->text(2)));
+ } else
+ if (role == i18n(subprojectLeaderStr.utf8()))
+ {
+ QString prjName = item->text(5);
+ savedSubprojects.append(prjName);
+ QDomElement subEl = d->dom.createElement("subproject");
+ for (uint i = 0; i < d->m_subprojects.count(); i++)
+ {
+ if (d->m_subprojects[i].name == prjName)
+ {
+ subEl.setAttribute("location", d->m_subprojects[i].location);
+ break;
+ }
+ }
+ subEl.setAttribute("name", prjName);
+ subLeadersNode.appendChild(subEl);
+ el = d->dom.createElement("subprojectleader");
+ el.setAttribute("name", item->text(0));
+ el.setAttribute("nickName", item->text(1));
+ el.setAttribute("email", item->text(2));
+ subEl.appendChild(el);
+ } else
+ if (role == i18n(taskLeaderStr.utf8()))
+ {
+ el = d->dom.createElement("projecttask");
+ el.setAttribute("tasklead", item->text(0));
+ el.setAttribute("nickName", item->text(1));
+ el.setAttribute("email", item->text(2));
+ el.setAttribute("task", item->text(4));
+ taskLeadersNode.appendChild(el);
+ } else
+ if (role == i18n(simpleMemberStr.utf8()))
+ {
+ QDomElement memberEl = d->dom.createElement("member");
+ memberEl.setAttribute("task", item->text(4));
+ teamNode.appendChild(memberEl);
+ el = d->dom.createElement("name");
+ memberEl.appendChild(el);
+ el.appendChild(d->dom.createTextNode(item->text(0)));
+ el = d->dom.createElement("nickName");
+ memberEl.appendChild(el);
+ el.appendChild(d->dom.createTextNode(item->text(1)));
+ el = d->dom.createElement("email");
+ memberEl.appendChild(el);
+ el.appendChild(d->dom.createTextNode(item->text(2)));
+ }
+ ++it;
+ }
+ //subprojects without a leader
+ for (uint i = 0; i < d->m_subprojects.count(); i++)
+ {
+ if (!savedSubprojects.contains(d->m_subprojects[i].name))
+ {
+ el = d->dom.createElement("subproject");
+ el.setAttribute("name", d->m_subprojects[i].name);
+ el.setAttribute("location", d->m_subprojects[i].location);
+ }
+ }
+
+ el = d->dom.createElement("mailinglist");
+ el.setAttribute("address", membersPage.mailingListEdit->text());
+ teamNode.appendChild(el);
+ projectNode.appendChild(teamNode);
+ teamNode = d->m_sessionDom.firstChild().namedItem("teamdata");
+ if (!teamNode.isNull())
+ d->m_sessionDom.firstChild().removeChild(teamNode);
+ d->m_yourself = membersPage.yourself();
+ el = d->m_sessionDom.createElement("teamdata");
+ el.setAttribute("yourself", d->m_yourself);
+ d->m_sessionDom.firstChild().appendChild(el);
+
+ eventsPage.saveEvents(d->dom);
+ d->m_eventsEnabled = eventsPage.enableEventsBox->isChecked();
+ projectNode.toElement().setAttribute("enableEvents", d->m_eventsEnabled?"true":"false");
+
+ setModified();
+ d->loadProjectXML();
+ }
+}
+
+void Project::slotUpload()
+{
+ if (! ViewManager::ref()->saveAll())
+ return;
+
+ if (!d->m_uploadDialog)
+ {
+ d->m_uploadDialog = new ProjectUpload(KURL(), "", false, false, false, i18n("Upload project items..."));
+ connect(d->m_uploadDialog, SIGNAL(eventHappened(const QString&, const QString&, const QString& )), this, SIGNAL(eventHappened(const QString&, const QString&, const QString& )));
+ d->m_uploadDialog->show();
+ } else
+ d->m_uploadDialog->raise();
+}
+
+void Project::slotUploadURL(const KURL& urlToUpload, const QString& profileName, bool quickUpload, bool markOnly)
+{
+ if (!ViewManager::ref()->saveAll())
+ return;
+
+ KURL url = QExtFileInfo::toRelative( urlToUpload, d->baseURL);
+ if (!d->m_uploadDialog)
+ {
+ d->m_uploadDialog = new ProjectUpload(url, profileName, false, quickUpload, markOnly, i18n("Upload project items..."));
+ connect(d->m_uploadDialog, SIGNAL(eventHappened(const QString&, const QString&, const QString& )), this, SIGNAL(eventHappened(const QString&, const QString&, const QString& )));
+ d->m_uploadDialog->show();
+ } else
+ d->m_uploadDialog->raise();
+}
+
+
+void Project::slotGetMessages(const QString& data)
+{
+ emit messages(data);
+}
+
+void Project::slotRescanPrjDir()
+{
+ RescanPrj *dlg = new RescanPrj( d->m_projectFiles, d->baseURL, d->excludeRx,
+ d->m_mainWindow, i18n("New Files in Project's Folder"));
+ if ( dlg->exec() )
+ {
+ d->insertFiles(dlg->files());
+ setModified();
+ emit reloadTree(&(d->m_projectFiles), false, QStringList());
+ }
+ delete dlg;
+}
+/** Returns the relative url with the prefix inserted. */
+KURL Project::urlWithPrefix(const KURL& url)
+{
+ KURL returnUrl = url;
+
+ if (d->usePreviewPrefix)
+ {
+ KURL tempUrl = QExtFileInfo::toRelative(url, d->baseURL );
+ if ( !tempUrl.path().startsWith("/") )
+ {
+ returnUrl = d->previewPrefix;
+ returnUrl.setPath(d->previewPrefix.path(1) + tempUrl.path());
+ }
+ }
+ return returnUrl;
+}
+
+
+/*Returns true if url is already in the project.*/
+bool Project::contains(const KURL& url)
+{
+ if (d->m_projectFiles.isEmpty())
+ d->m_projectFiles.readFromXML(d->dom, d->baseURL, d->templateURL, d->excludeRx);
+ return d->m_projectFiles.contains(url);
+}
+
+void Project::slotFileDescChanged(const KURL& url, const QString& desc)
+{
+ ProjectURL *proUrl = d->m_projectFiles.find(url);
+ if (! proUrl)
+ return;
+
+ QDomElement el = proUrl->domElement;
+ el.setAttribute("desc", desc);
+ proUrl->fileDesc = desc;
+ setModified();
+}
+
+void Project::slotUploadStatusChanged(const KURL& url, int status)
+{
+ if (! d->m_projectFiles.contains(url))
+ return;
+
+ QDomElement el;
+ QString urlStr = url.url();
+ ProjectList::Iterator it( d->m_projectFiles );
+ for ( ; it.current(); ++it)
+ {
+ if ( it.currentKey().startsWith(urlStr) || it.currentKey() + "/" == urlStr)
+ {
+ it.current()->uploadStatus = status;
+ el = it.current()->domElement;
+ el.setAttribute("uploadstatus", status);
+ }
+ }
+ setModified();
+}
+
+void Project::slotChangeDocumentFolderStatus(const KURL &url, bool status)
+{
+ ProjectURL *proUrl = d->m_projectFiles.find(url);
+ if (! proUrl)
+ return;
+
+ QDomElement el = proUrl->domElement;
+ el.setAttribute("documentFolder", (status ? "true" : "false"));
+ proUrl->documentFolder = status;
+ setModified();
+}
+
+
+/** Returns the project's base URL if it exists, the HOME dir if there is no project and no opened document (or the current opened document was not saved yet), and the base URL of the opened document, if it is saved somewhere. */
+KURL Project::projectBaseURL()
+{
+ KURL result;
+ if (hasProject())
+ {
+ result = d->baseURL;
+ } else
+ {
+ Document *w = ViewManager::ref()->activeDocument();
+ if ( !w || w->isUntitled() )
+ {
+ result = QExtFileInfo::home();
+ } else
+ {
+ result = QExtFileInfo::path(w->url());
+ }
+ }
+ return result;
+}
+
+void Project::savePassword(const QString &entry, const QString &passwd, bool store)
+{
+ d->m_passwdList[entry] = passwd;
+ KConfig *config = kapp->config();
+ config->setGroup("Projects");
+ if (store)
+ {
+ config->writeEntry(d->projectName + " | " + entry, KStringHandler::obscure(passwd));
+ //config->writeEntry(projectName + " | " + entry, passwd);
+ }
+ else
+ {
+ config->deleteEntry(d->projectName + " | " + entry);
+ }
+ config->sync();
+}
+
+QString Project::password(const QString &entry)
+{
+ if (d->m_passwdList.contains(entry))
+ return d->m_passwdList[entry];
+ else
+ {
+ KConfig *config = kapp->config();
+ config->setGroup("Projects");
+ QString passwd = KStringHandler::obscure(config->readEntry(d->projectName + " | " + entry,""));
+// QString passwd = config->readEntry(d->projectName + " | " + entry,"");
+ return passwd;
+ }
+}
+
+bool Project::passwordSaved(const QString &entry)
+{
+ KConfig *config = kapp->config();
+ config->setGroup("Projects");
+ QString passwd = KStringHandler::obscure(config->readEntry(d->projectName + " | " + entry,""));
+// QString passwd = config->readEntry(d->projectName + " | " + entry,"");
+ return !passwd.isEmpty();
+}
+
+KURL Project::documentFolderForURL(const KURL& url)
+{
+ KURL docFolderURL = d->baseURL;
+ ProjectList::Iterator it( d->m_projectFiles );
+ for ( ; it.current(); ++it) {
+ if (it.current()->documentFolder && it.current()->isParentOf(url)
+ && docFolderURL.isParentOf(*(it.current())))
+ {
+ docFolderURL = *(it.current());
+ }
+ }
+ return docFolderURL;
+}
+
+void Project::slotReloadProjectDocs()
+{
+ delete d->m_dirWatch;
+ d->m_dirWatch = new KDirWatch(this);
+ connect(d->m_dirWatch, SIGNAL(dirty(const QString &)), SIGNAL(reloadProjectDocs()));
+ connect(d->m_dirWatch, SIGNAL(deleted(const QString &)), SIGNAL(reloadProjectDocs()));
+ if (d->baseURL.isLocalFile())
+ d->m_dirWatch->addDir(d->baseURL.path() + "/doc");
+ KURL url;
+ QString path;
+ ProjectList::Iterator it( d->m_projectFiles );
+ for ( ; it.current(); ++it) {
+ url = *(it.current());
+ path = d->m_projectFiles.toRelative(url).path();
+ if (path.startsWith("doc/") && path.endsWith("/index.html"))
+ {
+ emit addProjectDoc(url);
+ if (url.isLocalFile())
+ d->m_dirWatch->addFile(url.path());
+ }
+ }
+}
+
+
+bool Project::hasProject()
+{
+ return !d->projectName.isNull();
+}
+
+QString Project::projectName()
+{
+ return d->projectName;
+}
+
+const QString& Project::defaultDTD()
+{
+ return d->m_defaultDTD;
+}
+
+
+const QString& Project::defaultEncoding()
+{
+ return d->m_defaultEncoding;
+}
+
+
+KURL Project::toolbarURL()
+{
+ return d->toolbarURL;
+}
+
+
+KURL Project::templateURL()
+{
+ return d->templateURL;
+}
+
+
+QString Project::email()
+{
+ return d->email;
+}
+
+QDomDocument* Project::dom()
+{
+ return &d->dom;
+}
+
+QDomDocument* Project::sessionDom()
+{
+ return &d->m_sessionDom;
+}
+
+QString Project::debuggerClient()
+{
+ return d->debuggerClient;
+}
+
+bool Project::debuggerPersistentBreakpoints( )
+{
+ return d->m_debuggerPersistentBreakpoints;
+}
+
+bool Project::debuggerPersistentWatches( )
+{
+ return d->m_debuggerPersistentWatches;
+}
+
+void Project::setModified(bool b)
+{
+ d->m_modified = b;
+ if (b)
+ d->saveProject();
+}
+
+EventActions* Project::events()
+{
+ if (hasProject())
+ return d->m_events;
+ else
+ return 0L;
+}
+
+QString Project::yourself()
+{
+ return d->m_yourself;
+}
+
+QStringList Project::yourRoles()
+{
+ QStringList roles;
+ if (d->m_yourself.isEmpty())
+ return roles;
+ QString yourNick = d->m_yourself.lower();
+ if (d->m_teamLeader.nickName.lower() == yourNick)
+ roles += "team leader";
+ QValueList<SubProject>::ConstIterator end = d->m_subprojects.constEnd();
+ for (QValueList<SubProject>::ConstIterator it = d->m_subprojects.constBegin(); it != end; ++it)
+ {
+ if (subprojectLeader((*it).name).nickName.lower() == yourNick)
+ roles += "subproject leader:" + (*it).name.lower();
+ }
+
+ for (QMap<QString, TeamMember>::ConstIterator it = d->m_taskLeaders.constBegin(); it != d->m_taskLeaders.constEnd(); ++it)
+ {
+ if (it.data().nickName.lower() == yourNick)
+ roles += "task leader:" + it.key().lower();
+ }
+
+ return roles;
+}
+
+TeamMember Project::teamLeader()
+{
+ return d->m_teamLeader;
+}
+
+TeamMember Project::subprojectLeader(const QString &name)
+{
+ if (d->m_subprojectLeaders.contains(name))
+ return d->m_subprojectLeaders[name];
+ else
+ return TeamMember();
+}
+
+TeamMember Project::taskLeader(const QString &name)
+{
+ if (d->m_taskLeaders.contains(name))
+ return d->m_taskLeaders[name];
+ else
+ return TeamMember();
+}
+
+QValueList<TeamMember> Project::simpleMembers()
+{
+ return d->m_simpleMembers;
+}
+
+QString Project::mailingList()
+{
+ return d->m_mailingList;
+}
+
+QValueList<SubProject>* Project::subprojects()
+{
+ return &d->m_subprojects;
+}
+
+QStringList Project::tasks()
+{
+ QStringList result;
+ for (QMap<QString, TeamMember>::ConstIterator it = d->m_taskLeaders.constBegin(); it != d->m_taskLeaders.constEnd(); ++it)
+ {
+ result << it.key();
+ }
+ return result;
+}
+
+QMap<QString, TeamMember> Project::allMembers()
+{
+ QMap<QString, TeamMember> members;
+ for (QValueList<TeamMember>::ConstIterator it = d->m_simpleMembers.constBegin(); it != d->m_simpleMembers.constEnd(); ++it)
+ {
+ members[(*it).name] = *it;
+ }
+ if (!d->m_teamLeader.name.isEmpty())
+ members[d->m_teamLeader.name] = d->m_teamLeader;
+ for (QMap<QString, TeamMember>::ConstIterator it = d->m_subprojectLeaders.constBegin(); it != d->m_subprojectLeaders.constEnd(); ++it)
+ {
+ members[it.data().name] = it.data();
+ }
+ for (QMap<QString, TeamMember>::ConstIterator it = d->m_taskLeaders.constBegin(); it != d->m_taskLeaders.constEnd(); ++it)
+ {
+ members[it.data().name] = it.data();
+ }
+
+ return members;
+}
+
+void Project::urlMoved(const KURL& srcURL, const KURL &destURL)
+{
+ emit eventHappened("after_file_move", srcURL.url(), destURL.url());
+}
+
+bool Project::queryClose()
+{
+ bool canExit = true;
+ if (hasProject())
+ {
+ emit eventHappened("before_project_close", d->baseURL.url(), QString::null);
+ d->config->setGroup("Projects");
+ KURL url = d->projectURL.url();
+ url.setPass("");
+ d->config->writePathEntry("Last Project", url.url());
+ canExit = d->uploadProjectFile();
+ if (! canExit)
+ {
+ if (KMessageBox::warningContinueCancel(d->m_mainWindow, i18n("Saving of project failed. Do you want to continue with exit (might cause data loss)?"), i18n("Project Saving Error"),KStdGuiItem::quit()) == KMessageBox::Continue)
+ canExit = true;
+ }
+ if (canExit)
+ {
+ emit eventHappened("after_project_close", d->baseURL.url(), QString::null);
+ // empty dom tree
+ d->dom.clear();
+ d->m_sessionDom.clear();
+ d->m_events->clear();
+ d->init();
+ newProjectLoaded(d->projectName, d->baseURL, d->templateURL);
+ reloadTree( &(d->m_projectFiles), true, QStringList());
+ d->adjustActions();
+ d->m_projectRecent->setCurrentItem(-1);
+ newStatus();
+// kapp->processEvents(QEventLoop::ExcludeUserInput | QEventLoop::ExcludeSocketNotifiers);
+ }
+ }
+ return canExit;
+}
+
+bool Project::eventsEnabled()
+{
+ return d->m_eventsEnabled;
+}
+
+void Project::slotShowProjectToolbar(bool show)
+{
+ if (d->m_mainWindow && d->m_mainWindow->factory())
+ {
+ QWidget *w = d->m_mainWindow->factory()->container("project_toolbar", d->m_mainWindow);
+ if (w)
+ {
+ if (show && m_projectToolbarVisible)
+ w->setShown(true);
+ else
+ if (!show)
+ {
+ m_projectToolbarVisible = w->isShown();
+ w->setShown(false);
+ }
+ }
+ }
+}
+
+void Project::loadBookmarks(const KURL &url, KTextEditor::MarkInterface *markIf)
+{
+ if (!markIf || !hasProject() || !contains(url) || !d->m_persistentBookmarks)
+ return;
+ QDomNodeList nl = d->dom.elementsByTagName("item");
+ QDomElement el;
+ KURL u = QExtFileInfo::toRelative(url, d->baseURL);
+ for ( uint i = 0; i < nl.count(); i++ )
+ {
+ el = nl.item(i).toElement();
+ if ( el.attribute("url") == QuantaCommon::qUrl(u) )
+ {
+ QString markListStr = el.attribute("bookmarks");
+ QStringList markList = QStringList::split(",", markListStr);
+ for (uint j = 0; j < markList.count(); j++)
+ {
+ int line = markList[j].toInt();
+ markIf->setMark(line, KTextEditor::MarkInterface::Bookmark);
+ }
+ break;
+ }
+ }
+}
+
+void Project::saveBookmarks(const KURL &url, KTextEditor::MarkInterface *markIf)
+{
+ if (!markIf || !hasProject() || !contains(url) || !d->m_persistentBookmarks)
+ return;
+ QStringList markList;
+ QPtrList<KTextEditor::Mark> marks = markIf->marks();
+ for (uint i = 0; i < marks.count(); i++)
+ {
+ KTextEditor::Mark *mark = marks.at(i);
+ if (mark->type == KTextEditor::MarkInterface::Bookmark)
+ markList << QString("%1").arg(mark->line);
+ }
+ QDomNodeList nl = d->dom.elementsByTagName("item");
+ QDomElement el;
+ KURL u = QExtFileInfo::toRelative(url, d->baseURL);
+ for ( uint i = 0; i < nl.count(); i++ )
+ {
+ el = nl.item(i).toElement();
+ if ( el.attribute("url") == QuantaCommon::qUrl(u) )
+ {
+ el.setAttribute("bookmarks", markList.join(","));
+ break;
+ }
+ }
+}
+
+void Project::loadCursorPosition(const KURL &url, KTextEditor::ViewCursorInterface *viewCursorIf)
+{
+ if (!viewCursorIf || !hasProject() || !contains(url))
+ return;
+ QDomNodeList nl = d->m_sessionDom.elementsByTagName("item");
+ QDomElement el;
+ KURL u = QExtFileInfo::toRelative(url, d->baseURL);
+ for ( uint i = 0; i < nl.count(); i++ )
+ {
+ el = nl.item(i).toElement();
+ if ( el.attribute("url") == QuantaCommon::qUrl(u) )
+ {
+ QString s = el.attribute("line");
+ uint line, col;
+ bool ok;
+ line = s.toUInt(&ok, 10);
+ if (ok)
+ {
+ s = el.attribute("column");
+ col = s.toUInt(&ok, 10);
+ if (ok)
+ viewCursorIf->setCursorPositionReal(line, col);
+ }
+ }
+ KURL u2 = d->baseURL;
+ QuantaCommon::setUrl(u2, el.attribute("url"));
+ if (!contains(u2))
+ {
+ el.parentNode().removeChild(el);
+ }
+ }
+}
+
+void Project::saveCursorPosition(const KURL &url, KTextEditor::ViewCursorInterface *viewCursorIf)
+{
+ if (!viewCursorIf || !hasProject() || !contains(url))
+ return;
+ QDomNodeList nl = d->m_sessionDom.elementsByTagName("item");
+ QDomElement el;
+ KURL u = QExtFileInfo::toRelative(url, d->baseURL);
+ uint line, col;
+ viewCursorIf->cursorPosition(&line, &col);
+ bool found = false;
+ for ( uint i = 0; i < nl.count(); i++ )
+ {
+ el = nl.item(i).toElement();
+ if ( el.attribute("url") == QuantaCommon::qUrl(u) )
+ {
+ el.setAttribute("line", line);
+ el.setAttribute("column", col);
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ {
+ el = d->m_sessionDom.createElement("item");
+ el.setAttribute("column", col);
+ el.setAttribute("line", line);
+ el.setAttribute("url", QuantaCommon::qUrl(u));
+ QDomNode no = d->m_sessionDom.firstChild().firstChild().namedItem("itemcursorpositions");
+ no.appendChild(el);
+ }
+}
+#include "project.moc"
diff --git a/quanta/project/project.h b/quanta/project/project.h
new file mode 100644
index 00000000..b6775da7
--- /dev/null
+++ b/quanta/project/project.h
@@ -0,0 +1,220 @@
+/***********************************************************************
+ project.h - description
+ -------------------
+ begin : Thu Mar 16 2000
+ copyright : (C) 2000 by Yacovlev Alexander & Dmitry Poplavsky <[email protected]>
+ (C) 2001-2005 by Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PROJECT_H
+#define PROJECT_H
+
+#include <qobject.h>
+
+#include "projecturl.h"
+
+class QDom;
+class ProjectPrivate;
+class ProjectList;
+namespace KTextEditor{
+ class MarkInterface;
+ class ViewCursorInterface;
+}
+struct EventAction;
+typedef QMap<QString, QValueList<EventAction> > EventActions;
+
+/**project
+ *@author Yacovlev Alexander & Dmitry Poplavsky & Andras Mantia & Jens Herden
+ */
+
+class KConfig;
+class KMainWindow;
+
+struct TeamMember {
+ QString name;
+ QString email;
+ QString nickName;
+ QString task;
+};
+
+struct SubProject {
+ QString name;
+ QString location;
+};
+
+class Project : public QObject {
+ Q_OBJECT
+ friend class ProjectPrivate; // need this because I use the signals
+
+public:
+
+ /**
+ * since this class is a singleton you must use this function to access it
+ *
+ * the parameter is only used at the first call to create the class
+ *
+ */
+ static Project* const ref(KMainWindow *parent = 0L)
+ {
+ static Project *m_ref;
+ if (!m_ref) m_ref = new Project(parent);
+ return m_ref;
+ }
+
+ ~Project();
+
+ bool hasProject();
+ QString projectName();
+
+ QStringList fileNameList();
+ KURL::List files();
+
+ void insertFile( const KURL& nameURL, bool repaint );
+ void readConfig(KConfig *);
+ /** loads the last project again if reload == true
+ but checks in any case if there is a left over project from a crash
+ */
+ void loadLastProject(bool reload);
+ /** Returns the relative url with the prefix inserted. */
+ KURL urlWithPrefix(const KURL& url);
+ bool contains(const KURL &url);
+ /** Read property of QString defaultDTD. */
+ const QString& defaultDTD();
+ const QString& defaultEncoding();
+
+ /** Returns the project's base URL if it exists,
+ * the HOME dir if there is no project and no opened document
+ * (or the current opened document was not saved yet),
+ * and the base URL of the opened document, if it is saved somewhere.
+ */
+ KURL projectBaseURL();
+ KURL documentFolderForURL(const KURL &url);
+
+ /** Saves the password for entry into a list. Stores on disc if store == true */
+ void savePassword(const QString& entry, const QString& passwd, bool store);
+ /** Returns the saved password for entry */
+ QString password(const QString &entry);
+ bool passwordSaved(const QString &entry);
+ QDomDocument *dom();
+ QDomDocument *sessionDom();
+ QString debuggerClient();
+ bool debuggerPersistentBreakpoints();
+ bool debuggerPersistentWatches();
+ bool keepPasswd;
+ QString email();
+ KURL templateURL();
+ KURL toolbarURL();
+ EventActions* events();
+ /**
+ * Get the nickname of the current user (you)
+ * @return the nickname
+ */
+ QString yourself();
+ /**
+ * Get the roles of the current user in the form "role:task".
+ * Examples: "team leader", "project leader:subprojectname", "task leader:taskname".
+ * @return the roles (in lowercase)
+ */
+ QStringList yourRoles();
+ TeamMember teamLeader();
+ TeamMember subprojectLeader(const QString &name);
+ TeamMember taskLeader(const QString &name);
+ QValueList<TeamMember> simpleMembers();
+ QString mailingList();
+ QValueList<SubProject>* subprojects();
+ QStringList tasks();
+ QMap<QString, TeamMember> allMembers();
+ bool eventsEnabled();
+ void setProjectToolbarVisible(bool visible) {m_projectToolbarVisible = visible;}
+
+ /** Called when an url was moved inside the project with drag &drop */
+ void urlMoved(const KURL& srcURL, const KURL &destURL);
+ /**
+ test if application can close
+
+ @return true if close is possible
+ */
+ bool queryClose();
+
+ /** Saves the bookmarks for the url into the project file */
+ void saveBookmarks(const KURL &url, KTextEditor::MarkInterface *markIf);
+ /** Loads the bookmarks for the url from the project file and sets them in the view*/
+ void loadBookmarks(const KURL &url, KTextEditor::MarkInterface *markIf);
+ void saveCursorPosition(const KURL &url, KTextEditor::ViewCursorInterface *viewCursorIf);
+ void loadCursorPosition(const KURL &url, KTextEditor::ViewCursorInterface *viewCursorIf);
+
+public slots:
+
+ void slotOpenProject(const KURL&);
+ void slotOptions();
+ void slotUpload();
+ void slotUploadURL(const KURL &urlToUpload, const QString &profileName, bool quickUpload, bool markOnly);
+
+ void slotAddDirectory(const KURL& dirURL, bool showDlg = true);
+ void slotInsertFile(const KURL& url);
+ void slotInsertFilesAfterCopying(const KURL::List& a_url);
+
+ /** if somewhere something was renamed */
+ void slotRenamed(const KURL& oldURL, const KURL& newURL);
+ void slotRemove(const KURL& urlToRemove);
+
+
+ void slotGetMessages(const QString&);
+
+ void slotRescanPrjDir();
+ void slotFileDescChanged(const KURL& url, const QString& desc);
+ void slotUploadStatusChanged(const KURL& url, int status);
+ void slotChangeDocumentFolderStatus(const KURL& url, bool status);
+
+ void slotReloadProjectDocs();
+
+ void slotShowProjectToolbar(bool show);
+
+ void setModified(bool b = true);
+
+signals:
+
+ void openFile( const KURL&, const QString& );
+ void openFiles( const KURL::List&, const QString& );
+ void closeFile( const KURL&);
+ void closeFiles();
+
+ void reloadTree(ProjectList *, bool, const QStringList &);
+
+ void messages(const QString& );
+ void enableMessageWidget();
+
+ void newStatus();
+ void statusMsg(const QString &);
+ /** No descriptions */
+ void newProjectLoaded(const QString &, const KURL &, const KURL &);
+ void reloadProjectDocs();
+ void hideSplash();
+ void addProjectDoc(const KURL &);
+ void getUserToolbarFiles(KURL::List *);
+ void loadToolbarFile(const KURL &);
+ /** ask for the tree status for saving in project */
+ void getTreeStatus(QStringList *);
+ void eventHappened(const QString&, const QString&, const QString& );
+
+private:
+ /** The constructor is privat because we use singleton patter.
+ * If you need the class use Project::ref() for
+ * construction and reference
+ */
+ Project(KMainWindow *parent);
+
+ ProjectPrivate *d;
+ bool m_projectToolbarVisible;
+};
+
+#endif
diff --git a/quanta/project/projectlist.cpp b/quanta/project/projectlist.cpp
new file mode 100644
index 00000000..f5fdc24e
--- /dev/null
+++ b/quanta/project/projectlist.cpp
@@ -0,0 +1,187 @@
+/***********************************************************************
+ projectlist.cpp - List of ProjectURL's
+ -------------------
+ begin : June 19 2004
+ copyright : (C) 2004 by Jens Herden <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// qt includes
+#include <qdom.h>
+#include <qstring.h>
+#include <qfileinfo.h>
+
+// kde includes
+#include <kprogress.h>
+
+#include "projectlist.h"
+#include "projecturl.h"
+#include "resource.h"
+#include "quantacommon.h"
+
+
+ProjectList::ProjectList(int size) : ProjectUrlList(size)
+{
+}
+
+
+void ProjectList::clear()
+{
+ m_baseURL = KURL();
+ ProjectUrlList::clear();
+}
+
+bool ProjectList::readFromXML(QDomDocument &dom, const KURL &baseURL,
+ const KURL &/*templateURL*/, const QRegExp &excludeRx)
+{
+ clear(); // empty the list
+ m_baseURL = baseURL; // remember this
+ bool modified = false;
+ QDomElement el;
+ QDomNodeList nl = dom.firstChild().firstChild().childNodes();
+ progressBar->setTotalSteps(nl.count() - 1);
+ progressBar->setValue(0);
+ progressBar->setTextEnabled(true);
+ QString path;
+ QString tmpString;
+ uint nlCount = nl.count();
+ for ( uint i = 0; i < nlCount; i++ )
+ {
+ KURL url = baseURL;
+ el = nl.item(i).toElement();
+ tmpString = el.attribute("url");
+ if (!tmpString.isEmpty())
+ {
+ QuantaCommon::setUrl(url,tmpString);
+ //Compatibility conversion
+ if (tmpString != QuantaCommon::qUrl(url))
+ {
+ el.setAttribute("url", QuantaCommon::qUrl(url));
+ modified = true;
+ }
+ }
+ path = url.path();
+ url = QExtFileInfo::toAbsolute(url, baseURL);
+ if ( el.nodeName() == "item" )
+ {
+ if (excludeRx.exactMatch(path) || find(url.url(-1)))
+ {
+ el.parentNode().removeChild(el);
+ modified = true;
+ i--;
+ } else
+ {
+ bool docFolder = (el.attribute("documentFolder", "false") == "true");
+ int uploadStatus = el.attribute("uploadstatus", "-1").toInt();
+ if (uploadStatus == -1)
+ el.setAttribute("uploadstatus", 1);
+ //remove non-existent local files
+ if ( url.isLocalFile() )
+ {
+ QFileInfo fi( url.path() );
+ if ( !fi.exists() )
+ {
+ el.parentNode().removeChild( el );
+ modified = true;
+ i--;
+ } else
+ {
+ insert(url.url(-1), new ProjectURL(url, el.attribute("desc"), el.attribute("uploadstatus", "1").toInt(),
+ docFolder, el));
+ }
+ } else
+ {
+ insert(url.url(-1), new ProjectURL(url, el.attribute("desc"), el.attribute("uploadstatus", "1").toInt(),
+ docFolder, el));
+ }
+ }
+ }
+ progressBar->advance(1);
+ }
+ ProjectURL *proUrl = find(baseURL);
+ if (!proUrl)
+ {
+ el = dom.createElement("item");
+ el.setAttribute("url", "");
+ el.setAttribute("uploadstatus", "1");
+ dom.firstChild().firstChild().appendChild(el);
+ insert(baseURL.url(-1), new ProjectURL(baseURL, "", ProjectURL::AlwaysUpload,
+ true, el));
+ modified = true;
+ }
+ progressBar->setTotalSteps(1);
+ progressBar->setValue(0);
+ progressBar->setTextEnabled(false);
+ return modified;
+}
+
+
+bool ProjectList::removeFromListAndXML(const KURL &url)
+{
+ ProjectURL *p = find(url);
+ if (p) {
+ QDomElement el = p->domElement;
+ el.parentNode().removeChild(el);
+ remove(url.url(-1));
+ return true;
+ }
+ return false;
+}
+
+
+bool ProjectList::contains(const KURL &url) const
+{
+ return ProjectUrlList::find(url.url(-1));
+}
+
+
+ProjectURL * ProjectList::find(const KURL &url) const
+{
+ return ProjectUrlList::find(url.url(-1));
+}
+
+
+void ProjectList::insert(ProjectURL *url)
+{
+ ProjectUrlList::insert(url->url(-1), url);
+}
+
+
+bool ProjectList::isFolder(const KURL &url) const
+{
+ ProjectURL *p = find(url);
+ return ( p && url.url(-1) != (*p).url() );
+}
+
+
+void ProjectList::insert(const QString & key, const ProjectURL * item)
+{
+ ProjectUrlList::insert(key, item);
+}
+
+
+ProjectURL * ProjectList::find ( const QString & key ) const
+{
+ return ProjectUrlList::find(key);
+}
+
+
+bool ProjectList::remove ( const QString & key )
+{
+ return ProjectUrlList::remove(key);
+}
+
+
+void ProjectList::replace(const QString & key, const ProjectURL * item)
+{
+ ProjectUrlList::replace(key, item);
+}
+
diff --git a/quanta/project/projectlist.h b/quanta/project/projectlist.h
new file mode 100644
index 00000000..505fbfd0
--- /dev/null
+++ b/quanta/project/projectlist.h
@@ -0,0 +1,115 @@
+/***********************************************************************
+ projectlist.h - List of ProjectURL's
+ -------------------
+ begin : June 19 2004
+ copyright : (C) 2004 by Jens Herden <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PROJECTLIST_H
+#define PROJECTLIST_H
+
+#include "projecturl.h"
+#include "qextfileinfo.h"
+
+class QDomDocument;
+
+
+/**
+ @short Container for the project files.
+
+ For fast lookup this container is based on QDict.
+ The key is generated without a trailing '/' so it doesn't matter if you
+ search for a folder in this container with or without trailing '/'
+*/
+
+class ProjectList : public ProjectUrlList
+{
+public:
+ /** 1009 is a guess for maximum files in an average project, this number should be prime (@ref QDict)
+ */
+ ProjectList( int size = 1009 );
+ ~ProjectList() {};
+
+ typedef QDictIterator<ProjectURL> Iterator;
+
+ /** resets @ref m_baseURL */
+ void clear();
+
+ /**
+ reads entries from the dom tree
+ invalid entries gets removed!
+ @return true if an old structure was found
+ */
+ bool readFromXML(QDomDocument &dom, const KURL &baseURL,
+ const KURL &templateURL, const QRegExp &excludeRx);
+ /**
+ @return the relative URL
+ */
+ KURL toRelative(const KURL &url) const
+ {
+ return QExtFileInfo::toRelative(url, m_baseURL, false);
+ }
+
+ /**
+ removes an url from the list and deletes the corresponding node
+
+ @return true if url was in list
+ */
+ bool removeFromListAndXML(const KURL &url);
+
+ /** @return true if url is in container
+ */
+ bool contains(const KURL &url) const;
+
+ /** @return pointer to the entry or 0 if not found
+ */
+ ProjectURL * find(const KURL &url) const;
+
+ /**
+ Attention: never delete the object you have given here because the
+ container takes ownership and deletes it later!
+
+ @param the ProjectURL to add to the container
+ */
+ void insert(ProjectURL *url);
+
+ /** @return true if url is in container and a folder
+ */
+ bool isFolder(const KURL &url) const;
+
+private:
+ KURL m_baseURL;
+
+ /**
+ private because I want to control the key.
+ use insert(ProjectURL *url) instead.
+ */
+ void insert(const QString & key, const ProjectURL * item);
+
+ /**
+ private because I want to control the key.
+ use find(const KURL &url) instead.
+ */
+ ProjectURL *find ( const QString & key ) const;
+
+ /**
+ private because I want to control the key.
+ */
+ bool remove ( const QString & key );
+
+ /**
+ private because I want to control the key.
+ */
+ void replace(const QString & key, const ProjectURL * item);
+};
+
+#endif // PROJECTFILES_H
diff --git a/quanta/project/projectnewfinal.cpp b/quanta/project/projectnewfinal.cpp
new file mode 100644
index 00000000..c1901e69
--- /dev/null
+++ b/quanta/project/projectnewfinal.cpp
@@ -0,0 +1,42 @@
+/***************************************************************************
+ projectnewgeneral.cpp - description
+ -------------------
+ begin : Fri Oct 27 2000
+ copyright : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon <[email protected],[email protected],[email protected]>
+ (C) 2001-2002 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// qt includes
+#include <qlabel.h>
+#include <qlayout.h>
+
+// kde includes
+#include <kiconloader.h>
+
+// app includes
+#include "projectnewfinal.h"
+#include "projectnewfinal.moc"
+
+ProjectNewFinal::ProjectNewFinal(QWidget *parent, const char *name )
+ : ProjectNewFinalS(parent,name)
+{
+ imagelabel->setPixmap( UserIcon("wiznewprjfin") );
+}
+
+ProjectNewFinal::~ProjectNewFinal(){
+}
+
+void ProjectNewFinal::setMargin(int i)
+{
+ layout()->setMargin(i);
+}
+
diff --git a/quanta/project/projectnewfinal.h b/quanta/project/projectnewfinal.h
new file mode 100644
index 00000000..5cde0ac5
--- /dev/null
+++ b/quanta/project/projectnewfinal.h
@@ -0,0 +1,36 @@
+/***************************************************************************
+ projectnewgeneral.h - description
+ -------------------
+ begin : Fri Oct 27 2000
+ copyright : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon <[email protected],[email protected],[email protected]>
+ (C) 2001-2002 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PROJECTNEWFINAL_H
+#define PROJECTNEWFINAL_H
+
+#include "projectnewfinals.h"
+
+/**
+ *@author Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon
+ */
+
+class ProjectNewFinal : public ProjectNewFinalS {
+ Q_OBJECT
+public:
+ ProjectNewFinal(QWidget *parent=0, const char *name=0);
+ ~ProjectNewFinal();
+
+ void setMargin(int);
+};
+
+#endif
diff --git a/quanta/project/projectnewfinals.ui b/quanta/project/projectnewfinals.ui
new file mode 100644
index 00000000..ffaac915
--- /dev/null
+++ b/quanta/project/projectnewfinals.ui
@@ -0,0 +1,296 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ProjectNewFinalS</class>
+<comment>/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+</comment>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>ProjectNewFinalS</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>620</width>
+ <height>418</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>620</width>
+ <height>410</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32000</width>
+ <height>32000</height>
+ </size>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>imagelabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>115</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>115</width>
+ <height>480</height>
+ </size>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ <property name="alignment">
+ <set>AlignTop|AlignLeft</set>
+ </property>
+ <property name="vAlign" stdset="0">
+ </property>
+ </widget>
+ <spacer row="1" column="1">
+ <property name="name">
+ <cstring>spacer10</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout11</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Prefix:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>lineAuthor</cstring>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0" rowspan="1" colspan="5">
+ <property name="name">
+ <cstring>GroupBox4</cstring>
+ </property>
+ <property name="title">
+ <string>Project Defaults</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel3_2_3</cstring>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Default DTD:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="1">
+ <property name="name">
+ <cstring>encodingCombo</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>TextLabel3_2_2_2</cstring>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Default encoding:</string>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="0" column="1">
+ <property name="name">
+ <cstring>dtdCombo</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QCheckBox" row="6" column="0" rowspan="1" colspan="5">
+ <property name="name">
+ <cstring>insertLocalTemplates</cstring>
+ </property>
+ <property name="text">
+ <string>Insert &amp;local templates</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="5" column="0" rowspan="1" colspan="5">
+ <property name="name">
+ <cstring>insertGlobalTemplates</cstring>
+ </property>
+ <property name="text">
+ <string>Insert &amp;global templates</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="5">
+ <property name="name">
+ <cstring>checkPrefix</cstring>
+ </property>
+ <property name="text">
+ <string>Use preview prefi&amp;x</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Author:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="4">
+ <property name="name">
+ <cstring>lineEmail</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <spacer row="0" column="2">
+ <property name="name">
+ <cstring>Spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="Line" row="4" column="0" rowspan="1" colspan="5">
+ <property name="name">
+ <cstring>Line4</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="3" column="1" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>linePrefix</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="3">
+ <property name="name">
+ <cstring>TextLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>Email:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>checkPrefix</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>linePrefix</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>checkPrefix</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>TextLabel1</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>lineAuthor</tabstop>
+ <tabstop>lineEmail</tabstop>
+ <tabstop>dtdCombo</tabstop>
+ <tabstop>encodingCombo</tabstop>
+ <tabstop>checkPrefix</tabstop>
+ <tabstop>linePrefix</tabstop>
+ <tabstop>insertGlobalTemplates</tabstop>
+ <tabstop>insertLocalTemplates</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/quanta/project/projectnewgeneral.cpp b/quanta/project/projectnewgeneral.cpp
new file mode 100644
index 00000000..3f5fe547
--- /dev/null
+++ b/quanta/project/projectnewgeneral.cpp
@@ -0,0 +1,254 @@
+/***************************************************************************
+ projectnewgeneral.cpp - description
+ -------------------
+ begin : Fri Oct 27 2000
+ copyright : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon <[email protected],[email protected],[email protected]>
+ (C) 2001-2002 by Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// qt includes
+#include <qdir.h>
+#include <qevent.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qradiobutton.h>
+#include <qcombobox.h>
+
+// kde includes
+#include <kfiledialog.h>
+#include <kiconloader.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kurl.h>
+#include <kprotocolinfo.h>
+#include <kdeversion.h>
+
+//app includes
+#include "projectnewgeneral.h"
+#include "quantacommon.h"
+#include "qextfileinfo.h"
+
+ProjectNewGeneral::ProjectNewGeneral(QWidget *parent, const char *name )
+ : ProjectNewGeneralS(parent,name)
+{
+ imagelabel->setPixmap( UserIcon("wiznewprjglb") );
+ linePrjName->setFocus();
+
+ QStringList protocols = KProtocolInfo::protocols();
+ protocols.sort();
+ for ( uint i=0; i<protocols.count(); i++ )
+ {
+ KURL p;
+ p.setProtocol(protocols[i]);
+ QString protocol = protocols[i];
+ if ( KProtocolInfo::supportsWriting(p) &&
+ KProtocolInfo::supportsMakeDir(p) &&
+ KProtocolInfo::supportsDeleting(p) &&
+ (protocol != "file" && protocol != "fonts" && protocol != "floppy" && protocol != "newcd" ))
+ {
+ comboProtocol->insertItem(protocol);
+ }
+ }
+ comboProtocol->setCurrentItem(0);
+
+ slotProtocolChanged(i18n("Local"));
+
+ linePrjTmpl->setText("templates");
+ linePrjToolbar->setText("toolbars");
+
+ connect(comboProtocol, SIGNAL(activated(const QString&)), SLOT(slotProtocolChanged(const QString &)));
+ connect( linePrjFile, SIGNAL(textChanged(const QString &)),
+ this, SLOT(slotLinePrjFile(const QString &)));
+ connect( linePrjName, SIGNAL(textChanged(const QString &)),
+ this, SLOT(slotLinePrjFile(const QString &)));
+ connect( linePrjDir, SIGNAL(textChanged(const QString &)),
+ this, SLOT(slotLinePrjFile(const QString &)));
+ connect( buttonDir, SIGNAL(clicked()),
+ this, SLOT(slotButtonDir()));
+ connect( linePrjName, SIGNAL(textChanged(const QString &)),
+ this, SLOT(slotChangeNames(const QString &)));
+ connect( linePrjTmpl, SIGNAL(textChanged(const QString &)), SLOT(slotLinePrjFile(const QString &)));
+ connect( buttonTmpl, SIGNAL(clicked()), SLOT(slotButtonTmpl()));
+ connect( linePrjToolbar, SIGNAL(textChanged(const QString &)), SLOT(slotLinePrjFile(const QString &)));
+ connect( buttonToolbar, SIGNAL(clicked()), SLOT(slotButtonToolbar()));
+
+ linePrjTmpl->installEventFilter(this);
+ linePrjToolbar->installEventFilter(this);
+}
+
+ProjectNewGeneral::~ProjectNewGeneral(){
+}
+
+void ProjectNewGeneral::slotButtonDir()
+{
+ slotLinePrjFile(""); // make sure baseUrl is correct
+ KURL url = KFileDialog::getExistingURL(baseUrl.url(), this,
+ i18n("Select Project Folder"));
+ if (!url.isEmpty())
+ {
+ linePrjDir->setText(url.path());
+ }
+}
+
+void ProjectNewGeneral::slotLinePrjFile( const QString & )
+{
+
+ bool valid = !(linePrjFile->text().isEmpty() ||
+ linePrjName->text().isEmpty() ||
+ linePrjDir ->text().isEmpty() ||
+ linePrjTmpl->text().isEmpty() ||
+ linePrjToolbar->text().isEmpty());
+ KURL url;
+ QString s = lineHost->text();
+ if (! s.isEmpty())
+ url.setHost(s);
+
+ s = lineUser->text();
+ if (! s.isEmpty())
+ url.setUser(s);
+ s = linePasswd->text();
+ if (! s.isEmpty())
+ url.setPass(s);
+
+ s = linePort->text();
+ if (! s.isEmpty())
+ url.setPort(linePort->text().toInt());
+
+ url.setProtocol(comboProtocol->currentText());
+ if (url.protocol() == i18n("Local")) url.setProtocol("file");
+ url.setPath(linePrjDir->text());
+ url.adjustPath(1);
+ if (!url.path().startsWith("/")) url.setPath("/"+url.path());
+
+ if (url.isValid())
+ {
+ emit setBaseURL(url);
+ baseUrl = url;
+ if (baseUrl.isLocalFile())
+ {
+ s = QExtFileInfo::canonicalPath(baseUrl.path());
+ if (!s.isEmpty())
+ baseUrl.setPath(s);
+ }
+ }
+ emit enableNextButton( this, valid );
+}
+
+void ProjectNewGeneral::slotChangeNames( const QString &text )
+{
+ int i;
+ QString fname = text.lower();
+ while( (i=fname.find(" ")) >=0 ) fname.remove(i,1);
+
+ linePrjFile->setText( fname+".webprj" );
+}
+
+QString ProjectNewGeneral::type()
+{
+// if ( radioCvs ->isChecked() ) return "CVS";
+ if ( radioLocal->isChecked() ) return "Local";
+ if ( radioWeb ->isChecked() ) return "Web";
+ return "Local";
+}
+
+void ProjectNewGeneral::setMargin(int i)
+{
+ layout()->setMargin(i);
+}
+
+void ProjectNewGeneral::slotButtonTmpl()
+{
+ slotLinePrjFile(""); // make sure baseUrl is correct
+ KURL url = KFileDialog::getExistingURL(baseUrl.url(), this,
+ i18n("Select Project Template Folder"));
+ if (!url.isEmpty() && baseUrl.isParentOf(url))
+ {
+ linePrjTmpl->setText(KURL::relativeURL(baseUrl, url));
+ } else
+ {
+ KMessageBox::sorry(this, i18n("<qt>The project templates must be stored under the main project folder: <br><br><b>%1</b></qt>").arg(baseUrl.prettyURL(0, KURL::StripFileProtocol)));
+ }
+}
+
+void ProjectNewGeneral::slotButtonToolbar()
+{
+ slotLinePrjFile(""); // make sure baseUrl is correct
+ KURL url = KFileDialog::getExistingURL(baseUrl.url(), this,
+ i18n("Select Project Toolbar & Actions Folder"));
+ if (!url.isEmpty() && baseUrl.isParentOf(url))
+ {
+ linePrjToolbar->setText(KURL::relativeURL(baseUrl, url));
+ }
+ {
+ KMessageBox::sorry(0, i18n("<qt>The project toolbars must be stored under the main project folder: <br><br><b>%1</b></qt>")
+ .arg(baseUrl.prettyURL(0, KURL::StripFileProtocol)));
+ }
+}
+
+
+void ProjectNewGeneral::slotProtocolChanged(const QString& protocol)
+{
+ bool status = true;
+ if (protocol == i18n("Local"))
+ {
+ status = false;
+ }
+ lineHost->setEnabled(status);
+ lineUser->setEnabled(status);
+ linePasswd->setEnabled(status);
+ linePort->setEnabled(status);
+ radioWeb->setEnabled(!status);
+ slotChangeNames(linePrjName->text());
+ if ( !status )
+ lineHost->clear();
+}
+
+bool ProjectNewGeneral::eventFilter ( QObject * watched, QEvent * e )
+{
+ if (e->type() == QEvent::FocusOut)
+ {
+ if (watched == linePrjTmpl)
+ {
+ KURL url = baseUrl;
+ QuantaCommon::setUrl(url, linePrjTmpl->text());
+ url = QExtFileInfo::toAbsolute(url, baseUrl);
+ if (!baseUrl.isParentOf(url))
+ {
+ KMessageBox::sorry(this,i18n("<qt>The project templates must be stored under the main project folder: <br><br><b>%1</b></qt>").arg(baseUrl.prettyURL(0, KURL::StripFileProtocol)));
+ linePrjTmpl->setFocus();
+ emit enableNextButton(this, false);
+ } else
+ emit enableNextButton(this, true);
+ } else
+ if (watched == linePrjToolbar)
+ {
+ KURL url = baseUrl;
+ QuantaCommon::setUrl(url, linePrjToolbar->text());
+ url = QExtFileInfo::toAbsolute(url, baseUrl);
+ if (!baseUrl.isParentOf(url))
+ {
+ KMessageBox::sorry(0,i18n("<qt>The project toolbars must be stored under the main project folder: <br><br><b>%1</b></qt>")
+ .arg(baseUrl.prettyURL(0, KURL::StripFileProtocol)));
+ linePrjToolbar->setFocus();
+ emit enableNextButton(this, false);
+ } else
+ emit enableNextButton(this, true);
+ }
+ }
+ return false;
+}
+
+#include "projectnewgeneral.moc"
+
+
diff --git a/quanta/project/projectnewgeneral.h b/quanta/project/projectnewgeneral.h
new file mode 100644
index 00000000..b167c15c
--- /dev/null
+++ b/quanta/project/projectnewgeneral.h
@@ -0,0 +1,58 @@
+/***************************************************************************
+ projectnewgeneral.h - description
+ -------------------
+ begin : Fri Oct 27 2000
+ copyright : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon <[email protected],[email protected],[email protected]>
+ (C) 2001, 2002 by Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PROJECTNEWGENERAL_H
+#define PROJECTNEWGENERAL_H
+
+#include "projectnewgenerals.h"
+
+/**
+ *@author Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon
+ */
+
+class KURL;
+
+class ProjectNewGeneral : public ProjectNewGeneralS {
+ Q_OBJECT
+public:
+ ProjectNewGeneral(QWidget *parent=0, const char *name=0);
+ ~ProjectNewGeneral();
+
+ QString type();
+ void setMargin(int);
+
+protected:
+ bool eventFilter ( QObject * watched, QEvent * e );
+
+public slots:
+ void slotButtonDir();
+ void slotLinePrjFile(const QString &);
+ void slotChangeNames(const QString &);
+ void slotButtonTmpl();
+ void slotButtonToolbar();
+ void slotProtocolChanged(const QString& protocol);
+
+
+signals:
+ void setBaseURL(const KURL&);
+ void enableNextButton(QWidget *, bool);
+
+private:
+ KURL baseUrl;
+};
+
+#endif
diff --git a/quanta/project/projectnewgenerals.ui b/quanta/project/projectnewgenerals.ui
new file mode 100644
index 00000000..dfc0e55f
--- /dev/null
+++ b/quanta/project/projectnewgenerals.ui
@@ -0,0 +1,454 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ProjectNewGeneralS</class>
+<comment>/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+</comment>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>ProjectNewGeneralS</cstring>
+ </property>
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>620</width>
+ <height>418</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>620</width>
+ <height>410</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32000</width>
+ <height>32000</height>
+ </size>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>imagelabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>115</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>115</width>
+ <height>480</height>
+ </size>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ <property name="alignment">
+ <set>AlignTop|AlignLeft</set>
+ </property>
+ <property name="vAlign" stdset="0">
+ </property>
+ </widget>
+ <spacer row="1" column="1">
+ <property name="name">
+ <cstring>spacer11</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout12</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox" row="2" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>GroupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Directory Settings</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit" row="1" column="2">
+ <property name="name">
+ <cstring>linePrjTmpl</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>TextLabel1_2_3</cstring>
+ </property>
+ <property name="text">
+ <string>Templates directory:</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="2" column="3">
+ <property name="name">
+ <cstring>buttonToolbar</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="2" column="2">
+ <property name="name">
+ <cstring>linePrjToolbar</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>TextLabel1_2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Toolbars directory:</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="3">
+ <property name="name">
+ <cstring>buttonTmpl</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="0" column="3">
+ <property name="name">
+ <cstring>buttonDir</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel2_3</cstring>
+ </property>
+ <property name="text">
+ <string>Main directory:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>linePrjDir</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLineEdit" row="0" column="3">
+ <property name="name">
+ <cstring>linePrjFile</cstring>
+ </property>
+ </widget>
+ <widget class="QButtonGroup" row="3" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>bGroupSources</cstring>
+ </property>
+ <property name="title">
+ <string>Project Sources</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>radioLocal</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Add local or remote files</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>radioWeb</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Use wget to download files from a site</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLabel" row="0" column="2">
+ <property name="name">
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>File:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="1" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>GroupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>Server Settings</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>TextLabel1_3</cstring>
+ </property>
+ <property name="text">
+ <string>Protocol: </string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="4">
+ <property name="name">
+ <cstring>TextLabel3_3</cstring>
+ </property>
+ <property name="text">
+ <string>Password:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="7">
+ <property name="name">
+ <cstring>linePort</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="0" column="2">
+ <item>
+ <property name="text">
+ <string>Local</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>comboProtocol</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="5">
+ <property name="name">
+ <cstring>linePasswd</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>26</height>
+ </size>
+ </property>
+ <property name="font">
+ <font>
+ <family>Lucida Console [Xft]</family>
+ </font>
+ </property>
+ <property name="echoMode">
+ <enum>Password</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="6">
+ <property name="name">
+ <cstring>TextLabel1_2_4</cstring>
+ </property>
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="4" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>lineHost</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="3">
+ <property name="name">
+ <cstring>TextLabel4_2</cstring>
+ </property>
+ <property name="text">
+ <string>Host:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>TextLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>User:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>lineUser</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>linePrjName</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<tabstops>
+ <tabstop>linePrjName</tabstop>
+ <tabstop>linePrjFile</tabstop>
+ <tabstop>comboProtocol</tabstop>
+ <tabstop>lineHost</tabstop>
+ <tabstop>lineUser</tabstop>
+ <tabstop>linePasswd</tabstop>
+ <tabstop>linePort</tabstop>
+ <tabstop>linePrjDir</tabstop>
+ <tabstop>buttonDir</tabstop>
+ <tabstop>linePrjTmpl</tabstop>
+ <tabstop>buttonTmpl</tabstop>
+ <tabstop>linePrjToolbar</tabstop>
+ <tabstop>buttonToolbar</tabstop>
+ <tabstop>radioLocal</tabstop>
+ <tabstop>radioWeb</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/quanta/project/projectnewlocal.cpp b/quanta/project/projectnewlocal.cpp
new file mode 100644
index 00000000..e037b662
--- /dev/null
+++ b/quanta/project/projectnewlocal.cpp
@@ -0,0 +1,361 @@
+/***************************************************************************
+ projectnewlocal.cpp - description
+ -------------------
+ begin : Fri Oct 27 2000
+ copyright : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon <[email protected],[email protected],[email protected]>
+ (C) 2001, 2002 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// qt includes
+#include <qlabel.h>
+#include <qfileinfo.h>
+#include <qlistview.h>
+#include <qlineedit.h>
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+#include <qpushbutton.h>
+#include <qregexp.h>
+
+// kde includes
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kfiledialog.h>
+#include <kprogress.h>
+#include <kmimetype.h>
+#include <kdeversion.h>
+#include <kurlrequesterdlg.h>
+#include <kurlrequester.h>
+
+//app includes
+#include "projectnewlocal.h"
+#include "projectnewgeneral.h"
+#include "copyto.h"
+#include "qextfileinfo.h"
+#include "uploadtreefolder.h"
+#include "uploadtreeview.h"
+#include "resource.h"
+#include "quantacommon.h"
+
+ProjectNewLocal::ProjectNewLocal(QWidget *parent, const char *name )
+ : ProjectNewLocalS(parent,name)
+{
+ imagelabel->setPixmap( UserIcon("wiznewprjloc") );
+
+// listView->setColumnAlignment(1,Qt::AlignRight);
+ listView->setColumnText(1, i18n("Add"));
+ listView->removeColumn(2);
+ listView->removeColumn(2);
+
+ mask->setText("*");
+
+ checkInsertWeb->setChecked( true );
+
+ connect( checkInsert, SIGNAL(toggled(bool)), this, SLOT(slotSetFiles(bool)));
+ connect( checkInsertWeb, SIGNAL(toggled(bool)), this, SLOT(slotSetFiles(bool)));
+ connect( checkInsertWithMask, SIGNAL(toggled(bool)), this, SLOT(slotSetFiles(bool)));
+
+ connect(addFiles, SIGNAL(clicked()),this,SLOT(slotAddFiles()));
+ connect(addFolder, SIGNAL(clicked()),this,SLOT(slotAddFolder()));
+ connect(clearList, SIGNAL(clicked()),this,SLOT(slotClearList()));
+}
+
+ProjectNewLocal::~ProjectNewLocal(){
+}
+
+void ProjectNewLocal::setBaseURL(const KURL& a_baseURL)
+{
+ baseURL = a_baseURL;
+ baseURL.adjustPath(1);
+ checkInsert->setText(i18n("Insert files from %1.").arg(baseURL.prettyURL(0, KURL::StripFileProtocol)));
+ listView->clear();
+ fileList.clear();
+ checkInsert->setChecked(false);
+}
+
+KURL::List ProjectNewLocal::files()
+{
+ //return fileList;
+ KURL::List r;
+
+ QListViewItem *item;
+ QListViewItemIterator it(listView);
+ for ( ; it.current(); ++it )
+ {
+ item = it.current();
+ if ( listView->isSelected( item ))
+ {
+ KURL u;
+ if (dynamic_cast<UploadTreeFolder*>(item))
+ {
+ u = dynamic_cast<UploadTreeFolder*>(item)->url();
+ } else
+ {
+ u = dynamic_cast<UploadTreeFile*>(item)->url();
+ }
+
+ if (!u.isEmpty()) r.append(u);
+ }
+ }
+ return r;
+}
+
+KURL::List ProjectNewLocal::projectFiles()
+{
+ KURL::List list;
+
+ if (!QExtFileInfo::exists(baseURL, false, this) ||
+ !baseURL.path().endsWith("/") ||
+ !checkInsert->isChecked() ) return list;
+
+ QString fmask = "*";
+ if ( checkInsertWeb->isChecked() )
+ {
+ KMimeType::List list = KMimeType::allMimeTypes();
+ KMimeType::List::iterator it;
+ QString name;
+ fmask = "";
+ for ( it = list.begin(); it != list.end(); ++it )
+ {
+ name = (*it)->name();
+ if (qConfig.markupMimeTypes.contains(name) ||
+ qConfig.scriptMimeTypes.contains(name) ||
+ qConfig.imageMimeTypes.contains(name))
+ {
+ QStringList patterns = (*it)->patterns();
+ for (uint i = 0 ; i < patterns.count(); i++)
+ {
+ fmask = fmask+patterns[i]+" ";
+ }
+ }
+ }
+ } else
+ {
+ fmask = mask->text();
+ }
+
+ list = QExtFileInfo::allFilesRelative(baseURL, fmask, this, false);
+
+ return list;
+}
+
+void ProjectNewLocal::slotSetFiles(bool)
+{
+ if ( checkInsert->isChecked() )
+ {
+ KURL::List files = projectFiles();
+ progressBar->setTotalSteps(files.count() - 1);
+ progressBar->setTextEnabled(true);
+ for (uint i = 0; i < files.count(); i++)
+ {
+ if ( !fileList.contains(files[i]))
+ {
+ fileList.append(files[i]);
+ QListViewItem *it = listView->addItem(files[i], KFileItem(KFileItem::Unknown, KFileItem::Unknown, KURL()));
+ if (it) it->setSelected(true);
+ progressBar->setValue(i);
+ }
+ }
+ progressBar->setTotalSteps(1);
+ progressBar->setValue(0);
+ progressBar->setTextEnabled(false);
+ listView->checkboxTree();
+ }
+}
+
+void ProjectNewLocal::resizeEvent ( QResizeEvent *t )
+{
+ ProjectNewLocalS::resizeEvent(t);
+ listView->setColumnWidth(0,listView->width()-listView->columnWidth(1)-20);
+}
+
+/** No descriptions */
+void ProjectNewLocal::slotAddFiles()
+{
+ QExtFileInfo::createDir(baseURL, this);
+ KURL::List list = KFileDialog::getOpenURLs(
+ baseURL.url(), i18n("*"), this, i18n("Insert Files in Project"));
+
+ if ( !list.isEmpty() )
+ {
+ KURL u = list.first();
+
+ u = QExtFileInfo::toRelative( u, baseURL, false );
+
+ if ( u.path().startsWith("..") || u.path().startsWith("/"))
+ {
+ KURLRequesterDlg *urlRequesterDlg = new KURLRequesterDlg( baseURL.prettyURL(), this, "");
+ 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(addFilesToProject(const KURL::List&)),
+ SLOT (slotInsertFilesAfterCopying(const KURL::List&)));
+ connect(dlg, SIGNAL(deleteDialog(CopyTo *)),
+ SLOT (slotDeleteCopyToDialog(CopyTo *)));
+ list = dlg->copy( list, destination );
+ return;
+ } else
+ {
+ return;
+ }
+ }
+
+ progressBar->setTotalSteps(list.count() - 1);
+ progressBar->setTextEnabled(true);
+ for (uint i = 0; i < list.count(); i++)
+ {
+ list[i] = QExtFileInfo::toRelative(list[i], baseURL, false);
+ if (!fileList.contains(list[i]))
+ {
+ fileList.append(list[i]);
+ QListViewItem *it = listView->addItem(list[i], KFileItem(KFileItem::Unknown, KFileItem::Unknown, KURL()));
+ if (it) it->setSelected(true);
+ progressBar->setValue(i);
+ }
+ }
+ progressBar->setTotalSteps(1);
+ progressBar->setValue(0);
+ progressBar->setTextEnabled(false);
+ }
+}
+
+/** No descriptions */
+void ProjectNewLocal::slotAddFolder()
+{
+//TODO/FIXME: This returns null if the selected directory is not on the local disk.
+//I think this is a KDE bug
+ QExtFileInfo::createDir(baseURL, this);
+ KURL dirURL ;
+ dirURL = KFileDialog::getExistingURL(
+ baseURL.url(), this, i18n("Insert Folder in Project"));
+
+ if ( !dirURL.isEmpty() )
+ {
+ dirURL.adjustPath(1);
+
+ KURL sdir = dirURL;
+ sdir = QExtFileInfo::toRelative( sdir, baseURL, false);
+
+ if ( sdir.path().startsWith("..") || sdir.path().startsWith("/") )
+ {
+
+ KURLRequesterDlg *urlRequesterDlg = new KURLRequesterDlg( baseURL.prettyURL(), this, "");
+ urlRequesterDlg->setCaption(i18n("%1: Copy to Project").arg(dirURL.prettyURL(0, KURL::StripFileProtocol)));
+ 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(addFilesToProject(const KURL::List&)),
+ SLOT (slotInsertFolderAfterCopying(const KURL::List&)));
+ connect(dlg, SIGNAL(deleteDialog(CopyTo *)),
+ SLOT (slotDeleteCopyToDialog(CopyTo *)));
+ dirURL = dlg->copy(dirURL, destination);
+ return;
+ } else
+ {
+ return;
+ }
+ }
+
+ slotInsertFolderAfterCopying(dirURL);
+ }
+}
+
+void ProjectNewLocal::slotDeleteCopyToDialog(CopyTo* dlg)
+{
+//The CopyTo dlg is deleted only here!!
+ delete dlg;
+}
+
+void ProjectNewLocal::slotInsertFolderAfterCopying(const KURL::List& a_urlList)
+{
+ KURL::List::ConstIterator it;
+ KURL dirURL;
+ for (it = a_urlList.begin(); it != a_urlList.end(); ++it)
+ {
+ dirURL = *it;
+ // dirURL.adjustPath(1);
+ KURL::List files = QExtFileInfo::allFilesRelative(dirURL, "*", this, false);
+ progressBar->setTotalSteps(files.count() - 1);
+ progressBar->setTextEnabled(true);
+ KURL u;
+ for (uint i = 0; i < files.count(); i++)
+ {
+ u = files[i];
+ if ( !fileList.contains(u) && u.path() != "." && u.path() != ".." )
+ {
+ fileList.append(u);
+ listView->addItem(u, KFileItem(KFileItem::Unknown, KFileItem::Unknown, KURL()));
+ QListViewItem *it = listView->itemByUrl(u);
+ if (it)
+ {
+ it->setSelected(true);
+ listView->slotSelectFile(it);
+ }
+ progressBar->setValue(i);
+ }
+ }
+ //listView->selectAll(false);
+ progressBar->setTotalSteps(1);
+ progressBar->setValue(0);
+ progressBar->setTextEnabled(false);
+ }
+}
+
+void ProjectNewLocal::slotInsertFilesAfterCopying(const KURL::List& a_urlList)
+{
+ KURL::List::ConstIterator it;
+ KURL u;
+ progressBar->setTotalSteps(a_urlList.count() - 1);
+ progressBar->setTextEnabled(true);
+ for (it = a_urlList.begin(); it != a_urlList.end(); ++it)
+ {
+ u = QExtFileInfo::toRelative(*it, baseURL, false);
+ if ( !fileList.contains(u))
+ {
+ fileList.append(u);
+ QListViewItem *it = listView->addItem(u, KFileItem(KFileItem::Unknown, KFileItem::Unknown, KURL()));
+ if (it)
+ {
+ it->setSelected(true);
+ listView->slotSelectFile(it);
+ }
+ progressBar->advance(1);
+ }
+ }
+ progressBar->setTotalSteps(1);
+ progressBar->setValue(0);
+ progressBar->setTextEnabled(false);
+}
+
+/** No descriptions */
+void ProjectNewLocal::slotClearList()
+{
+ //Really wondering why would we delete the files from baseURL???
+ //I've added this code, but I don't remember the reason. :-(
+ //Anyway, it is quite evil thing to do.
+ //KIO::del( baseURL );
+ listView->clear();
+ fileList.clear();
+ checkInsert->setChecked(false);
+}
+
+#include "projectnewlocal.moc"
diff --git a/quanta/project/projectnewlocal.h b/quanta/project/projectnewlocal.h
new file mode 100644
index 00000000..2d2d6d10
--- /dev/null
+++ b/quanta/project/projectnewlocal.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ projectnewlocal.h - description
+ -------------------
+ begin : Fri Oct 27 2000
+ copyright : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon <[email protected],[email protected],[email protected]>
+ (C) 2001-2003 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PROJECTNEWLOCAL_H
+#define PROJECTNEWLOCAL_H
+
+#include <qwidget.h>
+#include <kurl.h>
+#include <projectnewlocals.h>
+
+/**
+ *@author Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon & Andras Mantia
+ */
+
+class CopyTo;
+
+class ProjectNewLocal : public ProjectNewLocalS {
+ Q_OBJECT
+public:
+ ProjectNewLocal(QWidget *parent=0, const char *name=0);
+ ~ProjectNewLocal();
+
+ KURL::List files();
+ KURL::List projectFiles();
+
+public slots:
+ void slotSetFiles(bool);
+ void setBaseURL(const KURL& a_baseURL);
+ void slotAddFolder();
+ void slotAddFiles();
+ void slotClearList();
+ void slotInsertFolderAfterCopying(const KURL::List&);
+ void slotInsertFilesAfterCopying(const KURL::List&);
+ void slotDeleteCopyToDialog(CopyTo*);
+
+ virtual void resizeEvent( QResizeEvent * );
+
+private:
+ KURL baseURL;
+ KURL::List fileList;
+};
+
+#endif
diff --git a/quanta/project/projectnewlocals.ui b/quanta/project/projectnewlocals.ui
new file mode 100644
index 00000000..c752274f
--- /dev/null
+++ b/quanta/project/projectnewlocals.ui
@@ -0,0 +1,344 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ProjectNewLocalS</class>
+<comment>/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+</comment>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>ProjectNewLocalS</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>715</width>
+ <height>418</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>620</width>
+ <height>410</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32000</width>
+ <height>32000</height>
+ </size>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>imagelabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>115</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>115</width>
+ <height>480</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ <property name="alignment">
+ <set>AlignTop|AlignLeft</set>
+ </property>
+ <property name="vAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="0" column="0">
+ <property name="name">
+ <cstring>checkInsert</cstring>
+ </property>
+ <property name="text">
+ <string>Insert files from</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>TextLabel8</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Included files:</string>
+ </property>
+ </widget>
+ <widget class="QButtonGroup" row="1" column="0">
+ <property name="name">
+ <cstring>ButtonGroup12</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Filters</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>checkInsertWithMask</cstring>
+ </property>
+ <property name="text">
+ <string>Insert files with the following &amp;mask:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>mask</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>checkInsertWeb</cstring>
+ </property>
+ <property name="text">
+ <string>Insert onl&amp;y markup, script and image files</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="1">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="UploadTreeView" row="0" column="1">
+ <property name="name">
+ <cstring>listView</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>85</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>addFiles</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Add Files...</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>addFolder</cstring>
+ </property>
+ <property name="text">
+ <string>A&amp;dd Folder...</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>clearList</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Clear List</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer4_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>89</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <spacer row="0" column="0">
+ <property name="name">
+ <cstring>Spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>16</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>UploadTreeView</class>
+ <header location="local">../treeviews/uploadtreeview.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="XBM.GZ" length="79">789c534e494dcbcc4b554829cdcdad8c2fcf4c29c95030e0524611cd48cd4ccf28010a1797249664262b2467241641a592324b8aa363156c15aab914146aadb90067111b1f</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>checkInsertWithMask</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>mask</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>checkInsert</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>ButtonGroup12</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>checkInsert</tabstop>
+ <tabstop>checkInsertWeb</tabstop>
+ <tabstop>mask</tabstop>
+ <tabstop>addFiles</tabstop>
+ <tabstop>addFolder</tabstop>
+ <tabstop>clearList</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>uploadtreeview.h</includehint>
+</includehints>
+</UI>
diff --git a/quanta/project/projectnewweb.cpp b/quanta/project/projectnewweb.cpp
new file mode 100644
index 00000000..20685021
--- /dev/null
+++ b/quanta/project/projectnewweb.cpp
@@ -0,0 +1,245 @@
+/***************************************************************************
+ projectnewweb.cpp - description
+ -------------------
+ begin : Fri Oct 27 2000
+ copyright : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon <[email protected],[email protected],[email protected]>
+ (C) 2002, 2003 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// qt includes
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qstringlist.h>
+#include <qlistview.h>
+#include <qfileinfo.h>
+#include <qcombobox.h>
+
+// kde includes
+#include <klocale.h>
+#include <kprocess.h>
+#include <kiconloader.h>
+#include <kio/job.h>
+#include <kmessagebox.h>
+#include <kled.h>
+
+// app includes
+#include "projectnewweb.h"
+#include "qextfileinfo.h"
+#include "quantacommon.h"
+#include "uploadtreeview.h"
+
+ProjectNewWeb::ProjectNewWeb(QWidget *parent, const char *name )
+ : ProjectNewWebS(parent,name)
+{
+ button->setEnabled(false);
+ siteUrl->setFocus();
+
+ imagelabel->setPixmap( UserIcon("wiznewprjweb") );
+ listView->removeColumn(1);
+ listView->removeColumn(1);
+ listView->removeColumn(1);
+
+ connect( commandLine, SIGNAL(textChanged(const QString&)),
+ this, SLOT (enableStart(const QString&)));
+ connect( siteUrl, SIGNAL(textChanged(const QString&)),
+ this, SLOT (setCommandL(const QString&)));
+ connect( button, SIGNAL(clicked()),
+ this, SLOT (slotStart()));
+ connect( protocolCombo,SIGNAL(highlighted(const QString&)),
+ this, SLOT (setProtocol(const QString&)));
+
+ start = false;
+ KLed1->setState(KLed::Off);
+ KLed2->setState(KLed::Off);
+}
+
+ProjectNewWeb::~ProjectNewWeb(){
+}
+
+void ProjectNewWeb::enableStart(const QString&)
+{
+ if ( !commandLine->text().isEmpty() ) button->setEnabled(true);
+ else button->setEnabled(false);
+}
+
+void ProjectNewWeb::setCommandL(const QString& url)
+{
+ QString siteurl = url;
+
+ commandLine->setText("wget -c -np -r --level=5 -nH "+ protocolCombo->currentText().lower()+ "://"+siteurl);
+}
+
+/** No descriptions */
+void ProjectNewWeb::setProtocol(const QString& protocol)
+{
+ commandLine->setText("wget -c -np -r --level=5 -nH "+ protocol.lower()+ "://"+siteUrl->text());
+}
+
+
+
+void ProjectNewWeb::setBaseURL(const KURL& a_baseURL)
+{
+ baseURL = a_baseURL;
+ baseURL.adjustPath(1);
+}
+
+void ProjectNewWeb::slotStart()
+{
+ if ( !start )
+ {
+ emit enableMessagesWidget();
+
+ if (QExtFileInfo::createDir(baseURL, this))
+ {
+ if (baseURL.protocol() == "file")
+ {
+ chdir( baseURL.path(1));
+
+ proc = new KProcess();
+ proc ->clearArguments();
+
+ QStringList list = QStringList::split (" ", commandLine->text());
+
+ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
+ {
+ *proc << *it;
+ }
+
+ connect( proc, SIGNAL(receivedStdout( KProcess*,char*,int)), this,
+ SLOT( slotGetWgetOutput(KProcess*,char*,int)));
+ connect( proc, SIGNAL(receivedStderr( KProcess*,char*,int)), this,
+ SLOT( slotGetWgetOutput(KProcess*,char*,int)));
+ connect( proc, SIGNAL(processExited( KProcess *)), this,
+ SLOT( slotGetWgetExited(KProcess *)));
+
+ if (proc->start(KProcess::NotifyOnExit, KProcess::AllOutput))
+ {
+ start = true;
+ button->setText( i18n("Stop") );
+ emit enableNextButton((QWidget *)this->parent(),false);
+ } else
+ {
+ KMessageBox::error(this, i18n("There was an error while trying to run the \"wget\" application.\
+ Check first that it is present on your system and that it is in your PATH."));
+ delete proc;
+ }
+ } else
+ {
+ KMessageBox::sorry(this,i18n("This feature is available only if the project lies on a local disk."));
+ start = false;
+ button->setText( i18n("Start") );
+ emit enableNextButton((QWidget *)this->parent(),true);
+ }
+ } else
+ {
+ QuantaCommon::dirCreationError(this, baseURL);
+ start = false;
+ button->setText( i18n("Start") );
+ emit enableNextButton((QWidget *)this->parent(),true);
+ }
+ } else {
+
+ // STOPPING !!!
+
+ delete proc;
+
+ start = false;
+ button->setText( i18n("Start") );
+ emit enableNextButton((QWidget *)this->parent(),true);
+ }
+}
+
+void ProjectNewWeb::slotGetWgetExited(KProcess*)
+{
+ KLed2->setState(KLed::Off);
+ KLed1->setState(KLed::Off);
+ start = false;
+ button->setText( i18n("Start") );
+ emit messages(i18n("wget finished...\n"));
+ emit enableNextButton((QWidget *)this->parent(),true);
+}
+
+void ProjectNewWeb::slotGetWgetOutput(KProcess *, char *buffer, int buflen)
+{
+ QString output = buffer;
+ output = output.left( buflen );
+
+ emit messages(output);
+
+ int pos;
+ QString basePath = baseURL.path(1);
+ while ( (pos = output.find("saved")) != -1 )
+ {
+ if (KLed1->state() == KLed::Off)
+ {
+ KLed1->setState(KLed::On);
+ KLed2->setState(KLed::Off);
+ } else
+ {
+ KLed2->setState(KLed::On);
+ KLed1->setState(KLed::Off);
+ }
+ int begName = output.findRev('`',pos);
+ if ( begName == -1 ) {
+ output = output.remove(0,pos+1);
+ continue;
+ }
+
+ int endName = output.find('\'',begName);
+ if ( endName == -1 || endName > pos ) {
+ output = output.remove(0,pos+1);
+ continue;
+ }
+
+ QString fileName = output.left(endName);
+ fileName = fileName.right( endName - begName-1);
+
+ output = output.remove(0,pos+1);
+
+ KURL u = baseURL;
+ QuantaCommon::setUrl(u, fileName);
+ listView->addItem(u, KFileItem(KFileItem::Unknown, KFileItem::Unknown, KURL()));
+ }
+}
+
+KURL::List ProjectNewWeb::files()
+{
+ //return fileList;
+ KURL::List r;
+
+ KURL u;
+ QListViewItem *item;
+ QListViewItemIterator it(listView);
+ for ( ; it.current(); ++it )
+ {
+ item = it.current();
+ if (dynamic_cast<UploadTreeFolder*>(item))
+ {
+ u = dynamic_cast<UploadTreeFolder*>(item)->url();
+ } else
+ {
+ u = dynamic_cast<UploadTreeFile*>(item)->url();
+ }
+
+ if (!u.isEmpty()) r.append(u);
+ }
+ return r;
+}
+
+void ProjectNewWeb::resizeEvent ( QResizeEvent *t )
+{
+ ProjectNewWebS::resizeEvent(t);
+ // listView->setColumnWidth(0,listView->width()-listView->columnWidth(1)-20);
+}
+
+#include "projectnewweb.moc"
diff --git a/quanta/project/projectnewweb.h b/quanta/project/projectnewweb.h
new file mode 100644
index 00000000..62da219f
--- /dev/null
+++ b/quanta/project/projectnewweb.h
@@ -0,0 +1,75 @@
+/***************************************************************************
+ projectnewweb.h - description
+ -------------------
+ begin : Fri Oct 27 2000
+ copyright : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon <[email protected],[email protected],[email protected]>
+ (C) 2002 Andras Mantia
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PROJECTNEWWEB_H
+#define PROJECTNEWWEB_H
+
+//qt includes
+#include <qwidget.h>
+#include <qstringlist.h>
+
+//app includes
+#include "projectnewwebs.h"
+
+/**
+ *@author Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon
+ */
+
+class KProcess;
+class KURL;
+
+class ProjectNewWeb : public ProjectNewWebS {
+ Q_OBJECT
+public:
+ ProjectNewWeb(QWidget *parent=0, const char *name=0);
+ ~ProjectNewWeb();
+
+public slots:
+ void enableStart(const QString&);
+ void setCommandL(const QString&);
+ void setBaseURL(const KURL& a_baseURL);
+
+ void slotStart();
+
+ KURL::List files();
+
+ void slotGetWgetExited(KProcess *);
+ void slotGetWgetOutput(KProcess *proc, char *buffer, int buflen);
+
+ virtual void resizeEvent( QResizeEvent * );
+
+signals:
+
+ void enableMessagesWidget();
+
+ void messages(const QString& );
+ /** No descriptions */
+ void enableNextButton(QWidget *,bool);
+
+private:
+ KURL baseURL;
+
+ bool start;
+
+ KProcess *proc;
+
+private slots: // Private slots
+ /** No descriptions */
+ void setProtocol(const QString& protocol);
+};
+
+#endif
diff --git a/quanta/project/projectnewwebs.ui b/quanta/project/projectnewwebs.ui
new file mode 100644
index 00000000..b0b726e4
--- /dev/null
+++ b/quanta/project/projectnewwebs.ui
@@ -0,0 +1,292 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ProjectNewWebS</class>
+<comment>/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+</comment>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>ProjectNewWebS</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>620</width>
+ <height>418</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>620</width>
+ <height>410</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32000</width>
+ <height>32000</height>
+ </size>
+ </property>
+ <property name="layoutMargin" stdset="0">
+ </property>
+ <property name="layoutSpacing" stdset="0">
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>imagelabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>115</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>115</width>
+ <height>480</height>
+ </size>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ <property name="alignment">
+ <set>AlignTop|AlignLeft</set>
+ </property>
+ <property name="vAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="1">
+ <property name="name">
+ <cstring>layout7</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer row="1" column="2">
+ <property name="name">
+ <cstring>Spacer8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Fixed</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>309</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KLed" row="1" column="0">
+ <property name="name">
+ <cstring>KLed1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="shape">
+ <enum>Circular</enum>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="3">
+ <property name="name">
+ <cstring>button</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Start</string>
+ </property>
+ </widget>
+ <widget class="UploadTreeView" row="0" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>listView</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="KLed" row="1" column="1">
+ <property name="name">
+ <cstring>KLed2</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="shape">
+ <enum>Circular</enum>
+ </property>
+ <property name="look">
+ <enum>Raised</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout6</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>TextLabel10</cstring>
+ </property>
+ <property name="text">
+ <string>wget's command line:</string>
+ </property>
+ </widget>
+ <spacer row="1" column="2">
+ <property name="name">
+ <cstring>Spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>228</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QComboBox" row="1" column="1">
+ <item>
+ <property name="text">
+ <string>HTTP</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>FTP</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>protocolCombo</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>siteUrl</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Protocol:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="2" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>commandLine</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel9</cstring>
+ </property>
+ <property name="text">
+ <string>Site source:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>UploadTreeView</class>
+ <header location="local">../treeviews/uploadtreeview.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="XBM.GZ" length="79">789c534e494dcbcc4b554829cdcdad8c2fcf4c29c95030e0524611cd48cd4ccf28010a1797249664262b2467241641a592324b8aa363156c15aab914146aadb90067111b1f</data>
+ </image>
+</images>
+<tabstops>
+ <tabstop>siteUrl</tabstop>
+ <tabstop>protocolCombo</tabstop>
+ <tabstop>commandLine</tabstop>
+ <tabstop>button</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kled.h</includehint>
+ <includehint>uploadtreeview.h</includehint>
+ <includehint>kled.h</includehint>
+</includehints>
+</UI>
diff --git a/quanta/project/projectoptions.ui b/quanta/project/projectoptions.ui
new file mode 100644
index 00000000..163f1d4c
--- /dev/null
+++ b/quanta/project/projectoptions.ui
@@ -0,0 +1,540 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>ProjectOptions</class>
+<comment>/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+</comment>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>ProjectOptions</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>644</width>
+ <height>438</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="caption">
+ <string>Project Options</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton" row="2" column="5">
+ <property name="name">
+ <cstring>buttonToolbar</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="5">
+ <property name="name">
+ <cstring>buttonTmpl</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="3" column="4" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>lineEmail</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>200</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="3" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>lineAuthor</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="4" column="1" rowspan="1" colspan="5">
+ <property name="name">
+ <cstring>lineExclude</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="2" column="1" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>linePrjToolbar</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>linePrjTmpl</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1" rowspan="1" colspan="5">
+ <property name="name">
+ <cstring>linePrjName</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Project &amp;name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>linePrjName</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Templates folder:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>linePrjTmpl</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>TextLabel1_2_2</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <property name="text">
+ <string>T&amp;oolbars folder:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>linePrjToolbar</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>TextLabel4</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Author:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>lineAuthor</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="3">
+ <property name="name">
+ <cstring>TextLabel5</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>E&amp;mail:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>lineEmail</cstring>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="6" column="0" rowspan="1" colspan="6">
+ <property name="name">
+ <cstring>GroupBox5</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Project Defaults</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>TextLabel1_2_3</cstring>
+ </property>
+ <property name="text">
+ <string>Default &amp;DTD:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>dtdCombo</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>TextLabel1_3_2</cstring>
+ </property>
+ <property name="text">
+ <string>Default &amp;view:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>viewCombo</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel3_2_2_2</cstring>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Default &amp;encoding:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>encodingCombo</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="0" column="1">
+ <property name="name">
+ <cstring>encodingCombo</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="1">
+ <property name="name">
+ <cstring>viewCombo</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="2" column="1">
+ <property name="name">
+ <cstring>dtdCombo</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>New files will have the extension and highlighting according to this setting</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>E&amp;xclude from project:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>lineExclude</cstring>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="5" column="0" rowspan="1" colspan="6">
+ <property name="name">
+ <cstring>checkCvsignore</cstring>
+ </property>
+ <property name="text">
+ <string>Exclude &amp;files listed in .cvsignore</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>The files listed in &lt;i&gt;.cvsignore&lt;/i&gt; files will not appear in the project tree, nor will be shown when you rescan the project folder or upload the project. Files matching the &lt;i&gt;.cvsignore&lt;/i&gt; entries that were already present in the project will be removed from it, but they will not be removed from the disc.&lt;br&gt;
+&lt;b&gt;NOTE:&lt;/b&gt; This feature works only for local projects.</string>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="9" column="0" rowspan="1" colspan="6">
+ <property name="name">
+ <cstring>GroupBox5_debug</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Debugger</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel2_2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Debu&amp;gger:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>comboDebuggerClient</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="0" column="1">
+ <property name="name">
+ <cstring>comboDebuggerClient</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>4</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="autoCompletion">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="0" column="2">
+ <property name="name">
+ <cstring>buttonDebuggerOptions</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Optio&amp;ns</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>checkDebuggerPersistentBreakpoints</cstring>
+ </property>
+ <property name="text">
+ <string>Remember &amp;breakpoints across sessions</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>checkDebuggerPersistentWatches</cstring>
+ </property>
+ <property name="text">
+ <string>Remember watches across sessions</string>
+ </property>
+ <property name="accel">
+ <string></string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QCheckBox" row="8" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>checkPersistentBookmarks</cstring>
+ </property>
+ <property name="text">
+ <string>Use persistent boo&amp;kmarks</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="7" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>checkPrefix</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Use preview prefix:</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="7" column="2" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>linePrefix</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonTmpl</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectOptions</receiver>
+ <slot>buttonTemplate_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>buttonToolbar</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectOptions</receiver>
+ <slot>buttonToolbar_clicked()</slot>
+ </connection>
+ <connection>
+ <sender>checkPrefix</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>linePrefix</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>comboDebuggerClient</sender>
+ <signal>activated(int)</signal>
+ <receiver>ProjectOptions</receiver>
+ <slot>comboDebuggerClient_activated(int)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>linePrjName</tabstop>
+ <tabstop>linePrjTmpl</tabstop>
+ <tabstop>buttonTmpl</tabstop>
+ <tabstop>linePrjToolbar</tabstop>
+ <tabstop>buttonToolbar</tabstop>
+ <tabstop>lineAuthor</tabstop>
+ <tabstop>lineEmail</tabstop>
+ <tabstop>lineExclude</tabstop>
+ <tabstop>checkCvsignore</tabstop>
+ <tabstop>encodingCombo</tabstop>
+ <tabstop>viewCombo</tabstop>
+ <tabstop>dtdCombo</tabstop>
+ <tabstop>checkPrefix</tabstop>
+ <tabstop>linePrefix</tabstop>
+ <tabstop>checkPersistentBookmarks</tabstop>
+ <tabstop>comboDebuggerClient</tabstop>
+ <tabstop>buttonDebuggerOptions</tabstop>
+</tabstops>
+<includes>
+ <include location="local" impldecl="in implementation">projectoptions.ui.h</include>
+</includes>
+<slots>
+ <slot>buttonTemplate_clicked()</slot>
+ <slot>buttonToolbar_clicked()</slot>
+ <slot>comboDebuggerClient_activated( int idx )</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/quanta/project/projectoptions.ui.h b/quanta/project/projectoptions.ui.h
new file mode 100644
index 00000000..b6fc2202
--- /dev/null
+++ b/quanta/project/projectoptions.ui.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+** ui.h extension file, included from the uic-generated form implementation.
+**
+** If you wish to add, delete or rename functions or slots use
+** Qt Designer which will update this file, preserving your code. Create an
+** init() function in place of a constructor, and a destroy() function in
+** place of a destructor.
+*****************************************************************************/
+/***************************************************************************
+ * *
+ * 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 <kcombobox.h>
+#include <kfiledialog.h>
+#include <kdeversion.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+
+
+void ProjectOptions::buttonTemplate_clicked()
+{
+ KURL url = KFileDialog::getExistingURL(linePrjTmpl->text(), this,
+ i18n("Select Project Template Folder"));
+ if (!url.isEmpty())
+ {
+ linePrjTmpl->setText(url.url());
+ }
+}
+
+
+
+void ProjectOptions::buttonToolbar_clicked()
+{
+ KURL url = KFileDialog::getExistingURL(linePrjToolbar->text(), this,
+ i18n("Select Project Toolbar & Actions Folder"));
+ if (!url.isEmpty())
+ {
+ linePrjToolbar->setText(url.url());
+ }
+}
+
+void ProjectOptions::comboDebuggerClient_activated( int idx)
+{
+ buttonDebuggerOptions->setEnabled(idx > 0);
+ checkDebuggerPersistentBreakpoints->setEnabled(idx > 0);
+ checkDebuggerPersistentWatches->setEnabled(idx > 0);
+}
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 <[email protected]>
+ (C) 2001-2004 by Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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"
diff --git a/quanta/project/projectprivate.h b/quanta/project/projectprivate.h
new file mode 100644
index 00000000..3ab1a20a
--- /dev/null
+++ b/quanta/project/projectprivate.h
@@ -0,0 +1,255 @@
+/***************************************************************************
+ projectprivate.h - description
+ -------------------
+ begin : Thu Mar 16 2000
+ copyright : (C) 2000 by Yacovlev Alexander & Dmitry Poplavsky <[email protected]>
+ (C) 2001-2004 by Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PROJECTPRIVATE_H
+#define PROJECTPRIVATE_H
+
+//qt includes
+#include <qmap.h>
+#include <qregexp.h>
+#include <qguardedptr.h>
+
+//app includes
+#include "project.h"
+#include "projectlist.h"
+#include "projectupload.h"
+
+class QWidgetStack;
+
+class KAction;
+class KActionCollection;
+class KConfig;
+class KDirWatch;
+class KRecentFilesAction;
+class KSelectAction;
+class KTempFile;
+
+class CopyTo;
+class ProjectNewGeneral;
+class ProjectNewLocal;
+class ProjectNewWeb;
+class ProjectNewFinal;
+class ProjectList;
+struct EventAction;
+typedef QMap<QString, QValueList<EventAction> > EventActions;
+
+class ProjectPrivate
+ : public QObject
+{
+ Q_OBJECT
+public:
+ ProjectPrivate(Project *p);
+
+ ~ProjectPrivate();
+
+ Project *parent;
+ /** Point to the .webprj file */
+ KURL projectURL;
+ QString projectName;
+ /** Points to the directory of the .webprj file */
+ KURL baseURL;
+/** Points to the document root inside the project. Item under this folder
+are treated as the actual documents belonging to the site. They are automatically selected
+for upload, searching in project default to this directory, etc. Items outside of the
+document root are treated as external, control files and they are by default not selected for
+upload.*/
+
+ KURL previewPrefix;
+ bool usePreviewPrefix;
+ bool m_persistentBookmarks;
+ QString author;
+ KRecentFilesAction *m_projectRecent;
+
+ ProjectNewGeneral *png;
+ ProjectNewLocal *pnl;
+ ProjectNewWeb *pnw;
+ ProjectNewFinal *pnf;
+
+ QWidgetStack *stack;
+ QString currentProjectView;
+
+ KConfig *config;
+ bool m_modified;
+ bool m_excludeCvsignore;
+ /** Default DTD for this project. */
+ QString m_defaultDTD;
+ QString m_defaultEncoding;
+ QRegExp excludeRx;
+ QStringList excludeList;
+ KMainWindow *m_mainWindow;
+ QString m_debuggerClientEdit;
+ QMap<QString, QString> m_passwdList;
+ ProjectList m_projectFiles; ///< the list with the _absolute_ URL's of the project
+ KDirWatch *m_dirWatch; ///< watches some project directories for modification
+ KURL toolbarURL;
+ KURL templateURL;
+ QString email;
+ QDomDocument dom;
+ QDomDocument m_sessionDom;
+ QString debuggerClient;
+ bool m_debuggerPersistentBreakpoints;
+ bool m_debuggerPersistentWatches;
+ QGuardedPtr<ProjectUpload> m_uploadDialog;
+
+ TeamMember m_teamLeader;
+ QMap<QString, TeamMember> m_subprojectLeaders;
+ QMap<QString, TeamMember> m_taskLeaders;
+ QValueList<TeamMember> m_simpleMembers;
+ QValueList<SubProject> m_subprojects;
+ QString m_yourself;
+ QString m_mailingList;
+ bool m_showUploadTreeviews;
+ bool m_eventsEnabled;
+
+ KAction
+ *closeprjAction, *insertFileAction, *insertDirAction,
+ *uploadProjectAction, *rescanPrjDirAction,
+ *projectOptionAction, *saveAsProjectTemplateAction,
+ *saveSelectionAsProjectTemplateAction,
+ *savePrjViewAction, *saveAsPrjViewAction;
+
+ KSelectAction *openPrjViewAction, *deletePrjViewAction;
+ /** the filename of the local webprj file after download */
+ QString m_tmpProjectFile;
+ QString m_tmpSessionFile;
+ /** used for creating a new project */
+ KTempFile *tempFile;
+ KTempFile *sessionTempFile;
+ EventActions *m_events;
+
+ /** setup of the actions */
+ void initActions(KActionCollection *ac);
+
+ void adjustActions();
+
+ void adjustViewActions();
+
+ QStringList projectViewList();
+
+ void init();
+
+ void openCurrentView();
+ /** insert files */
+ void insertFiles( KURL::List files );
+
+ /** insert files from dir recursive */
+ void insertFiles(const KURL& pathURL, const QString& mask );
+
+ void loadProjectXML();
+
+ void slotAcceptCreateProject();
+
+ bool createEmptyDom();
+
+ /** load project file
+ @param url the url of the project file
+ */
+ bool loadProject(const KURL &url);
+
+ /** load project from temp file
+ @param url the url of the project file
+ @param tempFile the path of the already downloaded temp file
+ @param sessionTempFile the path of the downloaded project session file. Empty if no such file was downloaded
+ */
+ void loadProjectFromTemp(const KURL &url, const QString &tempFile, const QString &sessionTempFile);
+
+
+ void getStatusFromTree();
+
+ /** save project file to local file @ref tmpFileName
+ @return false if there was nothing to save or an error occured during save
+ */
+ bool saveProject();
+
+ /**
+ adds information about the current open project into config
+ */
+ void writeConfig();
+
+ /**
+ removes the project from the list of open projects in config
+
+ @param the url string of the project to remove
+ */
+ void removeFromConfig(const QString & urlStr);
+
+ /**
+ test if a project is in the list of open projects in config
+
+ @param the url string of the project to test
+ */
+ bool projectAlreadyOpen(const QString & urlStr);
+
+ /** uploads the project file
+ @return false if there was nothing to upload or an error occured during upload
+ */
+ bool uploadProjectFile();
+
+public slots:
+
+ void slotDebuggerOptions();
+
+ void slotDebuggerChanged(const QString &debugger);
+
+ /** create new project */
+ void slotNewProject();
+
+ /** open project file */
+ void slotOpenProject();
+
+ /** iniate closing of the project and the edited files */
+ void slotCloseProject();
+
+ /** Proceed with project closing.*/
+ void slotProceedWithCloseProject(bool success);
+
+ void slotAddDirectory();
+
+ void slotAddFiles();
+
+ /** Deletes a project view */
+ void slotDeleteProjectView(const QString &view);
+
+ /** Saves a project view (group of files & toolbars) asking for a name. */
+ void slotSaveAsProjectView(bool askForName = true);
+
+ /** Saves a project view (group of files & toolbars) without asking for a name. */
+ void slotSaveProjectView();
+
+ /** Opens a project view (toolbars & files). */
+ void slotOpenProjectView(const QString &view);
+
+ /** for the new project wizard */
+ void slotSelectProjectType(const QString &title);
+
+ void slotDeleteCopytoDlg(CopyTo *dlg);
+
+private slots:
+ void slotNewProjectHelpClicked();
+
+signals:
+ void setLocalFiles(bool);
+ void eventHappened(const QString&, const QString&, const QString& );
+
+private:
+ QStringList treeStatusFromXML();
+ QString m_wizTitle ;
+ bool m_createSessionDom;
+};
+
+
+#endif
diff --git a/quanta/project/projectupload.cpp b/quanta/project/projectupload.cpp
new file mode 100644
index 00000000..e95f9446
--- /dev/null
+++ b/quanta/project/projectupload.cpp
@@ -0,0 +1,819 @@
+/***************************************************************************
+ projectupload.cpp - description
+ -------------------
+ begin : Wed Nov 15 2000
+ copyright : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon <[email protected],[email protected],[email protected]>
+ (C) 2001-2003 by Andras Mantia
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+
+
+//qt includes
+#include <qlistview.h>
+#include <qeventloop.h>
+#include <qfileinfo.h>
+#include <qlineedit.h>
+#include <qpushbutton.h>
+#include <qstringlist.h>
+#include <qregexp.h>
+#include <qlabel.h>
+#include <qcombobox.h>
+#include <qurl.h>
+#include <qcheckbox.h>
+#include <qtimer.h>
+#include <qframe.h>
+#include <qtooltip.h>
+
+//kde includes
+#include <kapplication.h>
+#include <kurl.h>
+#include <kio/job.h>
+#include <kmessagebox.h>
+#include <kprotocolinfo.h>
+#include <kdebug.h>
+#include <kinputdialog.h>
+#include <kio/netaccess.h>
+#include <klocale.h>
+#include <klineedit.h>
+#include <kcombobox.h>
+#include <kprogress.h>
+#include <kpassdlg.h>
+#include <kpushbutton.h>
+#include <ktempfile.h>
+#include <kuser.h>
+
+//standard includes
+#include <time.h>
+
+//own includes
+#include "uploadprofiledlgs.h"
+#include "projectupload.h"
+#include "project.h"
+#include "quantacommon.h"
+#include "qextfileinfo.h"
+#include "resource.h"
+
+ProjectUpload::ProjectUpload(const KURL& url, const QString& profileName, bool showOnlyProfiles, bool quickUpload, bool markOnly, const char* name)
+ :ProjectUploadS( 0L, name, false, Qt::WDestructiveClose)
+{
+ m_quickUpload = quickUpload;
+ m_profilesOnly = showOnlyProfiles;
+ list->hide();
+ m_project = Project::ref();
+ initProjectInfo(profileName);
+ startUrl = url;
+ if (m_profilesOnly)
+ {
+ clearWFlags(Qt::WDestructiveClose);
+ uploadFrame->hide();
+ buttonCancel->hide();
+ adjustSize();
+ buttonUpload->setText(i18n("&Close"));
+ setCaption(i18n("Upload Profiles"));
+ } else
+ {
+ if (markOnly)
+ markAsUploaded->setChecked(true);
+ QTimer::singleShot(10, this, SLOT(slotBuildTree()));
+ currentItem = 0L;
+ }
+}
+
+
+ProjectUpload::~ProjectUpload()
+{
+ m_project->setModified(true);
+ delete baseUrl;
+}
+
+void ProjectUpload::initProjectInfo(const QString& defaultProfile)
+{
+ baseUrl = new KURL();
+
+// list->setMultiSelection(true);
+ QDomDocument *dom = m_project->sessionDom();
+ m_profilesNode = dom->firstChild().firstChild().namedItem("uploadprofiles");
+ if (m_profilesNode.isNull()) //compat code, remove when upgrade from 3.2 is not supported
+ {
+ m_currentProfileElement = dom->firstChild().firstChild().namedItem("upload").toElement();
+ m_defaultProfile = m_currentProfileElement.attribute("user","") + "@" + m_currentProfileElement.attribute("remote_host","");
+ QDomElement e = dom->createElement("uploadprofiles");
+ e.setAttribute("defaultProfile", m_defaultProfile);
+ QDomElement el = dom->createElement("profile");
+ el.setAttribute("remote_host", m_currentProfileElement.attribute("remote_host",""));
+ el.setAttribute("user", m_currentProfileElement.attribute("user",""));
+ el.setAttribute("remote_path", m_currentProfileElement.attribute("remote_path",""));
+ el.setAttribute("remote_port", m_currentProfileElement.attribute("remote_port",""));
+ el.setAttribute("remote_protocol", m_currentProfileElement.attribute("remote_protocol","ftp"));
+ el.setAttribute("name", m_defaultProfile);
+ e.appendChild(el);
+// m_project->dom.firstChild().firstChild().removeChild(m_currentProfileElement);
+ m_currentProfileElement = el;
+ dom->firstChild().firstChild().appendChild(e);
+ m_profilesNode = e;
+ comboProfile->insertItem(m_defaultProfile);
+ m_project->setModified(true);
+ } else
+ {
+ if (defaultProfile.isEmpty())
+ m_defaultProfile = m_profilesNode.toElement().attribute("defaultProfile");
+ else
+ m_defaultProfile = defaultProfile;
+ QDomNodeList profileList = m_profilesNode.toElement().elementsByTagName("profile");
+ QDomElement e;
+ m_currentProfileElement = profileList.item(0).toElement();
+ QString s;
+ int defaultIdx = 0;
+ for (uint i = 0; i < profileList.count(); i++)
+ {
+ e = profileList.item(i).toElement();
+ s = e.attribute("name");
+ comboProfile->insertItem(s);
+ if (s == m_defaultProfile)
+ {
+ defaultIdx = i;
+ m_currentProfileElement = e;
+ }
+ }
+ comboProfile->setCurrentItem(defaultIdx);
+ }
+ buttonRemoveProfile->setEnabled(comboProfile->count() > 1);
+ keepPasswords->setChecked(m_project->keepPasswd);
+ uploadInProgress = false;
+ connect( this, SIGNAL( uploadNext() ), SLOT( slotUploadNext() ) );
+ setProfileTooltip();
+}
+
+/** No descriptions */
+void ProjectUpload::slotBuildTree()
+{
+ emit eventHappened("upload_requested", m_project->projectBaseURL().url(), "");
+ loadRemoteUploadInfo();
+ KIO::UDSEntry entry;
+ QString strUrl = QuantaCommon::qUrl(startUrl);
+ bool isDirectory = strUrl.endsWith("/");
+ bool forceUpload = !startUrl.isEmpty();
+ QString s;
+ QDomElement el;
+ QDomNodeList nl = m_project->dom()->elementsByTagName("item");
+ totalProgress->setTotalSteps(nl.count() - 1 );
+ totalProgress->setValue(0);
+ totalText->setText(i18n("Scanning project files..."));
+
+ KURL u = m_project->projectBaseURL();
+ if (!startUrl.isEmpty())
+ {
+ u = QExtFileInfo::toAbsolute(startUrl, u);
+ }
+ QDict<KFileItem> projectDirFiles;
+
+ if (startUrl.isEmpty() || strUrl.endsWith("/")) //upload a folder
+ {
+ projectDirFiles = QExtFileInfo::allFilesDetailed(u, "*", this);
+ } else
+ {
+ projectDirFiles.insert(u.url(), new KFileItem(KFileItem::Unknown, KFileItem::Unknown, u, true));
+ }
+
+ QTime t;
+ t.start();
+
+ u = m_project->projectBaseURL();
+ KURL absUrl = u;
+ for (uint i = 0; i < nl.count(); i++)
+ {
+ el = nl.item(i).toElement();
+ s = el.attribute("url");
+ if (startUrl.isEmpty() || (s.startsWith(strUrl) && isDirectory) || s == strUrl)
+ {
+ QuantaCommon::setUrl(u, s);
+ absUrl.setPath(m_project->projectBaseURL().path(1)+u.path(-1));
+/* if (!QExtFileInfo::exists(absUrl))
+ continue; */
+ KFileItem *p_item = projectDirFiles.find(absUrl.url());
+ if (!p_item)
+ continue;
+ KFileItem item(*p_item);
+ UploadTreeFile *it = list->addItem(u, item);
+ if ( it != 0 )
+ {
+ int uploadedTime = -1;
+ if (m_uploadTimeList.contains(s))
+ uploadedTime = m_uploadTimeList[s];
+ int modifiedTime = item.time(KIO::UDS_MODIFICATION_TIME);
+ el.setAttribute("modified_time", modifiedTime);
+ int uploadStatus = el.attribute("uploadstatus", "1").toInt();
+ if (m_quickUpload || (forceUpload && uploadStatus == 0))
+ uploadStatus = 1;
+ if (m_quickUpload || (uploadedTime != modifiedTime && uploadStatus != 0))
+ {
+ modified.append( u );
+ it->setSelected(true);
+ }
+ if (uploadStatus == 2)
+ it->setConfirmUpload(true);
+ totalProgress->setValue(i);
+ }
+ }
+ }
+ projectDirFiles.setAutoDelete(true);
+ projectDirFiles.clear();
+ totalText->setText(i18n("Building the tree..."));
+ list->checkboxTree();
+ if (!startUrl.isEmpty())
+ expandAll();
+ list->show();
+ totalText->setText(i18n("Total:"));
+ totalProgress->setTotalSteps(1);
+ totalProgress->setValue(0);
+ //hack to force repainting of the treeview
+ resize(width() + 1, height());
+ resize(width() - 1, height());
+ if (m_quickUpload)
+ startUpload();
+}
+
+
+void ProjectUpload::buildSelectedItemList()
+{
+ QListViewItem *item;
+ QListViewItemIterator it(list);
+ toUpload.clear();
+ needsConfirmation.clear();
+ for ( ; it.current(); ++it )
+ {
+ item = it.current();
+ if ( list->isSelected( item ))
+ {
+ KURL u;
+ if (dynamic_cast<UploadTreeFolder*>(item))
+ {
+ u = dynamic_cast<UploadTreeFolder*>(item)->url();
+ } else
+ {
+ UploadTreeFile* fileItem = dynamic_cast<UploadTreeFile*>(item);
+ u = fileItem->url();
+ if (fileItem->confirmUpload() && !u.isEmpty())
+ needsConfirmation.append(item);
+ }
+
+ if (!u.isEmpty())
+ toUpload.append(item);
+ }
+ }
+}
+
+void ProjectUpload::initBaseUrl()
+{
+ QString path = m_currentProfileElement.attribute("remote_path","");
+ if (!path.startsWith("/"))
+ path.prepend("/");
+
+ baseUrl->setProtocol(m_currentProfileElement.attribute("remote_protocol","ftp"));
+ baseUrl->setPort(m_currentProfileElement.attribute("remote_port","").toInt());
+ baseUrl->setHost(m_currentProfileElement.attribute("remote_host",""));
+ baseUrl->setPath(path);
+ baseUrl->setUser(m_currentProfileElement.attribute("user",""));
+ QString password;
+ if (keepPasswords->isChecked())
+ {
+ m_project->keepPasswd = true;
+ password = m_project->password(m_currentProfileElement.attribute("remote_protocol") + "://" + m_currentProfileElement.attribute("user") + "@" + m_currentProfileElement.attribute("remote_host"));
+ } else
+ {
+ m_project->keepPasswd = false;
+ if (m_currentProfileElement != m_lastEditedProfileElement)
+ {
+ m_lastPassword = "";
+ }
+ password = m_lastPassword;
+ }
+ baseUrl->setPass(password);
+}
+
+void ProjectUpload::startUpload()
+{
+ if (m_profilesOnly)
+ {
+ QDialog::accept();
+ return;
+ }
+ stopUpload = false;
+ initBaseUrl();
+ if (markAsUploaded->isChecked())
+ {
+ QStringList selectedList;
+ QListViewItem *item;
+ QListViewItemIterator it(list);
+ for ( ; it.current(); ++it )
+ {
+ item = it.current();
+ if ( list->isSelected( item ))
+ {
+ KURL u;
+ if (dynamic_cast<UploadTreeFolder*>(item))
+ {
+ u = dynamic_cast<UploadTreeFolder*>(item)->url();
+ } else
+ {
+ u = dynamic_cast<UploadTreeFile*>(item)->url();
+ }
+
+ if (!u.isEmpty())
+ selectedList.append(QuantaCommon::qUrl(u));
+ }
+ }
+ //update upload time
+ QDomNodeList nl = m_project->dom()->elementsByTagName("item");
+ QDomElement el;
+ for ( uint i = 0; i < nl.count(); i++ )
+ {
+ el = nl.item(i).toElement();
+ if ( selectedList.contains(el.attribute("url")))
+ {
+ m_uploadTimeList[el.attribute("url")] = el.attribute("modified_time").toInt();
+ }
+ }
+ saveRemoteUploadInfo();
+ accept();
+ } else
+ {
+ buildSelectedItemList();
+ int confirmCount = needsConfirmation.count();
+ if (confirmCount > 0)
+ {
+ QValueList<QListViewItem*>::Iterator it;
+ QStringList confirmList;
+ for (it = needsConfirmation.begin(); it != needsConfirmation.end(); ++it)
+ {
+ confirmList.append(((UploadTreeFile*)(*it))->url().prettyURL(0, KURL::StripFileProtocol));
+ }
+ bool ok;
+ QStringList confirmedList = KInputDialog::getItemList(i18n("Confirm Upload"), i18n("Confirm that you want to upload the following files (unselect the files you do not want to upload):"), confirmList, confirmList, true, &ok, this);
+ if (!ok) return;
+ for (it = needsConfirmation.begin(); it != needsConfirmation.end(); ++it)
+ {
+ if (!confirmedList.contains(((UploadTreeFile*)(*it))->url().prettyURL(0, KURL::StripFileProtocol)))
+ toUpload.remove(*it);
+ }
+
+ }
+ int selectedNum = toUpload.count();
+ totalProgress->setProgress(0);
+ totalProgress->setTotalSteps(selectedNum);
+ uploadInProgress = true;
+ suspendUpload = false;
+ buttonUpload->setEnabled(false);
+ KURL u = *baseUrl;
+ u.setPath(u.protocol() == "file" ? "/" : "");
+ if (QExtFileInfo::exists(u, false, this) || (u.protocol() == "webdav" && QExtFileInfo::exists(*baseUrl, false, this)))
+ {
+ upload();
+ return;
+ } else
+ {
+ if (KMessageBox::warningContinueCancel(this, i18n("<qt><b>%1</b> seems to be unaccessible.<br>Do you want to proceed with upload?</qt>")
+ .arg(u.prettyURL(0, KURL::StripFileProtocol)),QString::null,KStdGuiItem::cont()) == KMessageBox::Continue)
+ {
+ upload();
+ return;
+ }
+ }
+ }
+ buttonUpload->setEnabled(true);
+ uploadInProgress = false;
+}
+
+void ProjectUpload::upload()
+{
+ if (stopUpload)
+ {
+ saveRemoteUploadInfo();
+ return;
+ }
+ KURL dir;
+ KURL to;
+ UploadTreeFile *fileItem;
+ UploadTreeFolder *folderItem;
+
+ if (toUpload.isEmpty())
+ {
+ saveRemoteUploadInfo();
+ accept();
+ return;
+ }
+ currentItem = toUpload.at(0);
+ if (dynamic_cast<UploadTreeFile*>(currentItem))
+ {
+ fileItem = static_cast<UploadTreeFile*>(currentItem);
+ folderItem = 0L;
+ currentURL = fileItem->url();
+ } else
+ {
+ fileItem = 0L;
+ folderItem = static_cast<UploadTreeFolder*>(currentItem);
+ currentURL = folderItem->url();
+ }
+
+
+ KURL from = QExtFileInfo::toAbsolute(currentURL, m_project->projectBaseURL());
+ to = *baseUrl;
+ to.addPath( currentURL.path() );
+ if (to.fileName(false).isEmpty())
+ {
+ dir = to;
+ }
+ else
+ {
+ dir = to.upURL() ;
+ }
+
+ if ( !madeDirs.contains(dir) )
+ {
+ madeDirs.append( dir );
+ if (!QExtFileInfo::createDir(dir, this))
+ {
+ QuantaCommon::dirCreationError(this, KURL( dir.prettyURL(0, KURL::StripFileProtocol) ));
+ buttonUpload->setEnabled(true);
+ uploadInProgress = false;
+ saveRemoteUploadInfo();
+ return;
+ }
+ }
+
+ // qDebug("%s -> %s", from.url().data(), to.url().data() );
+ if (!from.fileName(false).isEmpty() && fileItem)
+ {
+ emit eventHappened("before_upload", from.url(), to.url());
+ KIO::FileCopyJob *job = KIO::file_copy( from, to, fileItem->permissions(), true, false, false );
+
+ connect( job, SIGNAL( result( KIO::Job * ) ),this,
+ SLOT( uploadFinished( KIO::Job * ) ) );
+ connect( job, SIGNAL( percent( KIO::Job *,unsigned long ) ),
+ this, SLOT( uploadProgress( KIO::Job *,unsigned long ) ) );
+ connect( job, SIGNAL( infoMessage( KIO::Job *,const QString& ) ),
+ this, SLOT( uploadMessage( KIO::Job *,const QString& ) ) );
+
+ labelCurFile->setText(i18n("Current: %1").arg(currentURL.fileName()));
+ currentProgress->setProgress( 0 );
+ return;
+ } else //it is a dir, so just go to the next item
+ {
+ emit uploadNext();
+ return;
+ }
+ saveRemoteUploadInfo();
+ buttonUpload->setEnabled(true);
+ uploadInProgress = false;
+ reject();
+}
+
+void ProjectUpload::uploadFinished( KIO::Job *job )
+{
+ if ( !job ) return;
+
+ if ( job->error() )
+ {
+ job->showErrorDialog( this );
+ uploadInProgress = false;
+ buttonUpload->setEnabled(true);
+ saveRemoteUploadInfo();
+ return;
+ }
+ KIO::FileCopyJob *fJob = dynamic_cast<KIO::FileCopyJob *>(job);
+ if (fJob)
+ emit eventHappened("after_upload", fJob->srcURL().url(), fJob->destURL().url());
+ slotUploadNext();
+}
+
+void ProjectUpload::uploadProgress ( KIO::Job *, unsigned long percent )
+{
+ currentProgress->setProgress( percent );
+}
+
+void ProjectUpload::uploadMessage ( KIO::Job *, const QString & msg )
+{
+ labelCurFile->setText( currentURL.fileName() + " : " + msg );
+}
+
+void ProjectUpload::selectAll()
+{
+ list->selectAll(true);
+ list->checkboxTree();
+}
+
+void ProjectUpload::selectModified()
+{
+ for ( KURL::List::Iterator file = modified.begin(); file != modified.end(); ++file )
+ {
+ QListViewItem *it = list->findItem( (*file).path() );
+ it->setSelected(true);
+ it->repaint();
+ }
+ list->checkboxTree();
+}
+
+void ProjectUpload::clearSelection()
+{
+ list->selectAll(false);
+ list->checkboxTree();
+}
+
+void ProjectUpload::invertSelection()
+{
+ list->invertAll();
+ list->checkboxTree();
+}
+
+void ProjectUpload::expandAll()
+{
+ list->expandAll();
+}
+
+void ProjectUpload::collapseAll()
+{
+ list->collapseAll();
+}
+
+void ProjectUpload::resizeEvent ( QResizeEvent *t )
+{
+ ProjectUploadS::resizeEvent(t);
+ list->setColumnWidth(0,list->width()-list->columnWidth(1)-list->columnWidth(2)-20);
+}
+
+/** No descriptions */
+void ProjectUpload::slotUploadNext()
+{
+ if (!suspendUpload)
+ {
+ totalProgress->setProgress(totalProgress->progress()+1);
+ // QListViewItem *it = list->findItem( currentURL.path() );
+ QListViewItem *it = currentItem;
+ if (it)
+ {
+ it->setSelected(false);
+ UploadTreeFile *itf = dynamic_cast<UploadTreeFile*>(it);
+ if (itf)
+ itf->setWhichPixmap( "check_clear" );
+ it->repaint();
+ }
+ toUpload.remove( it );
+
+ //update upload time
+ QDomNodeList nl = m_project->dom()->elementsByTagName("item");
+ QDomElement el;
+ for ( uint i = 0; i < nl.count(); i++ )
+ {
+ el = nl.item(i).toElement();
+ if ( el.attribute("url") == QuantaCommon::qUrl(currentURL) )
+ {
+ m_uploadTimeList[el.attribute("url")] = el.attribute("modified_time").toInt();
+ break;
+ }
+ }
+
+ upload();
+ }
+}
+
+void ProjectUpload::clearProjectModified()
+{
+ QDomNodeList nl = m_project->dom()->elementsByTagName("item");
+ for ( unsigned int i=0; i<nl.count(); i++ )
+ {
+ QDomElement el = nl.item(i).toElement();
+ m_uploadTimeList[el.attribute("url")] = el.attribute("modified_time").toInt();
+ }
+ modified.clear();
+ list->clearSelection();
+ list->checkboxTree();
+}
+
+void ProjectUpload::slotNewProfile()
+{
+ UploadProfileDlgS *profileDlg = new UploadProfileDlgS(this);
+ QDomElement el = m_currentProfileElement;
+ m_currentProfileElement = m_project->dom()->createElement("profile");
+ fillProfileDlg(profileDlg);
+ if (profileDlg->exec())
+ {
+ readProfileDlg(profileDlg);
+ m_profilesNode.appendChild(m_currentProfileElement);
+ m_project->setModified(true);
+ comboProfile->insertItem(m_currentProfileElement.attribute("name"), 0);
+ setProfileTooltip();
+ } else
+ m_currentProfileElement = el;
+ delete profileDlg;
+ buttonRemoveProfile->setEnabled(comboProfile->count() > 1);
+}
+
+void ProjectUpload::slotEditProfile()
+{
+ UploadProfileDlgS *profileDlg = new UploadProfileDlgS(this);
+ fillProfileDlg(profileDlg);
+ if (profileDlg->exec())
+ {
+ readProfileDlg(profileDlg);
+ m_project->setModified(true);
+ comboProfile->changeItem(profileDlg->lineProfileName->text(), comboProfile->currentItem());
+ setProfileTooltip();
+ }
+ delete profileDlg;
+}
+
+void ProjectUpload::slotRemoveProfile()
+{
+ if (comboProfile->count() == 1)
+ {
+ KMessageBox::error(this, i18n("You cannot remove the last profile."), i18n("Profile Removal Error") );
+ } else
+ {
+ QString profileName = comboProfile->currentText();
+ if (KMessageBox::warningContinueCancel(this, i18n("<qt>Do you really want to remove the <b>%1</b> upload profile?</qt>").arg(profileName),
+ i18n("Profile Removal"), KStdGuiItem::del()) == KMessageBox::Continue)
+ {
+ m_profilesNode.removeChild(m_currentProfileElement);
+ int idx = comboProfile->currentItem();
+ int newIdx = idx + 1;
+ if (newIdx >= comboProfile->count())
+ newIdx = idx - 1;
+ comboProfile->setCurrentItem(newIdx);
+ QString currentProfile = comboProfile->currentText();
+ slotNewProfileSelected(currentProfile);
+ if (profileName == defaultProfile())
+ {
+ KMessageBox::information(this, i18n("<qt>You have removed your default profile.<br>The new default profile will be <b>%1</b>.</qt>").arg(currentProfile), i18n("Profile Removal"));
+ m_profilesNode.toElement().setAttribute("defaultProfile", currentProfile);
+ }
+ comboProfile->removeItem(idx);
+ m_project->setModified(true);
+ }
+ }
+ buttonRemoveProfile->setEnabled(comboProfile->count() > 1);
+}
+
+void ProjectUpload::fillProfileDlg(UploadProfileDlgS *profileDlg)
+{
+ profileDlg->lineProfileName->setText(m_currentProfileElement.attribute("name",""));
+ profileDlg->lineHost->setText(m_currentProfileElement.attribute("remote_host",""));
+ profileDlg->lineUser->setText(m_currentProfileElement.attribute("user",""));
+ profileDlg->linePath->setText(m_currentProfileElement.attribute("remote_path",""));
+ profileDlg->port->setText( m_currentProfileElement.attribute("remote_port","") );
+ QString def_p = m_currentProfileElement.attribute("remote_protocol","ftp");
+
+ QStringList protocols = KProtocolInfo::protocols();
+ protocols.sort();
+ for ( uint i=0; i<protocols.count(); i++ )
+ {
+ QString protocol = protocols[i];
+ KURL p;
+ p.setProtocol(protocol);
+ if ( KProtocolInfo::supportsWriting(p) &&
+ KProtocolInfo::supportsMakeDir(p) &&
+ KProtocolInfo::supportsDeleting(p) )
+ {
+ profileDlg->comboProtocol->insertItem(protocol);
+ if ( protocol == def_p )
+ profileDlg->comboProtocol->setCurrentItem(profileDlg->comboProtocol->count()-1 );
+ }
+ }
+ QString entry = profileDlg->comboProtocol->currentText() + "://" + profileDlg->lineUser->text() + "@" + profileDlg->lineHost->text();
+ if (m_project->keepPasswd || m_project->passwordSaved(entry))
+ {
+ profileDlg->linePasswd->insert(m_project->password(entry));
+ profileDlg->keepPasswd->setChecked(m_project->passwordSaved(entry));
+ } else
+ {
+ profileDlg->linePasswd->clear();
+ profileDlg->keepPasswd->setChecked(false);
+ }
+ if (m_profilesNode.toElement().attribute("defaultProfile") == profileDlg->lineProfileName->text())
+ profileDlg->defaultProfile->setChecked(true);
+}
+
+void ProjectUpload::readProfileDlg(UploadProfileDlgS *profileDlg)
+{
+ QString path = profileDlg->linePath->text();
+ if (path.startsWith("~/"))
+ {
+ KUser user;
+ path = user.homeDir() + path.mid(1);
+ }
+ m_currentProfileElement.setAttribute("name", profileDlg->lineProfileName->text());
+ m_currentProfileElement.setAttribute("remote_host", profileDlg->lineHost->text());
+ m_currentProfileElement.setAttribute("user", profileDlg->lineUser->text());
+ m_currentProfileElement.setAttribute("remote_path", path);
+ m_currentProfileElement.setAttribute("remote_port", profileDlg->port->text());
+ m_currentProfileElement.setAttribute("remote_protocol", profileDlg->comboProtocol->currentText());
+ QString passwd = QString(profileDlg->linePasswd->password());
+ m_project->savePassword(profileDlg->comboProtocol->currentText() + "://" + profileDlg->lineUser->text() + "@" + profileDlg->lineHost->text(), passwd, profileDlg->keepPasswd->isChecked());
+ m_lastEditedProfileElement = m_currentProfileElement;
+ m_lastPassword = passwd;
+ if (profileDlg->defaultProfile->isChecked())
+ m_profilesNode.toElement().setAttribute("defaultProfile", profileDlg->lineProfileName->text());
+}
+
+void ProjectUpload::slotNewProfileSelected(const QString& profileName)
+{
+ QDomNodeList profileList = m_profilesNode.toElement().elementsByTagName("profile");
+ QDomElement e;
+ QString s;
+ for (uint i = 0; i < profileList.count(); i++)
+ {
+ e = profileList.item(i).toElement();
+ s = e.attribute("name");
+ if (s == profileName)
+ {
+ m_currentProfileElement = e;
+ break;
+ }
+ }
+ m_project->setModified(true);
+ setProfileTooltip();
+ if (!m_profilesOnly)
+ {
+ list->clear();
+ slotBuildTree();
+ }
+}
+
+QString ProjectUpload::defaultProfile()
+{
+ return m_profilesNode.toElement().attribute("defaultProfile");
+}
+
+void ProjectUpload::reject()
+{
+ if (uploadInProgress && !m_profilesOnly)
+ {
+ suspendUpload = true;
+ //TODO when message freeze if lift: i18n("Upload") -> i18n("Continue") or "Continue upload"
+ if (KMessageBox::questionYesNo(this,i18n("Do you really want to abort the upload?"),
+ i18n("Abort Upload"), i18n("Abort the uploading", "Abort"), i18n("Upload")) == KMessageBox::No)
+ {
+ suspendUpload = false;
+ emit uploadNext();
+ return;
+ }
+ }
+
+ QDialog::reject();
+}
+
+
+void ProjectUpload::setProfileTooltip()
+{
+ QString tip = m_currentProfileElement.attribute("remote_protocol","ftp") + "://";
+ QString user = m_currentProfileElement.attribute("user","");
+ if (! user.isEmpty()) {
+ tip += user + "@";
+ }
+ tip += m_currentProfileElement.attribute("remote_host","");
+ QString port = m_currentProfileElement.attribute("remote_port","");
+ if (! port.isEmpty()) {
+ tip += ":" + port;
+ }
+ tip += m_currentProfileElement.attribute("remote_path","");
+
+ QToolTip::add(comboProfile, tip);
+}
+
+void ProjectUpload::loadRemoteUploadInfo()
+{
+ QDomNodeList nl = m_currentProfileElement.elementsByTagName("uploadeditem");
+ for (uint i = 0; i < nl.count(); i++)
+ {
+ QDomElement el = nl.item(i).toElement();
+ m_uploadTimeList[el.attribute("url")] = el.attribute("upload_time").toInt();
+ }
+}
+
+void ProjectUpload::saveRemoteUploadInfo()
+{
+ QDomNode parent = m_currentProfileElement.parentNode();
+ QDomNode profileNode = m_currentProfileElement.cloneNode(false);
+ parent.removeChild(m_currentProfileElement);
+ parent.appendChild(profileNode);
+ QMap<QString, int>::ConstIterator it;
+ for (it = m_uploadTimeList.constBegin(); it != m_uploadTimeList.constEnd(); ++it)
+ {
+ QDomElement el = m_uploadStatusDom.createElement("uploadeditem");
+ el.setAttribute("url", it.key());
+ el.setAttribute("upload_time", it.data());
+ profileNode.appendChild(el);
+ }
+ m_project->setModified(true);
+}
+
+
+#include "projectupload.moc"
diff --git a/quanta/project/projectupload.h b/quanta/project/projectupload.h
new file mode 100644
index 00000000..375898ec
--- /dev/null
+++ b/quanta/project/projectupload.h
@@ -0,0 +1,118 @@
+/***************************************************************************
+ projectupload.h - description
+ -------------------
+ begin : Wed Nov 15 2000
+ copyright : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon <[email protected],[email protected],[email protected]>
+ (C) 2002, 2004 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PROJECTUPLOAD_H
+#define PROJECTUPLOAD_H
+
+#include "projectuploads.h"
+#include "project.h"
+
+#include <qdom.h>
+#include <qptrlist.h>
+#include <qstringlist.h>
+
+#include <kio/job.h>
+
+/**
+ *@author Dmitry Poplavsky & Alexander Yakovlev & Andras Mantia
+ */
+
+class KURL;
+class Project;
+class UploadProfileDlgS;
+
+class ProjectUpload : public ProjectUploadS
+{
+ Q_OBJECT
+public:
+ /** Initializes the dialog. If showOnlyProfiles is true, the dialog
+ displays only the list of profiles, no real upload can be performed.
+ If quickUpload is true, the upload starts immediately without checking
+ for modifications or confirmation from the user. The url will be
+ uploaded to the default profile */
+ ProjectUpload(const KURL& url, const QString& profileName = QString::null, bool showOnlyProfiles = false, bool quickUpload = false, bool markOnly = false, const char * name = 0);
+ ~ProjectUpload();
+ QString defaultProfile();
+
+public slots: // Public slots
+ /** No descriptions */
+ void slotBuildTree();
+
+protected slots:
+ void startUpload();
+ void upload();
+ void uploadFinished( KIO::Job *job );
+ void uploadProgress ( KIO::Job *job, unsigned long percent );
+ void uploadMessage ( KIO::Job *, const QString & msg );
+ void slotUploadNext();
+
+ void clearSelection();
+ void selectAll();
+ void selectModified();
+ void invertSelection();
+ void expandAll();
+ void collapseAll();
+ void clearProjectModified();
+
+ void slotNewProfile();
+ void slotEditProfile();
+ void slotRemoveProfile();
+ void slotNewProfileSelected(const QString &profileName);
+
+ virtual void resizeEvent( QResizeEvent * );
+ virtual void reject();
+
+
+signals: // Signals
+ /** No descriptions */
+ void uploadNext();
+ void eventHappened(const QString&, const QString&, const QString&);
+
+private:
+ void buildSelectedItemList();
+ void fillProfileDlg(UploadProfileDlgS *profileDlg);
+ void readProfileDlg(UploadProfileDlgS *profileDlg);
+ void setProfileTooltip();
+ void loadRemoteUploadInfo();
+ void saveRemoteUploadInfo();
+ void initProjectInfo(const QString& defaultProfile);
+ void initBaseUrl(); /// Reads the current profile setting and initialize the baseUrl from it
+
+ KURL::List modified; // modified files
+ QValueList<QListViewItem*> needsConfirmation;
+ QPtrList<QListViewItem> toUpload; // list of files , still didn't uploaded
+ QListViewItem *currentItem;
+ KURL currentURL;
+ KURL::List madeDirs;
+ KURL *baseUrl;
+ KURL startUrl;
+ bool stopUpload;
+ bool uploadInProgress;
+ bool suspendUpload;
+ QString m_lastPassword;
+ Project *m_project;
+ QString m_defaultProfile;
+ QDomElement m_currentProfileElement;
+ QDomElement m_lastEditedProfileElement;
+ QDomNode m_profilesNode;
+ QDomDocument m_uploadStatusDom;
+ QMap<QString, int> m_uploadTimeList;
+ bool m_profilesOnly;
+ bool m_quickUpload;
+};
+
+#endif
diff --git a/quanta/project/projectuploads.ui b/quanta/project/projectuploads.ui
new file mode 100644
index 00000000..19a2328c
--- /dev/null
+++ b/quanta/project/projectuploads.ui
@@ -0,0 +1,497 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>ProjectUploadS</class>
+<comment>/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+</comment>
+<author>(C) 2002-2004 Andras Mantia &lt;[email protected]&gt;</author>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>ProjectUploadS</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>595</width>
+ <height>584</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="caption">
+ <string>Upload Project Files</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>false</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Profile &amp;name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>comboProfile</cstring>
+ </property>
+ </widget>
+ <widget class="KComboBox">
+ <property name="name">
+ <cstring>comboProfile</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4_2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Preferred</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>buttonNewProfile</cstring>
+ </property>
+ <property name="text">
+ <string>New...</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>buttonEditProfile</cstring>
+ </property>
+ <property name="text">
+ <string>Edit...</string>
+ </property>
+ </widget>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>buttonRemoveProfile</cstring>
+ </property>
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QPushButton" row="3" column="1">
+ <property name="name">
+ <cstring>buttonUpload</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Proceed</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="3" column="2">
+ <property name="name">
+ <cstring>buttonCancel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer row="3" column="0">
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>400</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>keepPasswords</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Keep passwords in memory</string>
+ </property>
+ </widget>
+ <widget class="QFrame" row="2" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>uploadFrame</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton" row="4" column="1">
+ <property name="name">
+ <cstring>buttonInvert</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Invert</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="3" column="1">
+ <property name="name">
+ <cstring>buttonClear</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;None</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="6" column="1">
+ <property name="name">
+ <cstring>buttonCollapse</cstring>
+ </property>
+ <property name="text">
+ <string>C&amp;ollapse All</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="7" column="1">
+ <property name="name">
+ <cstring>buttonUpdate</cstring>
+ </property>
+ <property name="text">
+ <string>U&amp;pdate All</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>This will cause all files to appear already uploaded</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="2" column="1">
+ <property name="name">
+ <cstring>buttonModified</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Modified</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="5" column="1">
+ <property name="name">
+ <cstring>buttonExpand</cstring>
+ </property>
+ <property name="text">
+ <string>E&amp;xpand All</string>
+ </property>
+ </widget>
+ <widget class="UploadTreeView" row="0" column="0" rowspan="8" colspan="1">
+ <property name="name">
+ <cstring>list</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="1">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Selection:</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="1" column="1">
+ <property name="name">
+ <cstring>buttonAll</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;All</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="8" column="0">
+ <property name="name">
+ <cstring>markAsUploaded</cstring>
+ </property>
+ <property name="text">
+ <string>Mark the selected files as uploaded instead of uploading them</string>
+ </property>
+ </widget>
+ <widget class="KProgress" row="12" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>totalProgress</cstring>
+ </property>
+ </widget>
+ <widget class="KProgress" row="10" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>currentProgress</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="9" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>labelCurFile</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Current: [none]</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QLabel" row="11" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>totalText</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Total:</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>UploadTreeView</class>
+ <header location="local">../treeviews/uploadtreeview.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="PNG" length="1110">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b0000041d49444154789c8d95c18b1c4514c67fbb29e5b54ea05b26da1d36b08d09a6c508138cb8c13d647141163de49043bca9f1628eb9294810f24f88c15b728b07617358888785d980427290b4a8d00b19a8821da8228cf42316ac87eed9247ac95c9aeaeef9eaabdffb5ebf85f178ccfcf7f5b79fec07a7280a08a008f25ceb7c29e5da573716e65a0be3f198ef6f5ededff9b9e1b34faf90882092a1ea21428b9220ffbf46054055b19386ba6970ae6665b5e0d2c5eb0b066067bbe1f21757c88f5504eff0c192189081303a5582b16854fccce2fe041f00cdd0a8103b874556405476b62d972ec2c2b90ff3fd8df5cb946549d80b34aea15ccaa94625450e2d0e558b460b7371a734b5e027251a155545678ab62d7eea90b4c504078908c107acb354cb251b1f8f08b1c18631aabbb4d18211404804f22545863561d2f060fb34aa8a18d0086204e72c46a32292e1a796f278c1da7a859d8da9a737506db04d0a24103d8949480b214d3bbee952a05c1d536f9d2684160c744f048311543d459eb1b65ee1754cedae13a64abd5d6127053c9d0281f22d4f75c6a2118a5c09272d7ab740638bf4ef2dd2174032d0d8d04c6fe19c32bedd8bc65e342aa3f785e2784bfd6bc1bd9db24b05505616a4edd67d5a8c1801a03a9962754c504bf34b8986acfb9be91cac7d54315a15541b36b134f74bd2dc53940115a5381e087bc25c6f71be831a8baa234cc1ee3eeb74ed83116beb2b8849d108a3730e8ce27e2bfb82419a7b407ac7c222fd0e6280a8078ce64e47ef54ac9d5be9aaae0162e0de568a44a18d3df90845d919c4f01463406340a44f40efb43a99b371618488e2670d1a2d7ee6f1d3be39342104e937ed85fb86599c33e9ee0be9a004946259d8b858909880d59aa00daa0d3280b5f39e34074c4b3a5434029a76a9e9f5cc0163b5c80024158a1cfc4cb1d3061d5834066cb0a403c008599a70f6bc27b8d03106ea3ae91987278c5b143b015547224ab5e24185cd9b81665273e7b6e7cecd82ddbf8098002de94049737bc09828cf3036f31c3735c8b0e98eb704672f348c7f7c93cd1fb2ae905119ff54e0dff3542b0e9dd983dcea2cc5eea6cf303e74ec687af5c41b6fa38f5e203c7ec8e1238ef85831a214afef21060ea781ec68247b65c6916353cc8b73d1ae79354606af2a930709aa118da1636c274dd7e3774b884a79aa6b5711a538d33cf9c01c1c9b83bc6a1f55c91ccb23b05b1deb43a7decdaffefd2862f61366aa8449c69e33642f012f2bb208fa98eeda1f3346f076c8eeef19475e9be115423364f78f84105a8643d34d90cfbfdcd8cf872589a45dc7f54cf3134a36f4e495c23f9da8db15bccb708d4014f2ca512cb5d4f7c13e84300d5cff6eb39b202bab053bdb9674f0648609427d0f8402ddeac30f4fcd3ced3efc3b422d406c09b340bedc1571e1bfc3d44dc281634c5fe5e758e7395cfbe6d6c130fd17d92372d2cb00c6470000000049454e44ae426082</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectUploadS</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>buttonUpload</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectUploadS</receiver>
+ <slot>startUpload()</slot>
+ </connection>
+ <connection>
+ <sender>buttonNewProfile</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectUploadS</receiver>
+ <slot>slotNewProfile()</slot>
+ </connection>
+ <connection>
+ <sender>buttonEditProfile</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectUploadS</receiver>
+ <slot>slotEditProfile()</slot>
+ </connection>
+ <connection>
+ <sender>buttonRemoveProfile</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectUploadS</receiver>
+ <slot>slotRemoveProfile()</slot>
+ </connection>
+ <connection>
+ <sender>comboProfile</sender>
+ <signal>activated(const QString&amp;)</signal>
+ <receiver>ProjectUploadS</receiver>
+ <slot>slotNewProfileSelected(const QString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>buttonAll</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectUploadS</receiver>
+ <slot>selectAll()</slot>
+ </connection>
+ <connection>
+ <sender>buttonModified</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectUploadS</receiver>
+ <slot>selectModified()</slot>
+ </connection>
+ <connection>
+ <sender>buttonInvert</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectUploadS</receiver>
+ <slot>invertSelection()</slot>
+ </connection>
+ <connection>
+ <sender>buttonClear</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectUploadS</receiver>
+ <slot>clearSelection()</slot>
+ </connection>
+ <connection>
+ <sender>buttonExpand</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectUploadS</receiver>
+ <slot>expandAll()</slot>
+ </connection>
+ <connection>
+ <sender>buttonCollapse</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectUploadS</receiver>
+ <slot>collapseAll()</slot>
+ </connection>
+ <connection>
+ <sender>buttonUpdate</sender>
+ <signal>clicked()</signal>
+ <receiver>ProjectUploadS</receiver>
+ <slot>clearProjectModified()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>comboProfile</tabstop>
+ <tabstop>buttonNewProfile</tabstop>
+ <tabstop>buttonEditProfile</tabstop>
+ <tabstop>buttonRemoveProfile</tabstop>
+ <tabstop>buttonUpload</tabstop>
+ <tabstop>buttonCancel</tabstop>
+</tabstops>
+<includes>
+ <include location="global" impldecl="in declaration">../treeviews/uploadtreeview.h</include>
+</includes>
+<slots>
+ <slot>clearSelection()</slot>
+ <slot>startUpload()</slot>
+ <slot>selectAll()</slot>
+ <slot>selectModified()</slot>
+ <slot>invertSelection()</slot>
+ <slot>expandAll()</slot>
+ <slot>collapseAll()</slot>
+ <slot>clearProjectModified()</slot>
+ <slot>slotNewProfile()</slot>
+ <slot>slotEditProfile()</slot>
+ <slot>slotRemoveProfile()</slot>
+ <slot>slotNewProfileSelected(const QString&amp;)</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>uploadtreeview.h</includehint>
+</includehints>
+</UI>
diff --git a/quanta/project/projecturl.h b/quanta/project/projecturl.h
new file mode 100644
index 00000000..67299d90
--- /dev/null
+++ b/quanta/project/projecturl.h
@@ -0,0 +1,64 @@
+/***********************************************************************
+ projecturl.h - ProjectURL class definition
+ -------------------
+ begin : Wed Feb 18 2004
+ copyright : (C) 2004 by Andrei Berezin <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef PROJECT_URL_H
+#define PROJECT_URL_H
+
+#include <qdom.h>
+#include <qdict.h>
+#include <qstring.h>
+
+#include <kurl.h>
+
+
+/**
+ * Project item.
+ * Consists of URL and description text.
+ */
+class ProjectURL : public KURL
+{
+public:
+ QString fileDesc;
+ int uploadStatus; ///< The upload state, see UploadStatus
+ bool documentFolder;
+ QDomElement domElement;
+
+ ProjectURL()
+ : KURL(), uploadStatus(1), documentFolder(false) {}
+
+ ProjectURL(const KURL& url)
+ : KURL(url), uploadStatus(1), documentFolder(false) {}
+
+ ProjectURL(const KURL& url, const QString& desc, int status, bool docFolder)
+ : KURL(url), fileDesc(desc), uploadStatus(status), documentFolder(docFolder) {}
+
+ ProjectURL(const KURL& url, const QString& desc, int status, bool docFolder, QDomElement el)
+ : KURL(url), fileDesc(desc), uploadStatus(status), documentFolder(docFolder), domElement(el) {}
+
+ virtual ~ProjectURL() {}
+
+ /** The default state for a file when uploading */
+ enum UploadStatus
+ {
+ NeverUpload = 0, ///< the files is not selected for upload, even if it was modified
+ AlwaysUpload, ///< the file is automatically selected for upload if it was modified
+ ConfirmUpload ///<the file is selected for upload, but the user must confirm the upload
+ };
+};
+
+typedef QDict<ProjectURL> ProjectUrlList;
+
+#endif // PROJECT_URL_H
diff --git a/quanta/project/rescanprj.cpp b/quanta/project/rescanprj.cpp
new file mode 100644
index 00000000..fe0bb588
--- /dev/null
+++ b/quanta/project/rescanprj.cpp
@@ -0,0 +1,249 @@
+/***************************************************************************
+ rescanprj.cpp - description
+ -------------------
+ begin : ?
+ copyright : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon <[email protected],[email protected],[email protected]>
+ (C) 2002, 2003 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// qt includes
+#include <qlistview.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qlabel.h>
+
+// kde includes
+#include <kdebug.h>
+#include <kurl.h>
+#include <klocale.h>
+#include <kfileitem.h>
+#include <kglobal.h>
+#include <kprogress.h>
+
+// app includes
+#include "rescanprj.h"
+#include "qextfileinfo.h"
+#include "quantacommon.h"
+#include "uploadtreefolder.h"
+#include "uploadtreeview.h"
+#include "resource.h"
+#include "projectlist.h"
+
+
+RescanPrj::RescanPrj(const ProjectList &p_prjFileList, const KURL& p_baseURL, const QRegExp &p_excludeRx,
+ QWidget *parent, const char *name, bool modal )
+ : RescanPrjDir(parent,name,modal)
+{
+ setCaption(name);
+
+ listView->setColumnText(1, i18n("Add"));
+ baseURL = p_baseURL;
+ baseURL.adjustPath(1);
+
+ prjFileList = p_prjFileList;
+ excludeRx = p_excludeRx;
+
+ progressText->setText(i18n("Reading folder:"));
+ KIO::ListJob *job = KIO::listRecursive( baseURL, false );
+ m_listJobCount = 1;
+
+ connect( job, SIGNAL(entries(KIO::Job *,const KIO::UDSEntryList &)),
+ this,SLOT (addEntries(KIO::Job *,const KIO::UDSEntryList &)));
+ connect( job, SIGNAL(result(KIO::Job *)),
+ this,SLOT (slotListDone(KIO::Job *)));
+
+
+ connect( buttonSelect, SIGNAL(clicked()),
+ this, SLOT(slotSelect()));
+ connect( buttonDeselect, SIGNAL(clicked()),
+ this, SLOT(slotDeselect()));
+ connect( buttonInvert, SIGNAL(clicked()),
+ this, SLOT(slotInvert()));
+ connect( buttonExpand, SIGNAL(clicked()),
+ this, SLOT(slotExpand()));
+ connect( buttonCollapse, SIGNAL(clicked()),
+ this, SLOT(slotCollapse()));
+}
+
+RescanPrj::~RescanPrj()
+{
+ for (uint i = 0; i < urlList.count(); i++)
+ {
+ delete urlList[i].fileItem;
+ }
+ urlList.clear();
+}
+
+void RescanPrj::addEntries(KIO::Job *job,const KIO::UDSEntryList &list)
+{
+ KURL url = static_cast<KIO::ListJob *>(job)->url();
+ url.adjustPath(-1);
+ // avoid creating these QStrings again and again
+ static const QString& dot = KGlobal::staticQString(".");
+ static const QString& dotdot = KGlobal::staticQString("..");
+
+ KIO::UDSEntryListConstIterator it = list.begin();
+ KIO::UDSEntryListConstIterator end = list.end();
+ KURL itemURL;
+ URLListEntry urlEntry;
+ QString name;
+ QPtrList<KFileItem> linkItems;
+ linkItems.setAutoDelete(true);
+ for ( ; it != end; ++it )
+ {
+ KFileItem item( *it, url, false, true );
+ name = item.name();
+ if (item.isDir() && item.isLink())
+ {
+ QString linkDest = item.linkDest();
+ kdDebug(24000) << "Got link: " << name << " Points to:" << linkDest << endl;
+ KURL u = item.url();
+ if (linkDest.startsWith("."))
+ {
+ u.setPath(u.directory(false, true) + linkDest);
+ u.cleanPath();
+ }
+ else
+ u.setPath(linkDest);
+ u.adjustPath(+1);
+ KURL u2 = QExtFileInfo::toRelative(u, baseURL);
+ bool found = false;
+ for (uint i = 0; i < urlList.count(); i++)
+ if (urlList[i].url == u2)
+ {
+ found = true;
+ break;
+ }
+ if (!prjFileList.contains(u) && !found)
+ {
+ linkItems.append(new KFileItem(item));
+ } else
+ {
+ kdDebug(24000) << "Recursive link - points to a place inside the project" << endl;
+ continue;
+ }
+ }
+ if (!name.isEmpty() && name != dot && name != dotdot && !excludeRx.exactMatch(name))
+ {
+ itemURL = item.url();
+ if (item.isDir())
+ itemURL.adjustPath(+1);
+ ProjectURL *proUrl = prjFileList.find(itemURL);
+ if (!proUrl)
+ {
+ urlEntry.url = prjFileList.toRelative(itemURL);
+ urlEntry.fileItem = new KFileItem(item);
+ urlList.append(urlEntry);
+ }
+ }
+ }
+ for (QPtrList<KFileItem>::ConstIterator it = linkItems.constBegin(); it != linkItems.constEnd(); ++it)
+ {
+ KIO::ListJob *ljob = KIO::listRecursive( (*it)->url(), false );
+ m_listJobCount++;
+
+ connect( ljob, SIGNAL(entries(KIO::Job *,const KIO::UDSEntryList &)),
+ this,SLOT (addEntries(KIO::Job *,const KIO::UDSEntryList &)));
+ connect( ljob, SIGNAL(result(KIO::Job *)),
+ this,SLOT (slotListDone(KIO::Job *)));
+ }
+}
+
+void RescanPrj::resizeEvent ( QResizeEvent *t )
+{
+ RescanPrjDir::resizeEvent(t);
+// listView->setColumnWidth(0,listView->width()-listView->columnWidth(1)-20);
+// MainLayout->setGeometry(childrenRect());
+}
+
+void RescanPrj::slotSelect()
+{
+ listView->selectAll(true);
+ listView->checkboxTree();
+}
+
+void RescanPrj::slotDeselect()
+{
+ listView->selectAll(false);
+ listView->checkboxTree();
+}
+
+void RescanPrj::slotInvert()
+{
+ listView->invertAll();
+ listView->checkboxTree();
+}
+
+void RescanPrj::slotExpand()
+{
+ listView->expandAll();
+}
+
+void RescanPrj::slotCollapse()
+{
+ listView->collapseAll();
+}
+
+KURL::List RescanPrj::files()
+{
+ KURL::List r;
+
+ QListViewItem *item;
+ QListViewItemIterator it(listView);
+ for ( ; it.current(); ++it )
+ {
+ item = it.current();
+ if ( listView->isSelected( item ))
+ {
+ KURL u;
+ if (dynamic_cast<UploadTreeFolder*>(item))
+ {
+ u = dynamic_cast<UploadTreeFolder*>(item)->url();
+ } else
+ {
+ u = dynamic_cast<UploadTreeFile*>(item)->url();
+ }
+
+ if (!u.isEmpty())
+ r.append( QExtFileInfo::toAbsolute(u, baseURL) );
+ }
+ }
+ return r;
+}
+/** No descriptions */
+void RescanPrj::slotListDone(KIO::Job *)
+{
+ m_listJobCount--;
+ // kdDebug(24000) << "slotListDone " << m_listJobCount << endl;
+ if (m_listJobCount == 0)
+ {
+ progressText->setText(i18n("Building tree:"));
+ progressText->repaint();
+ progress->setTotalSteps(urlList.count());
+ progress->setValue(0);
+ URLListEntry urlEntry;
+ for (uint i = 0; i < urlList.count(); i++)
+ {
+ urlEntry = urlList[i];
+ listView->addItem(urlEntry.url, *(urlEntry.fileItem));
+ progress->advance(1);
+ }
+
+ progress->setTotalSteps(1);
+ progress->setValue(0);
+ progress->setTextEnabled(false);
+ progressText->setText(i18n("Progress:"));
+ slotSelect();
+ }
+}
+
+#include "rescanprj.moc"
diff --git a/quanta/project/rescanprj.h b/quanta/project/rescanprj.h
new file mode 100644
index 00000000..1eb32d50
--- /dev/null
+++ b/quanta/project/rescanprj.h
@@ -0,0 +1,68 @@
+/***************************************************************************
+ rescanprj.h - description
+ -------------------
+ begin : ?
+ copyright : (C) 2000 by Dmitry Poplavsky & Alexander Yakovlev & Eric Laffoon <[email protected],[email protected],[email protected]>
+ (C) 2002,2003 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef RESCANPRJ_H
+#define RESCANPRJ_H
+
+#include <qregexp.h>
+#include <kio/job.h>
+
+
+#include "rescanprjdir.h"
+#include "projectlist.h"
+
+class KFileItem;
+
+struct URLListEntry{
+ KURL url;
+ KFileItem* fileItem;
+ };
+
+class RescanPrj : public RescanPrjDir {
+ Q_OBJECT
+public:
+ RescanPrj(const ProjectList &p_prjFileList, const KURL& p_baseURL, const QRegExp &p_excludeRx,
+ QWidget *parent=0, const char *name=0, bool modal = true);
+ ~RescanPrj();
+
+public slots:
+ void slotSelect();
+ void slotDeselect();
+ void slotInvert();
+ void slotExpand();
+ void slotCollapse();
+
+ virtual void resizeEvent( QResizeEvent * );
+
+ KURL::List files();
+
+ void addEntries(KIO::Job *,const KIO::UDSEntryList &);
+
+private:
+ KURL baseURL;
+ ProjectList prjFileList;
+ QRegExp excludeRx;
+ QValueList<URLListEntry> urlList;
+ int m_listJobCount;
+
+protected slots: // Protected slots
+ /** No descriptions */
+ void slotListDone(KIO::Job *);
+};
+
+#endif
+
diff --git a/quanta/project/rescanprjdir.ui b/quanta/project/rescanprjdir.ui
new file mode 100644
index 00000000..d4fdf556
--- /dev/null
+++ b/quanta/project/rescanprjdir.ui
@@ -0,0 +1,255 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>RescanPrjDir</class>
+<comment>/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+</comment>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>RescanPrjDir</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>620</width>
+ <height>540</height>
+ </rect>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>3</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>620</width>
+ <height>540</height>
+ </size>
+ </property>
+ <property name="caption">
+ <string>MyDialog</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KProgress" row="12" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>progress</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="11" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>progressText</cstring>
+ </property>
+ <property name="text">
+ <string>Progress:</string>
+ </property>
+ </widget>
+ <widget class="UploadTreeView" row="2" column="0" rowspan="9" colspan="1">
+ <property name="name">
+ <cstring>listView</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Add New Files in Project&lt;/b&gt;</string>
+ </property>
+ </widget>
+ <widget class="Line" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>Line2</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>4</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32767</width>
+ <height>4</height>
+ </size>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="9" column="1">
+ <property name="name">
+ <cstring>buttonCancel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="8" column="1">
+ <property name="name">
+ <cstring>buttonOk</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="6" column="1">
+ <property name="name">
+ <cstring>buttonCollapse</cstring>
+ </property>
+ <property name="text">
+ <string>Co&amp;llapse All</string>
+ </property>
+ </widget>
+ <spacer row="7" column="1">
+ <property name="name">
+ <cstring>Spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>144</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton" row="2" column="1">
+ <property name="name">
+ <cstring>buttonSelect</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;All</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="3" column="1">
+ <property name="name">
+ <cstring>buttonDeselect</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;None</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="5" column="1">
+ <property name="name">
+ <cstring>buttonExpand</cstring>
+ </property>
+ <property name="text">
+ <string>E&amp;xpand All</string>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="10" column="1">
+ <property name="name">
+ <cstring>buttonHelp</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Help</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="4" column="1">
+ <property name="name">
+ <cstring>buttonInvert</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Invert</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>UploadTreeView</class>
+ <header location="local">../treeviews/uploadtreeview.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>5</hordata>
+ <verdata>5</verdata>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="XPM.GZ" length="4350">789c6dd7594f23471007f0f7fd14d6d6db2aaaf58c3db647511eb831b7317794879ac30760cc61c010e5bba7dcf5af5688167664fdb66bbaababbb67cccf1f8dab93c3c68f9fdf5e16b298968d7222cf8d1fd5eb6cf6f1e75f7ffcfded7b9a3656ff9aad46fafdb76fdf078b46d9389a3fd42bf04841699e964933b830b79a7019dd0b96955b895b5a703bcd572e08eea576ff6570ae0eedd477b792103f854b8b2fc6d1163f77237e646e37113f89b6f8307e3bf1785a8b0eedbc696eb7ad9db7e01ee6476ee4ffe0c6fd158c7c69182cde4eec6e87fea50dfbf8176e6ba7d07f96669999cfa325ccaf862bcc97a36dbccf60f178cee11cde706761f16917ae30fe6b7488a7851bf14d7327417f676eb4f756eea41e2f57e6d83e83919f6cba117f04235fd9765b3b0fa36dfc398cf973edc67a6fb951ffe768ab6765ee26b8dff213ef5f4630e2b9e7463ea7ee8ee5ff60ee2618af8eb6fe3238437eb91bf1299cdbfacad3cadd5617f5a11738c7fe4adcb8ffd68d7aeec15e8fc3683b9f62ee2518ef33dafa3f75e3bc957086f86eb4d56f3db8e8e6dd56f01a5cc1bbe65e629673d8ebd18d0efdc9058cf9f2c08df9e630ce037db8719ec37c7a9a7fb708f10267b65e7cef46fb3e9ca3fd23dad6ef0cf67abe99f304f95ec3a8871cbb71be52d8d777e8b6fee412f6f958be3adf5ea817b561afe7d86ded7c67ce13c46fc37ede2766c17a17059cd9f38e466e8c3f8eb6fd700f0b9ef7095c37cd3d37de178f2be76dcf876fa343bd790267f012f67a77cc319f69b4ed872e2ca8e732daeabfe3c6fa9cc235f21f9b8bd4f2a5cd687bfedbfd659ee7ede017b842becf6eb44fa3cbd0df8559b0ffe808ceb0ff37e01afba3652e52cc87a26dbe276ecca7097790ff73b4cdef0616ac4fdf6df1c2d1d67ee8c6f80318eb4bd1180ff529513f0ecf7b694b62f5a002ceccb2662e523c2fb7605f9f0fd8fbbf75e3bc2dcd3e9ebcb9f17ce8c05e8f83685bcf701e44eb2db65e4fd1b65eebe62245be53b8c6f3ffdd8dfd3933fbf884761f5f0edcd88f951bf118bf44bde926dae24fe01ae7af76e3f9169e2f45bb143c0f5fdcf6fea23b18f773eac6f3e63ddac6db75e37df5e8c6fbae65aebcde6d37beaf84f528aa52f03c9dc3359ea79939c627d136deab1befaf75b883ef23e76e3ccfaea36d7dc2f795322b05ebfb0ad738af7db7ad371f99fd7e59b8b13f276e9cdf1318f5e54337e6d78cb67cf761ec170efba1acaa1afd9db92d3f3a36d729ea77efc6f33cbccf2beddfe6478fe6d85e45dbfd851bf1577007f5d877e3bc86f5a9ea3a2d6cffdfc1debe116df5db73a39e37b0e777191dda257c7fa83b6e8a2eaae00eeceb13d6b7d69f325b79b058fd32b170c1a55ebffaac2ccae2b9e6118f79c253bd6ef9ee3fd7587fef79c60f7acf3cc617fcc84ffcac6d8ffcc20b7ee5377ee7257ff027aff1bac66ff0269716cf5b1ab7cd3bbcabb17ddee37d3ee0433ee2633ee1019ff290cff89c2ff89229c48b66f1ac3d5df135df7093134eb9c56dcef4b3c35dee71ce393111dbfa8c784a4205955451cd1d1ad1982634a55bbad3f80eddd38c1ef882e66cf52ab5ff2b8d7ea4277aa6175ad06bb866f446efb4d4df0ffad4fed762ffb7b44e1b9cd2266dd142c75e5ddb3cd0bb3e347a477bd9d5f83ee245e3f7689f0ee830f67d44c77412ee186946033aa5e197fecfe85c7bf7be2fe892aee89a6ea84989f6bfa434f4eff9df52c509b5d0779b32ea684d13ea528f728d1e882ebfce37f6cf077422b4ea5b440ad14af1a15452ab473aee52c65ff39789b64fe955f44eb9937b5d858c5b32d377c0c32a7fee7ecd5fe61aff284ff22c2fb290577993775db1443fb53ef2219f5ff2bf93356d5b970dd9d41eb77820dbb223bbab155ed55ffab2f725ffb1eccb81aed6931cca116ab490633909d10339fd5ffdef795d869ae7923bc27226e772415d5986b51d683663b9d4fcfbb1ff190fe54aaec35aeaa577ee20f24673e94b531249a585fc2b69ebfe3ed7dae91f75ba964b5c03e9d344ba1add93bce0826c3f87f3b2a9fb6f18aeba10ba2f563f25eb1b563771a5d17531e2513c5fba538b3111cd690dd73c7ef6a95f4c8aa99de12fe77da4951de9ffffea730be7fd9fdfbffd0b690edc6c</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>RescanPrjDir</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>RescanPrjDir</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>buttonSelect</tabstop>
+ <tabstop>buttonDeselect</tabstop>
+ <tabstop>buttonInvert</tabstop>
+ <tabstop>buttonExpand</tabstop>
+ <tabstop>buttonCollapse</tabstop>
+ <tabstop>buttonOk</tabstop>
+ <tabstop>buttonCancel</tabstop>
+ <tabstop>buttonHelp</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kprogress.h</includehint>
+ <includehint>uploadtreeview.h</includehint>
+</includehints>
+</UI>
diff --git a/quanta/project/subprojecteditdlgs.ui b/quanta/project/subprojecteditdlgs.ui
new file mode 100644
index 00000000..422bf2b8
--- /dev/null
+++ b/quanta/project/subprojecteditdlgs.ui
@@ -0,0 +1,73 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>SubprojectEditDlgS</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>SubprojectEditDlgS</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>403</width>
+ <height>111</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel9</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>nameEdit</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>locationEdit</cstring>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>The relative path of the subproject folder inside the project.</string>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>nameEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel10</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Location:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>locationEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>createNew</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Create new subproject</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Check this if you want to create a new subproject with the above entered data.</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<tabstops>
+ <tabstop>nameEdit</tabstop>
+ <tabstop>locationEdit</tabstop>
+ <tabstop>createNew</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/quanta/project/teammembersdlg.cpp b/quanta/project/teammembersdlg.cpp
new file mode 100644
index 00000000..bd159186
--- /dev/null
+++ b/quanta/project/teammembersdlg.cpp
@@ -0,0 +1,263 @@
+/***************************************************************************
+ teammembersdlg.cpp - description
+ -------------------
+ begin : Wed Jul 7 2004
+ copyright : (C) 2004 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+//qt includes
+#include <qlabel.h>
+
+//kde includes
+#include <kcombobox.h>
+#include <kdialogbase.h>
+#include <klineedit.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+
+//app includes
+#include "teammembersdlg.h"
+#include "membereditdlg.h"
+#include "project.h"
+
+#define NAME_COL 0
+#define NICKNAME_COL 1
+#define EMAIL_COL 2
+#define ROLE_COL 3
+#define TASK_COL 4
+#define SUBPROJECT_COL 5
+
+
+extern QString simpleMemberStr;
+extern QString taskLeaderStr;
+extern QString teamLeaderStr;
+extern QString subprojectLeaderStr;
+
+TeamMembersDlg::TeamMembersDlg(QWidget *parent, const char *name)
+ : TeamMembersDlgS(parent, name)
+{
+ m_yourself = "";
+}
+
+
+TeamMembersDlg::~TeamMembersDlg()
+{
+}
+
+void TeamMembersDlg::slotAddMember()
+{
+ KDialogBase addDlg(this, "add_member", true, i18n("New Member"), KDialogBase::Ok | KDialogBase::Cancel);
+ MemberEditDlg memberDlg(&addDlg);
+ addDlg.setMainWidget(&memberDlg);
+ bool result;
+ do {
+ result = addDlg.exec();
+ if (result)
+ {
+ QString name = memberDlg.nameCombo->currentText();
+ QString role = memberDlg.roleCombo->currentText();
+ QString task = memberDlg.taskEdit->text();
+ QString subProject = memberDlg.subprojectCombo->currentText();
+ QString nickName = memberDlg.nicknameEdit->text();
+ QString email = memberDlg.emailEdit->text();
+ if (name.isEmpty())
+ {
+ KMessageBox::error(this, i18n("The member name cannot be empty."));
+ addDlg.show();
+ } else
+ if (nickName.isEmpty())
+ {
+ KMessageBox::error(this, i18n("The nickname cannot be empty as it is used as a unique identifier."));
+ addDlg.show();
+ } else
+ if (!checkDuplicates(0L, name, nickName, email, role, task, subProject))
+ {
+ addDlg.show();
+ } else
+ {
+ QListViewItem *item = new QListViewItem(membersListView, name, nickName, email, role, task);
+ if (memberDlg.subprojectCombo->isEnabled())
+ item->setText(SUBPROJECT_COL, subProject);
+ result = false;
+ }
+ }
+ } while (result);
+}
+
+void TeamMembersDlg::slotEditMember()
+{
+ QListViewItem *item =membersListView->currentItem();
+ if (!item) return;
+ KDialogBase editDlg(this, "edit_member", true, i18n("Edit Member"), KDialogBase::Ok | KDialogBase::Cancel);
+ MemberEditDlg memberDlg(&editDlg);
+ memberDlg.selectMember(item->text(NAME_COL));
+ memberDlg.nicknameEdit->setText(item->text(NICKNAME_COL));
+ memberDlg.emailEdit->setText(item->text(EMAIL_COL));
+ QString role = item->text(ROLE_COL);
+ for (int i = 0; i < memberDlg.roleCombo->count(); i++)
+ {
+ if (memberDlg.roleCombo->text(i) == role)
+ {
+ memberDlg.roleCombo->setCurrentItem(i);
+ memberDlg.slotRoleSelected(role);
+ break;
+ }
+ }
+ memberDlg.taskEdit->setText(item->text(TASK_COL));
+ int idx = 0;
+ int subprojectIdx = 0;
+ QValueList<SubProject> *subprojects = Project::ref()->subprojects();
+ for (QValueList<SubProject>::ConstIterator it = subprojects->constBegin(); it != subprojects->constEnd(); ++it)
+ {
+ if (item->text(SUBPROJECT_COL) == (*it).name)
+ {
+ subprojectIdx = idx;
+ break;
+ }
+ idx++;
+ }
+ memberDlg.subprojectCombo->setCurrentItem(subprojectIdx);
+
+ editDlg.setMainWidget(&memberDlg);
+ bool result;
+ do {
+ result = editDlg.exec();
+ if (result)
+ {
+ QString name = memberDlg.nameCombo->currentText();
+ QString nickName = memberDlg.nicknameEdit->text();
+ QString email = memberDlg.emailEdit->text();
+ QString role = memberDlg.roleCombo->currentText();
+ QString task = memberDlg.taskEdit->text();
+ QString subProject = memberDlg.subprojectCombo->currentText();
+ if (name.isEmpty())
+ {
+ KMessageBox::error(this, i18n("The member name cannot be empty."));
+ editDlg.show();
+ } else
+ if (nickName.isEmpty())
+ {
+ KMessageBox::error(this, i18n("The nickname cannot be empty as it is used as a unique identifier."));
+ editDlg.show();
+ } else
+ if (!checkDuplicates(item, name, nickName, email, role, task, subProject))
+ {
+ editDlg.show();
+ } else
+ {
+ item->setText(NAME_COL, name);
+ item->setText(NICKNAME_COL, nickName);
+ item->setText(EMAIL_COL, email);
+ item->setText(ROLE_COL, role);
+ item->setText(TASK_COL, task);
+ if (memberDlg.subprojectCombo->isEnabled())
+ item->setText(SUBPROJECT_COL, subProject);
+ result = false;
+ }
+ }
+ } while (result);
+}
+
+void TeamMembersDlg::slotDeleteMember()
+{
+ QListViewItem *item =membersListView->currentItem();
+ if (!item) return;
+
+ bool deleteYourself = (item->text(NICKNAME_COL) == m_yourself);
+ QListViewItemIterator it(membersListView);
+ while ( it.current() )
+ {
+ if (item != it.current() && it.current()->text(NICKNAME_COL) == m_yourself)
+ {
+ deleteYourself = false;
+ break;
+ }
+ ++it;
+ }
+
+ if (deleteYourself)
+ {
+ if (KMessageBox::warningContinueCancel(this, i18n("<qt>Are you sure that you want to remove yourself (<b>%1</b>) from the project team?<br>If you do so, you should select another member as yourself.</qt>").arg(item->text(NAME_COL)), i18n("Delete Member"), KStdGuiItem::del()) == KMessageBox::Continue)
+ {
+ delete item;
+ setYourself("");
+ }
+ } else
+ if (KMessageBox::warningContinueCancel(this, i18n("<qt>Are you sure that you want to remove <b>%1</b> from the project team?</qt>").arg(item->text(NAME_COL)), i18n("Delete Member"), KStdGuiItem::del()) == KMessageBox::Continue)
+ {
+ delete item;
+ }
+}
+
+bool TeamMembersDlg::checkDuplicates(QListViewItem *item, const QString &name, const QString &nickName, const QString &email, const QString &role, const QString &task, const QString &subProject)
+{
+ QString s;
+ QString nick;
+ QListViewItemIterator it(membersListView);
+ while ( it.current() )
+ {
+ s = it.current()->text(ROLE_COL);
+ nick = it.current()->text(NICKNAME_COL);
+ if (item != it.current() && s == role &&
+ (role == i18n(teamLeaderStr.utf8()) ||
+ (role == i18n(taskLeaderStr.utf8()) && it.current()->text(TASK_COL) == task) ||
+ (role == i18n(subprojectLeaderStr.utf8()) && it.current()->text(SUBPROJECT_COL) == subProject)
+ ) )
+ {
+ if (KMessageBox::warningYesNo(this, i18n("<qt>The <b>%1</b> role is already assigned to <b>%2</b>. Do you want to reassign it to the current member?</qt>").arg(role).arg(it.current()->text(NAME_COL)), QString::null, i18n("Reassign"), i18n("Do Not Reassign")) == KMessageBox::Yes)
+ {
+ it.current()->setText(ROLE_COL, i18n(simpleMemberStr.utf8()));
+ return true;
+ }
+ else
+ return false;
+ } else
+ if (nick.lower() == nickName.lower() && it.current() != item && (it.current()->text(EMAIL_COL) != email || it.current()->text(NAME_COL) != name))
+ {
+ KMessageBox::error(this, i18n("<qt>The <b>%1</b> nickname is already assigned to <b>%2 &lt;%3&gt;</b>.</qt>").arg(nickName).arg(it.current()->text(NAME_COL)).arg(it.current()->text(EMAIL_COL)));
+ return false;
+ }
+ ++it;
+ }
+ return true;
+}
+
+void TeamMembersDlg::slotSetToYourself()
+{
+ QListViewItem *item =membersListView->currentItem();
+ if (!item) return;
+ yourselfLabel->setText(item->text(NAME_COL) + " <" + item->text(EMAIL_COL) + ">");
+ m_yourself = item->text(NICKNAME_COL);
+}
+
+void TeamMembersDlg::setYourself(const QString &name)
+{
+ m_yourself = name;
+ if (name.isEmpty())
+ {
+ yourselfLabel->setText(i18n("Please select your identity from the member list."));
+ return;
+ }
+ QListViewItemIterator it(membersListView);
+ while ( it.current() )
+ {
+ if (it.current()->text(NICKNAME_COL).lower() == name.lower())
+ {
+ yourselfLabel->setText(it.current()->text(NAME_COL)+ " <" + it.current()->text(EMAIL_COL) + ">");
+ break;
+ }
+ ++it;
+ }
+}
+
+#include "teammembersdlg.moc"
+
diff --git a/quanta/project/teammembersdlg.h b/quanta/project/teammembersdlg.h
new file mode 100644
index 00000000..c3281e23
--- /dev/null
+++ b/quanta/project/teammembersdlg.h
@@ -0,0 +1,52 @@
+/***************************************************************************
+ teammembersdlg.h - description
+ -------------------
+ begin : Wed Jul 7 2004
+ copyright : (C) 2004 Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef TEAMMEMBERSDLG_H
+#define TEAMMEMBERSDLG_H
+
+#include "teammembersdlgs.h"
+
+/**
+@author Andras Mantia
+*/
+class TeamMembersDlg : public TeamMembersDlgS
+{
+Q_OBJECT
+public:
+ TeamMembersDlg(QWidget *parent = 0, const char *name = 0);
+
+ ~TeamMembersDlg();
+ void setYourself(const QString &name);
+ QString yourself() {return m_yourself;}
+
+public slots:
+ void slotAddMember();
+ void slotEditMember();
+ void slotDeleteMember();
+ void slotSetToYourself();
+
+private:
+ /** Check if the selected role conflicts with an already existing role or not, for
+ example a Team Leader is selected, while a team leader already exists. In case
+ of duplicate entries, it shows a dialog and if the user answer yes, the old
+ teamleader is set to Simple Member and the new member is set to teamleader
+ and the method returns true, otherwise it returns false. */
+ bool checkDuplicates(QListViewItem *item, const QString &name, const QString &nickName, const QString &email, const QString &role, const QString &task, const QString &subProject);
+
+ QString m_yourself;
+};
+
+#endif
diff --git a/quanta/project/teammembersdlgs.ui b/quanta/project/teammembersdlgs.ui
new file mode 100644
index 00000000..eb2689dc
--- /dev/null
+++ b/quanta/project/teammembersdlgs.ui
@@ -0,0 +1,249 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>TeamMembersDlgS</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>TeamMembersDlgS</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>579</width>
+ <height>492</height>
+ </rect>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Mailing list:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>mailingListEdit</cstring>
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>mailingListEdit</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>You are:</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="1">
+ <property name="name">
+ <cstring>yourselfLabel</cstring>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Please select your identity from the member list.</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>&amp;Team Members</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="KPushButton" row="1" column="0">
+ <property name="name">
+ <cstring>addMemberButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Add...</string>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="1" column="1">
+ <property name="name">
+ <cstring>editMemberButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Edit...</string>
+ </property>
+ </widget>
+ <widget class="KListView" row="0" column="0" rowspan="1" colspan="5">
+ <column>
+ <property name="text">
+ <string>Name</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Nickname</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Email</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Role</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Task</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Subproject</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>membersListView</cstring>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="1" column="2">
+ <property name="name">
+ <cstring>deleteMemberButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Delete</string>
+ </property>
+ </widget>
+ <spacer row="1" column="3">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>100</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton" row="1" column="4">
+ <property name="name">
+ <cstring>setToYourselfButton</cstring>
+ </property>
+ <property name="text">
+ <string>Set to &amp;Yourself</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>addMemberButton</sender>
+ <signal>clicked()</signal>
+ <receiver>TeamMembersDlgS</receiver>
+ <slot>slotAddMember()</slot>
+ </connection>
+ <connection>
+ <sender>deleteMemberButton</sender>
+ <signal>clicked()</signal>
+ <receiver>TeamMembersDlgS</receiver>
+ <slot>slotDeleteMember()</slot>
+ </connection>
+ <connection>
+ <sender>editMemberButton</sender>
+ <signal>clicked()</signal>
+ <receiver>TeamMembersDlgS</receiver>
+ <slot>slotEditMember()</slot>
+ </connection>
+ <connection>
+ <sender>membersListView</sender>
+ <signal>doubleClicked(QListViewItem*)</signal>
+ <receiver>TeamMembersDlgS</receiver>
+ <slot>slotEditMember()</slot>
+ </connection>
+ <connection>
+ <sender>setToYourselfButton</sender>
+ <signal>clicked()</signal>
+ <receiver>TeamMembersDlgS</receiver>
+ <slot>slotSetToYourself()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>mailingListEdit</tabstop>
+ <tabstop>membersListView</tabstop>
+ <tabstop>addMemberButton</tabstop>
+ <tabstop>editMemberButton</tabstop>
+ <tabstop>deleteMemberButton</tabstop>
+ <tabstop>setToYourselfButton</tabstop>
+</tabstops>
+<slots>
+ <slot>slotAddMember()</slot>
+ <slot>slotEditMember()</slot>
+ <slot>slotDeleteMember()</slot>
+ <slot>slotSetToYourself()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>klistview.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/quanta/project/uploadprofiledlgs.ui b/quanta/project/uploadprofiledlgs.ui
new file mode 100644
index 00000000..851a133c
--- /dev/null
+++ b/quanta/project/uploadprofiledlgs.ui
@@ -0,0 +1,310 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>UploadProfileDlgS</class>
+<comment>/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+</comment>
+<author>(C) 2004 Andras Mantia &lt;[email protected]&gt;</author>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>UploadProfileDlgS</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>710</width>
+ <height>215</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Upload Profile</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit" row="3" column="1" rowspan="1" colspan="10">
+ <property name="name">
+ <cstring>linePath</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>TextLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Host:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>lineHost</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;User:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>lineUser</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>TextLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Pa&amp;th:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>linePath</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Profile &amp;name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>lineProfileName</cstring>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="4" column="0" rowspan="1" colspan="5">
+ <property name="name">
+ <cstring>defaultProfile</cstring>
+ </property>
+ <property name="text">
+ <string>Use as &amp;default profile</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="2" column="1" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>lineUser</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="3">
+ <property name="name">
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Pass&amp;word:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>linePasswd</cstring>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="5" column="9" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>cancelButton</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="5" column="7" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>okButton</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>90</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="autoDefault">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer row="5" column="0" rowspan="1" colspan="7">
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>445</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLineEdit" row="1" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>lineHost</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QComboBox" row="1" column="5" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>comboProtocol</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="10">
+ <property name="name">
+ <cstring>port</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="8" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Po&amp;rt:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>port</cstring>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="6" rowspan="1" colspan="5">
+ <property name="name">
+ <cstring>keepPasswd</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&amp;Store password on disc</string>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Keep the password in a file. DANGEROUS! Read the "What's This?" text.</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;If you check this box, the password will be saved in the local Quanta configuration file, so every time you start Quanta and load this project, the password will be loaded and you don't have to enter it. Altough the local configuration file is readable only by you and the password
+is obscured, saving the password in any file is a security risk. Use this option at your own risk.&lt;br&gt;
+&lt;i&gt;Note:&lt;/i&gt; due to the security concerns, the password is not present in the project file, and moving the project files to another computer or uploading the project to a server will not move/upload the password to the new place.&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ <widget class="KPasswordEdit" row="2" column="4" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>linePasswd</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="4">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Protocol:</string>
+ </property>
+ <property name="alignment">
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>comboProtocol</cstring>
+ </property>
+ <property name="hAlign" stdset="0">
+ </property>
+ </widget>
+ <widget class="KLineEdit" row="0" column="2" rowspan="1" colspan="9">
+ <property name="name">
+ <cstring>lineProfileName</cstring>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>okButton</sender>
+ <signal>clicked()</signal>
+ <receiver>UploadProfileDlgS</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>cancelButton</sender>
+ <signal>clicked()</signal>
+ <receiver>UploadProfileDlgS</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>lineProfileName</tabstop>
+ <tabstop>lineHost</tabstop>
+ <tabstop>comboProtocol</tabstop>
+ <tabstop>port</tabstop>
+ <tabstop>lineUser</tabstop>
+ <tabstop>linePasswd</tabstop>
+ <tabstop>keepPasswd</tabstop>
+ <tabstop>linePath</tabstop>
+ <tabstop>defaultProfile</tabstop>
+ <tabstop>okButton</tabstop>
+ <tabstop>cancelButton</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/quanta/project/uploadprofiles.cpp b/quanta/project/uploadprofiles.cpp
new file mode 100644
index 00000000..d32596ed
--- /dev/null
+++ b/quanta/project/uploadprofiles.cpp
@@ -0,0 +1,120 @@
+/***********************************************************************
+ uploadprofiles.cpp - extended Map of UploadProfiles
+ -------------------
+ begin : July 11 2004
+ copyright : (C) 2004 by Jens Herden <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// qt includes
+#include <qobject.h>
+
+// KDE includes
+#include <kiconloader.h>
+#include <klocale.h>
+
+// app includes
+#include "servertreeview.h"
+#include "uploadprofiles.h"
+#include "quanta.h"
+#include "resource.h"
+#include "project.h"
+
+
+UploadProfiles::UploadProfiles() : UploadProfileMap()
+{
+}
+
+
+void UploadProfiles::readFromXML(const QDomDocument &dom)
+{
+ clear(); // empty the list
+ m_profilesNode = dom.firstChild().firstChild().namedItem("uploadprofiles");
+ if (m_profilesNode.isNull())
+ return;
+
+ QDomNodeList profileList = m_profilesNode.toElement().elementsByTagName("profile");
+ UploadProfile newProfile;
+ for (uint i = 0; i < profileList.count(); i++)
+ {
+ newProfile.domElement = profileList.item(i).toElement();
+ newProfile.name = newProfile.domElement.attribute("name");
+ newProfile.treeview = createTreeview(newProfile);
+ insert(newProfile.name, newProfile);
+ }
+}
+
+
+bool UploadProfiles::removeFromMapAndXML(const QString &name)
+{
+ UploadProfiles::Iterator it = find(name);
+ if ( it == end() )
+ return false;
+ // ok now remove
+ QDomElement el = (*it).domElement;
+ el.parentNode().removeChild(el);
+ erase(name);
+ return true;
+}
+
+void UploadProfiles::clear()
+{
+ // remove all treeviews
+ for (UploadProfiles::iterator it = begin(); it != end(); ++it)
+ {
+ if ( (*it).treeview )
+ {
+ quantaApp->deleteToolWindow( (*it).treeview );
+ }
+ }
+ // clear the map
+ UploadProfileMap::clear();
+}
+
+QWidget * UploadProfiles::createTreeview(const UploadProfile &profile)
+{
+ QWidget *widget = 0L;
+ KURL kurl = url(profile.domElement);
+ if (kurl.isValid() && ! kurl.isEmpty())
+ {
+ widget = new ServerTreeView(quantaApp->config(), quantaApp, kurl, "ServerTreeView" + profile.name);
+ widget->setIcon(SmallIcon("up"));
+ widget->setCaption( i18n("Upload Profile") + ": " + profile.name );
+ quantaApp->addToolWindow(widget, quantaApp->prevDockPosition(widget, KDockWidget::DockRight), quantaApp->getMainDockWidget());
+ }
+ return widget;
+}
+
+
+KURL UploadProfiles::url(const QDomElement &e)
+{
+ QString protocol = e.attribute("remote_protocol","ftp") + "://";
+ QString s = protocol;
+ QString host = e.attribute("remote_host","");
+ s += host;
+ QString port = e.attribute("remote_port","");
+ if (! port.isEmpty()) {
+ s += ":" + port;
+ }
+ s += e.attribute("remote_path","");
+ KURL url = KURL::fromPathOrURL(s);
+ QString user = e.attribute("user","");
+ if (!user.isEmpty()) {
+ url.setUser(user);
+ }
+ // check if we know the password
+ if ( !user.isEmpty() && Project::ref()->keepPasswd )
+ {
+ QString password = Project::ref()->password(protocol + user + "@" + host);
+ url.setPass(password);
+ }
+ return url;
+}
diff --git a/quanta/project/uploadprofiles.h b/quanta/project/uploadprofiles.h
new file mode 100644
index 00000000..20d77b80
--- /dev/null
+++ b/quanta/project/uploadprofiles.h
@@ -0,0 +1,108 @@
+//
+// C++ Interface: UploadProfiles
+//
+// Description:
+//
+//
+// Author: Jens Herden <[email protected]>, (C) 2004
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef UPLOADPROFILES_H
+#define UPLOADPROFILES_H
+
+// QT includes
+#include <qmap.h>
+#include <qdom.h>
+#include <qguardedptr.h>
+
+// KDE includes
+#include <kurl.h>
+
+
+class QObject;
+
+/**
+ @short The internal representation of upload profiles.
+
+*/
+
+
+struct UploadProfile
+{
+ QString name; ///< name of profile
+ QDomElement domElement; ///< domtree element of this profile
+ QGuardedPtr<QWidget> treeview; ///< treeview for this url
+};
+
+/** a map for the upload profiles */
+typedef QMap<QString, UploadProfile> UploadProfileMap;
+
+
+class UploadProfiles : public UploadProfileMap
+{
+public:
+ /**
+ * since this class is a singleton you must use this function to access it
+ */
+ static UploadProfiles* const ref()
+ {
+ static UploadProfiles *m_ref;
+ if (!m_ref) m_ref = new UploadProfiles();
+ return m_ref;
+ }
+
+ ~UploadProfiles();
+
+ /**
+ reads the available profiles from the tree and fills the map
+
+ @param the dom document to parse
+ */
+ void readFromXML(const QDomDocument &dom);
+
+ /**
+ removes a profile from the map and the dom tree
+
+ @param the profile to remove
+
+ @return true if profile was found and removed
+ */
+ bool removeFromMapAndXML(const QString &name);
+
+ /**
+ clears the map and removes all treeviews
+ */
+ void clear();
+
+private:
+ /** The constructor is privat because we use singleton pattern.
+ * If you need the class use UploadProfiles::ref() for
+ * construction and reference
+ */
+ UploadProfiles();
+
+ /**
+ creates a treeview for a profile and adds it to the right toolviews
+
+ @param profile the profile
+
+ @return the pointer to the treeview
+ */
+ QWidget * createTreeview(const UploadProfile &profile);
+
+ /**
+ creates a KURL from a QDomElement
+
+ @param e a QDomElement where the path is saved
+
+ @return KURL of the location
+ */
+ KURL url(const QDomElement &e);
+
+ QDomNode m_profilesNode; ///< under this node the profiles are saved in the dom tree
+};
+
+#endif
diff --git a/quanta/project/uploadprofilespage.ui b/quanta/project/uploadprofilespage.ui
new file mode 100644
index 00000000..745e0ba4
--- /dev/null
+++ b/quanta/project/uploadprofilespage.ui
@@ -0,0 +1,125 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>UploadProfilesPage</class>
+<comment>
+ /***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+</comment>
+<author>(C) 2004 by Andras Mantia</author>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>UploadProfilesPage</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>480</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string></string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLayoutWidget" row="0" column="0">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>pLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Default profile:</string>
+ </property>
+ </widget>
+ <widget class="KPushButton" row="0" column="2">
+ <property name="name">
+ <cstring>buttonEditProfiles</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Edit Profiles</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="0" column="1">
+ <property name="name">
+ <cstring>profileLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>x</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>checkShowUploadTreeviews</cstring>
+ </property>
+ <property name="text">
+ <string>Show a &amp;treeview for each profile</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonEditProfiles</sender>
+ <signal>clicked()</signal>
+ <receiver>UploadProfilesPage</receiver>
+ <slot>buttonEditProfiles_clicked()</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">uploadprofilespage.ui.h</include>
+</includes>
+<slots>
+ <slot>buttonEditProfiles_clicked()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/quanta/project/uploadprofilespage.ui.h b/quanta/project/uploadprofilespage.ui.h
new file mode 100644
index 00000000..cb7aad06
--- /dev/null
+++ b/quanta/project/uploadprofilespage.ui.h
@@ -0,0 +1,31 @@
+/****************************************************************************
+** ui.h extension file, included from the uic-generated form implementation.
+**
+** If you wish to add, delete or rename functions or slots use
+** Qt Designer which will update this file, preserving your code. Create an
+** init() function in place of a constructor, and a destroy() function in
+** place of a destructor.
+*****************************************************************************/
+/***********************************************************************
+ begin : Wed Jul 28 2004
+ copyright : (C) 2004 by Andras Mantia <[email protected]>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 "projectupload.h"
+
+void UploadProfilesPage::buttonEditProfiles_clicked()
+{
+ ProjectUpload* dlg = new ProjectUpload(KURL(), "", true);
+ dlg->exec();
+ profileLabel->setText(dlg->defaultProfile());
+ delete dlg;
+}