diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 114a878c64ce6f8223cfd22d76a20eb16d177e5e (patch) | |
tree | acaf47eb0fa12142d3896416a69e74cbf5a72242 /buildtools | |
download | tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.tar.gz tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdevelop@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'buildtools')
259 files changed, 57685 insertions, 0 deletions
diff --git a/buildtools/Makefile.am b/buildtools/Makefile.am new file mode 100644 index 00000000..1c61d027 --- /dev/null +++ b/buildtools/Makefile.am @@ -0,0 +1,48 @@ +## +## Do NOT remove the comments that start with "kdevelop:" +## They are actually directives to the kdevelop plugin system +## +## The include_xxxx variables are controlled by configure.in.in +## + +#kdevelop: ADA_BUILDTOOL = ada +if include_ada +ADA_BUILDTOOL = ada +endif + +#kdevelop: ANT_BUILDTOOL = ant +if include_ant +ANT_BUILDTOOL = ant +endif + +#kdevelop: AUTOTOOLS_BUILDTOOL = autotools +if include_autoproject +AUTOTOOLS_BUILDTOOL = autotools +endif + +#kdevelop: CUSTOMMAKEFILES_BUILDTOOL = custommakefiles +if include_customproject +CUSTOMMAKEFILES_BUILDTOOL = custommakefiles +endif + +#kdevelop: PASCAL_BUILDTOOL = pascal +if include_pascal +PASCAL_BUILDTOOL = pascal +endif + +#kdevelop: QMAKE_BUILDTOOL = qmake +if include_trollproject +QMAKE_BUILDTOOL = qmake +endif + +#kdevelop: SCRIPT_BUILDTOOL = script +if include_scriptproject +SCRIPT_BUILDTOOL = script +endif + +SUBDIRS = lib $(ADA_BUILDTOOL) $(ANT_BUILDTOOL) \ + $(AUTOTOOLS_BUILDTOOL) $(CUSTOMMAKEFILES_BUILDTOOL) $(PASCAL_BUILDTOOL) \ + $(QMAKE_BUILDTOOL) $(SCRIPT_BUILDTOOL) + +DOXYGEN_EMPTY = YES +include ../Doxyfile.am diff --git a/buildtools/ada/Makefile.am b/buildtools/ada/Makefile.am new file mode 100644 index 00000000..2de845ca --- /dev/null +++ b/buildtools/ada/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES = -I$(top_srcdir)/buildtools/lib/base -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/interfaces/external \ + -I$(top_srcdir)/lib/interfaces/extras -I$(top_srcdir)/lib/util $(all_includes) + +kde_module_LTLIBRARIES = libkdevadaproject.la +libkdevadaproject_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevadaproject_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/buildtools/lib/base/libkdevbuildbase.la $(top_builddir)/lib/interfaces/extras/libkdevextras.la + +libkdevadaproject_la_SOURCES = adaproject_part.cpp adaproject_widget.cpp adaproject_optionsdlgbase.ui adaprojectoptionsdlg.cpp adaglobaloptionsdlg.cpp service.cpp + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevadaproject.desktop + +rcdir = $(kde_datadir)/kdevadaproject +rc_DATA = kdevadaproject.rc diff --git a/buildtools/ada/README.dox b/buildtools/ada/README.dox new file mode 100644 index 00000000..24e0bd7e --- /dev/null +++ b/buildtools/ada/README.dox @@ -0,0 +1,17 @@ +/** \class AdaProjectPart +Ada Project: the common project part for all available ada +compilers (currently only gnat). +It holds the project file list and tries to abstract from their specifics. + +\authors <a href="mailto:okellogg AT users.sourceforge.net">Oliver Kellogg</a> + +\unmaintained This part is currently un-maintained + +\deprecated This class is deprecated, use GenericProjectPart (buildtools/generic) instead. + +\feature supports gnat compiler +\feature Holds the project file list and tries to abstract from their specifics + +\requirement Ada gnat compiler + +*/ diff --git a/buildtools/ada/adaglobaloptionsdlg.cpp b/buildtools/ada/adaglobaloptionsdlg.cpp new file mode 100644 index 00000000..a8171c81 --- /dev/null +++ b/buildtools/ada/adaglobaloptionsdlg.cpp @@ -0,0 +1,129 @@ +/* Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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 <qlayout.h> +#include <qlabel.h> +#include <qlineedit.h> +#include <qcombobox.h> + +#include <kurlrequester.h> +#include <kdebug.h> +#include <kconfig.h> + +#include "kdevcompileroptions.h" + +#include "service.h" +#include "adaproject_part.h" +#include "adaglobaloptionsdlg.h" + +AdaGlobalOptionsDlg::AdaGlobalOptionsDlg(AdaProjectPart *part, QWidget* parent, const char* name, WFlags fl) + :AdaProjectOptionsDlgBase(parent,name,fl), m_part(part) +{ + delete config_label; + delete config_combo; + delete addconfig_button; + delete removeconfig_button; + delete compiler_label; + delete configuration_layout; + delete configuration_line; + delete exec_label; + delete exec_edit; + delete mainSourceLabel; + delete mainSourceUrl; + delete defaultopts_button; + + offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Ada'"); + + ServiceComboBox::insertStringList(compiler_box, offers, &service_names, &service_execs); + + if (offers.isEmpty()) + options_button->setEnabled(false); + + currentCompiler = QString::null; + + /*kdDebug() << ServiceComboBox::defaultCompiler() << endl; + kdDebug() << ServiceComboBox::itemForText(ServiceComboBox::defaultCompiler(), service_names) << endl; + kdDebug() << compiler_box->text(ServiceComboBox::itemForText(ServiceComboBox::defaultCompiler(), service_names)) << endl; +*/ + ServiceComboBox::setCurrentText(compiler_box, ServiceComboBox::defaultCompiler(), service_names); + compiler_box_activated(compiler_box->currentText()); +} + +AdaGlobalOptionsDlg::~AdaGlobalOptionsDlg() +{ +} + +void AdaGlobalOptionsDlg::optionsButtonClicked() +{ + QString name = ServiceComboBox::currentText(compiler_box, service_names); + KDevCompilerOptions *plugin = m_part->createCompilerOptions(name); + + if (plugin) { + QString flags = plugin->exec(this, options_edit->text()); + options_edit->setText(flags); + delete plugin; + } +} + +void AdaGlobalOptionsDlg::compiler_box_activated(const QString& text) +{ + kdDebug() << "text changed from " << currentCompiler << " to " << text << endl; + if (currentCompiler == text) + return; + if (!currentCompiler.isEmpty()) + saveCompilerOpts(currentCompiler); + currentCompiler = text; + readCompilerOpts(currentCompiler); +} + +void AdaGlobalOptionsDlg::accept() +{ + saveCompilerOpts(currentCompiler); + + saveConfigCache(); +} + +void AdaGlobalOptionsDlg::saveCompilerOpts( QString compiler ) +{ + configCache[compiler] = options_edit->text(); +} + +void AdaGlobalOptionsDlg::readCompilerOpts( QString compiler ) +{ + QString settings = configCache[compiler]; + if (settings.isEmpty()) + { + KConfig *config = KGlobal::config(); + config->setGroup("Ada Compiler"); + settings = config->readPathEntry(compiler); + } + + options_edit->setText(settings); +} + +void AdaGlobalOptionsDlg::readConfigCache( ) +{ +/* KConfig *config = KGlobal::config(); + config->setGroup("Ada Compiler"); + + QMap<QString, QString> settings = config->entryMap("Ada Compiler"); +*/ +} + +void AdaGlobalOptionsDlg::saveConfigCache( ) +{ + KConfig *config = KGlobal::config(); + config->setGroup("Ada Compiler"); + + for (QMap<QString, QString>::iterator it = configCache.begin(); it != configCache.end(); ++it) + { + config->writeEntry(it.key(), it.data()); + } +} + +#include "adaglobaloptionsdlg.moc" diff --git a/buildtools/ada/adaglobaloptionsdlg.h b/buildtools/ada/adaglobaloptionsdlg.h new file mode 100644 index 00000000..92001a1b --- /dev/null +++ b/buildtools/ada/adaglobaloptionsdlg.h @@ -0,0 +1,50 @@ +/* Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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 ADAGLOBALOPTIONSDLG_H +#define ADAGLOBALOPTIONSDLG_H + +#include <qmap.h> + +#include <ktrader.h> + +#include "adaproject_optionsdlgbase.h" + +class AdaProjectPart; + +class AdaGlobalOptionsDlg : public AdaProjectOptionsDlgBase +{ + Q_OBJECT + +public: + AdaGlobalOptionsDlg(AdaProjectPart *part, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~AdaGlobalOptionsDlg(); + +public slots: + virtual void accept(); + +protected slots: + virtual void optionsButtonClicked(); + virtual void compiler_box_activated(const QString& text); + +private: + AdaProjectPart *m_part; + KTrader::OfferList offers; + QString currentCompiler; + QStringList service_names; + QStringList service_execs; + QMap<QString, QString> configCache; + + void saveCompilerOpts(QString compiler); + void readCompilerOpts(QString compiler); + + void readConfigCache(); + void saveConfigCache(); +}; + +#endif diff --git a/buildtools/ada/adaproject_optionsdlgbase.ui b/buildtools/ada/adaproject_optionsdlgbase.ui new file mode 100644 index 00000000..72e99f74 --- /dev/null +++ b/buildtools/ada/adaproject_optionsdlgbase.ui @@ -0,0 +1,472 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>AdaProjectOptionsDlgBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>AdaProjectOptionsDlgBase</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>480</height> + </rect> + </property> + <property name="caption"> + <string>Ada Compiler</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="10" 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>160</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget" row="0" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>configuration_layout</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + + <widget class="QLabel"> + <property name="name"> + <cstring>config_label</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Configuration:</string> + </property> + </widget> + <widget class="QComboBox"> + <property name="name"> + <cstring>config_combo</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer17_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>8</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>addconfig_button</cstring> + </property> + <property name="text"> + <string>Add</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>removeconfig_button</cstring> + </property> + <property name="text"> + <string>Remove</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer18_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QPushButton" row="6" column="4"> + <property name="name"> + <cstring>options_button</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>30</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + <widget class="QLabel" row="6" column="0"> + <property name="name"> + <cstring>options_label</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Compiler &options:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>compiler_box</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>compiler_label</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Ada &compiler:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>compiler_box</cstring> + </property> + </widget> + <widget class="QLineEdit" row="4" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>exec_edit</cstring> + </property> + </widget> + <widget class="QLineEdit" row="6" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>options_edit</cstring> + </property> + </widget> + <widget class="QComboBox" row="2" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>compiler_box</cstring> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>exec_label</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Compiler co&mmand:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>compiler_box</cstring> + </property> + </widget> + <widget class="Line" row="1" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>configuration_line</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>spacer11</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <spacer row="5" column="3"> + <property name="name"> + <cstring>spacer12</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="KURLRequester" row="9" column="1" rowspan="1" colspan="4"> + <property name="name"> + <cstring>mainSourceUrl</cstring> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>26</height> + </size> + </property> + <property name="focusPolicy"> + <enum>WheelFocus</enum> + </property> + </widget> + <widget class="QLabel" row="9" column="0"> + <property name="name"> + <cstring>mainSourceLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Main &source file:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>compiler_box</cstring> + </property> + </widget> + <spacer row="8" column="2"> + <property name="name"> + <cstring>spacer13</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>30</height> + </size> + </property> + </spacer> + <spacer row="7" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>spacer7</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="QPushButton" row="7" column="3" rowspan="1" colspan="2"> + <property name="name"> + <cstring>defaultopts_button</cstring> + </property> + <property name="text"> + <string>Load Default Compiler Options</string> + </property> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>compiler_box</sender> + <signal>activated(const QString&)</signal> + <receiver>AdaProjectOptionsDlgBase</receiver> + <slot>compiler_box_activated(const QString&)</slot> + </connection> + <connection> + <sender>removeconfig_button</sender> + <signal>clicked()</signal> + <receiver>AdaProjectOptionsDlgBase</receiver> + <slot>configRemoved()</slot> + </connection> + <connection> + <sender>config_combo</sender> + <signal>textChanged(const QString&)</signal> + <receiver>AdaProjectOptionsDlgBase</receiver> + <slot>configComboTextChanged(const QString&)</slot> + </connection> + <connection> + <sender>config_combo</sender> + <signal>activated(const QString&)</signal> + <receiver>AdaProjectOptionsDlgBase</receiver> + <slot>configChanged(const QString&)</slot> + </connection> + <connection> + <sender>addconfig_button</sender> + <signal>clicked()</signal> + <receiver>AdaProjectOptionsDlgBase</receiver> + <slot>configAdded()</slot> + </connection> + <connection> + <sender>options_button</sender> + <signal>clicked()</signal> + <receiver>AdaProjectOptionsDlgBase</receiver> + <slot>optionsButtonClicked()</slot> + </connection> + <connection> + <sender>exec_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>AdaProjectOptionsDlgBase</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>options_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>AdaProjectOptionsDlgBase</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>mainSourceUrl</sender> + <signal>textChanged(const QString&)</signal> + <receiver>AdaProjectOptionsDlgBase</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>mainSourceUrl</sender> + <signal>urlSelected(const QString&)</signal> + <receiver>AdaProjectOptionsDlgBase</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>compiler_box</sender> + <signal>activated(const QString&)</signal> + <receiver>AdaProjectOptionsDlgBase</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>compiler_box</sender> + <signal>textChanged(const QString&)</signal> + <receiver>AdaProjectOptionsDlgBase</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>defaultopts_button</sender> + <signal>clicked()</signal> + <receiver>AdaProjectOptionsDlgBase</receiver> + <slot>setDefaultOptions()</slot> + </connection> + <connection> + <sender>defaultopts_button</sender> + <signal>clicked()</signal> + <receiver>AdaProjectOptionsDlgBase</receiver> + <slot>setDirty()</slot> + </connection> +</connections> +<tabstops> + <tabstop>compiler_box</tabstop> + <tabstop>exec_edit</tabstop> + <tabstop>options_edit</tabstop> + <tabstop>options_button</tabstop> + <tabstop>mainSourceUrl</tabstop> + <tabstop>config_combo</tabstop> + <tabstop>addconfig_button</tabstop> + <tabstop>removeconfig_button</tabstop> +</tabstops> +<slots> + <slot access="protected">compiler_box_activated(const QString&)</slot> + <slot access="protected">addconfig_button_clicked()</slot> + <slot access="protected">configRemoved()</slot> + <slot access="protected">configComboTextChanged(const QString&)</slot> + <slot access="protected">configChanged(const QString&)</slot> + <slot access="protected">optionsButtonClicked()</slot> + <slot access="protected">configAdded()</slot> + <slot access="protected">setDirty()</slot> + <slot access="protected">setDefaultOptions()</slot> +</slots> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>qwidget.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/buildtools/ada/adaproject_part.cpp b/buildtools/ada/adaproject_part.cpp new file mode 100644 index 00000000..33ba166b --- /dev/null +++ b/buildtools/ada/adaproject_part.cpp @@ -0,0 +1,465 @@ +/* Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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 "adaproject_part.h" + +#include <qdom.h> +#include <qfileinfo.h> +#include <qdir.h> +#include <qvaluestack.h> +#include <qregexp.h> +#include <qvbox.h> + +#include <kiconloader.h> +#include <klocale.h> +#include <kaction.h> +#include <kgenericfactory.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <kmessagebox.h> +#include <klibloader.h> +#include <kprocess.h> +#include <kservice.h> +#include <kconfig.h> + +#include "domutil.h" +#include "kdevcore.h" +#include "kdevmainwindow.h" +#include "kdevmakefrontend.h" +#include "kdevappfrontend.h" +#include "kdevpartcontroller.h" +#include "kdevlanguagesupport.h" +#include "kdevcompileroptions.h" +#include "kdevgenericfactory.h" +#include <kdevplugininfo.h> + +#include "adaproject_widget.h" +#include "adaprojectoptionsdlg.h" +#include "adaglobaloptionsdlg.h" + +typedef KDevGenericFactory<AdaProjectPart> AdaProjectFactory; +static const KDevPluginInfo data("kdevadaproject"); +K_EXPORT_COMPONENT_FACTORY( libkdevadaproject, AdaProjectFactory( data ) ) + +AdaProjectPart::AdaProjectPart(QObject *parent, const char *name, const QStringList& ) + :KDevBuildTool(&data, parent, name ? name : "AdaProjectPart" ) +{ + setInstance(AdaProjectFactory::instance()); + setXMLFile("kdevadaproject.rc"); + + KAction *action; + action = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8, + this, SLOT(slotBuild()), + actionCollection(), "build_build" ); + action = new KAction( i18n("Execute Program"), "exec", 0, + this, SLOT(slotExecute()), + actionCollection(), "build_execute" ); + + connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), + this, SLOT(projectConfigWidget(KDialogBase*)) ); + + connect( core(), SIGNAL(configWidget(KDialogBase*)), + this, SLOT(configWidget(KDialogBase*)) ); + +// m_widget = new AdaProjectWidget(this); + +// QWhatsThis::add(m_widget, i18n("WHAT DOES THIS PART DO?")); + + // now you decide what should happen to the widget. Take a look at kdevcore.h + // or at other plugins how to embed it. + + // if you want to embed your widget as an outputview, simply uncomment + // the following line. + + // mainWindow()->embedOutputView( m_widget, "name that should appear", "enter a tooltip" ); + +} + +AdaProjectPart::~AdaProjectPart() +{ +// delete m_widget; +} + +/** + * This should really be merged with FileTreeWidget::matchesHidePattern() + * and put in its own class. Currently this is repeated in scriptprojectpart.cpp, pascalproject_part.cpp, adaproject_part.cpp + */ +static bool matchesPattern(const QString &fileName, const QStringList &patternList) +{ + QStringList::ConstIterator it; + for (it = patternList.begin(); it != patternList.end(); ++it) { + QRegExp re(*it, true, true); + if (re.search(fileName) == 0 && re.matchedLength() == (int)fileName.length()) + return true; + } + + return false; +} + +void AdaProjectPart::openProject(const QString &dirName, const QString &projectName) +{ + m_buildDir = dirName; + m_projectDir = dirName; + m_projectName = projectName; + + QDomDocument &dom = *projectDom(); + // Set the default directory radio to "executable" + if (DomUtil::readEntry(dom, "/kdevadaproject/run/directoryradio") == "" ) { + DomUtil::writeEntry(dom, "/kdevadaproject/run/directoryradio", "executable"); + } + + loadProjectConfig(); + + // Put all files from all subdirectories into file list + QValueStack<QString> s; + int prefixlen = m_projectDir.length()+1; + s.push(m_projectDir); + + QStringList includepatternList; + + if ( languageSupport() ) + { + KMimeType::List list = languageSupport()->mimeTypes(); + KMimeType::List::Iterator it = list.begin(); + while( it != list.end() ){ + includepatternList += (*it)->patterns(); + ++it; + } + } + + QString excludepatterns = "*~"; + QStringList excludepatternList = QStringList::split(",", excludepatterns); + + QDir dir; + do { + dir.setPath(s.pop()); + kdDebug() << "AdaProjectPart::openProject examining: " << dir.path() << endl; + const QFileInfoList *dirEntries = dir.entryInfoList(); + if( !dirEntries ) + break; + + QPtrListIterator<QFileInfo> it(*dirEntries); + for (; it.current(); ++it) { + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == "..") + continue; + QString path = it.current()->absFilePath(); + if (it.current()->isDir()) { + kdDebug() << "AdaProjectPart::openProject pushing: " << path << endl; + s.push(path); + } + else { + if (matchesPattern(path, includepatternList) + && !matchesPattern(path, excludepatternList)) { + kdDebug() << "AdaProjectPart::openProject adding: " << path << endl; + m_sourceFiles.append(path.mid(prefixlen)); + } else { + kdDebug() << "AdaProjectPart::openProject ignoring: " << path << endl; + } + } + } + } while (!s.isEmpty()); + + KDevProject::openProject( dirName, projectName ); +} + +void AdaProjectPart::closeProject() +{ +} + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList AdaProjectPart::runEnvironmentVars() const +{ + return DomUtil::readPairListEntry(*projectDom(), "/kdevadaproject/run/envvars", "envvar", "name", "value"); +} + + +/** Retuns the currently selected run directory + * The returned string can be: + * if run/directoryradio == executable + * The directory where the executable is + * if run/directoryradio == build + * The directory where the executable is relative to build directory + * if run/directoryradio == custom + * The custom directory absolute path + */ +QString AdaProjectPart::runDirectory() const +{ + QString cwd = defaultRunDirectory("kdevadaproject"); + if (cwd.isEmpty()) + cwd = buildDirectory(); + return cwd; +} + + +/** Retuns the currently selected main program + * The returned string can be: + * if run/directoryradio == executable + * The executable name + * if run/directoryradio == build + * The path to executable relative to build directory + * if run/directoryradio == custom or relative == false + * The absolute path to executable + */ +QString AdaProjectPart::mainProgram() const +{ + QDomDocument * dom = projectDom(); + + if ( !dom ) return QString(); + + QString DomMainProgram = DomUtil::readEntry( *dom, "/kdevadaproject/run/mainprogram"); + + if ( DomMainProgram.isEmpty() ) return QString(); + + if ( DomMainProgram.startsWith("/") ) // assume absolute path + { + return DomMainProgram; + } + else // assume project relative path + { + return projectDirectory() + "/" + DomMainProgram; + } + + return QString(); +} + +/** Retuns a QString with the run command line arguments */ +QString AdaProjectPart::debugArguments() const +{ + return DomUtil::readEntry(*projectDom(), "/kdevadaproject/run/globaldebugarguments"); +} + + +/** Retuns a QString with the run command line arguments */ +QString AdaProjectPart::runArguments() const +{ + return DomUtil::readEntry(*projectDom(), "/kdevadaproject/run/programargs"); +} + +QString AdaProjectPart::mainSource() const +{ + return projectDirectory() + "/" + m_mainSource; +} + +void AdaProjectPart::setMainSource(QString fullPath) +{ + QString olddir = activeDirectory(); + m_mainSource = fullPath.replace(QRegExp(QString(projectDirectory() + QString("/"))),""); + emit activeDirectoryChanged( olddir, activeDirectory() ); +} + +QString AdaProjectPart::projectDirectory() const +{ + return m_projectDir; +} + +QString AdaProjectPart::projectName() const +{ + return m_projectName; +} + +QString AdaProjectPart::activeDirectory() const +{ + QFileInfo fi(mainSource()); + return fi.dirPath(true).replace(QRegExp(projectDirectory()),""); +} + +QString AdaProjectPart::buildDirectory() const +{ + QFileInfo fi(mainSource()); + return fi.dirPath(true); +} + +void AdaProjectPart::listOfFiles(QStringList &result, QString path) const +{ + QDir d(path); + if (!d.exists()) + return; + + const QFileInfoList *entries = d.entryInfoList(QDir::Dirs | QDir::Files | QDir::Hidden); + if( !entries ) + return; + + QFileInfoListIterator it( *entries ); + while( const QFileInfo* fileInfo = it.current() ) + { + ++it; + + if (fileInfo->isDir() && fileInfo->filePath() != path) + { + kdDebug() << "entering dir " << fileInfo->dirPath() << endl; + listOfFiles(result, fileInfo->dirPath()); + } + else + { + kdDebug() << "adding to result: " << fileInfo->filePath() << endl; + result << fileInfo->filePath(); + } + } +} + +QStringList AdaProjectPart::allFiles() const +{ +// QStringList files; + +// listOfFiles(files, projectDirectory()); + +// return files; + return m_sourceFiles; +} + +void AdaProjectPart::addFile(const QString& /*fileName*/) +{ +} + +void AdaProjectPart::addFiles(const QStringList& /*fileList*/) +{ +} + +void AdaProjectPart::removeFile(const QString& /*fileName*/) +{ +} + +void AdaProjectPart::removeFiles(const QStringList& /*fileList*/) +{ +} + +void AdaProjectPart::slotBuild() +{ + if (partController()->saveAllFiles()==false) + return; //user cancelled + + QString cmdline = m_compilerExec + " " + m_compilerOpts + " "; + + if (cmdline.isEmpty()) + { + KMessageBox::sorry(0, i18n("Could not find ada compiler.\nCheck if your compiler settings are correct.")); + return; + } + + QFileInfo fi(mainSource()); + cmdline += fi.fileName(); + + QString dircmd = "cd "; + dircmd += KProcess::quote(buildDirectory()); + dircmd += " && "; + + makeFrontend()->queueCommand(buildDirectory(), dircmd + cmdline); +} + +void AdaProjectPart::slotExecute() +{ + partController()->saveAllFiles(); + QString program = "./"; + appFrontend()->startAppCommand(buildDirectory(), mainProgram(), true); +} + +void AdaProjectPart::changedFiles( const QStringList & fileList ) +{ + KDevProject::changedFiles(fileList); +} + +void AdaProjectPart::changedFile( const QString & fileName ) +{ + KDevProject::changedFile(fileName); +} + +void AdaProjectPart::projectConfigWidget( KDialogBase * dlg ) +{ + QVBox *vbox; + vbox = dlg->addVBoxPage(i18n("Ada Compiler")); + AdaProjectOptionsDlg *w = new AdaProjectOptionsDlg(this, vbox); + connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); + connect( dlg, SIGNAL(okClicked()), this, SLOT(loadProjectConfig()) ); +} + +void AdaProjectPart::loadProjectConfig( ) +{ + QDomDocument &dom = *(projectDom()); + + QString config = DomUtil::readEntry(dom, "/kdevadaproject/general/useconfiguration", "default"); + m_mainSource = DomUtil::readEntry(dom, QString("/kdevadaproject/configurations/") + config + QString("/mainsource") ); + m_compilerOpts = DomUtil::readEntry(dom, QString("/kdevadaproject/configurations/") + config + QString("/compileroptions")); + m_compilerExec = DomUtil::readEntry(dom, QString("/kdevadaproject/configurations/") + config + QString("/compilerexec")); + + if (m_compilerExec.isEmpty()) + { + KTrader::OfferList offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Ada'"); + QValueList<KService::Ptr>::ConstIterator it; + for (it = offers.begin(); it != offers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + m_compilerExec = (*it)->exec(); + break; + } + } + } +} + +void AdaProjectPart::configWidget( KDialogBase * dlg ) +{ + QVBox *vbox; + vbox = dlg->addVBoxPage(i18n("Ada Compiler")); + AdaGlobalOptionsDlg *w = new AdaGlobalOptionsDlg(this, vbox); + connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); +} + +KDevCompilerOptions *AdaProjectPart::createCompilerOptions(const QString &name) +{ + KService::Ptr service = KService::serviceByDesktopName(name); + if (!service) { + kdDebug() << "AdaProjectPart::createCompilerOptions can't find service " << name; + return 0; + } + + KLibFactory *factory = KLibLoader::self()->factory(QFile::encodeName(service->library())); + if (!factory) { + QString errorMessage = KLibLoader::self()->lastErrorMessage(); + KMessageBox::error(0, i18n("There was an error loading the module %1.\n" + "The diagnostics are:\n%2").arg(service->name()).arg(errorMessage)); + exit(1); + } + + QStringList args; + QVariant prop = service->property("X-KDevelop-Args"); + if (prop.isValid()) + args = QStringList::split(" ", prop.toString()); + + QObject *obj = factory->create(this, service->name().latin1(), + "KDevCompilerOptions", args); + + if (!obj->inherits("KDevCompilerOptions")) { + kdDebug() << "AdaProjectPart::createCompilerOptions: component does not inherit KDevCompilerOptions" << endl; + return 0; + } + KDevCompilerOptions *dlg = (KDevCompilerOptions*) obj; + + return dlg; +} + +QString AdaProjectPart::defaultOptions( const QString compiler ) +{ + KConfig *config = KGlobal::config(); + config->setGroup("Ada Compiler"); + return config->readPathEntry(compiler); +} + +#include "adaproject_part.moc" + + +/*! + \fn AdaProjectPart::distFiles() const + */ +QStringList AdaProjectPart::distFiles() const +{ + QStringList sourceList = allFiles(); + // Scan current source directory for any .pro files. + QString projectDir = projectDirectory(); + QDir dir(projectDir); + QStringList files = dir.entryList( "Makefile"); + return sourceList + files; +} diff --git a/buildtools/ada/adaproject_part.h b/buildtools/ada/adaproject_part.h new file mode 100644 index 00000000..88966ae2 --- /dev/null +++ b/buildtools/ada/adaproject_part.h @@ -0,0 +1,93 @@ +/* Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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 __KDEVPART_ADAPROJECT_H__ +#define __KDEVPART_ADAPROJECT_H__ + +#include <qguardedptr.h> + +#include "kdevbuildtool.h" + +class AdaProjectWidget; +class KDialogBase; +class KDevCompilerOptions; + +class AdaProjectPart : public KDevBuildTool +{ + Q_OBJECT +public: + AdaProjectPart(QObject *parent, const char *name, const QStringList &); + ~AdaProjectPart(); + + virtual void openProject(const QString &dirName, const QString &projectName); + virtual void closeProject(); + + /**Returns the name of the main source file without extension. + We assume that all Ada compilers call the binary that way. */ + virtual QString mainProgram() const; + /**Main source file (like src/main.adb)*/ + virtual QString mainSource() const; + virtual void setMainSource(QString fullPath); + + virtual QString projectDirectory() const; + virtual QString projectName() const; + virtual QString activeDirectory() const; + /**The location of the main source file*/ + virtual QString buildDirectory() const; + virtual QString runDirectory() const; + virtual QString debugArguments() const; + virtual QString runArguments() const; + virtual DomUtil::PairList runEnvironmentVars() const; + + /**Returns everything in the project directory*/ + virtual QStringList allFiles() const; + /**This does absolutelly nothing*/ + virtual void addFile(const QString &fileName); + /**This does absolutelly nothing*/ + virtual void addFiles(const QStringList &fileList); + /**This does absolutelly nothing*/ + virtual void removeFile(const QString &fileName); + /**This does absolutelly nothing*/ + virtual void removeFiles(const QStringList &fileList); + + virtual void changedFiles( const QStringList & fileList ); + virtual void changedFile( const QString & fileName ); + + KDevCompilerOptions *createCompilerOptions(const QString &name); + + virtual QString defaultOptions(const QString compiler); + QStringList distFiles() const; + +public slots: + /**loads config from project file*/ + void loadProjectConfig(); + +private slots: + void slotBuild(); + void slotExecute(); + void projectConfigWidget(KDialogBase *dlg); + void configWidget(KDialogBase *dlg); + +private: + QGuardedPtr<AdaProjectWidget> m_widget; + + void listOfFiles(QStringList &result, QString path) const; + + QString m_buildDir; + QString m_projectDir; + QString m_projectName; + + QString m_mainProg; + QString m_mainSource; + QString m_compilerExec; + QString m_compilerOpts; + + QStringList m_sourceFiles; +}; + +#endif diff --git a/buildtools/ada/adaproject_widget.cpp b/buildtools/ada/adaproject_widget.cpp new file mode 100644 index 00000000..d4bdf37b --- /dev/null +++ b/buildtools/ada/adaproject_widget.cpp @@ -0,0 +1,24 @@ +#include <kparts/part.h> +#include <klibloader.h> +#include <kurl.h> +#include <kdebug.h> + +#include <kdevcore.h> + +#include "adaproject_part.h" +#include "adaproject_widget.h" + + +AdaProjectWidget::AdaProjectWidget(AdaProjectPart *part) + : QWidget(0, "AdaProject widget") +{ + Q_UNUSED( part ); +} + + +AdaProjectWidget::~AdaProjectWidget() +{ +} + + +#include "adaproject_widget.moc" diff --git a/buildtools/ada/adaproject_widget.h b/buildtools/ada/adaproject_widget.h new file mode 100644 index 00000000..dc6b4ec4 --- /dev/null +++ b/buildtools/ada/adaproject_widget.h @@ -0,0 +1,21 @@ +#ifndef __ADAPROJECT_WIDGET_H__ +#define __ADAPROJECT_WIDGET_H__ + +#include <qwidget.h> +#include <qstring.h> + +class KDevProject; +class AdaProjectPart; + +class AdaProjectWidget : public QWidget +{ + Q_OBJECT + +public: + + AdaProjectWidget(AdaProjectPart *part); + ~AdaProjectWidget(); + +}; + +#endif diff --git a/buildtools/ada/adaprojectoptionsdlg.cpp b/buildtools/ada/adaprojectoptionsdlg.cpp new file mode 100644 index 00000000..3eafb082 --- /dev/null +++ b/buildtools/ada/adaprojectoptionsdlg.cpp @@ -0,0 +1,208 @@ +/* Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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 <kurlrequester.h> +#include <kservice.h> +#include <kdebug.h> +#include <kmessagebox.h> +#include <klocale.h> + +#include <qlineedit.h> +#include <qcombobox.h> +#include <qregexp.h> +#include <qvalidator.h> + +#include "domutil.h" +#include "kdevcompileroptions.h" + +#include "service.h" +#include "adaproject_part.h" +#include "adaprojectoptionsdlg.h" + +AdaProjectOptionsDlg::AdaProjectOptionsDlg(AdaProjectPart *part, QWidget* parent, const char* name, WFlags fl) + : AdaProjectOptionsDlgBase(parent,name, fl), m_part(part) +{ + config_combo->setValidator(new QRegExpValidator(QRegExp("^\\D.*"), this)); + + offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Ada'"); + + ServiceComboBox::insertStringList(compiler_box, offers, &service_names, &service_execs); + + if (offers.isEmpty()) + options_button->setEnabled(false); + + allConfigs = allBuildConfigs(); + config_combo->insertStringList(allConfigs); + + dirty = false; + + QDomDocument &dom = *(m_part->projectDom()); + currentConfig = QString::null; + configChanged(DomUtil::readEntry(dom, "/kdevadaproject/general/useconfiguration", "default")); +} + +AdaProjectOptionsDlg::~AdaProjectOptionsDlg() +{ +} + +QStringList AdaProjectOptionsDlg::allBuildConfigs() +{ + QDomDocument &dom = *(m_part->projectDom()); + + QStringList allConfigs; + allConfigs.append("default"); + + QDomNode node = dom.documentElement().namedItem("kdevadaproject").namedItem("configurations"); + QDomElement childEl = node.firstChild().toElement(); + while (!childEl.isNull()) { + QString config = childEl.tagName(); + kdDebug() << "Found config " << config << endl; + if (config != "default") + allConfigs.append(config); + childEl = childEl.nextSibling().toElement(); + } + + return allConfigs; +} + +void AdaProjectOptionsDlg::accept() +{ + DomUtil::writeEntry(*m_part->projectDom(), "/kdevadaproject/general/useconfiguration", currentConfig); + if (dirty) + { + saveConfig(currentConfig); + } +} + +void AdaProjectOptionsDlg::compiler_box_activated( const QString& /*s*/ ) +{ + QString exec = ServiceComboBox::currentText(compiler_box, service_execs); + exec_edit->setText(exec); +} + +void AdaProjectOptionsDlg::saveConfig( QString config ) +{ + QDomDocument dom = *m_part->projectDom(); + QString prefix = "/kdevadaproject/configurations/" + config + "/"; + + DomUtil::writeEntry(dom, prefix + "compiler", + ServiceComboBox::currentText(compiler_box, service_names)); + DomUtil::writeEntry(dom, prefix + "compileroptions", options_edit->text()); + DomUtil::writeEntry(dom, prefix + "compilerexec", exec_edit->text()); + DomUtil::writeEntry(dom, prefix + "mainsource", mainSourceUrl->url().replace(QRegExp(m_part->projectDirectory() + QString("/")),"")); +} + +void AdaProjectOptionsDlg::readConfig( QString config ) +{ + QDomDocument dom = *m_part->projectDom(); + QString prefix = "/kdevadaproject/configurations/" + config + "/"; + + QString compiler = DomUtil::readEntry(dom, prefix + "compiler", ""); + + if (compiler.isEmpty()) + { + offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Ada'"); + QValueList<KService::Ptr>::ConstIterator it; + for (it = offers.begin(); it != offers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + compiler = (*it)->name(); + kdDebug() << "compiler is " << compiler << endl; + break; + } + } + } + ServiceComboBox::setCurrentText(compiler_box, compiler, service_names); + + QString exec = DomUtil::readEntry(dom, prefix + "compilerexec", ""); + if (exec.isEmpty()) + exec = ServiceComboBox::currentText(compiler_box, service_execs); + exec_edit->setText(exec); + options_edit->setText(DomUtil::readEntry(dom, prefix + "compileroptions")); + mainSourceUrl->setURL(m_part->projectDirectory() + "/" + DomUtil::readEntry(dom, prefix + "mainsource")); +} + +void AdaProjectOptionsDlg::configComboTextChanged(const QString &config) +{ + bool canAdd = !allConfigs.contains(config) && !config.contains("/") && !config.isEmpty(); + bool canRemove = allConfigs.contains(config) && config != "default"; + addconfig_button->setEnabled(canAdd); + removeconfig_button->setEnabled(canRemove); +} + + +void AdaProjectOptionsDlg::configChanged(const QString &config) +{ + if (config == currentConfig || !allConfigs.contains(config)) + return; + + if (!currentConfig.isNull() && dirty) + saveConfig(currentConfig); + + currentConfig = config; + readConfig(config); + dirty = false; + + config_combo->blockSignals(true); + config_combo->setEditText(config); + config_combo->blockSignals(false); +} + + +void AdaProjectOptionsDlg::configAdded() +{ + QString config = config_combo->currentText(); + + allConfigs.append(config); + + config_combo->clear(); + config_combo->insertStringList(allConfigs); + configChanged(config); + setDirty(); // force saving +} + + +void AdaProjectOptionsDlg::configRemoved() +{ + QString config = config_combo->currentText(); + + QDomDocument dom = *m_part->projectDom(); + QDomNode node = dom.documentElement().namedItem("kdevadaproject").namedItem("configurations"); + node.removeChild(node.namedItem(config)); + allConfigs.remove(config); + + config_combo->clear(); + config_combo->insertStringList(allConfigs); + + currentConfig = QString::null; + configChanged("default"); +} + +void AdaProjectOptionsDlg::optionsButtonClicked( ) +{ + QString name = ServiceComboBox::currentText(compiler_box, service_names); + KDevCompilerOptions *plugin = m_part->createCompilerOptions(name); + + if (plugin) { + QString flags = plugin->exec(this, options_edit->text()); + options_edit->setText(flags); + delete plugin; + } +} + +void AdaProjectOptionsDlg::setDirty( ) +{ + dirty = true; +} + +void AdaProjectOptionsDlg::setDefaultOptions( ) +{ + if (!compiler_box->currentText().isEmpty()) + options_edit->setText(m_part->defaultOptions(compiler_box->currentText())); +} + +#include "adaprojectoptionsdlg.moc" diff --git a/buildtools/ada/adaprojectoptionsdlg.h b/buildtools/ada/adaprojectoptionsdlg.h new file mode 100644 index 00000000..d91c5266 --- /dev/null +++ b/buildtools/ada/adaprojectoptionsdlg.h @@ -0,0 +1,57 @@ +/* Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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 ADAPROJECTOPTIONSDLG_H +#define ADAPROJECTOPTIONSDLG_H + +#include <ktrader.h> + +#include "adaproject_optionsdlgbase.h" + +class AdaProjectPart; +class KDevCompilerOptions; + +class AdaProjectOptionsDlg : public AdaProjectOptionsDlgBase +{ + Q_OBJECT + +public: + AdaProjectOptionsDlg(AdaProjectPart *part, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~AdaProjectOptionsDlg(); + +public slots: + virtual void accept(); + +protected slots: + virtual void compiler_box_activated(const QString &s); + void configComboTextChanged(const QString &config); + void configChanged(const QString &config); + void configAdded(); + void configRemoved(); + void optionsButtonClicked(); + void setDirty(); + void setDefaultOptions(); + +private: + QStringList allConfigs; + QString currentConfig; + bool dirty; + + KTrader::OfferList offers; + QStringList service_names; + QStringList service_execs; + + AdaProjectPart *m_part; + + void saveConfig(QString config); + void readConfig(QString config); + QStringList allBuildConfigs(); +}; + +#endif + diff --git a/buildtools/ada/kdevadaproject.desktop b/buildtools/ada/kdevadaproject.desktop new file mode 100644 index 00000000..0e306f4b --- /dev/null +++ b/buildtools/ada/kdevadaproject.desktop @@ -0,0 +1,100 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=Ada Project +Comment[br]=Raktres Ada +Comment[ca]=Projecte Ada +Comment[cs]=Ada projekt +Comment[da]=Ada-projekt +Comment[de]=Ada-Projekt für KDevelop +Comment[el]=Έργο Ada +Comment[es]=Proyecto Ada +Comment[et]=Ada projekt +Comment[eu]=Ada proiektua +Comment[fa]=پروژۀ آدا +Comment[fr]=Projet en Ada +Comment[ga]=Tionscadal Ada +Comment[gl]=Proxecto Ada +Comment[hi]=एडीए परियोजना +Comment[hu]=Ada-projekt +Comment[is]=Ada verkefni +Comment[it]=Progetto Ada +Comment[ja]=Ada プロジェクト +Comment[ms]=Projek Ada +Comment[nds]=Ada-Projekt +Comment[ne]=एडा परियोजना +Comment[nl]=Ada-project +Comment[pa]=Ada ਪ੍ਰੋਜੈਕਟ +Comment[pl]=Projekt: Ada +Comment[pt]=Projecto Ada +Comment[pt_BR]=Projeto Ada +Comment[ro]=Proiect Ada +Comment[ru]=Проект Ada +Comment[sk]=Ada projekt +Comment[sl]=Projekt Ada +Comment[sr]=Ada пројекат +Comment[sr@Latn]=Ada projekat +Comment[sv]=Ada-projekt +Comment[ta]=அடா பிராஜக்ட் +Comment[tg]=Лоиҳаи Ada +Comment[tr]=Ada Projesi +Comment[uz]=Ada loyihasi +Comment[uz@cyrillic]=Ada лойиҳаси +Comment[zh_CN]=Ada 工程 +Comment[zh_TW]=Ada 專案 +Name=KDevAdaProject +Name[da]=KDevelop Ada-projekt +Name[de]=Ada-Projekt (KDevelop) +Name[fr]=Projet Ada pour KDevelop +Name[hi]=के-डेव-एडीए-परियोजना +Name[nds]=Ada-Projekt (KDevelop) +Name[ne]=केडीई विकास एडा परियोजना +Name[pl]=KDevProjektAda +Name[sk]=KDevAdaProjekt +Name[sv]=KDevelop Ada-projekt +Name[ta]=கெடெவ் அடா பிராஜக்ட் +Name[tg]=Лоиҳаи KDevAda +Name[zh_TW]=KDevelop Ada 專案 +GenericName=Ada Project +GenericName[br]=Raktres Ada +GenericName[ca]=Projecte Ada +GenericName[da]=Ada-projekt +GenericName[de]=Ada-Projekt +GenericName[el]=Έργο Ada +GenericName[es]=Proyecto Ada +GenericName[et]=Ada projekt +GenericName[eu]=Ada proiektua +GenericName[fa]=پروژۀ آدا +GenericName[fr]=Projet en Ada +GenericName[ga]=Tionscadal Ada +GenericName[gl]=Proxecto Ada +GenericName[hi]=एडीए परियोजना +GenericName[hu]=Ada-projekt +GenericName[is]=Ada verkefni +GenericName[it]=Project con Ada +GenericName[ja]=Ada プロジェクト +GenericName[ms]=Projek Ada +GenericName[nds]=Ada-Projekt +GenericName[ne]=एडा परियोजना +GenericName[nl]=Ada-project +GenericName[pa]=Ada ਪ੍ਰੋਜੈਕਟ +GenericName[pl]=Projekt: Ada +GenericName[pt]=Projecto Ada +GenericName[pt_BR]=Projeto Ada +GenericName[ru]=Проект Ada +GenericName[sk]=Ada projekt +GenericName[sl]=Projekt Ada +GenericName[sr]=Ada пројекат +GenericName[sr@Latn]=Ada projekat +GenericName[sv]=Ada-projekt +GenericName[ta]=அடா பிராஜக்ட் +GenericName[tg]=Лоиҳаи Ada +GenericName[tr]=Ada Projesi +GenericName[uz]=Ada loyihasi +GenericName[uz@cyrillic]=Ada лойиҳаси +GenericName[zh_CN]=Ada 工程 +GenericName[zh_TW]=Ada 專案 +ServiceTypes=KDevelop/Project +X-KDE-Library=libkdevadaproject +X-KDevelop-Version=5 +X-KDevelop-Language=Ada diff --git a/buildtools/ada/kdevadaproject.rc b/buildtools/ada/kdevadaproject.rc new file mode 100644 index 00000000..d7f260e1 --- /dev/null +++ b/buildtools/ada/kdevadaproject.rc @@ -0,0 +1,14 @@ +<!DOCTYPE kpartgui> +<kpartplugin name="KDevAdaProject" version="1"> +<MenuBar> + <Menu name="build" > + <Action name="build_build" /> + <Separator/> + <Action name="build_execute" /> + </Menu> +</MenuBar> +<ToolBar name="mainToolBar" noMerge="1"> + <Action name="build_build" group="build_operations" /> + <Action name="build_execute" group="build_operations" /> +</ToolBar> +</kpartplugin> diff --git a/buildtools/ada/service.cpp b/buildtools/ada/service.cpp new file mode 100644 index 00000000..02081a58 --- /dev/null +++ b/buildtools/ada/service.cpp @@ -0,0 +1,75 @@ +/* Copyright (C) 2001-2002 by Bernd Gehrmann + * bernd@kdevelop.org + * Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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 <qcombobox.h> +#include <qvaluelist.h> + +#include <kservice.h> +#include <kdebug.h> + +#include "service.h" + + +void ServiceComboBox::insertStringList(QComboBox *combo, const QValueList<KService::Ptr> &list, + QStringList *names, QStringList *execs) +{ + QValueList<KService::Ptr>::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + combo->insertItem((*it)->comment()); + (*names) << (*it)->desktopEntryName(); + (*execs) << (*it)->exec(); + kdDebug() << "insertStringList item " << (*it)->name() << "," << (*it)->exec() << endl; + } +} + +QString ServiceComboBox::currentText(QComboBox *combo, const QStringList &names) +{ + if (combo->currentItem() == -1) + return QString::null; + return names[combo->currentItem()]; +} + +void ServiceComboBox::setCurrentText(QComboBox *combo, const QString &str, const QStringList &names) +{ + QStringList::ConstIterator it; + int i = 0; + for (it = names.begin(); it != names.end(); ++it) { + if (*it == str) { + combo->setCurrentItem(i); + break; + } + ++i; + } +} + +int ServiceComboBox::itemForText(const QString &str, const QStringList &names) +{ + QStringList::ConstIterator it; + int i = 0; + for (it = names.begin(); it != names.end(); ++it) { + if (*it == str) { + return i; + } + ++i; + } + return 0; +} + +QString ServiceComboBox::defaultCompiler() +{ + KTrader::OfferList offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Ada'"); + QValueList<KService::Ptr>::ConstIterator it; + for (it = offers.begin(); it != offers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + return (*it)->name();; + } + } + return ""; +} diff --git a/buildtools/ada/service.h b/buildtools/ada/service.h new file mode 100644 index 00000000..f9671d0a --- /dev/null +++ b/buildtools/ada/service.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2001-2002 by Bernd Gehrmann + * bernd@kdevelop.org + * Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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 SERVICE_H +#define SERVICE_H + +#include <ktrader.h> + +class ServiceComboBox +{ +public: + static void insertStringList(QComboBox *combo, const QValueList<KService::Ptr> &list, + QStringList *names, QStringList *execs); + static QString currentText(QComboBox *combo, const QStringList &names); + static void setCurrentText(QComboBox *combo, const QString &str, const QStringList &names); + static int itemForText(const QString &str, const QStringList &names); + static QString defaultCompiler(); +}; + +#endif diff --git a/buildtools/ant/Makefile.am b/buildtools/ant/Makefile.am new file mode 100644 index 00000000..6a92a5b1 --- /dev/null +++ b/buildtools/ant/Makefile.am @@ -0,0 +1,21 @@ +# Here resides the ant project part. + +INCLUDES = -I$(top_srcdir)/buildtools/lib/base \ + -I$(top_srcdir)/buildtools/lib/widgets -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/util -I$(top_builddir)/buildtools/lib/widgets \ + $(all_includes) + +kde_module_LTLIBRARIES = libkdevantproject.la +libkdevantproject_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevantproject_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/buildtools/lib/widgets/libkdevbuildtoolswidgets.la $(top_builddir)/buildtools/lib/base/libkdevbuildbase.la + +libkdevantproject_la_SOURCES = antprojectpart.cpp antoptionswidget.ui classpathwidget.ui + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevantproject.desktop + +rcdir = $(kde_datadir)/kdevantproject +rc_DATA = kdevantproject.rc diff --git a/buildtools/ant/README.dox b/buildtools/ant/README.dox new file mode 100644 index 00000000..b4b8a7c9 --- /dev/null +++ b/buildtools/ant/README.dox @@ -0,0 +1,8 @@ +/** \class AntProjectPart +ant build tool part. + +\authors <a href="mailto:mh AT caldera.de">Matthias Hoelzer-Kluepfel</a> + +\unmaintained This part is currently un-maintained + +*/ diff --git a/buildtools/ant/antoptionswidget.ui b/buildtools/ant/antoptionswidget.ui new file mode 100644 index 00000000..fa78e97f --- /dev/null +++ b/buildtools/ant/antoptionswidget.ui @@ -0,0 +1,173 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>AntOptionsWidget</class> +<widget class="QWidget"> + <property name="name"> + <cstring>AntOptionsWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>410</width> + <height>266</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KComboBox" row="1" column="1"> + <item> + <property name="text"> + <string>Quiet</string> + </property> + </item> + <item> + <property name="text"> + <string>Verbose</string> + </property> + </item> + <item> + <property name="text"> + <string>Debug</string> + </property> + </item> + <property name="name"> + <cstring>Verbosity</cstring> + </property> + </widget> + <spacer row="3" column="2"> + <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>16</width> + <height>86</height> + </size> + </property> + </spacer> + <spacer row="3" column="0"> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>16</width> + <height>86</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>&Build file:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>BuildXML</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>&Verbosity:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>Verbosity</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>TextLabel3</cstring> + </property> + <property name="text"> + <string>&Properties:</string> + </property> + <property name="alignment"> + <set>AlignTop</set> + </property> + <property name="buddy" stdset="0"> + <cstring>Properties</cstring> + </property> + </widget> + <widget class="QTable" row="2" column="1" rowspan="1" colspan="2"> + <column> + <property name="text"> + <string>Property</string> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + </column> + <property name="name"> + <cstring>Properties</cstring> + </property> + <property name="numRows"> + <number>0</number> + </property> + <property name="numCols"> + <number>2</number> + </property> + </widget> + <spacer row="1" column="2"> + <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>240</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="KURLRequester" row="0" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>BuildXML</cstring> + </property> + </widget> + </grid> +</widget> +<tabstops> + <tabstop>BuildXML</tabstop> + <tabstop>Verbosity</tabstop> + <tabstop>Properties</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kcombobox.h</include> + <include location="global" impldecl="in implementation">klineedit.h</include> + <include location="global" impldecl="in implementation">kpushbutton.h</include> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>kcombobox.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/buildtools/ant/antprojectpart.cpp b/buildtools/ant/antprojectpart.cpp new file mode 100644 index 00000000..a7f0ea25 --- /dev/null +++ b/buildtools/ant/antprojectpart.cpp @@ -0,0 +1,608 @@ +#include "antprojectpart.h" + +#include <qapplication.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qpopupmenu.h> +#include <qvbox.h> +#include <qtable.h> +#include <qtextstream.h> +#include <qvaluestack.h> +#include <qdir.h> + + +#include <kdevgenericfactory.h> +#include <kdebug.h> +#include <kaction.h> +#include <kpopupmenu.h> +#include <kdialogbase.h> +#include <klineedit.h> +#include <kcombobox.h> +#include <keditlistbox.h> +#include <kurlrequester.h> + +#include <kdevplugininfo.h> + +#include <kdevcore.h> +#include <kdevmakefrontend.h> +#include <urlutil.h> + + +#include "antoptionswidget.h" +#include "classpathwidget.h" + + + + +typedef KDevGenericFactory<AntProjectPart> AntProjectFactory; +static const KDevPluginInfo data("kdevantproject"); +K_EXPORT_COMPONENT_FACTORY(libkdevantproject, AntProjectFactory( data )) + + +AntOptions::AntOptions() + : m_buildXML("build.xml"), m_verbosity(AntOptions::Quiet) +{ +} + + +AntProjectPart::AntProjectPart(QObject *parent, const char *name, const QStringList &) + : KDevBuildTool(&data, parent, name ? name : "AntProjectPart") +{ + setInstance(AntProjectFactory::instance()); + + setXMLFile("kdevantproject.rc"); + + m_buildProjectAction = new KAction(i18n("&Build Project"), "make_kdevelop", Key_F8, + this, SLOT(slotBuild()), + actionCollection(), "build_build" ); + m_buildProjectAction->setToolTip(i18n("Build project")); + m_buildProjectAction->setWhatsThis(i18n("<b>Build project</b><p>Executes <b>ant dist</b> command to build the project.")); + + KActionMenu *menu = new KActionMenu(i18n("Build &Target"), + actionCollection(), "build_target" ); + menu->setToolTip(i18n("Build target")); + menu->setWhatsThis(i18n("<b>Build target</b><p>Executes <b>ant target_name</b> command to build the specified target.")); + + m_targetMenu = menu->popupMenu(); + + connect(m_targetMenu, SIGNAL(activated(int)), this, SLOT(slotTargetMenuActivated(int))); + connect(core(), SIGNAL(projectConfigWidget(KDialogBase*)), this, SLOT(projectConfigWidget(KDialogBase*))); + connect(core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)), this, SLOT(contextMenu(QPopupMenu *, const Context *))); + + m_antOptionsWidget = 0; +} + + +AntProjectPart::~AntProjectPart() +{ +} + + +void AntProjectPart::openProject(const QString &dirName, const QString &projectName) +{ + m_projectDirectory = dirName; + m_projectName = projectName; + + QDomDocument &dom = *projectDom(); + // Set the default directory radio to "executable" + /// \FIXME there is no kdevantproject so this will not work ! + if (DomUtil::readEntry(dom, "/kdevantproject/run/directoryradio") == "" ) { + DomUtil::writeEntry(dom, "/kdevantproject/run/directoryradio", "executable"); + } + + /// @todo read alternative build file from properties + m_antOptions.m_buildXML = "build.xml"; + + parseBuildXML(); + + fillMenu(); + + QFile f(dirName + "/" + projectName.lower() + ".kdevelop" + ".filelist"); + if (f.open(IO_ReadOnly)) + { + QTextStream stream(&f); + while (!stream.atEnd()) + { + QString s = stream.readLine(); + if (!s.startsWith("#")) + m_sourceFiles << s; + } + } + else + populateProject(); + + KDevProject::openProject( dirName, projectName ); +} + + +void AntProjectPart::populateProject() +{ + QApplication::setOverrideCursor(Qt::waitCursor); + + QValueStack<QString> s; + int prefixlen = m_projectDirectory.length()+1; + s.push(m_projectDirectory); + + QDir dir; + do + { + dir.setPath(s.pop()); + kdDebug() << "Examining: " << dir.path() << endl; + const QFileInfoList *dirEntries = dir.entryInfoList(); + QPtrListIterator<QFileInfo> it(*dirEntries); + for (; it.current(); ++it) + { + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == "..") + continue; + QString path = it.current()->absFilePath(); + if (it.current()->isDir()) + { + kdDebug() << "Pushing: " << path << endl; + s.push(path); + } + else + { + kdDebug() << "Adding: " << path << endl; + m_sourceFiles.append(path.mid(prefixlen)); + } + } + } + while (!s.isEmpty()); + + QApplication::restoreOverrideCursor(); +} + + +void AntProjectPart::closeProject() +{ + m_projectDirectory = ""; + m_projectName = ""; + m_buildProjectAction->setEnabled(false); + + m_targetMenu->clear(); + + m_antOptions = AntOptions(); + + QFile f(m_projectDirectory + "/" + m_projectName.lower() + ".kdevelop" + ".filelist"); + if (!f.open(IO_WriteOnly)) + return; + + QTextStream stream(&f); + stream << "# KDevelop Ant Project File List" << endl; + + QStringList::ConstIterator it; + for (it = m_sourceFiles.begin(); it != m_sourceFiles.end(); ++it) + stream << (*it) << endl; + f.close(); +} + + +QString AntProjectPart::projectDirectory() const +{ + return m_projectDirectory; +} + + +QString AntProjectPart::buildDirectory() const +{ + return m_projectDirectory; +} + +QString AntProjectPart::projectName() const +{ + return m_projectName; +} + + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList AntProjectPart::runEnvironmentVars() const +{ + /// \FIXME there is no kdevantproject so this will not work ! + return DomUtil::readPairListEntry(*projectDom(), "/kdevantproject/run/envvars", "envvar", "name", "value"); +} + + +/** Retuns the currently selected run directory + * The returned string can be: + * if run/directoryradio == executable + * The directory where the executable is + * if run/directoryradio == build + * The directory where the executable is relative to build directory + * if run/directoryradio == custom + * The custom directory absolute path + */ +QString AntProjectPart::runDirectory() const +{ + return buildDirectory(); + /// \FIXME put the code below into use! + + QDomDocument &dom = *projectDom(); + + /// \FIXME there is no kdevantproject so this will not work ! + QString directoryRadioString = DomUtil::readEntry(dom, "/kdevantproject/run/directoryradio"); + QString DomMainProgram = DomUtil::readEntry(dom, "/kdevantproject/run/mainprogram"); + + if ( directoryRadioString == "build" ) + return buildDirectory(); + + if ( directoryRadioString == "custom" ) + return DomUtil::readEntry(dom, "/kdevantproject/run/customdirectory"); + + int pos = DomMainProgram.findRev('/'); + if (pos != -1) + return buildDirectory() + "/" + DomMainProgram.left(pos); + + return buildDirectory() + "/" + DomMainProgram; + +} + + +/** Retuns the currently selected main program + * The returned string can be: + * if run/directoryradio == executable + * The executable name + * if run/directoryradio == build + * The path to executable relative to build directory + * if run/directoryradio == custom or relative == false + * The absolute path to executable + */ +QString AntProjectPart::mainProgram() const +{ + QDomDocument * dom = projectDom(); + + if ( !dom ) return QString(); + + QString DomMainProgram = DomUtil::readEntry( *dom, "/kdevantproject/run/mainprogram"); + + if ( DomMainProgram.isEmpty() ) return QString(); + + if ( DomMainProgram.startsWith("/") ) // assume absolute path + { + return DomMainProgram; + } + else // assume project relative path + { + return projectDirectory() + "/" + DomMainProgram; + } + + return QString(); +} + + +QString AntProjectPart::debugArguments() const +{ + return QString(""); +} + +/** Retuns a QString with the run command line arguments */ +QString AntProjectPart::runArguments() const +{ + /// \FIXME there is no kdevantproject so this will not work ! + return DomUtil::readEntry(*projectDom(), "/kdevantproject/run/programargs"); +} + + +QString AntProjectPart::activeDirectory() const +{ + /// \FIXME + +// return m_projectDirectory; + + // returning m_projectDirectory is wrong, the path returned should be _relative_ to the project dir + // returning an empty string until antproject supports the idea of an active directory + return QString(""); +} + + +QStringList AntProjectPart::allFiles() const +{ +/* QStringList res; + + QStringList::ConstIterator it; + for (it = m_sourceFiles.begin(); it != m_sourceFiles.end(); ++it) + { + QString fileName = *it; + if (!fileName.startsWith("/")) + { + fileName.prepend("/"); + fileName.prepend(m_projectDirectory); + } + res += fileName; + } + + return res;*/ + + // return all files relative to the project directory! + return m_sourceFiles; +} + + +void AntProjectPart::addFile(const QString &fileName) +{ + QStringList fileList; + fileList.append ( fileName ); + + this->addFiles ( fileList ); +} + +void AntProjectPart::addFiles ( const QStringList& fileList ) +{ + QStringList::ConstIterator it; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) + { + m_sourceFiles.append (*it ); + } + + kdDebug() << "Emitting addedFilesToProject" << endl; + emit addedFilesToProject(fileList); +} + +void AntProjectPart::removeFile(const QString &fileName) +{ + QStringList fileList; + fileList.append ( fileName ); + + this->removeFiles ( fileList ); +} + +void AntProjectPart::removeFiles ( const QStringList& fileList ) +{ + kdDebug() << "Emitting removedFilesFromProject" << endl; + emit removedFilesFromProject(fileList); + + QStringList::ConstIterator it; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) + { + m_sourceFiles.remove ( *it ); + } +} + +void AntProjectPart::parseBuildXML() +{ + m_antOptions.m_targets.clear(); + m_antOptions.m_properties.clear(); + m_antOptions.m_defineProperties.clear(); + + // open build file + QFile bf(m_projectDirectory + "/" + m_antOptions.m_buildXML); + if (!bf.open(IO_ReadOnly)) + return; + + // parse build file + QDomDocument dom; + if (!dom.setContent(&bf)) + { + bf.close(); + return; + } + bf.close(); + + m_projectName = dom.documentElement().attribute("name", m_projectName); + m_antOptions.m_defaultTarget = dom.documentElement().attribute("default", ""); + + QDomNode node = dom.documentElement().firstChild(); + while (!node.isNull()) + { + if (node.toElement().tagName() == "target") + { + if (m_antOptions.m_defaultTarget.isEmpty()) + m_antOptions.m_defaultTarget = node.toElement().attribute("name"); + m_antOptions.m_targets.append(node.toElement().attribute("name")); + } + else if (node.toElement().tagName() == "property") + { + m_antOptions.m_properties.insert(node.toElement().attribute("name"), node.toElement().attribute("value")); + m_antOptions.m_defineProperties.insert(node.toElement().attribute("name"), false); + } + + /// @todo Handle property files + /// @todo evaluate properties' values + + node = node.nextSibling(); + } +} + + +void AntProjectPart::fillMenu() +{ + m_buildProjectAction->setEnabled(!m_antOptions.m_defaultTarget.isEmpty()); + + m_targetMenu->clear(); + int id = 0; + QStringList::ConstIterator it; + for (it = m_antOptions.m_targets.begin(); it != m_antOptions.m_targets.end(); ++it) + m_targetMenu->insertItem(*it, id++); +} + + +void AntProjectPart::slotBuild() +{ + ant(m_antOptions.m_defaultTarget); +} + + +void AntProjectPart::slotTargetMenuActivated(int id) +{ + ant(m_antOptions.m_targets[id]); +} + + +void AntProjectPart::ant(const QString &target) +{ + QString cmd = "%0 cd %1 && ant %2 -buildfile %3 %4 %5"; + + QString verb = ""; + switch (m_antOptions.m_verbosity) + { + case AntOptions::Quiet: + verb = "-quiet"; + break; + case AntOptions::Verbose: + verb = "-verbose"; + break; + default: + verb = "-debug"; + break; + } + + QString options = ""; + QMap<QString,QString>::Iterator it; + for (it = m_antOptions.m_properties.begin(); it != m_antOptions.m_properties.end(); ++it) + if (m_antOptions.m_defineProperties[it.key()]) + options += "-D" + it.key() + "=\"" + it.data() + "\" "; + + QString cp; + if (!m_classPath.count() == 0) + cp = "CLASSPATH="+m_classPath.join(":"); + + makeFrontend()->queueCommand(m_projectDirectory, cmd.arg(cp).arg(m_projectDirectory).arg(target).arg(m_antOptions.m_buildXML).arg(verb).arg(options)); +} + + +void AntProjectPart::projectConfigWidget(KDialogBase *dlg) +{ + QVBox *vbox = dlg->addVBoxPage(i18n("Ant Options")); + m_antOptionsWidget = new AntOptionsWidget(vbox); + + m_antOptionsWidget->BuildXML->setURL(m_antOptions.m_buildXML); + + switch (m_antOptions.m_verbosity) + { + case AntOptions::Quiet: + m_antOptionsWidget->Verbosity->setCurrentItem(0); + break; + case AntOptions::Verbose: + m_antOptionsWidget->Verbosity->setCurrentItem(1); + break; + default: + m_antOptionsWidget->Verbosity->setCurrentItem(2); + break; + } + + m_antOptionsWidget->Properties->setNumRows(m_antOptions.m_properties.count()); + m_antOptionsWidget->Properties->setNumCols(2); + + QMap<QString,QString>::Iterator it; + int i=0; + for (it = m_antOptions.m_properties.begin(); it != m_antOptions.m_properties.end(); ++it) + { + QCheckTableItem *citem = new QCheckTableItem(m_antOptionsWidget->Properties, it.key()); + citem->setChecked(m_antOptions.m_defineProperties[it.key()]); + m_antOptionsWidget->Properties->setItem(i,0, citem); + QTableItem *item = new QTableItem(m_antOptionsWidget->Properties, QTableItem::WhenCurrent, it.data()); + m_antOptionsWidget->Properties->setItem(i,1, item); + ++i; + } + + connect(dlg, SIGNAL(okClicked()), this, SLOT(optionsAccepted())); + + vbox = dlg->addVBoxPage(i18n("Classpath")); + m_classPathWidget = new ClassPathWidget(vbox); + + m_classPathWidget->ClassPath->insertStringList(m_classPath); +} + + +void AntProjectPart::optionsAccepted() +{ + if (!m_antOptionsWidget || !m_classPathWidget) + return; + + m_antOptions.m_buildXML = m_antOptionsWidget->BuildXML->url(); + + switch (m_antOptionsWidget->Verbosity->currentItem()) + { + case 1: + m_antOptions.m_verbosity = AntOptions::Verbose; + break; + case 2: + m_antOptions.m_verbosity = AntOptions::Debug; + break; + default: + m_antOptions.m_verbosity = AntOptions::Quiet; + break; + } + + for (int i=0; i<m_antOptionsWidget->Properties->numRows(); ++i) + { + QString key = m_antOptionsWidget->Properties->text(i,0); + m_antOptions.m_properties.replace(key, m_antOptionsWidget->Properties->text(i,1)); + kdDebug() << "PROP: " << key << " = " << m_antOptionsWidget->Properties->text(i,1); + + QCheckTableItem *item =(QCheckTableItem*) m_antOptionsWidget->Properties->item(i,0); + m_antOptions.m_defineProperties.replace(key, item->isChecked()); + } + + m_classPath = m_classPathWidget->ClassPath->items(); + + m_antOptionsWidget = 0; + m_classPathWidget = 0; +} + + +void AntProjectPart::contextMenu(QPopupMenu *popup, const Context *context) +{ + if (!context->hasType( Context::FileContext )) + return; + + const FileContext *fcontext = static_cast<const FileContext*>(context); + KURL url = fcontext->urls().first(); + if (URLUtil::isDirectory(url)) + return; + + m_contextFileName = url.fileName(); + bool inProject = project()->allFiles().contains(m_contextFileName.mid ( project()->projectDirectory().length() + 1 ) ); + QString popupstr = QFileInfo(m_contextFileName).fileName(); + if (m_contextFileName.startsWith(projectDirectory()+ "/")) + m_contextFileName.remove(0, projectDirectory().length()+1); + + popup->insertSeparator(); + if (inProject) + { + int id = popup->insertItem( i18n("Remove %1 From Project").arg(popupstr), + this, SLOT(slotRemoveFromProject()) ); + popup->setWhatsThis(id, i18n("<b>Remove from project</b><p>Removes current file from the project.")); + } + else + { + int id = popup->insertItem( i18n("Add %1 to Project").arg(popupstr), + this, SLOT(slotAddToProject()) ); + popup->setWhatsThis(id, i18n("<b>Add to project</b><p>Adds current file from the project.")); + } +} + + +void AntProjectPart::slotAddToProject() +{ + QStringList fileList; + fileList.append ( m_contextFileName ); + addFiles ( fileList ); +} + + +void AntProjectPart::slotRemoveFromProject() +{ + QStringList fileList; + fileList.append ( m_contextFileName ); + removeFiles ( fileList ); +} + + +#include "antprojectpart.moc" + + +/*! + \fn AntProjectPart::distFiles() const + */ +QStringList AntProjectPart::distFiles() const +{ + QStringList sourceList = allFiles(); + // Scan current source directory for any .pro files. + QString projectDir = projectDirectory(); + QDir dir(projectDir); + QStringList files = dir.entryList( "build.xml"); + return sourceList + files; +} diff --git a/buildtools/ant/antprojectpart.h b/buildtools/ant/antprojectpart.h new file mode 100644 index 00000000..d6540c48 --- /dev/null +++ b/buildtools/ant/antprojectpart.h @@ -0,0 +1,117 @@ +#ifndef _ANTPROJECTPART_H_ +#define _ANTPROJECTPART_H_ + + +#include <qstring.h> +#include <qstringlist.h> +#include <qmap.h> + + +class QPopupMenu; + + +class KAction; +class KDialogBase; +class Context; +class ClassPathWidget; + + +#include "kdevbuildtool.h" + + +class AntOptionsWidget; + + +class AntOptions +{ +public: + + AntOptions(); + + enum Verbosity { Quiet, Verbose, Debug }; + + QString m_buildXML; + QString m_defaultTarget; + QStringList m_targets; + QMap<QString,QString> m_properties; + QMap<QString,bool> m_defineProperties; + Verbosity m_verbosity; + +}; + + +class AntProjectPart : public KDevBuildTool +{ + Q_OBJECT + +public: + + AntProjectPart(QObject *parent, const char *name, const QStringList &args); + ~AntProjectPart(); + QStringList distFiles() const; + + +protected: + + virtual void openProject(const QString &dirName, const QString &projectName); + virtual void closeProject(); + + virtual QString projectDirectory() const; + virtual QString projectName() const; + virtual QString mainProgram() const; + virtual QString activeDirectory() const; + virtual QStringList allFiles() const; + virtual QString buildDirectory() const; + virtual QString runDirectory() const; + virtual QString runArguments() const; + virtual QString debugArguments() const; + virtual DomUtil::PairList runEnvironmentVars() const; + + virtual void addFile(const QString &fileName); + virtual void addFiles ( const QStringList &fileList ); + virtual void removeFile(const QString &fileName); + virtual void removeFiles ( const QStringList& fileList ); + + +private slots: + + void slotBuild(); + void slotTargetMenuActivated(int id); + + void projectConfigWidget(KDialogBase *dlg); + void contextMenu(QPopupMenu *popup, const Context *context); + + void optionsAccepted(); + + void slotAddToProject(); + void slotRemoveFromProject(); + + +private: + + void parseBuildXML(); + void fillMenu(); + void populateProject(); + + void ant(const QString &target); + + QString m_projectDirectory, m_projectName; + QStringList m_classPath; + + QStringList m_sourceFiles; + + AntOptions m_antOptions; + + KAction *m_buildProjectAction; + + QPopupMenu *m_targetMenu; + + AntOptionsWidget *m_antOptionsWidget; + ClassPathWidget *m_classPathWidget; + + QString m_contextFileName; + +}; + + +#endif diff --git a/buildtools/ant/classpathwidget.ui b/buildtools/ant/classpathwidget.ui new file mode 100644 index 00000000..8bfde971 --- /dev/null +++ b/buildtools/ant/classpathwidget.ui @@ -0,0 +1,39 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>ClassPathWidget</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ClassPathWidget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>471</width> + <height>288</height> + </rect> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KEditListBox"> + <property name="name"> + <cstring>ClassPath</cstring> + </property> + <property name="title"> + <string>Class&path</string> + </property> + </widget> + </hbox> +</widget> +<includes> + <include location="global" impldecl="in implementation">keditlistbox.h</include> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>keditlistbox.h</includehint> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/buildtools/ant/kdevantproject.desktop b/buildtools/ant/kdevantproject.desktop new file mode 100644 index 00000000..231339ea --- /dev/null +++ b/buildtools/ant/kdevantproject.desktop @@ -0,0 +1,96 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=Ant Project +Comment[br]=Raktres Ant +Comment[ca]=Projecte Ant +Comment[cs]=Ant projekt +Comment[da]=Ant-projekt +Comment[de]=Ant-Projekt für KDevelop +Comment[el]=Έργο Ant +Comment[es]=Proyecto Ant +Comment[et]=Ant projekt +Comment[eu]=Ant proiektua +Comment[fa]=پروژۀ Ant +Comment[fr]=Projet avec Ant +Comment[ga]=Comhad tionscadail Ant +Comment[gl]=Proxecto Ant +Comment[hi]=एएनटी परियोजना +Comment[hu]=Ant-projekt +Comment[is]=Ant verkefni +Comment[it]=Progetto Ant +Comment[ja]=Ant プロジェクト +Comment[ms]=Projek Ant +Comment[nds]=Ant-Projekt +Comment[ne]=एन्ट परियोजना +Comment[nl]=Ant-project +Comment[pa]=Ant ਪ੍ਰੋਜੈਕਟ +Comment[pl]=Projekt: Ant +Comment[pt]=Projecto Ant +Comment[pt_BR]=Projeto Ant +Comment[ru]=Проект Ant +Comment[sk]=Ant projekt +Comment[sl]=Projekt Ant +Comment[sr]=Ant пројекат +Comment[sr@Latn]=Ant projekat +Comment[sv]=Ant-projekt +Comment[ta]=ஆன்ட்பிராஜக்ட் +Comment[tg]=Лоиҳаи Ant +Comment[tr]=Ant Projesi +Comment[uz]=Ant loyihasi +Comment[uz@cyrillic]=Ant лойиҳаси +Comment[zh_CN]=Ant 工程 +Comment[zh_TW]=Ant 專案 +Name=KDevAntProject +Name[da]=KDevelop Ant-projekt +Name[de]=Ant-Projekt (KDevelop) +Name[hi]=के-डेव-एएनटी-परियोजना +Name[nds]=Ant-Projekt (KDevelop) +Name[ne]=केडीई विकास एन्ट परियोजना +Name[pl]=KDevProjektAnt +Name[sk]=KDevAntProjekt +Name[sv]=KDevelop Ant-projekt +Name[ta]=கெடெவ்ஆன்ட் பிராஜக்ட் +Name[tg]=Лоиҳаи KDevAnt +Name[zh_TW]=KDevelop Ant 專案 +GenericName=Ant Project +GenericName[br]=Raktres Ant +GenericName[ca]=Projecte Ant +GenericName[da]=Ant-projekt +GenericName[de]=Ant-Projekt +GenericName[el]=Έργο Ant +GenericName[es]=Proyecto Ant +GenericName[et]=Ant projekt +GenericName[eu]=Ant proiektua +GenericName[fa]=پروژۀ Ant +GenericName[fr]=Projet avec Ant +GenericName[ga]=Comhad tionscadail Ant +GenericName[gl]=Proxecto Ant +GenericName[hi]=एएनटी परियोजना +GenericName[hu]=Ant-projekt +GenericName[it]=Project con Ant +GenericName[ja]=Ant プロジェクト +GenericName[ms]=Projek Ant +GenericName[nds]=Ant-Projekt +GenericName[ne]=एन्ट परियोजना +GenericName[nl]=Ant-project +GenericName[pl]=Projekt: Ant +GenericName[pt]=Projecto Ant +GenericName[pt_BR]=Projeto Ant +GenericName[ru]=Проект Ant +GenericName[sk]=Ant projekt +GenericName[sl]=Projekt Ant +GenericName[sr]=Ant пројекат +GenericName[sr@Latn]=Ant projekat +GenericName[sv]=Ant-projekt +GenericName[ta]=ஆன்ட்பிராஜக்ட் +GenericName[tg]=Лоиҳаи Ant +GenericName[tr]=Ant Projesi +GenericName[uz]=Ant loyihasi +GenericName[uz@cyrillic]=Ant лойиҳаси +GenericName[zh_CN]=Ant 工程 +GenericName[zh_TW]=Ant 專案 +ServiceTypes=KDevelop/Project +X-KDE-Library=libkdevantproject +X-KDevelop-Version=5 +X-KDevelop-Args= diff --git a/buildtools/ant/kdevantproject.rc b/buildtools/ant/kdevantproject.rc new file mode 100644 index 00000000..df892b3c --- /dev/null +++ b/buildtools/ant/kdevantproject.rc @@ -0,0 +1,14 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KDevAntProject" version="2"> +<MenuBar> + <Menu name="build" > + <Action name="build_build" /> +<!-- <Action name="build_compilefile" /> --> + <Action name="build_target" /> +<!-- <Action name="build_clean" /> + <Separator/> + <Action name="build_execute" /> --> + </Menu> +</MenuBar> +</kpartgui> + diff --git a/buildtools/autotools/Makefile.am b/buildtools/autotools/Makefile.am new file mode 100644 index 00000000..5972b662 --- /dev/null +++ b/buildtools/autotools/Makefile.am @@ -0,0 +1,38 @@ +# Here resides the automake project part. + +INCLUDES = -I$(top_srcdir)/buildtools/lib -I$(top_srcdir)/buildtools/lib/base \ + -I$(top_srcdir)/buildtools/lib/parsers/autotools -I$(top_srcdir)/buildtools/lib/widgets -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/interfaces/external \ + -I$(top_srcdir)/lib/interfaces/extras -I$(top_srcdir)/lib/util $(all_includes) \ + -I$(top_builddir)/buildtools/lib/widgets + + +kde_module_LTLIBRARIES = libkdevautoproject.la +libkdevautoproject_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevautoproject_la_LIBADD = \ + $(top_builddir)/buildtools/lib/base/libkdevbuildbase.la \ + $(top_builddir)/buildtools/lib/parsers/autotools/libkdevautotoolsparser.la $(top_builddir)/buildtools/lib/widgets/libkdevbuildtoolswidgets.la \ + $(top_builddir)/lib/interfaces/extras/libkdevextras.la $(top_builddir)/lib/libkdevelop.la + +libkdevautoproject_la_SOURCES = autoprojectpart.cpp autoprojectwidget.cpp \ + configureoptionswidget.cpp configureoptionswidgetbase.ui subprojectoptionsdlg.cpp \ + subprojectoptionsdlgbase.ui targetoptionsdlg.cpp targetoptionsdlgbase.ui addservicedlg.cpp \ + addservicedlgbase.ui addapplicationdlg.cpp addapplicationdlgbase.ui addtargetdlg.cpp \ + addtargetdlgbase.ui addsubprojectdlg.cpp addfiledlgbase.ui addfiledlg.cpp \ + removefiledlgbase.ui removefiledlg.cpp addicondlgbase.ui addicondlg.cpp \ + addtranslationdlg.cpp addprefixdlg.cpp kfilednddetailview.cpp kfiledndiconview.cpp \ + fileselectorwidget.cpp misc.cpp addsubprojectdlgbase.ui removetargetdlg.cpp \ + removetargetdlgbase.ui choosetargetdialog.cpp choosetargetdlgbase.ui addexistingdlgbase.ui \ + addexistingfilesdlg.cpp addexistingdirectoriesdlg.cpp kimporticonview.cpp \ + autosubprojectview.cpp autodetailsview.cpp autolistviewitems.cpp managecustomcommandsbase.ui \ + managecustomcommand.cpp autoprojectviewbase.ui autotoolsaction.cpp makefilehandler.cpp + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevautoproject.desktop kdevkdeautoproject.desktop + +rcdir = $(kde_datadir)/kdevautoproject +rc_DATA = kdevautoproject.rc + +noinst_HEADERS = managecustomcommand.h autotoolsaction.h makefilehandler.h diff --git a/buildtools/autotools/README b/buildtools/autotools/README new file mode 100644 index 00000000..487cec41 --- /dev/null +++ b/buildtools/autotools/README @@ -0,0 +1 @@ +Please read the README.dox file
diff --git a/buildtools/autotools/README.dox b/buildtools/autotools/README.dox new file mode 100644 index 00000000..acad3e64 --- /dev/null +++ b/buildtools/autotools/README.dox @@ -0,0 +1,39 @@ +/** \class AutoProjectPart +Autoprojectpart is a projectmanager for Automake based projects. + +Loads and maintains Makefile.am files. + +\authors <a href="mailto:bernd AT kdevelop.org">Bernd Gehrmann</a> + +\maintainer <a href="mailto:victor_roeder AT gmx.de">Victor Rder</a> +\maintainer <a href="mailto:a.lucas AT tu-bs.de">Amilcar do Carmo Lucas</a> + +\feature supports creating subprojects, targets, services (.desktop) and applications (.desktop). +\feature Automake projects can be configured on subprojects, targets (except DATA and HEADER targets). +\feature It will regenerate the projects Makefile.am files dynamically as you add or +reconfigure subprojects**. +\feature Unsupported automake features will be left unchanged +(hopefully), no major testing has been run yet (at least not by myself). + +\bug bugs in <a href="http://bugs.kde.org/buglist.cgi?product=kdevelop&component=autoproject&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&order=Bug+Number"> autoproject component at Bugzilla database</a> +\bug Lower Automake Manager view does not update it's view when adding a subproject (and targets, etc to the new subproject) +\bug If removing the Active Target, update the .kdevelop file, too! + + +\note +If you want to change the default implemention for running/starting the binary +please add the following to your project file +\verbatim +<kdevautoproject> + <run> + <disable_default>true</disable_default> + </run> +</kdevautoproject> +\endverbatim +with this configuration the "Automake Manager" doesn't insert the menuentry "execute program" +and doesn't show the "Run Options" in the project configuration.<br> +Now you can implement this features with your own special plugin. +For an example please look at the projects generated for GBA using the VisualBoy Advance Plugin. +This plugin starts a GBA binary with an emulator. -- <a href="mailto:smeier AT kdevelop.org">Sandy Meier</a> + +*/ diff --git a/buildtools/autotools/addapplicationdlg.cpp b/buildtools/autotools/addapplicationdlg.cpp new file mode 100644 index 00000000..04e132dd --- /dev/null +++ b/buildtools/autotools/addapplicationdlg.cpp @@ -0,0 +1,207 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "addapplicationdlg.h" + +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qfile.h> +#include <qheader.h> +#include <qlistview.h> +#include <qtextstream.h> +#include <qapplication.h> +#include <klineedit.h> +#include <kdebug.h> +#include <kicondialog.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kmimetype.h> + +#include "autolistviewitems.h" + +#include "misc.h" +#include "autoprojectwidget.h" +#include "autoprojectpart.h" + + +AddApplicationDialog::AddApplicationDialog(AutoProjectWidget *widget, SubprojectItem *spitem, + QWidget *parent, const char *name) + : AddApplicationDialogBase(parent, name, true) +{ + filename_edit->setText(".desktop"); + filename_edit->home(false); + filename_edit->setFocus(); + chosentypes_listview->header()->hide(); + availtypes_listview->header()->hide(); + QString addApplication = add_button->text(); + QString removeApplication = remove_button->text(); + + add_button->setText( QApplication::reverseLayout() ? removeApplication : addApplication ); + remove_button->setText( QApplication::reverseLayout() ? addApplication : removeApplication ); + + m_widget = widget; + subProject = spitem; + + // Fill the combo box with program names in the directory + QPtrListIterator<TargetItem> tit(spitem->targets); + for (; tit.current(); ++tit) { + if ((*tit)->primary == "PROGRAMS") + executable_combo->insertItem(QString((*tit)->name)); + } + + // Fill the list of available mime types + KMimeType::List l = KMimeType::allMimeTypes(); + KMimeType::List::Iterator it; + for (it = l.begin(); it != l.end(); ++it) + new QListViewItem(availtypes_listview, (*it)->name()); + + setIcon ( SmallIcon ( "window_new" ) ); +} + + +AddApplicationDialog::~AddApplicationDialog() +{} + + +void AddApplicationDialog::iconClicked() +{ + KIconLoader *loader = AutoProjectFactory::instance()->iconLoader(); + QString name = KIconDialog::getIcon(KIcon::Desktop); + if (!name.isNull()) { + iconName = name; + icon_button->setPixmap(loader->loadIcon(name, KIcon::Desktop)); + } +} + + +void AddApplicationDialog::addTypeClicked() +{ + QListViewItem *selitem = availtypes_listview->selectedItem(); + if (!selitem) + return; + + QListViewItem *olditem = chosentypes_listview->firstChild(); + while (olditem) { + if (selitem->text(0) == olditem->text(0)) + return; + olditem = olditem->nextSibling(); + } + new QListViewItem(chosentypes_listview, selitem->text(0)); +} + + +void AddApplicationDialog::removeTypeClicked() +{ + delete chosentypes_listview->currentItem(); +} + + +void AddApplicationDialog::accept() +{ + // Create list of mime types + QStringList mimeTypes; + QListViewItem *item = chosentypes_listview->firstChild(); + while (item) { + mimeTypes.append(item->text(0)); + item = item->nextSibling(); + } + + // Some plausibility tests + QString fileName = filename_edit->text(); + if (fileName.isEmpty() || fileName == ".desktop") { + KMessageBox::sorry(this, i18n("You have to enter a file name.")); + filename_edit->setFocus(); + return; + } + + QString executable = executable_combo->currentText(); + if (executable.isEmpty()) { + KMessageBox::sorry(this, i18n("You have to enter the file name of an executable program.")); + executable_combo->setFocus(); + return; + } + + QString name = name_edit->text(); + if (name.isEmpty()) { + KMessageBox::sorry(this, i18n("You have to enter an application name.")); + name_edit->setFocus(); + return; + } + + QFile f(subProject->path + "/" + fileName); + if (f.exists()) { + KMessageBox::sorry(this, i18n("A file with this name exists already.")); + filename_edit->setFocus(); + return; + } + if (!f.open(IO_WriteOnly)) { + KMessageBox::sorry(this, i18n("Could not open file for writing.")); + return; + } + + QTextStream stream(&f); + stream << "[Desktop Entry]" << endl; + stream << "Type=Application" << endl; + stream << "Name=" << name << endl; + stream << "Exec=" << (executable + " -caption \"%c\" %i %m %u") << endl; + stream << "Comment=" << comment_edit->text() << endl; + if (!iconName.isNull()) + stream << "Icon=" << iconName << endl; + stream << "MimeTypes=" << mimeTypes.join(";") << endl; + stream << "Terminal=" << (terminal_box->isChecked()? "true" : "false") << endl; + f.close(); + + // Find a prefix that points to the applnk directory. + // If there is none, use appslnksection + QString section = section_combo->currentText(); + QString appsdir = "$(kde_appsdir)/" + section; + QMap<QString,QString>::ConstIterator it; + for (it = subProject->prefixes.begin(); it != subProject->prefixes.end(); ++it) + if (it.data() == appsdir) + break; + + QMap<QString, QString> replaceMap; + QString prefix; + if (it == subProject->prefixes.end()) { + prefix = "applnk" + section; + replaceMap.insert(prefix + "dir", appsdir); + subProject->prefixes.insert(prefix, appsdir); + } else { + prefix = it.key(); + } + QString varname = prefix + "_DATA"; + + // Look if a list view item for this prefix exists already. + // Create a new one otherwise + TargetItem *titem = 0; + for (uint i=0; i < subProject->targets.count(); ++i) { + TargetItem *tmptitem = subProject->targets.at(i); + if ("DATA" == tmptitem->primary && prefix == tmptitem->prefix) { + titem = tmptitem; + break; + } + } + if (!titem) { + titem = m_widget->createTargetItem("", prefix, "DATA", false); + subProject->targets.append(titem); + } + // Add this file to the target + FileItem *fitem = m_widget->createFileItem(fileName, subProject); + titem->sources.append(fitem); + + subProject->variables[varname] += (" " + fileName); + replaceMap.insert(varname, subProject->variables[varname]); + AutoProjectTool::addToMakefileam(subProject->path + "/Makefile.am", replaceMap); + + QDialog::accept(); +} + +#include "addapplicationdlg.moc" diff --git a/buildtools/autotools/addapplicationdlg.h b/buildtools/autotools/addapplicationdlg.h new file mode 100644 index 00000000..d9f8e6fc --- /dev/null +++ b/buildtools/autotools/addapplicationdlg.h @@ -0,0 +1,45 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#ifndef _ADDAPPLICATIONDLG_H_ +#define _ADDAPPLICATIONDLG_H_ + +#include "addapplicationdlgbase.h" + +class AutoProjectWidget; +class SubprojectItem; +class TargetItem; + + +class AddApplicationDialog : public AddApplicationDialogBase +{ + Q_OBJECT + +public: + AddApplicationDialog( AutoProjectWidget *widget, SubprojectItem *spitem, + QWidget *parent = 0, const char *name = 0 ); + ~AddApplicationDialog(); + +protected: + virtual void iconClicked(); + virtual void addTypeClicked(); + virtual void removeTypeClicked(); + virtual void accept(); + +private: + AutoProjectWidget *m_widget; + SubprojectItem *subProject; + QString iconName; +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/addapplicationdlgbase.ui b/buildtools/autotools/addapplicationdlgbase.ui new file mode 100644 index 00000000..5e6def81 --- /dev/null +++ b/buildtools/autotools/addapplicationdlgbase.ui @@ -0,0 +1,552 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>AddApplicationDialogBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>add_application_dialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>586</width> + <height>425</height> + </rect> + </property> + <property name="caption"> + <string>Add New Application .desktop File</string> + </property> + <property name="sizeGripEnabled"> + <bool>false</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>GroupBox7</cstring> + </property> + <property name="title"> + <string>&Application File</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="2" column="1"> + <property name="name"> + <cstring>terminal_box</cstring> + </property> + <property name="text"> + <string>Start in t&erminal</string> + </property> + </widget> + <widget class="KLineEdit" row="3" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>comment_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>filename_edit</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="3"> + <property name="name"> + <cstring>Layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>icon_button</cstring> + </property> + <property name="maximumSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + <spacer> + <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>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QComboBox" row="0" column="3"> + <property name="name"> + <cstring>executable_combo</cstring> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + <widget class="KLineEdit" row="1" column="1"> + <property name="name"> + <cstring>name_edit</cstring> + </property> + </widget> + <widget class="QComboBox" row="2" column="3"> + <item> + <property name="text"> + <string>Application</string> + </property> + </item> + <item> + <property name="text"> + <string>Games</string> + </property> + </item> + <item> + <property name="text"> + <string>Development</string> + </property> + </item> + <item> + <property name="text"> + <string>Editors</string> + </property> + </item> + <item> + <property name="text"> + <string>Graphics</string> + </property> + </item> + <item> + <property name="text"> + <string>Internet</string> + </property> + </item> + <item> + <property name="text"> + <string>Multimedia</string> + </property> + </item> + <item> + <property name="text"> + <string>Office</string> + </property> + </item> + <item> + <property name="text"> + <string>Settings</string> + </property> + </item> + <item> + <property name="text"> + <string>System</string> + </property> + </item> + <item> + <property name="text"> + <string>Toys</string> + </property> + </item> + <item> + <property name="text"> + <string>Utilities</string> + </property> + </item> + <item> + <property name="text"> + <string>WordProcessing</string> + </property> + </item> + <property name="name"> + <cstring>section_combo</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="2"> + <property name="name"> + <cstring>name_label_2</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>E&xecutable:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>executable_combo</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="2"> + <property name="name"> + <cstring>icon_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&Icon:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>icon_button</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="2"> + <property name="name"> + <cstring>section_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&Section:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>section_combo</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>filename_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&File name:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>filename_edit</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>name_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&Name:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>name_edit</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>comment_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Co&mment:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>comment_edit</cstring> + </property> + </widget> + </grid> + </widget> + <spacer> + <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>20</height> + </size> + </property> + </spacer> + <widget class="QGroupBox"> + <property name="name"> + <cstring>GroupBox6</cstring> + </property> + <property name="title"> + <string>Mime &Types</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QListView"> + <column> + <property name="text"> + <string></string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>chosentypes_listview</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>add_button</cstring> + </property> + <property name="text"> + <string><-</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>remove_button</cstring> + </property> + <property name="text"> + <string>-></string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QListView"> + <column> + <property name="text"> + <string></string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>availtypes_listview</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + </hbox> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>okbutton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelbutton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>cancelbutton</sender> + <signal>clicked()</signal> + <receiver>add_application_dialog</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>okbutton</sender> + <signal>clicked()</signal> + <receiver>add_application_dialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>icon_button</sender> + <signal>clicked()</signal> + <receiver>add_application_dialog</receiver> + <slot>iconClicked()</slot> + </connection> + <connection> + <sender>add_button</sender> + <signal>clicked()</signal> + <receiver>add_application_dialog</receiver> + <slot>addTypeClicked()</slot> + </connection> + <connection> + <sender>remove_button</sender> + <signal>clicked()</signal> + <receiver>add_application_dialog</receiver> + <slot>removeTypeClicked()</slot> + </connection> +</connections> +<tabstops> + <tabstop>filename_edit</tabstop> + <tabstop>executable_combo</tabstop> + <tabstop>name_edit</tabstop> + <tabstop>icon_button</tabstop> + <tabstop>terminal_box</tabstop> + <tabstop>section_combo</tabstop> + <tabstop>comment_edit</tabstop> + <tabstop>chosentypes_listview</tabstop> + <tabstop>add_button</tabstop> + <tabstop>remove_button</tabstop> + <tabstop>availtypes_listview</tabstop> + <tabstop>okbutton</tabstop> + <tabstop>cancelbutton</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<slots> + <slot access="protected">addTypeClicked()</slot> + <slot access="protected">iconClicked()</slot> + <slot access="protected">removeTypeClicked()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +</UI> diff --git a/buildtools/autotools/addexistingdirectoriesdlg.cpp b/buildtools/autotools/addexistingdirectoriesdlg.cpp new file mode 100644 index 00000000..625d6af1 --- /dev/null +++ b/buildtools/autotools/addexistingdirectoriesdlg.cpp @@ -0,0 +1,388 @@ +/*************************************************************************** + ------------------- + begin : 12/21/2002 + copyright : (C) 2002 by Victor R�er + email : victor_roeder@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 <qgroupbox.h> +#include <qlayout.h> + +#include <kprogress.h> +#include <klocale.h> +#include <kio/netaccess.h> +#include <kprocess.h> + +#include "autolistviewitems.h" +#include "autosubprojectview.h" + +#include "autoprojectwidget.h" +#include "autoprojectpart.h" + +#include "kimporticonview.h" + +#include "urlutil.h" + +#include "addexistingdirectoriesdlg.h" + +AddExistingDirectoriesDialog::AddExistingDirectoriesDialog ( AutoProjectPart* part, AutoProjectWidget *widget, SubprojectItem* spitem, QWidget* parent, const char* name, bool modal, WFlags fl ) + : AddExistingDlgBase ( parent, name, modal, fl ) +{ + setIcon ( SmallIcon ( "fileimport.png" ) ); + + m_spitem = spitem; + + m_part = part; + m_widget = widget; + + KFile::Mode mode = KFile::Directory; + +// if ( spitem && spitem->type() == ProjectItem::Subproject ) +// { +// destStaticLabel->setText ( i18n ( "Subproject:" ) ); +// destLabel->setText ( spitem->subdir ); +// targetLabel->setText ( i18n ( "none" ) ); +// directoryLabel->setText ( i18n ( spitem->path ) ); +// } + + sourceSelector = new FileSelectorWidget ( part, mode, sourceGroupBox, "source file selector" ); + sourceGroupBoxLayout->addWidget ( sourceSelector ); + + importView = new KImportIconView ( i18n("Drag one or more directories with an existing Makefile.am from the left view and drop it here."), destGroupBox, "destination icon view" ); + destGroupBoxLayout->addWidget ( importView ); + + setIcon ( SmallIcon ( "fileimport.png" ) ); + + QWidget::setTabOrder(sourceSelector, addAllButton); + QWidget::setTabOrder(addAllButton, addSelectedButton); + QWidget::setTabOrder(addSelectedButton, importView); + QWidget::setTabOrder(importView, removeAllButton); + QWidget::setTabOrder(removeAllButton, removeSelectedButton); + QWidget::setTabOrder(removeSelectedButton, okButton); + QWidget::setTabOrder(okButton, cancelButton); + + sourceSelector->setFocus(); + + init(); +} + + +AddExistingDirectoriesDialog::~AddExistingDirectoriesDialog() +{ +} + +void AddExistingDirectoriesDialog::init() +{ + progressBar->hide(); + + importView->setMode ( KIconView::Select ); + importView->setItemsMovable ( false ); + + connect ( okButton, SIGNAL ( clicked () ), this, SLOT ( slotOk () ) ); + + connect ( addSelectedButton, SIGNAL ( clicked () ), this, SLOT ( slotAddSelected() ) ); + connect ( addAllButton, SIGNAL ( clicked () ), this, SLOT ( slotAddAll() ) ); + connect ( removeSelectedButton, SIGNAL ( clicked () ), this, SLOT ( slotRemoveSelected() ) ); + connect ( removeAllButton, SIGNAL ( clicked () ), this, SLOT ( slotRemoveAll() ) ); + + connect ( importView, SIGNAL ( dropped( QDropEvent* ) ), this, SLOT ( slotDropped ( QDropEvent* ) ) ); + + importView->setSelectionMode ( KFile::Multi ); + + sourceSelector->setDir ( m_spitem->path ); +} + +void AddExistingDirectoriesDialog::importItems() +{ + if( !importView->items() ) + return; + + // items added via button or drag 'n drop + KFileItemListIterator itemList ( m_importList ); + + // items already added to the importView + KFileItemListIterator importedList ( *importView->items() ); + + QStringList duplicateList; + + importedList.toFirst(); + + for ( ; importedList.current(); ++importedList ) + { + itemList.toFirst(); + + for ( ; itemList.current(); ++itemList ) + { + if ( ( *importedList )->name() == ( *itemList )->name() ) + { + m_importList.remove ( ( *itemList ) ); + + // to avoid that a item is added twice + if ( !duplicateList.remove ( ( *importedList )->name() ) ) + { + duplicateList.append ( ( *importedList )->name() ); + } + } + } + } + + itemList.toFirst(); + + for ( ; itemList.current(); ++itemList ) + { + KURL amURL = itemList.current()->url(); + amURL.addPath("Makefile.am"); + if (KIO::NetAccess::exists(amURL)) + { + importView->insertItem ( ( *itemList ) ); + } + } + + importView->somethingDropped ( true ); + + m_importList.clear(); + + importView->update (); +} + +void AddExistingDirectoriesDialog::slotOk() +{ + if ( importView->items()->count() == 0 ) QDialog::reject(); + + KFileItemListIterator items ( *importView->items() ); + + QStringList dirs; + + for ( ; items.current(); ++items ) + { + //if the directory is outside the project directory +// kdDebug( 9020 ) << "dir to add " << items.current()->url().path() << " subproject " << m_spitem->path << endl; + if (items.current()->url().path() != m_spitem->path) + { + //copy + //FIXME: check this after 3.0 release and add a possibility to link, not just copy + KProcess proc; + + proc << "cp"; + proc << "-r"; + proc << items.current()->url().path(); + proc << m_spitem->path; + proc.start(KProcess::Block); + } + dirs << items.current()->name(); + } + + for (QStringList::const_iterator it = dirs.begin(); it != dirs.end(); ++it) + { + QString name = *it; + + // Adjust SUBDIRS variable in containing Makefile.am + if (m_spitem->variables["SUBDIRS"].find("$(TOPSUBDIRS)") != -1) + { + QFile subdirsfile( m_spitem->path + "/subdirs" ); + if ( subdirsfile.open( IO_WriteOnly | IO_Append ) ) + { + QTextStream subdirsstream( &subdirsfile ); + subdirsstream << name << endl; + subdirsfile.close(); + } + } + else if (m_spitem->variables["SUBDIRS"].find("$(AUTODIRS)") != -1) + { + } + else + { + m_spitem->variables["SUBDIRS"] += (" " + name); + QMap<QString,QString> replaceMap; + replaceMap.insert("SUBDIRS", m_spitem->variables["SUBDIRS"]); + AutoProjectTool::addToMakefileam(m_spitem->path + "/Makefile.am", replaceMap); + } + + // Create new item in tree view + SubprojectItem *newitem = new SubprojectItem(m_spitem, name); + newitem->subdir = name; + newitem->path = m_spitem->path + "/" + name; + newitem->variables["INCLUDES"] = m_spitem->variables["INCLUDES"]; + newitem->setOpen(true); + + // Move to the bottom of the list + QListViewItem *lastItem = m_spitem->firstChild(); + while (lastItem->nextSibling()) + lastItem = lastItem->nextSibling(); + if (lastItem != newitem) + newitem->moveItem(lastItem); + + // Create a Makefile in the new subdirectory + + QDir dir( m_spitem->path + "/" + name ); + QFile f( dir.filePath("Makefile.am") ); + if (f.exists()) { + m_widget->getSubprojectView()->parse( newitem ); + } else { + if (!f.open(IO_WriteOnly)) { +// KMessageBox::sorry(this, i18n("Could not create Makefile.am in subdirectory %1.").arg(name)); + continue; + } + QTextStream stream(&f); + stream << "INCLUDES = " << newitem->variables["INCLUDES"] << endl << "METASOURCES = AUTO" << endl; + f.close(); + } + + + + // if !isKDE: add the new sub-proj to configure.in or configure.ac + if ( !m_part->isKDE() ) { + QString projroot = m_part->projectDirectory() + "/"; + QString subdirectory = dir.path(); + QString relpath = subdirectory.replace(0, projroot.length(),""); + + QString configureFile = m_part->getAutoConfFile(projroot); + + QStringList list = AutoProjectTool::configureinLoadMakefiles(configureFile); + if ( !list.isEmpty() ) + { + list.push_back( relpath + "/Makefile" ); + AutoProjectTool::configureinSaveMakefiles(configureFile, list); + } + } + + m_part->needMakefileCvs(); + + } + QDialog::accept(); +} + +void AddExistingDirectoriesDialog::slotAddSelected() +{ + KFileItemListIterator it ( *sourceSelector->dirOperator()->selectedItems() ); + + for ( ; it.current(); ++it ) + { + QString relPath = URLUtil::extractPathNameRelative(m_part->projectDirectory(), ( *it )->url()); + if (relPath[relPath.length()-1] == '/') + relPath = relPath.left(relPath.length()-1); + if ( (relPath.isEmpty()) || (! m_widget->allSubprojects().contains( relPath )) ) + { + m_importList.append ( ( *it ) ); + } + } + + importItems(); +} + +void AddExistingDirectoriesDialog::slotAddAll() +{ + KFileItemListIterator it ( *sourceSelector->dirOperator()->view()->items() ); + + for ( ; it.current(); ++it ) + { + QString relPath = URLUtil::extractPathNameRelative(m_part->projectDirectory(), ( *it )->url()); + if (relPath[relPath.length()-1] == '/') + relPath = relPath.left(relPath.length()-1); + if ( (relPath.isEmpty()) || ( ! m_widget->allSubprojects().contains( relPath )) ) + { + m_importList.append ( ( *it ) ); + } + } + + importItems(); +} + +void AddExistingDirectoriesDialog::slotRemoveAll() +{ + KURL::List deletedFiles; + KFileItemListIterator it ( *importView->items() ); + + for ( ; it.current(); ++it ) + { + kdDebug ( 9020 ) << "AddExistingDirectoriesDialog::slotRemoveAll()" << endl; + //deletedFiles.append ( ( *it )->url() ); + if ( (*it ) ) importView->removeItem ( *it ); + } + + importView->somethingDropped ( false ); + + importView->viewport()->update(); +} + +void AddExistingDirectoriesDialog::slotRemoveSelected() +{ + KFileItemListIterator items ( *importView->items() ); + + KFileItemList* selectedList = (KFileItemList*) importView->selectedItems(); + + KFileItem * deleteItem = 0L; + + for ( ; items.current(); ++items ) + { + deleteItem = selectedList->first(); + + while ( deleteItem ) + { + if ( deleteItem == ( *items ) ) + { + importView->removeItem ( deleteItem ); + deleteItem = selectedList->current(); + } + else + { + deleteItem = selectedList->next(); + } + } + } + + if ( importView->items()->count() == 0 ) importView->somethingDropped ( false ); + + importView->viewport()->update(); +} + +void AddExistingDirectoriesDialog::slotDropped ( QDropEvent* ev ) +{ + kdDebug ( 9020 ) << "AddExistingDirectoriesDialog::dropped()" << endl; + + KURL::List urls; + + KURLDrag::decode( ev, urls ); + + KFileItem* item = 0L; + KMimeType::Ptr type = 0L; + + + for ( KURL::List::Iterator it = urls.begin(); it != urls.end(); ++it ) + { + //check if this subproject is already in project + QString relPath = URLUtil::extractPathNameRelative(m_part->projectDirectory(), *it); + if (relPath[relPath.length()-1] == '/') + relPath = relPath.left(relPath.length()-1); + if ( (relPath.isEmpty()) || ( ! m_widget->allSubprojects().contains( relPath )) ) + { + type = KMimeType::findByURL ( ( *it ) ); + + if ( type->name() != KMimeType::defaultMimeType() ) + { + item = new KFileItem ( ( *it ) , type->name(), 0 ); + } + else + { + item = new KFileItem ( ( *it ), "inode/directory", 0 ); + } + + m_importList.append ( item ); + } + } + + importItems(); +} + +#include "addexistingdirectoriesdlg.moc" + +//kate: indent-mode csands; tab-width 4; space-indent off; diff --git a/buildtools/autotools/addexistingdirectoriesdlg.h b/buildtools/autotools/addexistingdirectoriesdlg.h new file mode 100644 index 00000000..c4dd048e --- /dev/null +++ b/buildtools/autotools/addexistingdirectoriesdlg.h @@ -0,0 +1,74 @@ +/*************************************************************************** + ------------------- + begin : 12/21/2002 + copyright : (C) 2002 by Victor R�er + email : victor_roeder@gmx.de +***************************************************************************/ + +/*************************************************************************** + * * + * 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 _ADDEXISTINGDIRECTORIESDLG_H_ +#define _ADDEXISTINGDIRECTORIESDLG_H_ + +#include "addexistingdlgbase.h" + +#include <qdialog.h> +#include <kfile.h> + +#include "misc.h" +#include "fileselectorwidget.h" + +class FileSelectorWidget; +class AutoProjectWidget; +class AutoProjectPart; +class SubprojectItem; +class TargetItem; +class KFileItem; +class KImportIconView; + +class AddExistingDirectoriesDialog : public AddExistingDlgBase +{ + Q_OBJECT + +public: + AddExistingDirectoriesDialog ( AutoProjectPart* part, AutoProjectWidget *widget, + SubprojectItem* spitem, QWidget* parent = 0, + const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~AddExistingDirectoriesDialog(); + +private: + FileSelectorWidget* sourceSelector; + KImportIconView* importView; + + AutoProjectPart* m_part; + AutoProjectWidget* m_widget; + + TargetItem* m_titem; + SubprojectItem* m_spitem; + + KFileItemList m_importList; + +protected: + void init(); + void importItems (); + +protected slots: + void slotAddSelected(); + void slotAddAll(); + void slotRemoveAll(); + void slotRemoveSelected(); + void slotDropped ( QDropEvent* ev ); + + void slotOk(); +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/addexistingdlgbase.ui b/buildtools/autotools/addexistingdlgbase.ui new file mode 100644 index 00000000..cf73ee21 --- /dev/null +++ b/buildtools/autotools/addexistingdlgbase.ui @@ -0,0 +1,459 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>AddExistingDlgBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>AddExistingDlgBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>592</width> + <height>445</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>ImportExistingDlgBase</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="3" column="0"> + <property name="name"> + <cstring>layout10</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>buttonSpacer</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>317</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>okButton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelButton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </hbox> + </widget> + <widget class="KProgress" row="2" column="0"> + <property name="name"> + <cstring>progressBar</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + </widget> + <widget class="QGroupBox" row="0" column="0"> + <property name="name"> + <cstring>infoGroupBox</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>32767</height> + </size> + </property> + <property name="frameShape"> + <enum>Box</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="title"> + <string>Subproject Information</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>infoLayout1</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>directoryStaticLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Directory:</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>targetStaticLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Target:</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>infoLayout2</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="KSqueezedTextLabel"> + <property name="name"> + <cstring>directoryLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>[DIRECTORY]</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>targetLabel</cstring> + </property> + <property name="text"> + <string>[TARGET]</string> + </property> + </widget> + </vbox> + </widget> + </hbox> + </widget> + <widget class="QSplitter" row="1" column="0"> + <property name="name"> + <cstring>splitter2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout12</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout10</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>arrowSpacer1</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>84</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>addAllButton</cstring> + </property> + <property name="text"> + <string>A&dd All</string> + </property> + <property name="toolTip" stdset="0"> + <string>Import by creating symbolic links (recommended)</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>addSelectedButton</cstring> + </property> + <property name="text"> + <string>&Add Selected</string> + </property> + <property name="toolTip" stdset="0"> + <string>Import by copying (not recommended)</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>arrowSpacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>84</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>sourceGroupBox</cstring> + </property> + <property name="minimumSize"> + <size> + <width>240</width> + <height>250</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>32767</height> + </size> + </property> + <property name="title"> + <string>&Source Directory</string> + </property> + <property name="toolTip" stdset="0"> + <string></string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + </vbox> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout13</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout11</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>arrowSpacer1_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>21</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>removeAllButton</cstring> + </property> + <property name="text"> + <string>R&emove All</string> + </property> + <property name="toolTip" stdset="0"> + <string>Removes all added files.</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>removeSelectedButton</cstring> + </property> + <property name="text"> + <string>&Remove Selected</string> + </property> + <property name="toolTip" stdset="0"> + <string>Removes the selected files.</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>arrowSpacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>destGroupBox</cstring> + </property> + <property name="minimumSize"> + <size> + <width>140</width> + <height>100</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>32767</height> + </size> + </property> + <property name="title"> + <string>Add &Following</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + </vbox> + </widget> + </vbox> + </widget> + </widget> + </grid> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>AddExistingDlgBase</receiver> + <slot>reject()</slot> + </connection> +</connections> +<tabstops> + <tabstop>addAllButton</tabstop> + <tabstop>addSelectedButton</tabstop> + <tabstop>removeAllButton</tabstop> + <tabstop>removeSelectedButton</tabstop> + <tabstop>okButton</tabstop> + <tabstop>cancelButton</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">ksqueezedtextlabel.h</include> + <include location="global" impldecl="in implementation">kprogress.h</include> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>kprogress.h</includehint> + <includehint>ksqueezedtextlabel.h</includehint> +</includehints> +</UI> diff --git a/buildtools/autotools/addexistingfilesdlg.cpp b/buildtools/autotools/addexistingfilesdlg.cpp new file mode 100644 index 00000000..00f3e61b --- /dev/null +++ b/buildtools/autotools/addexistingfilesdlg.cpp @@ -0,0 +1,451 @@ +/*************************************************************************** + ------------------- + begin : Frag' mich was leichteres + copyright : (C) 2002 by Victor Rder + email : victor_roeder@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +/** Here resides the Import-existing-files-dialog of the Automake Manager (a KDevelop build tool part) **/ + +#include <qapplication.h> +#include <qgroupbox.h> +#include <qlabel.h> +//#include <qlistbox.h> +#include <qpushbutton.h> +#include <qlayout.h> +#include <qtooltip.h> +#include <qwhatsthis.h> +#include <qpixmap.h> + +#include <kdebug.h> +#include <kfileview.h> +#include <kguiitem.h> +#include <kprogress.h> +#include <kprocess.h> +#include <kurldrag.h> +#include <kmessagebox.h> +#include <kmimetype.h> +#include <kiconview.h> +#include <ksqueezedtextlabel.h> + +#include "urlutil.h" + +#include "autolistviewitems.h" + +#include "autoprojectwidget.h" +#include "autoprojectpart.h" + +#include "kimporticonview.h" + +#include "addexistingfilesdlg.h" + +/* + * Constructs a AddExistingFilesDialog which is a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ + +AddExistingFilesDialog::AddExistingFilesDialog ( AutoProjectPart* part, AutoProjectWidget *widget, SubprojectItem* spitem, TargetItem* titem, QWidget* parent, const char* name, bool modal, WFlags fl ) + : AddExistingDlgBase ( parent, name, modal, fl ) +{ + m_spitem = spitem; + m_titem = titem; + + m_part = part; + m_widget = widget; + + KFile::Mode mode = KFile::Files; + + if ( titem && spitem && titem->type() == ProjectItem::Target && spitem->type() == ProjectItem::Subproject ) + { + + if ( titem->name.isEmpty() ) + { + QString target = i18n ( "%1 in %2" ).arg ( titem->primary ).arg ( titem->prefix ); + targetLabel->setText ( target ); + } + else + { + targetLabel->setText ( titem->name ); + } + directoryLabel->setText ( spitem->path ); + } + + sourceSelector = new FileSelectorWidget ( m_part, mode, sourceGroupBox, "source file selector" ); + sourceGroupBoxLayout->addWidget ( sourceSelector ); + + importView = new KImportIconView ( i18n ( "Drag one or more files from the left view and drop it here." ), destGroupBox, "destination icon view" ); + destGroupBoxLayout->addWidget ( importView ); + //destGroupBoxLayout->setStretchFactor(dir, 2); + + QWidget::setTabOrder(sourceSelector, addAllButton); + QWidget::setTabOrder(addAllButton, addSelectedButton); + QWidget::setTabOrder(addSelectedButton, importView); + QWidget::setTabOrder(importView, removeAllButton); + QWidget::setTabOrder(removeAllButton, removeSelectedButton); + QWidget::setTabOrder(removeSelectedButton, okButton); + QWidget::setTabOrder(okButton, cancelButton); + + sourceSelector->setFocus(); + + setIcon ( SmallIcon ( "fileimport.png" ) ); + + init(); +} + + +/* + * Destroys the object and frees any allocated resources + */ +AddExistingFilesDialog::~AddExistingFilesDialog() +{ + // no need to delete child widgets, Qt does it all for me +} + + +// void AddExistingFilesDialog::resizeEvent ( QResizeEvent* ev ) +// { +// AddExistingDlgBase::resizeEvent ( ev ); +// //importView->update(); +// } + + +void AddExistingFilesDialog::init() +{ + progressBar->hide(); + + importView->setMode ( KIconView::Select ); + importView->setItemsMovable ( false ); + + connect ( okButton, SIGNAL ( clicked () ), this, SLOT ( slotOk () ) ); + + connect ( addSelectedButton, SIGNAL ( clicked () ), this, SLOT ( slotAddSelected() ) ); + connect ( addAllButton, SIGNAL ( clicked () ), this, SLOT ( slotAddAll() ) ); + connect ( removeSelectedButton, SIGNAL ( clicked () ), this, SLOT ( slotRemoveSelected() ) ); + connect ( removeAllButton, SIGNAL ( clicked () ), this, SLOT ( slotRemoveAll() ) ); + + connect ( importView, SIGNAL ( dropped( QDropEvent* ) ), this, SLOT ( slotDropped ( QDropEvent* ) ) ); + + importView->setSelectionMode ( KFile::Multi ); + + Q_ASSERT( m_spitem ); + sourceSelector->setDir ( m_spitem->path ); +} + +void AddExistingFilesDialog::importItems() +{ + if( !importView->items() ) + return; + + // items added via button or drag 'n drop + KFileItemListIterator itemList ( m_importList ); + + // items already added to the importView + KFileItemListIterator importedList ( *importView->items() ); + + QListViewItem* child = m_titem->firstChild(); + + QStringList duplicateList; + + while ( child ) + { + FileItem* curItem = static_cast<FileItem*> ( child ); + + itemList.toFirst(); + + for ( ; itemList.current(); ++itemList ) + { + if ( ( *itemList )->name() == curItem->name ) + { + duplicateList.append ( ( *itemList )->name() ); + m_importList.remove ( ( *itemList ) ); + } + } + + child = child->nextSibling(); + } + + importedList.toFirst(); + + for ( ; importedList.current(); ++importedList ) + { + itemList.toFirst(); + + for ( ; itemList.current(); ++itemList ) + { + if ( ( *importedList )->name() == ( *itemList )->name() ) + { + m_importList.remove ( ( *itemList ) ); + + // to avoid that a item is added twice + if ( !duplicateList.remove ( ( *importedList )->name() ) ) + { + duplicateList.append ( ( *importedList )->name() ); + } + } + } + } + + if ( duplicateList.count() > 0 ) + { + if ( KMessageBox::warningContinueCancelList ( this, i18n ( + "The following file(s) already exist(s) in the target!\n" + "Press Continue to import only the new files.\n" + "Press Cancel to abort the complete import." ), + duplicateList, "Warning", KGuiItem ( i18n ( "Continue" ) ) ) == KMessageBox::Cancel ) + { + m_importList.clear(); + return; + } + } + + itemList.toFirst(); + + for ( ; itemList.current(); ++itemList ) + { + if ( !( *itemList )->isDir() ) + { + importView->insertItem ( ( *itemList ) ); + } + } + + importView->somethingDropped ( true ); + + m_importList.clear(); + + importView->update (); +} + +void AddExistingFilesDialog::slotOk() +{ + if ( importView->items()->count() == 0 ) QDialog::reject(); + + progressBar->show(); + progressBar->setFormat ( i18n ( "Importing... %p%" ) ); + + qApp->processEvents(); + + KFileItemListIterator items ( *importView->items() ); + + // contains at the end only the imported files outside the subproject directory + KFileItemList outsideList; + + QStringList stringList; + + for ( ; items.current(); ++items ) + { + // kdDebug ( 9020 ) << " **** " << ( *items )->url().directory() << "***** " << m_spitem->path << endl; + if ( ( *items )->url().directory() != m_spitem->path ) + { + stringList.append ( ( *items )->name() ); + outsideList.append ( ( *items ) ); + } + } + + progressBar->setTotalSteps ( outsideList.count() + importView->items()->count() ); + + if ( outsideList.count() > 0 ) + { + if ( KMessageBox::questionYesNoList ( this, i18n ( + "The following file(s) are not in the Subproject directory.\n" + "Press Link to add the files by creating symbolic links.\n" + "Press Copy to copy the files into the directory." ), + stringList, i18n("Warning"), KGuiItem ( i18n ( "Link (recommended)" ) ), KGuiItem ( i18n ( "Copy (not recommended)" ) ) ) == KMessageBox::No ) + { + // Copy files into the Subproject directory + KFileItemListIterator it ( outsideList ) ; + + for ( ; it.current(); ++it ) + { + KProcess proc; + + proc << "cp"; + proc << ( *it )->url().path(); + proc << m_spitem->path; + proc.start(KProcess::DontCare); + + progressBar->setValue ( progressBar->value() + 1 ); + } + } + else + { + // Link them into the Subproject directory + KFileItemListIterator it ( outsideList ) ; + + for ( ; it.current(); ++it ) + { + KProcess proc; + + proc << "ln"; + proc << "-s"; + proc << URLUtil::relativePathToFile( m_spitem->path, ( *it )->url().path() ); + proc << m_spitem->path; + proc.start(KProcess::DontCare); + + progressBar->setValue ( progressBar->value() + 1 ); + } + } + } + + items.toFirst(); + + QString canontargetname = AutoProjectTool::canonicalize ( m_titem->name ); + QString varname; + if( m_titem->primary == "PROGRAMS" || m_titem->primary == "LIBRARIES" || m_titem->primary == "LTLIBRARIES" ) + varname = canontargetname + "_SOURCES"; + else + varname = m_titem->prefix + "_" + m_titem->primary; + + QMap<QString,QString> replaceMap; + FileItem* fitem = 0L; + QStringList fileList; + + for ( ; items.current(); ++items ) + { + m_spitem->variables [ varname ] += ( " " + ( *items )->name() ); + replaceMap.insert ( varname, m_spitem->variables [ varname ] ); + + fitem = m_widget->createFileItem ( ( *items )->name(), m_spitem ); + m_titem->sources.append ( fitem ); + m_titem->insertItem ( fitem ); + + fileList.append ( m_spitem->path.mid ( m_part->projectDirectory().length() + 1 ) + "/" + ( *items )->name() ); + + progressBar->setValue ( progressBar->value() + 1 ); + } + + m_widget->emitAddedFiles ( fileList ); + + AutoProjectTool::addToMakefileam ( m_spitem->path + "/Makefile.am", replaceMap ); + + QDialog::accept(); + +} + +void AddExistingFilesDialog::slotAddSelected() +{ + KFileItemListIterator it ( *sourceSelector->dirOperator()->selectedItems() ); + + for ( ; it.current(); ++it ) + { + if ( ( *it )->url().isLocalFile() ) // maybe unnecessary + { + m_importList.append ( ( *it ) ); + } + } + + importItems(); +} + + +void AddExistingFilesDialog::slotAddAll() +{ + KFileItemListIterator it ( *sourceSelector->dirOperator()->view()->items() ); + + for ( ; it.current(); ++it ) + { + if ( ( *it )->url().isLocalFile() ) // maybe unnecessary + { + m_importList.append ( ( *it ) ); + } + } + + importItems(); +} + +void AddExistingFilesDialog::slotRemoveAll() +{ + KURL::List deletedFiles; + KFileItemListIterator it ( *importView->items() ); + + for ( ; it.current(); ++it ) + { + kdDebug ( 9020 ) << "AddExistingFilesDialog::slotRemoveAll()" << endl; + //deletedFiles.append ( ( *it )->url() ); + if ( (*it ) ) importView->removeItem ( *it ); + } + + importView->somethingDropped ( false ); + + importView->viewport()->update(); +} + +void AddExistingFilesDialog::slotRemoveSelected() +{ + KFileItemListIterator items ( *importView->items() ); + + KFileItemList* selectedList = (KFileItemList*) importView->selectedItems(); + + KFileItem * deleteItem = 0L; + + for ( ; items.current(); ++items ) + { + deleteItem = selectedList->first(); + + while ( deleteItem ) + { + if ( deleteItem == ( *items ) ) + { + importView->removeItem ( deleteItem ); + deleteItem = selectedList->current(); + } + else + { + deleteItem = selectedList->next(); + } + } + } + + if ( importView->items()->count() == 0 ) importView->somethingDropped ( false ); + + importView->viewport()->update(); +} + + +void AddExistingFilesDialog::slotDropped ( QDropEvent* ev ) +{ + kdDebug ( 9020 ) << "AddExistingFilesDialog::dropped()" << endl; + + KURL::List urls; + + KURLDrag::decode( ev, urls ); + + KFileItem* item = 0L; + KMimeType::Ptr type = 0L; + + + for ( KURL::List::Iterator it = urls.begin(); it != urls.end(); ++it ) + { + if ( ( *it ).isLocalFile() ) // maybe unnecessary + { + type = KMimeType::findByURL ( ( *it ) ); + + if ( type->name() != KMimeType::defaultMimeType() ) + { + item = new KFileItem ( ( *it ) , type->name(), 0 ); + } + else + { + // take a text-file-icon instead of the ugly question-mark-icon + item = new KFileItem ( ( *it ), "text/plain", 0 ); + } + + m_importList.append ( item ); + } + } + + importItems(); +} + +#include "addexistingfilesdlg.moc" diff --git a/buildtools/autotools/addexistingfilesdlg.h b/buildtools/autotools/addexistingfilesdlg.h new file mode 100644 index 00000000..5bee18b6 --- /dev/null +++ b/buildtools/autotools/addexistingfilesdlg.h @@ -0,0 +1,77 @@ +/*************************************************************************** + ------------------- + begin : Frag' mich was leichteres + copyright : (C) 2002 by Victor Rder + email : victor_roeder@gmx.de +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +/** Here resides the Import-existing-files-dialog of the Automake Manager **/ +/** (a KDevelop build tool part) **/ + +#ifndef ADDEXISTINGFILESDLG_H +#define ADDEXISTINGFILESDLG_H + +#include <qdialog.h> +#include <kfile.h> + +#include "addexistingdlgbase.h" +#include "fileselectorwidget.h" + +#include "misc.h" + +class KImportIconView; +class FileSelectorWidget; +class AutoProjectWidget; +class AutoProjectPart; +class SubprojectItem; +class TargetItem; +class KFileItem; + +class AddExistingFilesDialog : public AddExistingDlgBase +{ + Q_OBJECT + +public: + AddExistingFilesDialog( AutoProjectPart* part, AutoProjectWidget *widget, + SubprojectItem* spitem, TargetItem* titem, QWidget* parent = 0, + const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~AddExistingFilesDialog(); + +private: + FileSelectorWidget* sourceSelector; + KImportIconView* importView; + + AutoProjectPart* m_part; + AutoProjectWidget* m_widget; + + TargetItem* m_titem; + SubprojectItem* m_spitem; + + KFileItemList m_importList; + +protected: + // virtual void resizeEvent ( QResizeEvent* ev ); + void init(); + void importItems (); + +protected slots: + void slotAddSelected(); + void slotAddAll(); + void slotRemoveAll(); + void slotRemoveSelected(); + void slotDropped ( QDropEvent* ev ); + + void slotOk(); +}; + +#endif // ADDEXISTINGFILESDLG_H +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/addfiledlg.cpp b/buildtools/autotools/addfiledlg.cpp new file mode 100644 index 00000000..46529086 --- /dev/null +++ b/buildtools/autotools/addfiledlg.cpp @@ -0,0 +1,135 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "addfiledlg.h" + +#include <qcheckbox.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qpushbutton.h> +#include <qtextstream.h> + +#include <kbuttonbox.h> +#include <kdebug.h> +#include <kdialog.h> +#include <klineedit.h> +#include <kmessagebox.h> +#include <ksqueezedtextlabel.h> +#include <kurl.h> + +#include "autolistviewitems.h" + +#include "filetemplate.h" +#include "misc.h" +#include "urlutil.h" +#include "autoprojectpart.h" +#include "autoprojectwidget.h" + +#include "kdevpartcontroller.h" + +AddFileDialog::AddFileDialog(AutoProjectPart *part, AutoProjectWidget *widget, + SubprojectItem *spitem, TargetItem *item, + QWidget *parent, const char *name) + : AddFileDlgBase(parent, name, true) +{ + connect ( createButton, SIGNAL ( clicked() ), this, SLOT ( accept() ) ); + connect ( cancelButton, SIGNAL ( clicked() ), this, SLOT ( reject() ) ); + + directoryLabel->setText ( spitem->path ); + if ( item->name.isEmpty() ) + targetLabel->setText ( i18n ( "%1 in %2" ).arg ( item->primary ).arg ( item->prefix ) ); + else + targetLabel->setText ( item->name ); + + setIcon ( SmallIcon ( "filenew.png" ) ); + + m_part = part; + m_widget = widget; + subProject = spitem; + target = item; +} + + +AddFileDialog::~AddFileDialog() +{} + + +void AddFileDialog::accept() +{ + QString name = fileEdit->text(); + if (name.find('/') != -1) { + KMessageBox::sorry(this, i18n("Please enter the file name without '/' and so on.")); + return; + } + + QListViewItem *child = target->firstChild(); + while (child) { + FileItem *item = static_cast<FileItem*>(child); + if (name == item->name) { + KMessageBox::sorry(this, i18n("This file is already in the target.")); + return; + } + child = child->nextSibling(); + } + + if (templateCheckBox->isChecked()) { + QString srcdir = m_part->projectDirectory(); + QString destdir = subProject->path; + QString destpath = destdir + "/" + name; + if (QFileInfo(destpath).exists()) { + KMessageBox::sorry(this, i18n("<b>A file with this name already exists.</b><br><br>Please use the \"Add existing file\" dialog.")); + return; + } + if( !FileTemplate::copy(m_part, QFileInfo(name).extension(), destpath) ) + kdDebug(9020) << "cannot create file " << destpath << endl; + } else { + // create an empty file + QString srcdir = m_part->projectDirectory(); + QString destdir = subProject->path; + QString destpath = destdir + "/" + name; + + if (QFileInfo(destpath).exists()) { + KMessageBox::sorry(this, i18n("<b>A file with this name already exists.</b><br><br>Please use the \"Add existing file\" dialog.")); + return; + } + + QFile f( destpath ); + if( f.open(IO_WriteOnly) ) + f.close(); + } + + FileItem *fitem = m_widget->createFileItem(name, subProject); + target->sources.append(fitem); + target->insertItem(fitem); + + QString canontargetname = AutoProjectTool::canonicalize(target->name); + QString varname; + if( target->primary == "PROGRAMS" || target->primary == "LIBRARIES" || target->primary == "LTLIBRARIES" ) + varname = canontargetname + "_SOURCES"; + else + varname = target->prefix + "_" + target->primary; + subProject->variables[varname] += (" " + name); + + QMap<QString,QString> replaceMap; + replaceMap.insert(varname, subProject->variables[varname]); + + AutoProjectTool::addToMakefileam(subProject->path + "/Makefile.am", replaceMap); + + m_widget->emitAddedFile( subProject->path.mid ( m_part->project()->projectDirectory().length() + 1 ) + "/" + name ); + m_part->partController()->editDocument ( KURL ( subProject->path + "/" + name ) ); + + QDialog::accept(); +} + +#include "addfiledlg.moc" diff --git a/buildtools/autotools/addfiledlg.h b/buildtools/autotools/addfiledlg.h new file mode 100644 index 00000000..328e3593 --- /dev/null +++ b/buildtools/autotools/addfiledlg.h @@ -0,0 +1,47 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#ifndef _ADDFILEDLG_H_ +#define _ADDFILEDLG_H_ + +#include <qdialog.h> + +#include "addfiledlgbase.h" + +class QCheckBox; +class QLineEdit; +class AutoProjectPart; +class AutoProjectWidget; +class SubprojectItem; +class TargetItem; + + +class AddFileDialog : public AddFileDlgBase +{ + Q_OBJECT + +public: + AddFileDialog( AutoProjectPart *part, AutoProjectWidget *widget, + SubprojectItem *spitem, TargetItem *item, + QWidget *parent = 0, const char *name = 0 ); + ~AddFileDialog(); + +protected: + virtual void accept(); + +private: + AutoProjectPart *m_part; + AutoProjectWidget *m_widget; + SubprojectItem *subProject; + TargetItem *target; +}; + +#endif diff --git a/buildtools/autotools/addfiledlgbase.ui b/buildtools/autotools/addfiledlgbase.ui new file mode 100644 index 00000000..dc8e38b2 --- /dev/null +++ b/buildtools/autotools/addfiledlgbase.ui @@ -0,0 +1,289 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>AddFileDlgBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>AddFileDlgBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>521</width> + <height>217</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>32767</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="caption"> + <string>Add New Created File to Target</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox" row="0" column="0"> + <property name="name"> + <cstring>targetBox</cstring> + </property> + <property name="frameShape"> + <enum>Box</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="title"> + <string>Subproject Information</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>targetLayout</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="KSqueezedTextLabel" row="0" column="1"> + <property name="name"> + <cstring>directoryLabel</cstring> + </property> + <property name="text"> + <string>[TARGET DIRECTORY]</string> + </property> + </widget> + <widget class="QLabel" row="1" column="1"> + <property name="name"> + <cstring>targetLabel</cstring> + </property> + <property name="text"> + <string>[TARGET NAME]</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>directoryStaticLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Directory:</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>targetStaticLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Target:</string> + </property> + </widget> + </grid> + </widget> + </hbox> + </widget> + <widget class="QGroupBox" row="1" column="0"> + <property name="name"> + <cstring>fileGroupBox</cstring> + </property> + <property name="title"> + <string>File Information</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KLineEdit" row="1" column="0"> + <property name="name"> + <cstring>fileEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </widget> + <widget class="QCheckBox" row="1" column="1"> + <property name="name"> + <cstring>templateCheckBox</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Use file template</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>fileStaticLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>New file &name (with extension):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>fileEdit</cstring> + </property> + </widget> + </grid> + </widget> + <spacer row="2" column="0"> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget" row="3" column="0"> + <property name="name"> + <cstring>buttonLayout</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>buttonSpacer</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>createButton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelButton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<includes> + <include location="global" impldecl="in implementation">ksqueezedtextlabel.h</include> + <include location="global" impldecl="in implementation">klineedit.h</include> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>ksqueezedtextlabel.h</includehint> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/buildtools/autotools/addicondlg.cpp b/buildtools/autotools/addicondlg.cpp new file mode 100644 index 00000000..251601f7 --- /dev/null +++ b/buildtools/autotools/addicondlg.cpp @@ -0,0 +1,115 @@ +/*************************************************************************** + * Copyright (C) 2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "addicondlg.h" + +#include <qcombobox.h> +#include <qlabel.h> +#include <klineedit.h> +#include <kdebug.h> +#include <klocale.h> +#include <kprocess.h> +#include <kstandarddirs.h> +#include <kicontheme.h> +#include <kdeversion.h> // fix me! + +#include "autolistviewitems.h" + +#include "autoprojectpart.h" +#include "autoprojectwidget.h" + + +const char *type_map[] = { + "app", "action", "device", "filesys", "mime" +}; + + +const char *size_map[] = { + "hi16", "hi22", "hi32", "hi48", "hi64", "hi128" +}; + + +AddIconDialog::AddIconDialog(AutoProjectPart *part, AutoProjectWidget *widget, + SubprojectItem *spitem, TargetItem *titem, + QWidget *parent, const char *name) + : AddIconDialogBase(parent, name, true) +{ + type_combo->insertItem(i18n("Application")); + type_combo->insertItem(i18n("Action")); + type_combo->insertItem(i18n("Device")); + type_combo->insertItem(i18n("File System")); + type_combo->insertItem(i18n("MIME Type")); + + size_combo->insertItem("16"); + size_combo->insertItem("22"); + size_combo->insertItem("32"); + size_combo->insertItem("48"); + size_combo->insertItem("64"); + size_combo->insertItem("128"); + + somethingChanged(); + + setIcon ( SmallIcon ( "iconadd_kdevelop" ) ); + + m_part = part; + m_widget = widget; + m_subProject = spitem; + m_target = titem; +} + + +AddIconDialog::~AddIconDialog() +{} + + +void AddIconDialog::somethingChanged() +{ + QString size = size_map[size_combo->currentItem()]; + QString type = type_map[type_combo->currentItem()]; + QString name = name_edit->text(); + + filename_edit->setText(size + "-" + type + "-" + name + ".png"); +} + + +void AddIconDialog::accept() +{ + QString name = filename_edit->text(); + + QString destdir = m_subProject->subdir; + QString destpath = destdir + "/" + name; + + QString size = size_combo->currentText(); + QString unknown = KIconTheme::defaultThemeName()+ "/" + size + "x" + size + "/mimetypes/unknown.png"; + + QString templateFileName = locate("icon", unknown); + kdDebug(9020) << "Unknown: " << unknown << ", template: " << templateFileName << endl; + + if (!templateFileName.isEmpty()) { + KProcess proc; + proc << "cp"; + proc << templateFileName; + proc << destpath; + proc.start(KProcess::DontCare); + } + + FileItem *fitem = m_widget->createFileItem(name, m_subProject); + m_target->sources.append(fitem); + m_target->insertItem(fitem); + + m_part->startMakeCommand(destdir, QString::fromLatin1("force-reedit")); + + m_widget->emitAddedFile(destpath); + + QDialog::accept(); +} + +#include "addicondlg.moc" diff --git a/buildtools/autotools/addicondlg.h b/buildtools/autotools/addicondlg.h new file mode 100644 index 00000000..64fac0a5 --- /dev/null +++ b/buildtools/autotools/addicondlg.h @@ -0,0 +1,44 @@ +/*************************************************************************** +* Copyright (C) 2002 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#ifndef _ADDICONDLG_H_ +#define _ADDICONDLG_H_ + +#include "addicondlgbase.h" + +class AutoProjectPart; +class AutoProjectWidget; +class SubprojectItem; +class TargetItem; + + +class AddIconDialog : public AddIconDialogBase +{ + Q_OBJECT + +public: + AddIconDialog( AutoProjectPart *part, AutoProjectWidget *widget, + SubprojectItem *spitem, TargetItem *titem, + QWidget *parent = 0, const char *name = 0 ); + ~AddIconDialog(); + + +private: + virtual void somethingChanged(); + virtual void accept(); + + AutoProjectPart *m_part; + AutoProjectWidget *m_widget; + SubprojectItem *m_subProject; + TargetItem *m_target; +}; + +#endif diff --git a/buildtools/autotools/addicondlgbase.ui b/buildtools/autotools/addicondlgbase.ui new file mode 100644 index 00000000..7fec5097 --- /dev/null +++ b/buildtools/autotools/addicondlgbase.ui @@ -0,0 +1,273 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>AddIconDialogBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>add_icon_dialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>301</width> + <height>218</height> + </rect> + </property> + <property name="caption"> + <string>Add New Icon</string> + </property> + <property name="sizeGripEnabled"> + <bool>false</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>type_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&Type:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>type_combo</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>size_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&Size:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>size_combo</cstring> + </property> + </widget> + <widget class="QComboBox" row="1" column="1"> + <property name="name"> + <cstring>size_combo</cstring> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>filename_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>File name:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>filename_edit</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>name_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&Name:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>name_edit</cstring> + </property> + </widget> + <widget class="Line" row="5" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Line1</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="QLayoutWidget" row="6" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>okbutton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelbutton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>name_edit</cstring> + </property> + <property name="text"> + <string>unknown</string> + </property> + </widget> + <widget class="QComboBox" row="0" column="1"> + <property name="name"> + <cstring>type_combo</cstring> + </property> + </widget> + <widget class="QLabel" row="4" column="1"> + <property name="name"> + <cstring>filename_edit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>Spacer22</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> +</widget> +<connections> + <connection> + <sender>okbutton</sender> + <signal>clicked()</signal> + <receiver>add_icon_dialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>cancelbutton</sender> + <signal>clicked()</signal> + <receiver>add_icon_dialog</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>name_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>add_icon_dialog</receiver> + <slot>somethingChanged()</slot> + </connection> + <connection> + <sender>type_combo</sender> + <signal>activated(int)</signal> + <receiver>add_icon_dialog</receiver> + <slot>somethingChanged()</slot> + </connection> + <connection> + <sender>size_combo</sender> + <signal>activated(int)</signal> + <receiver>add_icon_dialog</receiver> + <slot>somethingChanged()</slot> + </connection> +</connections> +<tabstops> + <tabstop>type_combo</tabstop> + <tabstop>size_combo</tabstop> + <tabstop>name_edit</tabstop> + <tabstop>okbutton</tabstop> + <tabstop>cancelbutton</tabstop> +</tabstops> +<slots> + <slot>somethingChanged()</slot> +</slots> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> + +</UI> + diff --git a/buildtools/autotools/addprefixdlg.cpp b/buildtools/autotools/addprefixdlg.cpp new file mode 100644 index 00000000..d1557114 --- /dev/null +++ b/buildtools/autotools/addprefixdlg.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "addprefixdlg.h" + +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <kbuttonbox.h> +#include <kfiledialog.h> +#include <klocale.h> +#include <kstdguiitem.h> +#include <kdeversion.h> + +AddPrefixDialog::AddPrefixDialog( const QString& nameEdit, const QString& pathEdit, + QWidget *parent, const char *name) + : QDialog(parent, name, true) +{ + setCaption(i18n("Add Prefix")); + + QLabel *name_label = new QLabel(i18n("&Name:"), this); + name_edit = new KLineEdit(nameEdit, this); + name_edit->setFocus(); + name_label->setBuddy(name_edit); + connect( name_edit, SIGNAL( textChanged ( const QString & ) ), SLOT( slotPrefixChanged() ) ); + + QLabel *path_label = new QLabel(i18n("&Path:"), this); + path_edit = new KLineEdit(pathEdit, this); + path_label->setBuddy(path_edit); + QFontMetrics fm(path_edit->fontMetrics()); + path_edit->setMinimumWidth(fm.width('X')*35); + connect( path_edit, SIGNAL( textChanged ( const QString & ) ), SLOT( slotPrefixChanged() ) ); + + QVBoxLayout *layout = new QVBoxLayout(this, 10); + + QGridLayout *grid = new QGridLayout(2, 2); + layout->addLayout(grid); + grid->addWidget(name_label, 0, 0); + grid->addWidget(name_edit, 0, 1); + grid->addWidget(path_label, 1, 0); + grid->addWidget(path_edit, 1, 1); + + QFrame *frame = new QFrame(this); + frame->setFrameStyle(QFrame::HLine | QFrame::Sunken); + layout->addWidget(frame, 0); + + KButtonBox *buttonbox = new KButtonBox(this); + buttonbox->addStretch(); + m_pOk = buttonbox->addButton(KStdGuiItem::ok()); + QPushButton *cancel = buttonbox->addButton(KStdGuiItem::cancel()); + m_pOk->setDefault(true); + connect( m_pOk, SIGNAL(clicked()), this, SLOT(accept()) ); + connect( cancel, SIGNAL(clicked()), this, SLOT(reject()) ); + buttonbox->layout(); + layout->addWidget(buttonbox, 0); + slotPrefixChanged(); +} + + +AddPrefixDialog::~AddPrefixDialog() +{} + +void AddPrefixDialog::slotPrefixChanged() +{ + m_pOk->setEnabled( !name_edit->text().isEmpty() && !path_edit->text().isEmpty() ); +} + +#include "addprefixdlg.moc" diff --git a/buildtools/autotools/addprefixdlg.h b/buildtools/autotools/addprefixdlg.h new file mode 100644 index 00000000..a20bc63a --- /dev/null +++ b/buildtools/autotools/addprefixdlg.h @@ -0,0 +1,45 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#ifndef _ADDPREFIXDLG_H_ +#define _ADDPREFIXDLG_H_ + +#include <qdialog.h> +#include <klineedit.h> +class QPushButton; + +class AddPrefixDialog : public QDialog +{ + Q_OBJECT + +public: + AddPrefixDialog( const QString& nameEdit = "", const QString& pathEdit = "", + QWidget *parent = 0, const char *name = 0 ); + ~AddPrefixDialog(); + + QString name() const + { + return name_edit->text(); + } + QString path() const + { + return path_edit->text(); + } +private slots: + void slotPrefixChanged(); + +private: + KLineEdit *name_edit; + KLineEdit *path_edit; + QPushButton *m_pOk; +}; + +#endif diff --git a/buildtools/autotools/addservicedlg.cpp b/buildtools/autotools/addservicedlg.cpp new file mode 100644 index 00000000..2dc76e5e --- /dev/null +++ b/buildtools/autotools/addservicedlg.cpp @@ -0,0 +1,233 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "addservicedlg.h" + +#include <qcombobox.h> +#include <qfile.h> +#include <qheader.h> +#include <qlistview.h> +#include <qtextstream.h> +#include <klineedit.h> +#include <kdebug.h> +#include <kicondialog.h> +#include <kinputdialog.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kservicetype.h> + +#include "autolistviewitems.h" + +#include "misc.h" +#include "autoprojectwidget.h" +#include "autoprojectpart.h" + + +AddServiceDialog::AddServiceDialog(AutoProjectWidget *widget, SubprojectItem *spitem, + QWidget *parent, const char *name) + : AddServiceDialogBase(parent, name, true) +{ + filename_edit->setText(".desktop"); + filename_edit->home(false); + filename_edit->setFocus(); + chosentypes_listview->header()->hide(); + availtypes_listview->header()->hide(); + + m_widget = widget; + subProject = spitem; + + // Fill the combo box with library names in the directory + QPtrListIterator<TargetItem> tit(spitem->targets); + for (; tit.current(); ++tit) { + if ((*tit)->primary == "LTLIBRARIES") + library_combo->insertItem(QString((*tit)->name)); + } + + // Fill the list of available service types + KServiceType::List l = KServiceType::allServiceTypes(); + KServiceType::List::Iterator it; + for (it = l.begin(); it != l.end(); ++it) + if (!(*it)->isType(KST_KMimeType)) + new QListViewItem(availtypes_listview, (*it)->name()); + + setIcon ( SmallIcon ( "servicenew_kdevelop.png" ) ); +} + + +AddServiceDialog::~AddServiceDialog() +{} + + +void AddServiceDialog::updateProperties() +{ + QStringList props; + + QListViewItem *item = static_cast<QCheckListItem*>(chosentypes_listview->firstChild()); + while (item) { + KServiceType::Ptr type = KServiceType::serviceType(item->text(0)); + if (type) { + QStringList stprops = type->propertyDefNames(); + QStringList::ConstIterator stit; + for (stit = stprops.begin(); stit != stprops.end(); ++stit) + if (props.find(*stit) == props.end() && (*stit) != "Name" && (*stit) != "Comment" + && (*stit) != "Icon") + props.append(*stit); + } + item = item->nextSibling(); + } + + properties_listview->clear(); + QStringList::ConstIterator it; + for (it = props.begin(); it != props.end(); ++it) + new QListViewItem(properties_listview, *it); +} + + +void AddServiceDialog::iconClicked() +{ + KIconLoader *loader = AutoProjectFactory::instance()->iconLoader(); + QString name = KIconDialog::getIcon(KIcon::Desktop); + if (!name.isNull()) { + iconName = name; + icon_button->setPixmap(loader->loadIcon(name, KIcon::Desktop)); + } +} + + +void AddServiceDialog::addTypeClicked() +{ + QListViewItem *selitem = availtypes_listview->selectedItem(); + if (!selitem) + return; + + QListViewItem *olditem = chosentypes_listview->firstChild(); + while (olditem) { + if (selitem->text(0) == olditem->text(0)) + return; + olditem = olditem->nextSibling(); + } + new QListViewItem(chosentypes_listview, selitem->text(0)); + + updateProperties(); +} + + +void AddServiceDialog::removeTypeClicked() +{ + delete chosentypes_listview->currentItem(); + + updateProperties(); +} + + +void AddServiceDialog::propertyExecuted(QListViewItem *item) +{ + if (!item) + return; + + QString prop = item->text(0); + QString value = item->text(1); + bool ok; + value = KInputDialog::getText(i18n("Enter Value"), i18n("Property %1:").arg(prop), value, &ok, this); + if (!ok) + return; + + item->setText(1, value); +} + + +void AddServiceDialog::accept() +{ + // Create list of service types + QStringList serviceTypes; + QListViewItem *item = chosentypes_listview->firstChild(); + while (item) { + serviceTypes.append(item->text(0)); + item = item->nextSibling(); + } + + // Some plausibility tests + QString fileName = filename_edit->text(); + if (fileName.isEmpty() || fileName == ".desktop") { + KMessageBox::sorry(this, i18n("You have to enter a file name.")); + filename_edit->setFocus(); + return; + } + + QString name = name_edit->text(); + if (name.isEmpty()) { + KMessageBox::sorry(this, i18n("You have to enter a service name.")); + name_edit->setFocus(); + return; + } + + QFile f(subProject->path + "/" + fileName); + if (f.exists()) { + KMessageBox::sorry(this, i18n("A file with this name exists already.")); + filename_edit->setFocus(); + return; + } + if (!f.open(IO_WriteOnly)) { + KMessageBox::sorry(this, i18n("Could not open file for writing.")); + return; + } + + QTextStream stream(&f); + stream << "[Desktop Entry]" << endl; + stream << "Type=Service" << endl; + stream << "Name=" << name << endl; + stream << "Comment=" << comment_edit->text() << endl; + if (!iconName.isNull()) + stream << "Icon=" << iconName << endl; + stream << "ServiceTypes=" << serviceTypes.join(",") << endl; + item = properties_listview->firstChild(); + while (item) { + stream << item->text(0) << "=" << item->text(1) << endl; + item = item->nextSibling(); + } + f.close(); + + // Find a prefix that points to the services directory. + // If there is none, use kde_services + QMap<QString,QString>::ConstIterator it; + for (it = subProject->prefixes.begin(); it != subProject->prefixes.end(); ++it) + if (it.data() == "$(kde_servicesdir)") + break; + QString prefix = (it == subProject->prefixes.end())? QString("kde_services") : it.key(); + QString varname = prefix + "_DATA"; + + // Look if a list view item for this prefix exists already. + // Create a new one otherwise + TargetItem *titem = 0; + for (uint i=0; i < subProject->targets.count(); ++i) { + TargetItem *tmptitem = subProject->targets.at(i); + if ("DATA" == tmptitem->primary && prefix == tmptitem->prefix) { + titem = tmptitem; + break; + } + } + if (!titem) { + titem = m_widget->createTargetItem("", prefix, "DATA", false); + subProject->targets.append(titem); + } + // Add this file to the target + FileItem *fitem = m_widget->createFileItem(fileName, subProject); + titem->sources.append(fitem); + + subProject->variables[varname] += (" " + fileName); + QMap<QString, QString> replaceMap; + replaceMap.insert(varname, subProject->variables[varname]); + AutoProjectTool::addToMakefileam(subProject->path + "/Makefile.am", replaceMap); + + QDialog::accept(); +} + +#include "addservicedlg.moc" diff --git a/buildtools/autotools/addservicedlg.h b/buildtools/autotools/addservicedlg.h new file mode 100644 index 00000000..c8b694a5 --- /dev/null +++ b/buildtools/autotools/addservicedlg.h @@ -0,0 +1,46 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#ifndef _ADDSERVICEDLG_H_ +#define _ADDSERVICEDLG_H_ + +#include "addservicedlgbase.h" + +class AutoProjectWidget; +class SubprojectItem; +class TargetItem; + + +class AddServiceDialog : public AddServiceDialogBase +{ + Q_OBJECT + +public: + AddServiceDialog( AutoProjectWidget *widget, SubprojectItem *spitem, + QWidget *parent = 0, const char *name = 0 ); + ~AddServiceDialog(); + +protected: + virtual void iconClicked(); + virtual void addTypeClicked(); + virtual void removeTypeClicked(); + virtual void propertyExecuted( QListViewItem *item ); + virtual void accept(); + +private: + void updateProperties(); + + AutoProjectWidget *m_widget; + SubprojectItem *subProject; + QString iconName; +}; + +#endif diff --git a/buildtools/autotools/addservicedlgbase.ui b/buildtools/autotools/addservicedlgbase.ui new file mode 100644 index 00000000..050f8066 --- /dev/null +++ b/buildtools/autotools/addservicedlgbase.ui @@ -0,0 +1,544 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>AddServiceDialogBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>add_service_dialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>602</width> + <height>422</height> + </rect> + </property> + <property name="caption"> + <string>Add New Service</string> + </property> + <property name="sizeGripEnabled"> + <bool>false</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + + <widget class="QGroupBox"> + <property name="name"> + <cstring>GroupBox1</cstring> + </property> + <property name="title"> + <string>&Service File</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>filename_edit</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="QLabel" row="1" column="2"> + <property name="name"> + <cstring>icon_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&Icon:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>icon_button</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="3"> + <property name="name"> + <cstring>Layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + + <widget class="QPushButton"> + <property name="name"> + <cstring>icon_button</cstring> + </property> + <property name="maximumSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + <property name="text"> + <string></string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + <spacer> + <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>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="KLineEdit" row="2" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>comment_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="1" column="1"> + <property name="name"> + <cstring>name_edit</cstring> + </property> + </widget> + <widget class="QComboBox" row="0" column="3"> + <property name="name"> + <cstring>library_combo</cstring> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="0" column="2"> + <property name="name"> + <cstring>library_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&Library:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>library_combo</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>filename_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&File name:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>filename_edit</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>name_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&Name:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>name_edit</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>comment_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Co&mment:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>comment_edit</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>GroupBox2</cstring> + </property> + <property name="title"> + <string>Service &Types</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + + <widget class="QLayoutWidget" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + + <widget class="QListView"> + <column> + <property name="text"> + <string></string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>chosentypes_listview</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + + <spacer> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>add_button</cstring> + </property> + <property name="text"> + <string><-</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>remove_button</cstring> + </property> + <property name="text"> + <string>-></string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QListView"> + <column> + <property name="text"> + <string></string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>availtypes_listview</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + </hbox> + </widget> + <widget class="QListView" row="1" column="1"> + <column> + <property name="text"> + <string>Property</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>properties_listview</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="resizeMode"> + <enum>AllColumns</enum> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>properties_label</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&Properties:</string> + </property> + <property name="alignment"> + <set>AlignTop|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>properties_listview</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>okbutton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelbutton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>okbutton</sender> + <signal>clicked()</signal> + <receiver>add_service_dialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>cancelbutton</sender> + <signal>clicked()</signal> + <receiver>add_service_dialog</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>remove_button</sender> + <signal>clicked()</signal> + <receiver>add_service_dialog</receiver> + <slot>removeTypeClicked()</slot> + </connection> + <connection> + <sender>properties_listview</sender> + <signal>doubleClicked(QListViewItem*)</signal> + <receiver>add_service_dialog</receiver> + <slot>propertyExecuted(QListViewItem*)</slot> + </connection> + <connection> + <sender>properties_listview</sender> + <signal>returnPressed(QListViewItem*)</signal> + <receiver>add_service_dialog</receiver> + <slot>propertyExecuted(QListViewItem*)</slot> + </connection> + <connection> + <sender>icon_button</sender> + <signal>clicked()</signal> + <receiver>add_service_dialog</receiver> + <slot>iconClicked()</slot> + </connection> + <connection> + <sender>add_button</sender> + <signal>clicked()</signal> + <receiver>add_service_dialog</receiver> + <slot>addTypeClicked()</slot> + </connection> +</connections> +<tabstops> + <tabstop>filename_edit</tabstop> + <tabstop>library_combo</tabstop> + <tabstop>name_edit</tabstop> + <tabstop>icon_button</tabstop> + <tabstop>comment_edit</tabstop> + <tabstop>chosentypes_listview</tabstop> + <tabstop>add_button</tabstop> + <tabstop>remove_button</tabstop> + <tabstop>availtypes_listview</tabstop> + <tabstop>properties_listview</tabstop> + <tabstop>okbutton</tabstop> + <tabstop>cancelbutton</tabstop> +</tabstops> +<slots> + <slot access="protected">iconClicked()</slot> + <slot access="protected">addTypeClicked()</slot> + <slot access="protected">propertyExecuted(QListViewItem*)</slot> + <slot access="protected">removeTypeClicked()</slot> +</slots> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +</UI> diff --git a/buildtools/autotools/addsubprojectdlg.cpp b/buildtools/autotools/addsubprojectdlg.cpp new file mode 100644 index 00000000..8011886b --- /dev/null +++ b/buildtools/autotools/addsubprojectdlg.cpp @@ -0,0 +1,198 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "addsubprojectdlg.h" + +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qstringlist.h> +#include <qtextstream.h> +#include <kbuttonbox.h> +#include <kdebug.h> +#include <kfiledialog.h> +#include <kiconloader.h> +#include <klineedit.h> +#include <kmessagebox.h> + +#include "autolistviewitems.h" + +#include "kdevmakefrontend.h" +#include "misc.h" +#include "autoprojectpart.h" +#include "autosubprojectview.h" + + +AddSubprojectDialog::AddSubprojectDialog(AutoProjectPart *part, AutoSubprojectView *view, + SubprojectItem *item, QWidget *parent, const char *name) + : AddSubprojectDlgBase(parent, name, true) +{ + setIcon(SmallIcon("folder_new.png")); + + connect( createButton, SIGNAL(clicked()), this, SLOT(accept()) ); + connect( cancelButton, SIGNAL(clicked()), this, SLOT(reject()) ); + + m_subProject = item; + m_subprojectView = view; + m_part = part; +} + + +AddSubprojectDialog::~AddSubprojectDialog() +{} + + +void AddSubprojectDialog::accept() +{ + QString name = spEdit->text().stripWhiteSpace(); + + if (name.isEmpty()) { + KMessageBox::sorry(this, i18n("You have to give the subproject a name.")); + return; + } + + QListViewItem *childItem = m_subProject->firstChild(); + while (childItem) { + if (name == static_cast<SubprojectItem*>(childItem)->subdir) { + KMessageBox::sorry(this, i18n("A subproject with this name already exists.")); + return; + } + childItem = childItem->nextSibling(); + } + + +#if 0 + // check for config.status + if( !QFileInfo(m_part->projectDirectory(), "config.status").exists() ){ + KMessageBox::sorry(this, i18n("There is no config.status in the project root directory. Run 'Configure' first")); + QDialog::accept(); + return; + } +#endif + + QDir dir( m_subProject->path ); + QFileInfo file( dir, name ); + + if( file.exists() && !file.isDir() ) { + KMessageBox::sorry(this, i18n("A file named %1 already exists.").arg(name)); + QDialog::accept(); + return; + } else if( file.isDir() ) { + if( KMessageBox::warningContinueCancel(this, + i18n("A subdirectory %1 already exists. " + "Do you wish to add it as a subproject?").arg(name)) + == KMessageBox::Cancel ){ + QDialog::accept(); + return; + } + } else if (!dir.mkdir(name)) { + KMessageBox::sorry(this, i18n("Could not create subdirectory %1.").arg(name)); + QDialog::accept(); + return; + } + + if(!dir.cd(name)) { + KMessageBox::sorry(this, i18n("Could not access the subdirectory %1.").arg(name)); + QDialog::accept(); + return; + } + + // Adjust SUBDIRS variable in containing Makefile.am + if (m_subProject->variables["SUBDIRS"].find("$(TOPSUBDIRS)") != -1) + { + QFile subdirsfile( m_subProject->path + "/subdirs" ); + if ( subdirsfile.open( IO_WriteOnly | IO_Append ) ) + { + QTextStream subdirsstream( &subdirsfile ); + subdirsstream << name << endl; + subdirsfile.close(); + } + } + else if (m_subProject->variables["SUBDIRS"].find("$(AUTODIRS)") != -1) + { + } + else + { + m_subProject->variables["SUBDIRS"] += (" " + name); + QMap<QString,QString> replaceMap; + replaceMap.insert("SUBDIRS", m_subProject->variables["SUBDIRS"]); + AutoProjectTool::addToMakefileam(m_subProject->path + "/Makefile.am", replaceMap); + } + + // Create new item in tree view + SubprojectItem *newitem = new SubprojectItem(m_subProject, name); + newitem->subdir = name; + newitem->path = m_subProject->path + "/" + name; + newitem->variables["INCLUDES"] = m_subProject->variables["INCLUDES"]; + newitem->setOpen(true); + + // Move to the bottom of the list + QListViewItem *lastItem = m_subProject->firstChild(); + while (lastItem->nextSibling()) + lastItem = lastItem->nextSibling(); + if (lastItem != newitem) + newitem->moveItem(lastItem); + + // Create a Makefile in the new subdirectory + + QFile f( dir.filePath("Makefile.am") ); + if (f.exists()) { + m_subprojectView->parse( newitem ); + } else { + if (!f.open(IO_WriteOnly)) { + KMessageBox::sorry(this, i18n("Could not create Makefile.am in subdirectory %1.").arg(name)); + return; + } + QTextStream stream(&f); + stream << "INCLUDES = " << newitem->variables["INCLUDES"] << endl << "METASOURCES = AUTO" << endl; + f.close(); + } + + + + // if !isKDE: add the new sub-proj to configure.in + if ( !m_part->isKDE() ) { + QString projroot = m_part->projectDirectory() + "/"; + QString subdirectory = dir.path(); + QString relpath = subdirectory.replace(0, projroot.length(),""); + + QString configureFile = m_part->getAutoConfFile(projroot); + + QStringList list = AutoProjectTool::configureinLoadMakefiles(configureFile); + if ( !list.isEmpty() ) + { + list.push_back( relpath + "/Makefile" ); + AutoProjectTool::configureinSaveMakefiles(configureFile, list); + } + } + +#if 0 + QString relmakefile = (m_subProject->path + "/" + name + "/Makefile").mid(m_part->projectDirectory().length()+1); + kdDebug(9020) << "Relative makefile path: " << relmakefile << endl; + + QString cmdline = "cd "; + cmdline += KProcess::quote(m_part->projectDirectory()); + cmdline += " && automake "; + cmdline += KProcess::quote(relmakefile); + cmdline += " && CONFIG_HEADERS=config.h CONFIG_FILES="; + cmdline += KProcess::quote(relmakefile); + cmdline += " ./config.status"; + + m_part->makeFrontend()->queueCommand( m_part->projectDirectory(), cmdline ); + m_part->makeFrontend()->queueCommand( m_part->projectDirectory(), m_part->configureCommand() ); +#endif + + m_part->needMakefileCvs(); + + QDialog::accept(); +} + +#include "addsubprojectdlg.moc" diff --git a/buildtools/autotools/addsubprojectdlg.h b/buildtools/autotools/addsubprojectdlg.h new file mode 100644 index 00000000..eabfc0e1 --- /dev/null +++ b/buildtools/autotools/addsubprojectdlg.h @@ -0,0 +1,44 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#ifndef _ADDSUBPROJECTDLG_H_ +#define _ADDSUBPROJECTDLG_H_ + +#include <qdialog.h> +#include <klineedit.h> + +#include "addsubprojectdlgbase.h" + +class AutoProjectPart; +class AutoSubprojectView; +class SubprojectItem; + + +class AddSubprojectDialog : public AddSubprojectDlgBase +{ + Q_OBJECT + +public: + AddSubprojectDialog( AutoProjectPart *part, AutoSubprojectView *widget, + SubprojectItem *item, QWidget *parent = 0, const char *name = 0 ); + ~AddSubprojectDialog(); + +private: + virtual void accept(); + + KLineEdit *name_edit; + + SubprojectItem *m_subProject; + AutoSubprojectView *m_subprojectView; + AutoProjectPart *m_part; +}; + +#endif diff --git a/buildtools/autotools/addsubprojectdlgbase.ui b/buildtools/autotools/addsubprojectdlgbase.ui new file mode 100644 index 00000000..b4c762b1 --- /dev/null +++ b/buildtools/autotools/addsubprojectdlgbase.ui @@ -0,0 +1,198 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>AddSubprojectDlgBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>AddSubprojectDlgBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>445</width> + <height>126</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>32767</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="caption"> + <string>Add New Subproject</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox" row="0" column="0"> + <property name="name"> + <cstring>fileGroupBox</cstring> + </property> + <property name="title"> + <string>Subproject</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>spStaticLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Subproject &name:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>spEdit</cstring> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>spEdit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget" row="2" column="0"> + <property name="name"> + <cstring>buttonLayout</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>buttonSpacer</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>createButton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelButton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<tabstops> + <tabstop>spEdit</tabstop> + <tabstop>createButton</tabstop> + <tabstop>cancelButton</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">klineedit.h</include> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/buildtools/autotools/addtargetdlg.cpp b/buildtools/autotools/addtargetdlg.cpp new file mode 100644 index 00000000..b01b5b82 --- /dev/null +++ b/buildtools/autotools/addtargetdlg.cpp @@ -0,0 +1,226 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "addtargetdlg.h" + +#include <qcheckbox.h> +#include <qcombobox.h> +#include <qgroupbox.h> +#include <qvalidator.h> + +#include <klineedit.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <ksqueezedtextlabel.h> + +#include "autolistviewitems.h" + +#include "misc.h" +#include "autodetailsview.h" +#include "autoprojectwidget.h" + + +AddTargetDialog::AddTargetDialog(AutoProjectWidget *widget, SubprojectItem *item, + QWidget *parent, const char *name) + : AddTargetDialogBase(parent, name, true) +{ + m_subproject = item; + m_widget = widget; +// m_detailsView = view; + + primary_combo->setFocus(); + primary_combo->insertItem(i18n("Program")); + primary_combo->insertItem(i18n("Library")); + primary_combo->insertItem(i18n("Libtool Library")); + primary_combo->insertItem(i18n("Script")); + primary_combo->insertItem(i18n("Header")); + primary_combo->insertItem(i18n("Data File")); + primary_combo->insertItem(i18n("Java")); + + primaryChanged(); // updates prefix combo + + if (widget->kdeMode()) + ldflagsother_edit->setText("$(all_libraries)"); + + connect( filename_edit, SIGNAL( textChanged(const QString&) ), this, SLOT( slotFileNameChanged (const QString&) ) ); + + setIcon ( SmallIcon ( "targetnew_kdevelop.png" ) ); + + canonicalLabel->setText ( QString::null ); +} + + +AddTargetDialog::~AddTargetDialog() +{} + + +void AddTargetDialog::primaryChanged() +{ + QStringList list; + switch (primary_combo->currentItem()) { + case 0: // Program + list.append("bin"); + list.append("sbin"); + list.append("libexec"); + list.append("pkglib"); + list.append("noinst"); + break; + case 1: // Library + case 2: // Libtool library + list.append("lib"); + list.append("pkglib"); + list.append("noinst"); + if (m_widget->kdeMode()) + list.append("kde_module"); + break; + case 3: // Script + list.append("bin"); + list.append("sbin"); + list.append("libexec"); + list.append("pkgdata"); + list.append("noinst"); + break; + case 4: // Header + list.append("include"); + list.append("oldinclude"); + list.append("pkginclude"); + list.append("noinst"); + break; + case 5: // Data + list.append("bin"); + list.append("sbin"); + list.append("noinst"); + break; + case 6: // Java + list.append("java"); + list.append("noinst"); + break; + } + + prefix_combo->clear(); + + prefix_combo->insertStringList(list); + QStringList prefixes; + QMap<QString,QString>::ConstIterator it; + for (it = m_subproject->prefixes.begin(); it != m_subproject->prefixes.end(); ++it) + prefix_combo->insertItem(it.key()); + + // Only enable ldflags stuff for libtool libraries + bool lt = primary_combo->currentItem() == 2; + bool prog = primary_combo->currentItem() == 0; + allstatic_box->setEnabled(lt); + avoidversion_box->setEnabled(lt); + module_box->setEnabled(lt); + noundefined_box->setEnabled(lt); + ldflagsother_edit->setEnabled(lt || prog); +} + + +void AddTargetDialog::accept() +{ + QString name = filename_edit->text().stripWhiteSpace(); + QString prefix = prefix_combo->currentText(); + + QString primary; + switch (primary_combo->currentItem()) { + case 0: primary = "PROGRAMS"; break; + case 1: primary = "LIBRARIES"; break; + case 2: primary = "LTLIBRARIES"; break; + case 3: primary = "SCRIPTS"; break; + case 4: primary = "HEADERS"; break; + case 5: primary = "DATA"; break; + case 6: primary = "JAVA"; break; + default: ; + } + + if (name.isEmpty()) { + KMessageBox::sorry(this, i18n("You have to give the target a name")); + return; + } + +#if 0 + if (primary == "LIBRARIES" && !name.startsWith("lib")) { + KMessageBox::sorry(this, i18n("Libraries must have a lib prefix.")); + return; + } + + if (primary == "LTLIBRARIES" && !name.startsWith("lib")) { + KMessageBox::sorry(this, i18n("Libtool libraries must have a lib prefix.")); + return; + } + + if (primary == "LTLIBRARIES" && name.right(3) != ".la") { + KMessageBox::sorry(this, i18n("Libtool libraries must have a .la suffix.")); + return; + } + +#endif + + if( primary.endsWith("LIBRARIES") && !name.startsWith("lib") && !module_box->isChecked() ) + name.prepend( QString::fromLatin1("lib") ); + + if( primary == "LTLIBRARIES" && !name.endsWith(".la") ) + name.append( QString::fromLatin1(".la") ); + + if ( primary == "LIBRARIES" && !name.endsWith(".a") ) + name.append ( QString::fromLatin1(".a") ); + + QPtrListIterator<TargetItem> it(m_subproject->targets); + for (; it.current(); ++it) + if (name == (*it)->name) { + KMessageBox::sorry(this, i18n("A target with this name already exists.")); + return; + } + + QStringList flagslist; + if (primary == "LTLIBRARIES") { + if (allstatic_box->isChecked()) + flagslist.append("-all-static"); + if (avoidversion_box->isChecked()) + flagslist.append("-avoid-version"); + if (module_box->isChecked()) + flagslist.append("-module"); + if (noundefined_box->isChecked()) + flagslist.append("-no-undefined"); + } + flagslist.append(ldflagsother_edit->text()); + QString ldflags = flagslist.join( " " ); + + TargetItem *titem = m_widget->createTargetItem(name, prefix, primary, false); + // m_detailsView->insertItem ( titem ); + m_subproject->targets.append(titem); + + QString canonname = AutoProjectTool::canonicalize(name); + + QMap<QString,QString> replaceMap; + + if( primary == "PROGRAMS" || primary == "LIBRARIES" || primary == "LTLIBRARIES" || primary == "DATA" ){ + QString varname = prefix + "_" + primary; + m_subproject->variables[varname] += (" " + name); + replaceMap.insert(varname, m_subproject->variables[varname]); + if ( primary != "DATA" ){ + replaceMap.insert(canonname + "_SOURCES", ""); + } + } + if (primary == "LTLIBRARIES" || primary == "PROGRAMS") + replaceMap.insert(canonname + "_LDFLAGS", ldflags); + + AutoProjectTool::addToMakefileam(m_subproject->path + "/Makefile.am", replaceMap); + + QDialog::accept(); +} + +void AddTargetDialog::slotFileNameChanged ( const QString& text ) +{ + canonicalLabel->setText ( AutoProjectTool::canonicalize ( text ) ); +} + +#include "addtargetdlg.moc" diff --git a/buildtools/autotools/addtargetdlg.h b/buildtools/autotools/addtargetdlg.h new file mode 100644 index 00000000..98708531 --- /dev/null +++ b/buildtools/autotools/addtargetdlg.h @@ -0,0 +1,43 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#ifndef _ADDTARGETDLG_H_ +#define _ADDTARGETDLG_H_ + +#include "addtargetdlgbase.h" + +class AutoDetailsView; +class AutoProjectWidget; +class SubprojectItem; + + +class AddTargetDialog : public AddTargetDialogBase +{ + Q_OBJECT + +public: + AddTargetDialog( AutoProjectWidget *widget, SubprojectItem *item, + QWidget *parent = 0, const char *name = 0 ); + ~AddTargetDialog(); + +protected slots: + virtual void slotFileNameChanged ( const QString& ); + +private: + virtual void primaryChanged(); + virtual void accept(); + + SubprojectItem *m_subproject; + AutoProjectWidget *m_widget; + AutoDetailsView* m_detailsView; +}; + +#endif diff --git a/buildtools/autotools/addtargetdlgbase.ui b/buildtools/autotools/addtargetdlgbase.ui new file mode 100644 index 00000000..25687563 --- /dev/null +++ b/buildtools/autotools/addtargetdlgbase.ui @@ -0,0 +1,348 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>AddTargetDialogBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>add_target_dialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>585</width> + <height>356</height> + </rect> + </property> + <property name="caption"> + <string>Add New Target</string> + </property> + <property name="sizeGripEnabled"> + <bool>false</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox2</cstring> + </property> + <property name="title"> + <string>&Target</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>primary_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&Primary:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>primary_combo</cstring> + </property> + </widget> + <widget class="QComboBox" row="0" column="1"> + <property name="name"> + <cstring>primary_combo</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>prefix_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Pre&fix:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>prefix_combo</cstring> + </property> + </widget> + <widget class="QComboBox" row="1" column="1"> + <property name="name"> + <cstring>prefix_combo</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>filename_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>File &name:</string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignRight</set> + </property> + <property name="buddy" stdset="0"> + <cstring>filename_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>filename_edit</cstring> + </property> + </widget> + <spacer row="1" column="2" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Spacer21</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>246</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KSqueezedTextLabel" row="2" column="3"> + <property name="name"> + <cstring>canonicalLabel</cstring> + </property> + <property name="text"> + <string>[CANONICALIZED NAME]</string> + </property> + </widget> + <widget class="QLabel" row="2" column="2"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="font"> + <font> + <bold>1</bold> + </font> + </property> + <property name="text"> + <string></string> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + </widget> + </grid> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer22</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QGroupBox"> + <property name="name"> + <cstring>ldflags_group</cstring> + </property> + <property name="title"> + <string>Linker Flags (&LDFLAGS)</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>allstatic_box</cstring> + </property> + <property name="text"> + <string>Do not link against shared libraries (-all-static)</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>avoidversion_box</cstring> + </property> + <property name="text"> + <string>Do not assign version numbers to libraries (-avoid-version)</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>module_box</cstring> + </property> + <property name="text"> + <string>Create a library that can be dynamically loaded (-module)</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>noundefined_box</cstring> + </property> + <property name="text"> + <string>Library does not depend on external symbols (-no-undefined)</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout11_2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>ldflagsother_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Ot&her:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>ldflagsother_edit</cstring> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>ldflagsother_edit</cstring> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>okbutton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelbutton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<images> + <image name="image0"> + <data format="XPM.GZ" length="394">789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523234530022230543251d2e253d856405bffcbc54105b19c856360003b0141ac02ba68c4d4c199b98323631656c62cad8c494891423ce0ee2dc4c6418208bd55a7301009c7f45ef</data> + </image> +</images> +<connections> + <connection> + <sender>okbutton</sender> + <signal>clicked()</signal> + <receiver>add_target_dialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>cancelbutton</sender> + <signal>clicked()</signal> + <receiver>add_target_dialog</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>primary_combo</sender> + <signal>activated(int)</signal> + <receiver>add_target_dialog</receiver> + <slot>primaryChanged()</slot> + </connection> +</connections> +<tabstops> + <tabstop>primary_combo</tabstop> + <tabstop>prefix_combo</tabstop> + <tabstop>filename_edit</tabstop> + <tabstop>allstatic_box</tabstop> + <tabstop>avoidversion_box</tabstop> + <tabstop>module_box</tabstop> + <tabstop>noundefined_box</tabstop> + <tabstop>ldflagsother_edit</tabstop> + <tabstop>okbutton</tabstop> + <tabstop>cancelbutton</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<slots> + <slot access="protected">primaryChanged()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>ksqueezedtextlabel.h</includehint> +</includehints> +</UI> diff --git a/buildtools/autotools/addtranslationdlg.cpp b/buildtools/autotools/addtranslationdlg.cpp new file mode 100644 index 00000000..993dee7d --- /dev/null +++ b/buildtools/autotools/addtranslationdlg.cpp @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "addtranslationdlg.h" + +#include <qcombobox.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qhbox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qpushbutton.h> +#include <qstrlist.h> +#include <kbuttonbox.h> +#include <kdialog.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kstdguiitem.h> +#include <kdeversion.h> + +#include "misc.h" +#include "autoprojectpart.h" + + +AddTranslationDialog::AddTranslationDialog(AutoProjectPart *part, QWidget *parent, const char *name) + : QDialog(parent, name, true) +{ + setCaption(i18n("Add Translation")); + + m_part = part; + + QHBox *hbox = new QHBox(this); + (void) new QLabel(i18n("Language:"), hbox); + lang_combo = new QComboBox(hbox); + + QVBoxLayout *layout = new QVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint()); + layout->addWidget(hbox); + + QFrame *frame = new QFrame(this); + frame->setFrameStyle(QFrame::HLine | QFrame::Sunken); + layout->addWidget(frame, 0); + + KButtonBox *buttonbox = new KButtonBox(this); + buttonbox->addStretch(); + QPushButton *ok_button = buttonbox->addButton(KStdGuiItem::ok()); + QPushButton *cancel_button = buttonbox->addButton(KStdGuiItem::cancel()); + ok_button->setDefault(true); + connect( ok_button, SIGNAL(clicked()), this, SLOT(accept()) ); + connect( cancel_button, SIGNAL(clicked()), this, SLOT(reject()) ); + buttonbox->layout(); + layout->addWidget(buttonbox, 0); + + QStringList rawlist, list; + rawlist << "af" << "ar" << "bg" << "bo" << "br" << "bs" << "ca" << "cs" << "cy" << "da" + << "de" << "el" << "en_GB" << "eo" << "es" << "et" << "eu" << "fi" << "fr"; + rawlist << "ga" << "gl" << "gu" << "he" << "hi" << "hu" << "id" << "is" << "it" << "ja" + << "km" << "ko" << "lt" << "lv" << "mi" << "mk" << "mr" << "nl" << "no" << "no_NY"; + rawlist << "oc" << "pl" << "pt" << "pt_BR" << "ro" << "ru" << "sk" << "sl" << "sr" << "sv" + << "ta" << "th" << "tr" << "uk" << "wa" << "zh_CN.GB2312" << "zh_TW.Big5"; + + // Remove already added languages + QStringList::ConstIterator it; + for (it = rawlist.begin(); it != rawlist.end(); ++it) { + QFileInfo fi(m_part->projectDirectory() + "/po/" + (*it) + ".po"); + if (!fi.exists()) + list.append(*it); + } + + if (list.isEmpty()) { + KMessageBox::information(this, i18n("Your sourcecode is already translated to all supported languages.")); + ok_button->setEnabled(false); + } + lang_combo->insertStringList(list); +} + + +AddTranslationDialog::~AddTranslationDialog() +{} + + +void AddTranslationDialog::accept() +{ + QString dir = m_part->projectDirectory() + "/po"; + QString fileName = dir + "/" + lang_combo->currentText() + ".po"; + + QFile f(fileName); + if (f.exists()) { + KMessageBox::information(this, i18n("A translation file for the language %1 exists already.")); + return; + } + f.open(IO_WriteOnly); + f.close(); + + dir = m_part->buildDirectory() + "/po"; + m_part->startMakeCommand(dir, QString::fromLatin1("force-reedit")); + + QDialog::accept(); +} + +#include "addtranslationdlg.moc" diff --git a/buildtools/autotools/addtranslationdlg.h b/buildtools/autotools/addtranslationdlg.h new file mode 100644 index 00000000..cd14ddf2 --- /dev/null +++ b/buildtools/autotools/addtranslationdlg.h @@ -0,0 +1,36 @@ +/*************************************************************************** +* Copyright (C) 1999 by Sandy Meier * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#ifndef _ADDTRANSLATIONDLG_H_ +#define _ADDTRANSLATIONDLG_H_ + +#include <qdialog.h> + +class QComboBox; +class AutoProjectPart; + + +class AddTranslationDialog : public QDialog +{ + Q_OBJECT + +public: + AddTranslationDialog( AutoProjectPart *part, QWidget *parent = 0, const char *name = 0 ); + ~AddTranslationDialog(); + +private: + virtual void accept(); + + QComboBox *lang_combo; + AutoProjectPart *m_part; +}; + +#endif diff --git a/buildtools/autotools/autodetailsview.cpp b/buildtools/autotools/autodetailsview.cpp new file mode 100644 index 00000000..26255fd3 --- /dev/null +++ b/buildtools/autotools/autodetailsview.cpp @@ -0,0 +1,728 @@ +/* + KDevelop Autotools Support + Copyright (c) 2002 by Victor Roeder <victor_roeder@gmx.de> + Copyright (c) 2005 by Matt Rogers <mattr@kde.org> + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + *************************************************************************** +*/ + +#include "autodetailsview.h" + +/** Qt */ +#include <qregexp.h> +#include <qlistview.h> +#include <qwidget.h> +#include <qheader.h> +#include <qlayout.h> + + /** KDE Libs */ +#include <kxmlguiclient.h> +#include <kaction.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <klocale.h> +#include <klistview.h> +#include <kpopupmenu.h> + +/** KDevelop */ +#include "kdevappfrontend.h" +#include "kdevcore.h" +#include "kdevmainwindow.h" +#include "kdevpartcontroller.h" +#include "kdevcreatefile.h" +#include "kdevlanguagesupport.h" +#include "kdevmakefrontend.h" +#include "urlutil.h" + +#include "domutil.h" + +#include "targetoptionsdlg.h" +#include "addfiledlg.h" +#include "addicondlg.h" +#include "addexistingfilesdlg.h" +#include "removefiledlg.h" +#include "removetargetdlg.h" + +#include "autolistviewitems.h" +#include "autotoolsaction.h" +#include "autoprojectpart.h" +#include "autoprojectwidget.h" + +#include "subclassesdlg.h" + +AutoDetailsView::AutoDetailsView(AutoProjectWidget* widget, AutoProjectPart* part, QWidget *parent, const char *name) + : AutoProjectViewBase(parent, name) +{ + m_widget = widget; + m_part = part; + + initActions(); + QDomDocument dom = *(m_part->projectDom()); + m_subclasslist = DomUtil::readPairListEntry(dom, "/kdevautoproject/subclassing", + "subclass","sourcefile", "uifile"); + + m_listView->setAllColumnsShowFocus( true ); + m_listView->setRootIsDecorated( true ); + m_listView->setResizeMode( QListView::LastColumn ); + m_listView->addColumn( QString::null ); + m_listView->header()->hide(); + targetOptionsAction->setEnabled( false ); + addNewFileAction->setEnabled( false ); + addExistingFileAction->setEnabled( false ); + buildTargetAction->setEnabled( false ); + executeTargetAction->setEnabled( false ); + removeDetailAction->setEnabled(false); + connect( m_listView, SIGNAL( selectionChanged( QListViewItem* ) ), + this, SLOT( slotSelectionChanged( QListViewItem* ) ) ); + connect( m_listView, SIGNAL( selectionChanged() ), + this, SLOT( slotSelectionChanged( ) ) ); +} + + +AutoDetailsView::~AutoDetailsView() +{ +} + +/** + * If nothing selected, disable all the icons. + */ +void AutoDetailsView::slotSelectionChanged( ){ + + if ( m_listView->selectedItems().isEmpty()){ + targetOptionsAction->setEnabled( false ); + addNewFileAction->setEnabled( false ); + addExistingFileAction->setEnabled( false ); + buildTargetAction->setEnabled( false ); + executeTargetAction->setEnabled( false ); + removeDetailAction->setEnabled(false); + } +} + +/** + * Change the enabled icons depending on what is selected. + * This is never called if nothing is selected.. + * @param item + */ +void AutoDetailsView::slotSelectionChanged( QListViewItem* item ) +{ + bool isTarget = false; + bool isRegularTarget = false; + bool isFile = false; + bool isProgram = false; + + if ( item ) + { + // We assume here that ALL items in the detail list view + // are ProjectItem's + ProjectItem * pvitem = static_cast<ProjectItem*>( item ); + TargetItem* titem = 0; + + if ( pvitem->type() == ProjectItem::File ) + { + titem = static_cast <TargetItem*> ( pvitem->parent() ); + + QString primary = titem->primary; + if ( primary == "PROGRAMS" || primary == "LIBRARIES" || + primary == "LTLIBRARIES" || primary == "JAVA" ) + { + isRegularTarget = true; // not a data group + isFile = true; + } + } + else + { + titem = static_cast <TargetItem*> ( pvitem ); + isTarget = true; + } + + QString primary = titem->primary; + if ( primary == "PROGRAMS" || primary == "LIBRARIES" || + primary == "LTLIBRARIES" || primary == "JAVA" ) + { + isRegularTarget = true; // not a data group + } + + if ( primary == "PROGRAMS" ) + isProgram = true; + } + + targetOptionsAction->setEnabled( isRegularTarget && !isFile ); + addNewFileAction->setEnabled( isTarget ); + addExistingFileAction->setEnabled( isTarget ); + removeDetailAction->setEnabled ( true ); + + if ( isRegularTarget && isFile || isRegularTarget ) + { + buildTargetAction->setEnabled ( true ); + if( isProgram ) + executeTargetAction->setEnabled ( true ); + } + else + { + buildTargetAction->setEnabled ( false ); + executeTargetAction->setEnabled ( false ); + } + emit selectionChanged( item ); +} + +void AutoDetailsView::initActions() +{ + KActionCollection * actions = new KActionCollection( this ); + + targetOptionsAction = new AutoToolsAction( i18n( "Options..." ), "configure", 0, + this, SLOT( slotTargetOptions() ), actions, + "target options" ); + targetOptionsAction->setWhatsThis(i18n("<b>Options</b><p>Target options dialog that " + "provides settings for linker flags and lists " + "of dependencies and external libraries that " + "are used when compiling the target.")); + targetOptionsAction->plug( m_optionsButton ); + targetOptionsAction->setEnabled( false ); + + QToolTip::add( m_button1, tr2i18n( "Create New File..." ) ); + addNewFileAction = new AutoToolsAction( i18n( "Create New File..." ), "filenew", 0, + this, SLOT( slotAddNewFile() ), actions, + "add new file" ); + addNewFileAction->setWhatsThis(i18n("<b>Create new file</b><p>Creates a new file and " + "adds it to a currently selected target.")); + addNewFileAction->plug( m_button1 ); + addNewFileAction->setEnabled( false ); + + QToolTip::add( m_button2, tr2i18n( "Add Existing Files..." ) ); + addExistingFileAction = new AutoToolsAction( i18n( "Add Existing Files..." ), "fileimport", 0, + this, SLOT( slotAddExistingFile() ), actions, + "add existing file" ); + addExistingFileAction->setWhatsThis(i18n("<b>Add existing files</b><p>Adds existing " + "file to a currently selected target. Header " + "files will not be included in SOURCES list " + "of a target. They will be added to " + "noinst_HEADERS instead.")); + addExistingFileAction->plug( m_button2 ); + addExistingFileAction->setEnabled( false ); + + addIconAction = new KAction( i18n( "Add Icon..." ), "iconadd_kdevelop", 0, + this, SLOT( slotAddIcon() ), actions, "add icon" ); + addIconAction->setWhatsThis(i18n("<b>Add icon</b><p>Adds an icon to a KDEICON target.")); + + QToolTip::add( m_button4, tr2i18n( "Build Target")); + buildTargetAction = new AutoToolsAction( i18n( "Build Target..." ), "launch", 0, + this, SLOT( slotBuildTarget() ), actions, + "build target" ); + buildTargetAction->setWhatsThis(i18n("<b>Build target</b><p>Constructs a series of " + "make commands to build the selected target. " + "Also builds dependent targets.")); + buildTargetAction->plug( m_button4 ); + buildTargetAction->setEnabled( false ); + + QToolTip::add( m_button5, tr2i18n( "Execute Target...")); + executeTargetAction = new AutoToolsAction( i18n( "Execute Target..." ), "exec", 0, + this, SLOT( slotExecuteTarget() ), actions, + "execute target" ); + executeTargetAction->setWhatsThis(i18n("<b>Execute target</b><p>Executes the target " + "and tries to build in case it is not built.")); + executeTargetAction->plug( m_button5 ); + executeTargetAction->setEnabled( false ); + + setActiveTargetAction = new KAction( i18n( "Make Target Active" ), "", 0, + this, SLOT( slotSetActiveTarget() ), actions, + "set active target" ); + setActiveTargetAction->setWhatsThis(i18n("<b>Make target active</b><p>Marks the " + "currently selected target as 'active'. New " + "files and classes by default go to an active " + "target. " + "Using the <b>Build Active Target</b> menu " + "command builds it.")); + + QToolTip::add( m_button3, tr2i18n( "Remove")); + removeDetailAction = new AutoToolsAction( i18n( "Remove" ), "editdelete", 0, this, + SLOT( slotRemoveDetail() ), actions, + "remove detail" ); + removeDetailAction->setWhatsThis(i18n("<b>Remove</b><p>Shows a list of targets " + "dependent on the selected target or file and " + "asks for removal. Also asks if the target or " + "file should be removed from disk.")); + removeDetailAction->plug( m_button3 ); + removeDetailAction->setEnabled( false ); + + connect( m_listView, SIGNAL( executed( QListViewItem* ) ), + this, SLOT( slotDetailsExecuted( QListViewItem* ) ) ); + connect( m_listView, SIGNAL( returnPressed( QListViewItem* ) ), + this, SLOT( slotDetailsExecuted( QListViewItem* ) ) ); + connect( m_listView, SIGNAL( contextMenu( KListView*, QListViewItem*, const QPoint& ) ), + this, SLOT( slotDetailsContextMenu( KListView*, QListViewItem*, const QPoint& ) ) ); +} + +QString AutoDetailsView::getUiFileLink(const QString& relpath, const QString& filename) +{ + DomUtil::PairList::iterator it; + + for (it=m_subclasslist.begin(); it != m_subclasslist.end(); ++it) + { + if ((*it).first == QString("/")+relpath+filename) + return (*it).second; + } + + return QString::null; +} + +void AutoDetailsView::slotTargetOptions() +{ + kdDebug( 9020 ) << "AutoDetailsView::slotTargetOptions()" << endl; + TargetItem *titem = dynamic_cast <TargetItem*> ( m_listView->selectedItem() ); + + if ( !titem ) + return; + + TargetOptionsDialog dlg( m_widget, titem, this, "target options dialog" ); + + dlg.setCaption ( i18n ( "Target Options for '%1'" ).arg ( titem->name ) ); + + dlg.exec(); +} + + +void AutoDetailsView::slotAddNewFile() +{ + TargetItem * titem = dynamic_cast <TargetItem*> ( m_listView->selectedItem() ); + if ( !titem ) + return; + + KDevCreateFile * createFileSupport = m_part->extension<KDevCreateFile>("KDevelop/CreateFile"); + if (createFileSupport) + { + KDevCreateFile::CreatedFile crFile = + createFileSupport->createNewFile(QString::null, + m_widget->selectedSubproject()->path); +/* if (crFile.status == KDevCreateFile::CreatedFile::STATUS_OK) + { + FileItem *fitem = m_widget->createFileItem(crFile.filename, m_widget->selectedSubproject()); + titem->sources.append(fitem); + titem->insertItem(fitem); + emit selectionChanged( titem ); // update list view + }*/ + } else { + AddFileDialog dlg( m_part, m_widget, m_widget->selectedSubproject(), titem, + this, "add file dialog" ); + QString caption; + if ( titem->name.isEmpty() ) + caption = i18n ( "%1 in %2" ).arg ( titem->primary ).arg ( titem->prefix ); + else + caption = titem->name; + + dlg.setCaption ( i18n ( "Add New File to '%1'" ).arg ( caption ) ); + + if ( dlg.exec() ) + emit selectionChanged( titem ); // update list view + } +} + + +void AutoDetailsView::slotAddExistingFile() +{ + TargetItem * titem = dynamic_cast <TargetItem*> ( m_listView->selectedItem() ); + if ( !titem ) + return; + + AddExistingFilesDialog dlg( m_part, m_widget, m_widget->selectedSubproject(), titem, + this, "add existing files" ); + QString caption; + if ( titem->name.isEmpty() ) + caption = i18n ( "%1 in %2" ).arg ( titem->primary ).arg ( titem->prefix ); + else + caption = titem->name; + + dlg.setCaption( i18n( "Add Existing Files to '%1'" ).arg ( caption ) ); + + dlg.exec(); +} + + +void AutoDetailsView::slotAddIcon() +{ + TargetItem * titem = dynamic_cast <TargetItem*> ( m_listView->selectedItem() ); + if ( !titem ) + return ; + + AddIconDialog dlg( m_part, m_widget, m_widget->selectedSubproject(), titem, + this, "add icon" ); + dlg.exec(); +} + + +void AutoDetailsView::slotBuildTarget() +{ + ProjectItem * pvitem = dynamic_cast<ProjectItem*>( m_listView->selectedItem() ); + if ( !pvitem ) + return; + + TargetItem* titem = 0; + + if ( pvitem->type() == ProjectItem::File ) + titem = static_cast <TargetItem*> ( pvitem->parent() ); + else + titem = static_cast <TargetItem*> ( m_listView->selectedItem() ); + + QString relpath = URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + m_widget->selectedSubproject()->relativePath(); + + m_part->buildTarget(relpath, titem); +} + +void AutoDetailsView::slotExecuteTarget() +{ + ProjectItem * pvitem = dynamic_cast<ProjectItem*>( m_listView->selectedItem() ); + if ( !pvitem ) + return; + + TargetItem* titem = 0; + + if ( pvitem->type() == ProjectItem::File ) + titem = static_cast <TargetItem*> ( pvitem->parent() ); + else + titem = static_cast <TargetItem*> ( m_listView->selectedItem() ); + + QString relpath = URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + m_part->activeDirectory(); + m_part->executeTarget(QDir( DomUtil::readEntry( *m_part->projectDom(), "/kdevautoproject/run/cwd/"+titem->name )), titem); +} + +void AutoDetailsView::slotRemoveDetail() +{ + ProjectItem * pvitem = dynamic_cast<ProjectItem*>( m_listView->selectedItem() ); + + if ( pvitem && ( pvitem->type() == ProjectItem::File ) ) + { + FileItem * fitem = static_cast <FileItem*> ( m_listView->selectedItem() ); + if(fitem && fitem->is_subst) + { + fitem->changeMakefileEntry(""); + return; + } + + QListViewItem* sibling = fitem->nextSibling(); + + if ( !fitem ) + return; + + TargetItem *titem = static_cast<TargetItem*>( fitem->parent() ); + + RemoveFileDialog dlg( m_widget, m_part, m_widget->selectedSubproject(), + titem, fitem->text( 0 ), this, "remove file dialog" ); + + QString caption; + if ( titem->name.isEmpty() ) + caption = i18n ( "%1 in %2" ).arg ( titem->primary ).arg ( titem->prefix ); + else + caption = titem->name; + + dlg.setCaption ( i18n ( "Remove File From '%1'" ).arg ( caption ) ); + + if ( dlg.exec() ) + { + emit selectionChanged( titem ); + + if ( sibling) + { + m_listView->setSelected ( sibling, true ); + m_listView->ensureItemVisible ( sibling ); + } + } + + return; + } + + if ( pvitem && ( pvitem->type() == ProjectItem::Target ) ) + { + TargetItem* titem = static_cast <TargetItem*> ( m_listView->selectedItem() ); + QListViewItem* sibling = titem->nextSibling(); + + if ( !titem ) return; + + bool isactive = ( titem == m_widget->activeTarget() ); + RemoveTargetDialog dlg ( m_widget, m_part, m_widget->selectedSubproject(), + titem, this, "remove target dialog" ); + + dlg.setCaption ( i18n ( "Remove Target From '%1'" ).arg ( m_widget->selectedSubproject()->subdir ) ); + + if ( dlg.exec() ) + { + //details->takeItem ( titem ); + + m_widget->slotOverviewSelectionChanged ( m_widget->selectedSubproject() ); + + if( isactive ) + m_widget->setActiveTarget(""); + if ( sibling) + { + m_listView->setSelected ( sibling, true ); + m_listView->ensureItemVisible ( sibling ); + } + } + + return; + } +} + + +void AutoDetailsView::slotDetailsContextMenu( KListView *, QListViewItem *item, const QPoint &p ) +{ + if ( !item ) + return; + + ProjectItem *pvitem = dynamic_cast<ProjectItem*>( item ); + if ( !pvitem ) + { + kdDebug(9020) << k_funcinfo << "Cast to type of ProjectItem* failed." + << "Details context menu will be empty!"; + return; + } + + if ( pvitem->type() == ProjectItem::Target ) + { + + TargetItem * titem = dynamic_cast<TargetItem*>( pvitem ); + if ( !titem ) + { + kdDebug(9020) << k_funcinfo << "Unable to populate target item menu" + << " due to failed cast. " << endl; + return; + } + + QString caption; + if ( titem->name.isEmpty() ) + caption = i18n ( "%1 in %2" ).arg ( titem->primary ).arg ( titem->prefix ); + else + caption = titem->name; + + KPopupMenu popup( i18n( "Target: %1" ).arg( caption ), this ); + + if ( titem->primary == "PROGRAMS" || titem->primary == "LIBRARIES" + || titem->primary == "LTLIBRARIES" || titem->primary == "JAVA" ) + { + targetOptionsAction->plug( &popup ); + popup.insertSeparator(); + addNewFileAction->plug( &popup ); + addExistingFileAction->plug( &popup ); + popup.insertSeparator(); + removeDetailAction->plug( &popup ); + popup.insertSeparator(); + setActiveTargetAction->plug( &popup ); + popup.insertSeparator(); + buildTargetAction->plug( &popup ); + if( titem->primary == "PROGRAMS") + executeTargetAction->plug( &popup ); + } + else if ( titem->primary == "KDEDOCS" ) + { + addNewFileAction->plug( &popup ); + addExistingFileAction->plug( &popup ); + popup.insertSeparator(); + removeDetailAction->plug( &popup ); + popup.insertSeparator(); + buildTargetAction->plug( &popup ); + } + else if ( titem->primary == "KDEICON" ) + { + addIconAction->plug( &popup ); + popup.insertSeparator(); + removeDetailAction->plug( &popup ); + } + else + { + addNewFileAction->plug( &popup ); + addExistingFileAction->plug( &popup ); + popup.insertSeparator(); + removeDetailAction->plug( &popup ); + } + + popup.exec( p ); + + } + else if ( pvitem->type() == ProjectItem::File ) + { + + FileItem * fitem = dynamic_cast<FileItem*>( pvitem ); + if ( !fitem ) + { + kdDebug(9020) << k_funcinfo << "Unable to populate file item menu" + << " due to failed cast. " << endl; + return; + } + + KPopupMenu popup( i18n( "File: %1" ).arg( fitem->name ), this ); + + removeDetailAction->plug( &popup ); + KURL::List urls; + urls.append(m_widget->selectedSubproject()->path + "/" + fitem->name); + FileContext context(urls); + + int idSubclassWidget = popup.insertItem(SmallIconSet("qmake_subclass"), + i18n("Subclassing Wizard...") ); + popup.setWhatsThis(idSubclassWidget, i18n("<b>Subclass widget</b><p>Launches " + "<b>Subclassing</b> wizard. " + "It allows to create a subclass from the " + "class defined in .ui file. " + "There is also possibility to implement " + "slots and functions defined in the base " + "class.")); + int idUISubclasses = popup.insertItem(SmallIconSet("qmake_subclass"), + i18n("List of Subclasses...")); + popup.setWhatsThis(idUISubclasses, i18n("<b>List of subclasses</b><p>Shows " + "subclasses list editor. " + "There is possibility to add or remove " + "subclasses from the list.")); + int idUpdateWidgetclass = popup.insertItem(SmallIconSet("qmake_subclass"), + i18n("Edit ui-Subclass...")); + popup.setWhatsThis(idUpdateWidgetclass, i18n("<b>Edit ui-subclass</b><p>Launches " + "<b>Subclassing</b> wizard and prompts " + "to implement missing in childclass " + "slots and functions.")); + int idViewUIH = popup.insertItem(SmallIconSet("qmake_ui_h"), + i18n("Open ui.h File")); + popup.setWhatsThis(idViewUIH, i18n("<b>Open ui.h file</b><p>Opens .ui.h file " + "associated with the selected .ui.")); + + if (!fitem->name.contains(QRegExp("ui$")) || fitem->is_subst == true) + { + popup.removeItem(idUISubclasses); + popup.removeItem(idViewUIH); + popup.removeItem(idSubclassWidget); + } + + if (fitem->uiFileLink.isEmpty()) + popup.removeItem(idUpdateWidgetclass); + + if(fitem->is_subst == false) + m_part->core()->fillContextMenu( &popup, &context ); + + int r = popup.exec( p ); + + if(r == idViewUIH) + { + m_part->partController()->editDocument(KURL(m_widget->selectedSubproject()->path + + "/" + QString(fitem->name + ".h"))); + } + else if (r == idSubclassWidget) + { + QStringList newFileNames; + newFileNames = m_part->languageSupport()->subclassWidget(m_widget->selectedSubproject()->path + "/" + fitem->name); + if (!newFileNames.empty()) + { + QDomDocument &dom = *(m_part->projectDom()); + for (uint i=0; i<newFileNames.count(); i++) + { + QString srcfile_relpath = newFileNames[i]; + srcfile_relpath.remove(0,m_part->projectDirectory().length()); + QString uifile_relpath = QString(m_widget->selectedSubproject()->path + "/" + fitem->name).remove(0,m_part->projectDirectory().length()); + DomUtil::PairList list = DomUtil::readPairListEntry(dom,"/kdevautoproject/subclassing", + "subclass","sourcefile", "uifile"); + + list << DomUtil::Pair(srcfile_relpath,uifile_relpath); + DomUtil::writePairListEntry(dom, "/kdevautoproject/subclassing", + "subclass", "sourcefile", "uifile", list); + newFileNames[i] = newFileNames[i].replace(QRegExp(m_part->projectDirectory()+"/"),""); + } + m_subclasslist = DomUtil::readPairListEntry(dom,"/kdevautoproject/subclassing", + "subclass","sourcefile", "uifile"); + m_part->addFiles(newFileNames); + } + } + else if (r == idUpdateWidgetclass) + { + QString noext = m_widget->selectedSubproject()->path + "/" + fitem->name; + + if (noext.findRev('.')>-1) + noext = noext.left(noext.findRev('.')); + + QStringList dummy; + QString uifile = fitem->uiFileLink; + + if (uifile.findRev('/')>-1) + { + QStringList uisplit = QStringList::split('/',uifile); + uifile=uisplit[uisplit.count()-1]; + } + + m_part->languageSupport()->updateWidget(m_widget->selectedSubproject()->path + + "/" + uifile, noext); + } + else if (r == idUISubclasses) + { + QDomDocument &dom = *(m_part->projectDom()); + DomUtil::PairList list = DomUtil::readPairListEntry(dom,"/kdevautoproject/subclassing", + "subclass","sourcefile", "uifile"); + SubclassesDlg *sbdlg = new SubclassesDlg( QString(m_widget->selectedSubproject()->path + "/" +fitem->name).remove(0,m_part->projectDirectory().length()), + list, m_part->projectDirectory()); + + if (sbdlg->exec()) + { + QDomElement el = DomUtil::elementByPath( dom, "/kdevautoproject"); + QDomElement el2 = DomUtil::elementByPath( dom, "/kdevautoproject/subclassing"); + if ( (!el.isNull()) && (!el2.isNull()) ) + { + el.removeChild(el2); + } + + DomUtil::writePairListEntry(dom, "/kdevautoproject/subclassing", "subclass", + "sourcefile", "uifile", list); + + m_subclasslist = DomUtil::readPairListEntry(dom,"/kdevautoproject/subclassing", + "subclass","sourcefile", "uifile"); + } + } + } +} + + +void AutoDetailsView::slotDetailsExecuted( QListViewItem *item ) +{ + if ( !item ) + return ; + + ProjectItem *pvitem = static_cast<ProjectItem*>( item ); + if ( pvitem->type() != ProjectItem::File ) + return ; + + if ( !m_widget->selectedSubproject() ) + return; + + QString dirName = m_widget->selectedSubproject()->path; + FileItem *fitem = static_cast<FileItem*>( item ); + if(fitem->is_subst) + { + fitem->changeSubstitution(); + return; + } + + m_part->partController()->editDocument( KURL( dirName + "/" + fitem->name ) ); +} + +void AutoDetailsView::slotSetActiveTarget() +{ + TargetItem * titem = static_cast<TargetItem*>( m_listView->selectedItem() ); + if ( !titem ) return ; + + SubprojectItem * subpitem = m_widget->selectedSubproject(); + if ( !subpitem ) return; + + QString targetPath = subpitem->path + "/" + titem->name; + targetPath = targetPath.mid( m_part->projectDirectory().length() + 1 ); + kdDebug( 9020 ) << "Setting active " << targetPath << endl; + m_widget->setActiveTarget( targetPath ); + QDomDocument &dom = *m_part->projectDom(); + DomUtil::writeEntry( dom, "/kdevautoproject/general/activetarget", targetPath ); +} + +void AutoDetailsView::focusOutEvent(QFocusEvent */*e*/) +{ + m_widget->setLastFocusedView(AutoProjectWidget::DetailsView); +} + +#include "autodetailsview.moc" + +//kate: indent-mode csands; tab-width 4; space-indent off; diff --git a/buildtools/autotools/autodetailsview.h b/buildtools/autotools/autodetailsview.h new file mode 100644 index 00000000..ee67558d --- /dev/null +++ b/buildtools/autotools/autodetailsview.h @@ -0,0 +1,88 @@ +/* + KDevelop Autotools Support + Copyright (c) 2002 by Victor Roeder <victor_roeder@gmx.de> + Copyright (c) 2005 by Matt Rogers <mattr@kde.org> + +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +*************************************************************************** +*/ + +#ifndef AUTODETAILSVIEW_H +#define AUTODETAILSVIEW_H + +#include "autoprojectviewbase.h" + +#include "domutil.h" +#include "autolistviewitems.h" + +class KAction; + +class AutoProjectPart; +class AutoProjectWidget; +class AutoToolsAction; + +class AutoDetailsView : protected AutoProjectViewBase +{ + friend class RemoveFileDialog; + friend class FileItem; + Q_OBJECT + +public: + AutoDetailsView( AutoProjectWidget* widget, AutoProjectPart* part, QWidget *parent, const char *name ); + virtual ~AutoDetailsView(); + + QString getUiFileLink( const QString &path, const QString& filename ); + KListView* listView() + { + return m_listView; + } + +public slots: + void slotSelectionChanged( QListViewItem* item ); + void slotSelectionChanged(); + +signals: + void selectionChanged( QListViewItem* ); + +protected: + void initActions (); + virtual void focusOutEvent( QFocusEvent *e ); + +private slots: + void slotDetailsExecuted( QListViewItem *item ); + void slotDetailsContextMenu( KListView *, QListViewItem *item, const QPoint &p ); + + void slotTargetOptions (); + void slotAddNewFile(); + void slotAddExistingFile(); + void slotAddIcon(); + void slotBuildTarget(); + void slotExecuteTarget(); + void slotRemoveDetail(); + void slotSetActiveTarget(); + +private: + AutoProjectWidget* m_widget; + AutoProjectPart* m_part; + + DomUtil::PairList m_subclasslist; + + AutoToolsAction* targetOptionsAction; + AutoToolsAction* addNewFileAction; + AutoToolsAction* addExistingFileAction; + KAction* addIconAction; + AutoToolsAction* buildTargetAction; + AutoToolsAction* executeTargetAction; + KAction* setActiveTargetAction; + AutoToolsAction* removeDetailAction; + +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/autolistviewitems.cpp b/buildtools/autotools/autolistviewitems.cpp new file mode 100644 index 00000000..454d12f5 --- /dev/null +++ b/buildtools/autotools/autolistviewitems.cpp @@ -0,0 +1,181 @@ +/*************************************************************************** +* Copyright (C) 2001-2002 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* Copyright (C) 2002 by Victor Rder * +* victor_roeder@gmx.de * +* * +* 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 <qpainter.h> +#include <qinputdialog.h> +#include <qregexp.h> + +#include <kiconloader.h> +#include "misc.h" +#include "autolistviewitems.h" +#include "autoprojectpart.h" +#include "autoprojectwidget.h" +#include "autodetailsview.h" + +/** +* Class ProjectItem +*/ + +ProjectItem::ProjectItem( Type type, QListView *parent, const QString &text ) + : QListViewItem( parent, text ), typ( type ) +{ + bld = false; +} + + +ProjectItem::ProjectItem( Type type, ProjectItem *parent, const QString &text ) + : QListViewItem( parent, text ), typ( type ) +{ + bld = false; +} + + +void ProjectItem::paintCell( QPainter *p, const QColorGroup &cg, + int column, int width, int alignment ) +{ + if ( isBold() ) + { + QFont font( p->font() ); + font.setBold( true ); + p->setFont( font ); + } + QListViewItem::paintCell( p, cg, column, width, alignment ); +} + + +/** +* Class SubprojectItem +*/ + +SubprojectItem::SubprojectItem( QListView *parent, const QString &text ) + : ProjectItem( Subproject, parent, text ) +{ + init(); +} + + +SubprojectItem::SubprojectItem( SubprojectItem *parent, const QString &text ) + : ProjectItem( Subproject, parent, text ) +{ + init(); +} + + +void SubprojectItem::init() +{ + targets.setAutoDelete( true ); + setPixmap( 0, SmallIcon( "folder" ) ); +} + + +QString SubprojectItem::relativePath() +{ + QString relpath = subdir; + + SubprojectItem *it = this; + while ( (it= dynamic_cast<SubprojectItem*>(it->parent())) ) + { + relpath.prepend(it->subdir + "/"); + } + relpath.remove(0, 2); + + return relpath; +} + + +/** +* Class TargetItem +*/ + +TargetItem::TargetItem( QListView *lv, bool group, const QString &text ) + : ProjectItem( Target, lv, text ) +{ + sources.setAutoDelete( true ); + setPixmap( 0, group ? SmallIcon( "tar" ) : SmallIcon( "binary" ) ); +} + + +/** +* Class FileItem +*/ + +FileItem::FileItem( QListView *lv, const QString &text, bool set_is_subst ) + : ProjectItem( File, lv, text ) , is_subst(set_is_subst) +{ + if(!is_subst) + { + setPixmap( 0, SmallIcon( "document" ) ); + } + else + { + setPixmap( 0, SmallIcon( "variablenew" ) ); + } +} + + +void FileItem::changeSubstitution() +{ +if(!is_subst) +return; + + bool ok; + QString text = QInputDialog::getText( + i18n("Edit Substitution"), i18n("Substitution:"), QLineEdit::Normal, + name, &ok ); + if ( ok && !text.isEmpty() ) + { + // user entered something and pressed OK + QString new_name = text; + if(new_name == name) + return; + setText(0,new_name); + changeMakefileEntry(new_name); + name = new_name; + } + else + { + // user entered nothing or pressed Cancel + + } +} + +void FileItem::changeMakefileEntry(const QString& new_name) +{ + TargetItem* target = dynamic_cast<TargetItem*>(parent()); + + QMap<QString,QString> replaceMap; + + QString canontargetname = AutoProjectTool::canonicalize(target->name); + QString varname; + if( target->primary == "PROGRAMS" || target->primary == "LIBRARIES" || target->primary == "LTLIBRARIES" ) + varname = canontargetname + "_SOURCES"; + else + varname = target->prefix + "_" + target->primary; + if( AutoDetailsView* lv = dynamic_cast<AutoDetailsView*>(listView()) ) + { + if ( SubprojectItem* subProject = lv->m_part->m_widget->selectedSubproject() ) + { + QStringList sources = QStringList::split(QRegExp("[ \t\n]"), subProject->variables[varname]); + QStringList::iterator it = sources.find(name); + (*it) = new_name; + subProject->variables[varname] = sources.join(" "); + replaceMap.insert(varname, subProject->variables[varname]); + + AutoProjectTool::addToMakefileam(subProject->path + "/Makefile.am", replaceMap); + + if(new_name == "") + target->sources.remove(this); + } + } +} diff --git a/buildtools/autotools/autolistviewitems.h b/buildtools/autotools/autolistviewitems.h new file mode 100644 index 00000000..0dece2a2 --- /dev/null +++ b/buildtools/autotools/autolistviewitems.h @@ -0,0 +1,143 @@ +/*************************************************************************** +* Copyright (C) 2001-2002 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* Copyright (C) 2002 by Victor Rder * +* victor_roeder@gmx.de * +* * +* 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 AUTOLISTVIEWITEMS_H +#define AUTOLISTVIEWITEMS_H + +#include <qptrlist.h> + +#include <qlistview.h> + +class TargetItem; +class FileItem; +class AutoProjectPart; + +/** +* Base class for all items appearing in ProjectOverview and ProjectDetails. +*/ +class ProjectItem : public QListViewItem +{ +public: + enum Type { Subproject, Target, File }; + + ProjectItem( Type type, QListView *parent, const QString &text ); + ProjectItem( Type type, ProjectItem *parent, const QString &text ); + + void paintCell( QPainter *p, const QColorGroup &cg, + int column, int width, int alignment ); + void setBold( bool b ) + { + bld = b; + } + bool isBold() const + { + return bld; + } + Type type() + { + return typ; + } + +private: + Type typ; + bool bld; + +}; + + +/** +* Stores the content of one Makefile.am +*/ +class SubprojectItem : public ProjectItem +{ +public: + SubprojectItem( QListView *parent, const QString &text ); + SubprojectItem( SubprojectItem *parent, const QString &text ); + + /** name of the directory */ + QString subdir; + /** absolute path */ + QString path; + /** mapping from prefix to path */ + QMap<QString, QString> prefixes; + /** mapping from variable name to value */ + QMap<QString, QString> variables; + /** list of targets */ + QPtrList<TargetItem> targets; + + QString relativePath(); + +private: + void init(); +}; + + +/** +* Stores one target +* For e.g. the line +* bin_LTLIBRARIES = foo.la +* generates a target with name 'foo.la', primary LTLIBRARIES and prefix 'bin' +* In order to make things not too simple ;-) headers and data are handled +* a bit different from programs, libraries and scripts: All headers for a +* certain prefix (analogously for data) are put in _one_ TargetItem object, +* and the names of the files are put in the sources variable. This avoids +* cluttering the list view with lots of header items. +*/ +class TargetItem : public ProjectItem +{ +public: + //enum TargetKind { Program, Library, DataGroup, IconGroup, DocGroup }; + + TargetItem( QListView *lv, bool group, const QString &text ); + + // Target kind - not used currently + //TargetKind kind; + //! Name of target, e.g. foo + QString name; + //! One of PROGRAMS, LIBRARIES, LTLIBRARIES, SCRIPTS, HEADERS, DATA, JAVA + //! In addition to these automake primaries, we use KDEICON and KDEDOCS + //! for am_edit magic + QString primary; + //! May be bin, pkglib, noinst, check, sbin, pkgdata, java... + QString prefix; + //! Content of foo_SOURCES (or java_JAVA) assignment + QPtrList<FileItem> sources; + //! Content of foo_LDFLAGS assignment + QString ldflags; + //! Content of foo_LDADD assignment + QString ldadd; + //! Content of foo_LIBADD assignment + QString libadd; + //! Content of foo_DEPENDENCIES assignment + QString dependencies; +}; + + +// Not sure if this complexity is really necessary... +class FileItem : public ProjectItem +{ + +public: + FileItem( QListView *lv, const QString &text, bool set_is_subst = false ); + void changeSubstitution(); + void changeMakefileEntry( const QString& ); + + QString name; + QString uiFileLink; + const bool is_subst; +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/autoprojectpart.cpp b/buildtools/autotools/autoprojectpart.cpp new file mode 100644 index 00000000..ea0b6896 --- /dev/null +++ b/buildtools/autotools/autoprojectpart.cpp @@ -0,0 +1,1474 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * Copyright (C) 2002 by Victor Roeder * + * victor_roeder@gmx.de * + * * + * 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 <config.h> + +#include "autoprojectpart.h" +#include "autolistviewitems.h" +#include "configureoptionswidget.h" +#include "addtranslationdlg.h" +#include "addicondlg.h" +#include "autoprojectwidget.h" + +#include <qdom.h> +#include <qdir.h> +#include <qfileinfo.h> +#include <qpopupmenu.h> +#include <qstringlist.h> +#include <qwhatsthis.h> +#include <qregexp.h> +#include <qgroupbox.h> + + +#include <kapplication.h> +#include <kconfig.h> +#include <kaction.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kparts/part.h> +#include <kdeversion.h> +#include <kprocess.h> + +#include <domutil.h> +#include <kdevcore.h> +#include <kdevmakefrontend.h> +#include <kdevappfrontend.h> +#include <kdevmainwindow.h> +#include <kdevpartcontroller.h> +#include <makeoptionswidget.h> +#include <runoptionswidget.h> +#include <envvartools.h> + +#include <configwidgetproxy.h> +#include <kdevplugininfo.h> +#include <urlutil.h> + +#define CONFIGURE_OPTIONS 1 +#define RUN_OPTIONS 2 +#define MAKE_OPTIONS 3 + +static const KDevPluginInfo data("kdevautoproject"); + +K_EXPORT_COMPONENT_FACTORY( libkdevautoproject, AutoProjectFactory( data ) ) + +AutoProjectPart::AutoProjectPart(QObject *parent, const char *name, const QStringList &args) + : KDevBuildTool(&data, parent, name ? name : "AutoProjectPart") + , m_lastCompilationFailed(false) +{ + setInstance(AutoProjectFactory::instance()); + + setXMLFile("kdevautoproject.rc"); + + m_executeAfterBuild = false; + m_isKDE = (args[0] == "kde"); + m_needMakefileCvs = false; + + m_widget = new AutoProjectWidget(this, m_isKDE); + m_widget->setIcon(SmallIcon( info()->icon() )); + m_widget->setCaption(i18n("Automake Manager")); + QWhatsThis::add(m_widget, i18n("<b>Automake manager</b><p>" + "The project tree consists of two parts. The 'overview' " + "in the upper half shows the subprojects, each one having a " + "Makefile.am. The 'details' view in the lower half shows the " + "targets and files for the subproject selected in the overview.")); + + mainWindow()->embedSelectViewRight(m_widget, i18n("Automake Manager"), i18n("Automake manager")); + KAction *action; + + action = new KAction( i18n("Add Translation..."), 0, + this, SLOT(slotAddTranslation()), + actionCollection(), "project_addtranslation" ); + action->setToolTip(i18n("Add translation")); + action->setWhatsThis(i18n("<b>Add translation</b><p>Creates .po file for the selected language.")); + action->setGroup("autotools"); + + + if (!m_isKDE) + action->setEnabled(false); + + action = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8, + this, SLOT(slotBuild()), + actionCollection(), "build_build" ); + action->setToolTip(i18n("Build project")); + action->setWhatsThis(i18n("<b>Build project</b><p>Runs <b>make</b> from the project directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("Build &Active Target"), "make_kdevelop", Key_F7, + this, SLOT(slotBuildActiveTarget()), + actionCollection(), "build_buildactivetarget" ); + action->setToolTip(i18n("Build active target")); + action->setWhatsThis(i18n("<b>Build active target</b><p>Constructs a series of make commands to build an active target. " + "Also builds dependent targets.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("Compile &File"), "make_kdevelop", + this, SLOT(slotCompileFile()), + actionCollection(), "build_compilefile" ); + action->setToolTip(i18n("Compile file")); + action->setWhatsThis(i18n("<b>Compile file</b><p>Runs <b>make filename.o</b> command from the directory where 'filename' is the name of currently opened file.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("Run Configure"), 0, + this, SLOT(slotConfigure()), + actionCollection(), "build_configure" ); + action->setToolTip(i18n("Run configure")); + action->setWhatsThis(i18n("<b>Run configure</b><p>Executes <b>configure</b> with flags, arguments " + "and environment variables specified in the project settings dialog, " + "<b>Configure Options</b> tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("Run automake && friends"), 0, + this, SLOT(slotMakefilecvs()), + actionCollection(), "build_makefilecvs" ); + action->setToolTip(i18n("Run automake && friends")); + action->setWhatsThis(i18n("<b>Run automake && friends</b><p>Executes<br><b>make -f Makefile.cvs</b><br><b>./configure</b><br>commands from the project directory.")); + action->setGroup("autotools"); + + action = new KAction( i18n("Install"), 0, + this, SLOT(slotInstall()), + actionCollection(), "build_install" ); + action->setToolTip(i18n("Install")); + action->setWhatsThis(i18n("<b>Install</b><p>Runs <b>make install</b> command from the project directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("Install (as root user)"), 0, + this, SLOT(slotInstallWithKdesu()), + actionCollection(), "build_install_kdesu" ); + action->setToolTip(i18n("Install as root user")); + action->setWhatsThis(i18n("<b>Install</b><p>Runs <b>make install</b> command from the project directory with root privileges.<br>" + "It is executed via kdesu command.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("&Clean Project"), 0, + this, SLOT(slotClean()), + actionCollection(), "build_clean" ); + action->setToolTip(i18n("Clean project")); + action->setWhatsThis(i18n("<b>Clean project</b><p>Runs <b>make clean</b> command from the project directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("&Distclean"), 0, + this, SLOT(slotDistClean()), + actionCollection(), "build_distclean" ); + action->setToolTip(i18n("Distclean")); + action->setWhatsThis(i18n("<b>Distclean</b><p>Runs <b>make distclean</b> command from the project directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("Make Messages && Merge"), 0, + this, SLOT(slotMakeMessages()), + actionCollection(), "build_messages" ); + action->setToolTip(i18n("Make messages && merge")); + action->setWhatsThis(i18n("<b>Make messages && merge</b><p>Runs <b>make package-messages</b> command from the project directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + action->setGroup("autotools"); + + if (!m_isKDE) + action->setEnabled(false); + + buildConfigAction = new KSelectAction( i18n("Build Configuration"), 0, + actionCollection(), "project_configuration" ); + buildConfigAction->setToolTip(i18n("Build configuration menu")); + buildConfigAction->setWhatsThis(i18n("<b>Build configuration menu</b><p>Allows to switch between project build configurations.<br>" + "Build configuration is a set of build and top source directory settings, " + "configure flags and arguments, compiler flags, etc.<br>" + "Modify build configurations in project settings dialog, <b>Configure Options</b> tab.")); + buildConfigAction->setGroup("autotools"); + + QDomDocument &dom = *projectDom(); + if (!DomUtil::readBoolEntry(dom, "/kdevautoproject/run/disable_default")) { + //ok we handle the execute in this kpart + action = new KAction( i18n("Execute Program"), "exec", SHIFT+Key_F9, + this, SLOT(slotExecute()), + actionCollection(), "build_execute" ); + action->setToolTip(i18n("Execute program")); + action->setWhatsThis(i18n("<b>Execute program</b><p>Executes the currently active target or the main program specified in project settings, <b>Run Options</b> tab.")); + action->setGroup("autotools"); + } + + connect( buildConfigAction, SIGNAL(activated(const QString&)), + this, SLOT(slotBuildConfigChanged(const QString&)) ); + connect( buildConfigAction->popupMenu(), SIGNAL(aboutToShow()), + this, SLOT(slotBuildConfigAboutToShow()) ); + +// connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), this, SLOT(projectConfigWidget(KDialogBase*)) ); + + _configProxy = new ConfigWidgetProxy( core() ); + _configProxy->createProjectConfigPage( i18n("Configure Options"), CONFIGURE_OPTIONS, info()->icon() ); + _configProxy->createProjectConfigPage( i18n("Run Options"), RUN_OPTIONS, info()->icon() ); + _configProxy->createProjectConfigPage( i18n("Make Options"), MAKE_OPTIONS, info()->icon() ); + connect( _configProxy, SIGNAL(insertConfigWidget(const KDialogBase*, QWidget*, unsigned int )), + this, SLOT(insertConfigWidget(const KDialogBase*, QWidget*, unsigned int )) ); + + + connect( makeFrontend(), SIGNAL(commandFinished(const QString&)), + this, SLOT(slotCommandFinished(const QString&)) ); + connect( makeFrontend(), SIGNAL(commandFailed(const QString&)), + this, SLOT(slotCommandFailed(const QString&)) ); + + setWantautotools(); + + +} + + +AutoProjectPart::~AutoProjectPart() +{ + if (m_widget) + { + mainWindow()->removeView(m_widget); + } + delete m_widget; + delete _configProxy; +} + + +void AutoProjectPart::insertConfigWidget( const KDialogBase* dlg, QWidget * page, unsigned int pagenumber ) +{ + switch ( pagenumber ) + { + case CONFIGURE_OPTIONS: + { + ConfigureOptionsWidget *w2 = new ConfigureOptionsWidget(this, page ); + connect( dlg, SIGNAL(okClicked()), w2, SLOT(accept()) ); + } + break; + + case RUN_OPTIONS: + { + QDomDocument &dom = *projectDom(); + if (!DomUtil::readBoolEntry(dom, "/kdevautoproject/run/disable_default")) + { + //ok we handle the execute in this kpart + RunOptionsWidget *w3 = new RunOptionsWidget(*projectDom(), "/kdevautoproject", buildDirectory(), page ); + connect( dlg, SIGNAL(okClicked()), w3, SLOT(accept()) ); + } + } + break; + + case MAKE_OPTIONS: + { + MakeOptionsWidget *w4 = new MakeOptionsWidget(*projectDom(), "/kdevautoproject", page ); + connect( dlg, SIGNAL(okClicked()), w4, SLOT(accept()) ); + } + break; + } +} + +void AutoProjectPart::openProject(const QString &dirName, const QString &projectName) +{ + m_projectName = projectName; + m_projectPath =dirName; + + m_widget->openProject(dirName); + + QDomDocument &dom = *projectDom(); + QString activeTarget = DomUtil::readEntry(dom, "/kdevautoproject/general/activetarget"); + kdDebug(9020) << k_funcinfo << "activeTarget " << activeTarget << endl; + if (!activeTarget.isEmpty()) + m_widget->setActiveTarget(activeTarget); + else + { + KMessageBox::information( m_widget, i18n("No active target specified, running the application will\n" + "not work until you make a target active in the Automake Manager\n" + "on the right side or use the Main Program options under\n" + "Project -> Project Options -> Run Options"), i18n("No active target specified"), "kdevelop_open_project_no_active_target"); + } + + KDevProject::openProject( dirName, projectName ); +} + + +void AutoProjectPart::closeProject() +{ + m_widget->closeProject(); +} + + +QString AutoProjectPart::projectDirectory() const +{ + return m_projectPath; +} + + +QString AutoProjectPart::projectName() const +{ + return m_projectName; +} + + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList AutoProjectPart::runEnvironmentVars() const +{ + return DomUtil::readPairListEntry(*projectDom(), "/kdevautoproject/run/envvars", "envvar", "name", "value"); +} + + +/** Retuns the currently selected run directory + * If no main Program was selected in the Run Options dialog + * use the currently active target instead to calculate it. + * The returned string can be: + * if /kdevautoproject/run/directoryradio == executable + * The directory where the executable is + * if /kdevautoproject/run/directoryradio == build + * The directory where the executable is relative to build directory + * if /kdevautoproject/run/directoryradio == custom + * The custom directory absolute path + */ +QString AutoProjectPart::runDirectory() const +{ + + QDomDocument &dom = *projectDom(); + + QString cwd; + if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) || !m_widget->activeTarget() ) + { + cwd = defaultRunDirectory("kdevautoproject"); + }else + { + cwd = DomUtil::readEntry( dom, "/kdevautoproject/run/cwd/"+m_widget->activeTarget()->name ); + } + if( cwd.isEmpty() ) + cwd = buildDirectory() +"/"+ URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) +"/"+m_widget->activeDirectory(); + + return cwd; +} + + +/** Retuns the currently selected main program + * If no main Program was selected in the Run Options dialog + * use the currently active target instead. + * The returned string can be: + * if /kdevautoproject/run/directoryradio == executable + * The executable name + * if /kdevautoproject/run/directoryradio == build + * The path to executable relative to build directory + * if /kdevautoproject/run/directoryradio == custom or relative == false + * The absolute path to executable + */ + +QString AutoProjectPart::mainProgram() const +{ + QDomDocument * dom = projectDom(); + + if ( !dom ) return QString(); + + if( DomUtil::readBoolEntry(*dom, "/kdevautoproject/run/useglobalprogram", false) ) + { + QString DomMainProgram = DomUtil::readEntry(*dom, "/kdevautoproject/run/mainprogram"); + + if ( DomMainProgram.isEmpty() ) return QString(); + + if ( DomMainProgram.startsWith("/") ) // assume absolute path + { + return DomMainProgram; + } + else // assume builddir relative path + { + QString relprojectpath = URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ); + if( !relprojectpath.isEmpty() ) + relprojectpath = "/" + relprojectpath; + return buildDirectory() + relprojectpath + "/" + DomMainProgram; + } + + } + else // If no Main Program was specified, return the active target + { + TargetItem* titem = m_widget->activeTarget(); + + if ( !titem ) { + KMessageBox::error( m_widget, i18n("There is no active target.\n" + "Unable to determine the main program."), i18n("No active target found") ); + kdDebug ( 9020 ) << k_funcinfo << "Error! : There's no active target! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl; + return QString::null; + } + + if ( titem->primary != "PROGRAMS" ) { + KMessageBox::error( m_widget, i18n("Active target \"%1\" is not binary ( %2 ).\n" + "Unable to determine the main program. If you want this\n" + "to be the active target, set a main program under\n" + "Project -> Project Options -> Run Options").arg(titem->name).arg(titem->primary), i18n("Active target is not a library") ); + kdDebug ( 9020 ) << k_funcinfo << "Error! : Active target isn't binary (" << titem->primary << ") ! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl; + return QString::null; + } + + QString relprojectpath = URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ); + if( !relprojectpath.isEmpty() ) + relprojectpath = "/" + relprojectpath; + return buildDirectory() + relprojectpath + "/" + activeDirectory() + "/" + titem->name; + } +} + + +/** Retuns a QString with the debug command line arguments */ +QString AutoProjectPart::debugArguments() const +{ + QDomDocument &dom = *projectDom(); + + if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) || !m_widget->activeTarget() ) + { + return DomUtil::readEntry(dom, "/kdevautoproject/run/globaldebugarguments"); + }else + { + return DomUtil::readEntry(dom, "/kdevautoproject/run/debugarguments/" + m_widget->activeTarget()->name); + } +} + + +/** Retuns a QString with the run command line arguments */ +QString AutoProjectPart::runArguments() const +{ + QDomDocument &dom = *projectDom(); + + if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) || !m_widget->activeTarget() ) + { + return DomUtil::readEntry(dom, "/kdevautoproject/run/programargs"); + }else + { + return DomUtil::readEntry(dom, "/kdevautoproject/run/runarguments/" + m_widget->activeTarget()->name); + } +} + + +QString AutoProjectPart::activeDirectory() const +{ + return m_widget->activeDirectory(); +} + + +QStringList AutoProjectPart::allFiles() const +{ + return m_widget->allFiles(); +} + + +void AutoProjectPart::setWantautotools() +{ + QDomDocument &dom = *projectDom(); + QDomElement el = DomUtil::elementByPath(dom, "/kdevautoproject/make"); + if ( el.namedItem("envvars").isNull() ) { + DomUtil::PairList list; + list << DomUtil::Pair("WANT_AUTOCONF_2_5", "1"); + list << DomUtil::Pair("WANT_AUTOMAKE_1_6", "1"); + DomUtil::writePairListEntry(dom, "/kdevautoproject/make/envvars", "envvar", "name", "value", list); + } +} + + +QString AutoProjectPart::makeEnvironment() const +{ + // Get the make environment variables pairs into the environstr string + // in the form of: "ENV_VARIABLE=ENV_VALUE" + // Note that we quote the variable value due to the possibility of + // embedded spaces + DomUtil::PairList envvars = + DomUtil::readPairListEntry(*projectDom(), "/kdevautoproject/make/envvars", "envvar", "name", "value"); + + QString environstr; + DomUtil::PairList::ConstIterator it; + for (it = envvars.begin(); it != envvars.end(); ++it) + { + environstr += (*it).first; + environstr += "="; + environstr += EnvVarTools::quote((*it).second); + environstr += " "; + } + + KConfigGroup grp( kapp->config(), "MakeOutputView" ); + if( grp.readBoolEntry( "ForceCLocale", true ) ) + environstr += "LC_MESSAGES="+EnvVarTools::quote("C")+" "+"LC_CTYPE="+EnvVarTools::quote("C")+" "; + + return environstr; +} + + +void AutoProjectPart::addFile(const QString &fileName) +{ + QStringList fileList; + fileList.append ( fileName ); + + this->addFiles ( fileList ); +} + +void AutoProjectPart::addFiles ( const QStringList& fileList ) +{ + QString directory, name; + QStringList::ConstIterator it; + bool messageBoxShown = false; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) + { + int pos = ( *it ).findRev('/'); + if (pos != -1) + { + directory = ( *it ).left(pos); + name = ( *it ).mid(pos+1); + } + else + { + directory = ""; + name = ( *it ); + } + + if (directory != m_widget->activeDirectory() || + directory.isEmpty()) + { + if ( !messageBoxShown ) + { + KMessageBox::information(m_widget, i18n("The directory you selected is not the active directory.\n" + "You should 'activate' the target you're currently working on in Automake Manager.\n" + "Just right-click a target and choose 'Make Target Active'."), + i18n ( "No Active Target Found" ), "No automake manager active target warning" ); + messageBoxShown = true; + } + } + } + + m_widget->addFiles(fileList); +} + +void AutoProjectPart::removeFile(const QString &fileName) +{ + QStringList fileList; + fileList.append ( fileName ); + + this->removeFiles ( fileList ); +} + +void AutoProjectPart::removeFiles ( const QStringList& fileList ) +{ + /// \FIXME m_widget->removeFiles does nothing! + m_widget->removeFiles ( fileList ); + + emit removedFilesFromProject ( fileList ); +} + +QStringList AutoProjectPart::allBuildConfigs() const +{ + QDomDocument &dom = *projectDom(); + + QStringList allConfigs; + allConfigs.append("default"); + + QDomNode node = dom.documentElement().namedItem("kdevautoproject").namedItem("configurations"); + QDomElement childEl = node.firstChild().toElement(); + while (!childEl.isNull()) + { + QString config = childEl.tagName(); + kdDebug(9020) << k_funcinfo << "Found config " << config << endl; + if (config != "default") + allConfigs.append(config); + childEl = childEl.nextSibling().toElement(); + } + + return allConfigs; +} + + +QString AutoProjectPart::currentBuildConfig() const +{ + QDomDocument &dom = *projectDom(); + + QString config = DomUtil::readEntry(dom, "/kdevautoproject/general/useconfiguration"); + if (config.isEmpty() || !allBuildConfigs().contains(config)) + config = "default"; + + return config; +} + + +QString AutoProjectPart::buildDirectory() const +{ + QString prefix = "/kdevautoproject/configurations/" + currentBuildConfig() + "/"; + + QString builddir = DomUtil::readEntry(*projectDom(), prefix + "builddir"); + if (builddir.isEmpty()) + return topsourceDirectory(); + else if (builddir.startsWith("/")) + return builddir; + else + return projectDirectory() + "/" + builddir; +} + +QString AutoProjectPart::topsourceDirectory() const +{ + QString prefix = "/kdevautoproject/configurations/" + currentBuildConfig() + "/"; + + QString topsourcedir = DomUtil::readEntry(*projectDom(), prefix + "topsourcedir"); + if (topsourcedir.isEmpty()) + return projectDirectory(); + else if (topsourcedir.startsWith("/")) + return topsourcedir; + else + return projectDirectory() + "/" + topsourcedir; +} + +QString AutoProjectPart::constructMakeCommandLine(const QString &dir, const QString &target) const +{ + + QString preCommand; + QFileInfo fi1(); + kdDebug(9020) << k_funcinfo << "Looking for Makefile in " << dir << endl; + if ( !QFile::exists(dir + "/GNUmakefile") && !QFile::exists(dir + "/makefile") + && ! QFile::exists(dir + "/Makefile") ) + { + if (!QFile::exists(buildDirectory() + "/configure")) + { + int r = KMessageBox::questionYesNo(m_widget, i18n("%1\nThere is no Makefile in this directory\n" + "and no configure script for this project.\n" + "Run automake & friends and configure first?").arg(buildDirectory()), QString::null, i18n("Run Them"), i18n("Do Not Run")); + if (r == KMessageBox::No) + return QString::null; + preCommand = makefileCvsCommand(); + if (preCommand.isNull()) + return QString::null; + preCommand += " && "; + preCommand += configureCommand() + " && "; + } + else + { + int r = KMessageBox::questionYesNo(m_widget, i18n("%1\nThere is no Makefile in this directory. Run 'configure' first?").arg(dir), QString::null, i18n("Run configure"), i18n("Do Not Run")); + if (r == KMessageBox::No) + return QString::null; + preCommand = configureCommand() + " && "; + } + } + QDomDocument &dom = *projectDom(); + + QString cmdline = DomUtil::readEntry(dom, "/kdevautoproject/make/makebin"); + int prio = DomUtil::readIntEntry(dom, "/kdevautoproject/make/prio"); + QString nice; + kdDebug(9020) << k_funcinfo << "nice = " << prio<< endl; + if (prio != 0) + { + nice = QString("nice -n%1 ").arg(prio); + } + + if (cmdline.isEmpty()) + cmdline = MAKE_COMMAND; + if (!DomUtil::readBoolEntry(dom, "/kdevautoproject/make/abortonerror")) + cmdline += " -k"; + bool runmultiple = DomUtil::readBoolEntry(dom, "/kdevautoproject/make/runmultiplejobs"); + int jobs = DomUtil::readIntEntry(dom, "/kdevautoproject/make/numberofjobs"); + if (runmultiple && jobs != 0) + { + cmdline += " -j"; + cmdline += QString::number(jobs); + } + if (DomUtil::readBoolEntry(dom, "/kdevautoproject/make/dontact")) + cmdline += " -n"; + + cmdline += " "; + cmdline += target; + cmdline.prepend(nice); + cmdline.prepend(makeEnvironment()); + + QString dircmd = "cd "; + dircmd += KProcess::quote(dir); + dircmd += " && "; + + return preCommand + dircmd + cmdline; +} + + +void AutoProjectPart::startMakeCommand(const QString &dir, const QString &target, bool withKdesu) +{ + if (partController()->saveAllFiles()==false) + return; //user cancelled + kdDebug(9020) << "startMakeCommand:" << dir << ": "<< target << endl; + m_buildCommand = constructMakeCommandLine(dir, target); + + if (withKdesu) + m_buildCommand = "kdesu -t -c '" + m_buildCommand + "'"; + + if (!m_buildCommand.isNull()) + makeFrontend()->queueCommand(dir, m_buildCommand); +} + + +/** Adds the make command for the libraries that the target depends on + * to the make frontend queue (this is a recursive function) */ +bool AutoProjectPart::queueInternalLibDependenciesBuild(TargetItem* titem, QStringList& alreadyScheduledDeps) +{ + + QString addstr = (titem->primary == "PROGRAMS")? titem->ldadd : titem->libadd; + QStringList l2 = QStringList::split(QRegExp("[ \t]"), addstr); // list of dependencies + QString tdir; // temp target directory + QString tname; // temp target name + QString tcmd; // temp command line + QStringList::Iterator l2it; + for (l2it = l2.begin(); l2it != l2.end(); ++l2it) + { + QString dependency = *l2it; + if (dependency.startsWith("$(top_builddir)/")) + { + // These are the internal libraries + dependency.remove("$(top_builddir)/"); + + if( !alreadyScheduledDeps.contains(*l2it) ) + { + alreadyScheduledDeps << *l2it; + tdir = buildDirectory(); + if (!tdir.endsWith("/") && !tdir.isEmpty()) + tdir += "/"; + int pos = dependency.findRev('/'); + if (pos == -1) + { + tname = dependency; + } + else + { + tdir += dependency.left(pos+1); + tname = dependency.mid(pos+1); + } + kdDebug(9020) << "Scheduling : <" << tdir << "> target <" << tname << ">" << endl; + // Recursively queue the dependencies for building + SubprojectItem *spi = m_widget->subprojectItemForPath( dependency.left(pos) ); + if (spi) + { + QPtrList< TargetItem > tl = spi->targets; + // Cycle through the list of targets to find the one we're looking for + TargetItem *ti = tl.first(); + do + { + if (ti->name == tname) + { + // found it: queue it and stop looking + if( !queueInternalLibDependenciesBuild(ti, alreadyScheduledDeps) ) + return false; + break; + } + ti = tl.next(); + } + while (ti); + } + + kdDebug(9020) << "queueInternalLibDependenciesBuild:" << tdir << ": "<< tname << endl; + tcmd = constructMakeCommandLine(tdir, tname); + if (!tcmd.isNull()) + { + makeFrontend()->queueCommand( tdir, tcmd); + } + }else + { + //Message box about circular deps. + tdir = buildDirectory(); + if (!tdir.endsWith("/") && !tdir.isEmpty()) + tdir += "/"; + int pos = dependency.findRev('/'); + if (pos == -1) + { + tname = dependency; + } + else + { + tdir += dependency.left(pos+1); + tname = dependency.mid(pos+1); + } + KMessageBox::error( 0, i18n("Found a circular dependency in the project, between this target and %1.\nCannot build this project until this is resolved.").arg(tname), i18n("Circular Dependency found") ); + return false; + } + } + } + return true; +} + + +void AutoProjectPart::slotBuild() +{ + //m_lastCompilationFailed = false; + + if( m_needMakefileCvs ) + { + slotMakefilecvs(); + slotConfigure(); + m_needMakefileCvs = false; + } + + startMakeCommand(buildDirectory(), QString::fromLatin1("")); +} + + +void AutoProjectPart::buildTarget(QString relpath, TargetItem* titem) +{ + + if ( !titem ) + return; + + //m_lastCompilationFailed = false; + + // Calculate the complete name of the target and store it in name + QString name = titem->name; + if ( titem->primary == "KDEDOCS" ) + name = "index.cache.bz2"; + + // Calculate the full path of the target and store it in path + QString path = buildDirectory(); + if (!path.endsWith("/") && !path.isEmpty()) + path += "/"; + if (relpath.at(0) == '/') + path += relpath.mid(1); + else + path += relpath; + + // Save all files once + partController()->saveAllFiles(); + + // Add the make command for the libraries that the target depends on to the make frontend queue + // if this recursive behavour is un-wanted comment the next line + QStringList deps; + if( !queueInternalLibDependenciesBuild(titem, deps) ) + return; + + // Calculate the "make" command line for the target + //QString relpath = dir.path().mid( projectDirectory().length() ); + m_runProg=buildDirectory() + "/" + relpath+"/"+name; + kdDebug(9020) << "buildTarget:" << buildDirectory()<< endl; + kdDebug(9020) << "buildTarget:" << relpath << " " << path << ": "<< name << " : " << m_runProg << endl; + QString tcmd = constructMakeCommandLine( path, name ); + + // Call make + if (!tcmd.isNull()) + { + m_buildCommand = tcmd; + makeFrontend()->queueCommand( path, tcmd); + } +} + + +void AutoProjectPart::slotBuildActiveTarget() +{ + // Get a pointer to the active target + TargetItem* titem = m_widget->activeTarget(); + + if ( !titem ) + return; + + // build it + buildTarget( URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) + "/" + activeDirectory(), titem); +} + + +void AutoProjectPart::slotCompileFile() +{ + KParts::ReadWritePart *part = dynamic_cast<KParts::ReadWritePart*>(partController()->activePart()); + if (!part || !part->url().isLocalFile()) + return; + + QString fileName = part->url().path(); + QFileInfo fi(fileName); + QString sourceDir = fi.dirPath(); + QString baseName = fi.baseName(true); + kdDebug(9020) << "Compiling " << fileName + << " in dir " << sourceDir + << " with baseName " << baseName << endl; + + QString projectDir = projectDirectory(); + if (!sourceDir.startsWith(projectDir)) { + KMessageBox::sorry(m_widget, i18n("Can only compile files in directories which belong to the project.")); + return; + } + + QString buildDir = buildDirectory() + sourceDir.mid(projectDir.length()); + QString target = baseName + ".lo"; + kdDebug(9020) << "builddir " << buildDir << ", target " << target << endl; + + startMakeCommand(buildDir, target); +} + +QString AutoProjectPart::configureCommand() const +{ + QDomDocument &dom = *projectDom(); + QString prefix = "/kdevautoproject/configurations/" + currentBuildConfig() + "/"; + + QString cmdline = "\"" + topsourceDirectory(); + cmdline += "/configure\""; + QString cc = DomUtil::readEntry(dom, prefix + "ccompilerbinary"); + if (!cc.isEmpty()) + cmdline.prepend(QString("CC=%1 ").arg(cc)); + QString cflags = DomUtil::readEntry(dom, prefix + "cflags"); + if (!cflags.isEmpty()) + cmdline.prepend(QString("CFLAGS=\"%1\" ").arg(cflags)); + QString cxx = DomUtil::readEntry(dom, prefix + "cxxcompilerbinary"); + if (!cxx.isEmpty()) + cmdline.prepend(QString("CXX=%1 ").arg(cxx)); + QString cxxflags = DomUtil::readEntry(dom, prefix + "cxxflags"); + if (!cxxflags.isEmpty()) + cmdline.prepend(QString("CXXFLAGS=\"%1\" ").arg(cxxflags)); + QString f77 = DomUtil::readEntry(dom, prefix + "f77compilerbinary"); + if (!f77.isEmpty()) + cmdline.prepend(QString("F77=%1 ").arg(f77)); + QString fflags = DomUtil::readEntry(dom, prefix + "f77flags"); + if (!fflags.isEmpty()) + cmdline.prepend(QString("FFLAGS=\"%1\" ").arg(fflags)); + QString cppflags = DomUtil::readEntry(dom, prefix + "cppflags"); + if (!cppflags.isEmpty()) + cmdline.prepend(QString("CPPFLAGS=\"%1\" ").arg(cppflags)); + QString ldflags = DomUtil::readEntry(dom, prefix + "ldflags"); + if (!ldflags.isEmpty()) + cmdline.prepend(QString("LDFLAGS=\"%1\" ").arg(ldflags)); + + QString configargs = DomUtil::readEntry(dom, prefix + "configargs"); + if (!configargs.isEmpty()) { + cmdline += " "; + cmdline += configargs; + } + + DomUtil::PairList envvars = + DomUtil::readPairListEntry(*projectDom(), prefix + "envvars", "envvar", "name", "value"); + + QString environstr; + DomUtil::PairList::ConstIterator it; + for (it = envvars.begin(); it != envvars.end(); ++it) { + environstr += (*it).first; + environstr += "="; + environstr += EnvVarTools::quote((*it).second); + environstr += " "; + } + cmdline.prepend(environstr); + + QString builddir = buildDirectory(); + QString dircmd; + + // if the build directory doesn't exist, add it's creation to the configureCommand + if ( !QFile::exists(builddir)) { + dircmd = "mkdir "; + dircmd += KProcess::quote(builddir); + dircmd += " && "; + } + + // add "cd into the build directory" to the configureCommand + dircmd += "cd "; + dircmd += KProcess::quote(builddir); + dircmd += " && "; + + return dircmd + cmdline; +} + +void AutoProjectPart::slotConfigure() +{ + QString cmdline = configureCommand(); + if (cmdline.isNull()) + return; + + makeFrontend()->queueCommand(buildDirectory(), cmdline); +} + +QString AutoProjectPart::makefileCvsCommand() const +{ + kdDebug(9020) << "makefileCvsCommand: runDirectory :" << runDirectory() << ":" <<endl; + kdDebug(9020) << "makefileCvsCommand: topsourceDirectory :" << topsourceDirectory() << ":" <<endl; + kdDebug(9020) << "makefileCvsCommand: makeEnvironment :" << makeEnvironment() << ":" <<endl; + kdDebug(9020) << "makefileCvsCommand: currentBuildConfig :" << currentBuildConfig() << ":" <<endl; + + + QString cmdline = DomUtil::readEntry(*projectDom(), "/kdevautoproject/make/makebin"); + if (cmdline.isEmpty()) + cmdline = MAKE_COMMAND; + + int prio = DomUtil::readIntEntry(*projectDom(), "/kdevautoproject/make/prio"); + QString nice; + kdDebug(9020) << "makefileCvsCommand() nice = " << prio<< endl; + if (prio != 0) { + nice = QString("nice -n%1 ").arg(prio); + } + + if (QFile::exists(topsourceDirectory() + "/Makefile.cvs")) + cmdline += " -f Makefile.cvs"; + else if (QFile::exists(topsourceDirectory() + "/Makefile.dist")) + cmdline += " -f Makefile.dist"; + else if (QFile::exists(topsourceDirectory() + "/autogen.sh")) + cmdline = "./autogen.sh"; + else { + KMessageBox::sorry(m_widget, i18n("There is neither a Makefile.cvs file nor an " + "autogen.sh script in the project directory.")); + return QString::null; + } + + cmdline.prepend(nice); + cmdline.prepend(makeEnvironment()); + + QString dircmd = "cd "; + dircmd += KProcess::quote(topsourceDirectory()); + dircmd += " && "; + + return dircmd + cmdline; +} + +void AutoProjectPart::slotMakefilecvs() +{ + QString cmdline = makefileCvsCommand(); + if ( cmdline.isNull() ) + return; + + makeFrontend()->queueCommand(projectDirectory(), cmdline); +} + + +void AutoProjectPart::slotInstall() +{ + startMakeCommand(buildDirectory(), QString::fromLatin1("install")); +} + + +void AutoProjectPart::slotInstallWithKdesu() +{ + // First issue "make" to build the entire project with the current user + // This way we make sure all files are up to date before we do the "make install" + slotBuild(); + + // After that issue "make install" with the root user + startMakeCommand(buildDirectory(), QString::fromLatin1("install"), true); +} + + +void AutoProjectPart::slotClean() +{ + startMakeCommand(buildDirectory(), QString::fromLatin1("clean")); +} + + +void AutoProjectPart::slotDistClean() +{ + startMakeCommand(buildDirectory(), QString::fromLatin1("distclean")); +} + + +void AutoProjectPart::slotMakeMessages() +{ + startMakeCommand(buildDirectory(), QString::fromLatin1("package-messages")); +} + + +/** Checks if the currently selected main program or, + * if no main Program was selected in the Run Options dialog, + * the currently active target is up-to-date and builds it if necessary. + * In the end checks if the program is already running and if not calls the + * slotExecute2() function to execute it or asks the user what to do. + */ +void AutoProjectPart::slotExecute() +{ + partController()->saveAllFiles(); + QDomDocument &dom = *projectDom(); + + m_runProg=m_runProg.isEmpty()?mainProgram():m_runProg; + + bool _auto = false; + if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/autocompile", true) && isDirty() ){ + m_executeAfterBuild = true; + if ( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) ){ + // A Main Program was specified, build all targets because we don't know which is it + kdDebug(9020) << "slotExecute: before slotBuild" << endl; + slotBuild(); + + } + else{ + // If no Main Program was specified, build the active target + kdDebug(9020) << "slotExecute: before slotBuildActiveTarget" << endl; + slotBuildActiveTarget(); + } + _auto = true; + } + + if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/autoinstall", false) && isDirty() ){ + m_executeAfterBuild = true; + // Use kdesu?? + if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/autokdesu", false) ){ + //slotInstallWithKdesu assumes that it hasn't just been build... + kdDebug(9020) << "slotExecute: before startMakeCommand" << endl; + _auto ? slotInstallWithKdesu() : startMakeCommand(buildDirectory(), QString::fromLatin1("install"), true); + } + else{ + kdDebug(9020) << "slotExecute: before slotInstall" << endl; + slotInstall(); + } + _auto = true; + } + + if ( _auto ){ + m_runProg.truncate(0); + return; + } + + if (appFrontend()->isRunning()) { + if (KMessageBox::questionYesNo(m_widget, i18n("Your application is currently running. Do you want to restart it?"), i18n("Application Already Running"), i18n("&Restart Application"), i18n("Do &Nothing")) == KMessageBox::No) + return; + connect(appFrontend(), SIGNAL(processExited()), SLOT(slotExecute2())); + appFrontend()->stopApplication(); + return; + } + kdDebug(9020) << "slotExecute: before slotExecute2" << endl; + slotExecute2(); +} + +void AutoProjectPart::executeTarget(const QDir& dir, const TargetItem* titem) +{ + m_executeAfterBuild=true; + partController()->saveAllFiles(); + + bool is_dirty = false; + QDateTime t = QFileInfo(dir , titem->name ).lastModified(); + QPtrListIterator<FileItem> it( titem->sources ); + for( ; it.current() ; ++it ) + { + if( t < QFileInfo(dir , (*it)->name).lastModified()) + is_dirty = true; + } + + if( DomUtil::readBoolEntry(*projectDom(), "/kdevautoproject/run/autocompile", true) && is_dirty ) + { + connect( makeFrontend(), SIGNAL(commandFinished(const QString&)), this, SLOT(slotExecuteTargetAfterBuild(const QString&)) ); + connect( makeFrontend(), SIGNAL(commandFailed(const QString&)), this, SLOT(slotNotExecuteTargetAfterBuildFailed(const QString&)) ); + + m_runProg=titem->name; + m_executeTargetAfterBuild.first = dir; + m_executeTargetAfterBuild.second = const_cast<TargetItem*>(titem); + + QString relpath = "/" + URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) + "/" + m_widget->selectedSubproject()->subdir; + kdDebug(9020) << "executeTarget: before buildTarget " << relpath << endl; + buildTarget(relpath, const_cast<TargetItem*>(titem)); + return; + } + + + bool inTerminal = DomUtil::readBoolEntry(*projectDom(), "/kdevautoproject/run/terminal"); + + QString program = environString(); + + if ( !titem ) { + KMessageBox::error( m_widget, i18n("There is no active target.\n" + "Unable to determine the main program"), i18n("No active target found") ); + kdDebug ( 9020 ) << k_funcinfo << "Error! : There's no active target! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl; + program += titem->name; + }else if ( titem->primary != "PROGRAMS" ) { + KMessageBox::error( m_widget, i18n("Active target \"%1\" is not binary ( %2 ).\n" + "Unable to determine the main program. If you want this\n" + "to be the active target, set a main program under\n" + "Project -> Project Options -> Run Options").arg(titem->name).arg(titem->primary), i18n("Active target is not a library") ); + kdDebug ( 9020 ) << k_funcinfo << "Error! : Active target isn't binary (" << titem->primary << ") ! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl; + program += titem->name; + }else + program += buildDirectory() + "/" + URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) + "/" + m_widget->selectedSubproject()->relativePath()+ "/" + titem->name; + + QString args = DomUtil::readEntry(*projectDom(), "/kdevautoproject/run/runarguments/" + titem->name); + + program += " " + args; + kdDebug(9020) << "executeTarget:cmd=" << dir.path() << " " << program << endl; + appFrontend()->startAppCommand(dir.path(), program ,inTerminal); + m_executeAfterBuild=false; + +} + +void AutoProjectPart::slotExecuteTargetAfterBuild(const QString& command) +{ + kdDebug(9020) << "slotExecuteTargetAfterBuild " << command << endl; + if ( m_executeAfterBuild && constructMakeCommandLine(m_executeTargetAfterBuild.first.path(), m_executeTargetAfterBuild.second->name) == command ) + { + disconnect( makeFrontend(), SIGNAL(commandFinished(const QString&)), this, SLOT(slotExecuteAfterTargetBuild()) ); + disconnect( makeFrontend(), SIGNAL(commandFailed(const QString&)), this, SLOT(slotExecuteAfterTargetBuildFailed()) ); + kdDebug(9020) << "slotExecuteTargetAfterBuild " << endl; + executeTarget(m_executeTargetAfterBuild.first, m_executeTargetAfterBuild.second); + } + +} + +void AutoProjectPart::slotNotExecuteTargetAfterBuildFailed(const QString& command) +{ + kdDebug(9020) << "executeTargetAfterBuildFailed" << endl; + if ( constructMakeCommandLine(m_executeTargetAfterBuild.first.path(), m_executeTargetAfterBuild.second->name) == command ) + { + m_executeAfterBuild=false; + disconnect( makeFrontend(), SIGNAL(commandFinished(const QString&)), this, SLOT(slotExecuteTargetAfterBuild()) ); + disconnect( makeFrontend(), SIGNAL(commandFailed(const QString&)), this, SLOT(slotNotExecuteTargetAfterBuildFailed()) ); + } +} + + +/* Get the run environment variables pairs into the environstr string + * in the form of: "ENV_VARIABLE=ENV_VALUE" + * Note that we quote the variable value due to the possibility of + * embedded spaces. */ +QString AutoProjectPart::environString() const +{ + DomUtil::PairList envvars = runEnvironmentVars(); + QString environstr; + DomUtil::PairList::ConstIterator it; + for (it = envvars.begin(); it != envvars.end(); ++it) { + environstr += (*it).first; + environstr += "="; + environstr += EnvVarTools::quote((*it).second); + environstr += " "; + } + return environstr; +} + +/** Executes the currently selected main program. + * If no main Program was selected in the Run Options dialog + * the currently active target is executed instead. + */ +void AutoProjectPart::slotExecute2() +{ + disconnect(appFrontend(), SIGNAL(processExited()), this, SLOT(slotExecute2())); + + if (m_runProg.isEmpty()){ + // Do not execute non executable targets + return; + } + + QString program = environString(); + // Adds the ./ that is necessary to execute the program in bash shells + if (!m_runProg.startsWith("/")){ + program += "./"; + } + program += m_runProg; + program += " " + runArguments(); + + bool inTerminal = DomUtil::readBoolEntry(*projectDom(), "/kdevautoproject/run/terminal"); + + kdDebug(9020) << "slotExecute2: runDirectory: <" << runDirectory() << ">" <<endl; + kdDebug(9020) << "slotExecute2: environstr : <" << environString() << ">" <<endl; + kdDebug(9020) << "slotExecute2: mainProgram : <" << mainProgram() << ">" <<endl; + kdDebug(9020) << "slotExecute2: runArguments: <" << runArguments() << ">" <<endl; + kdDebug(9020) << "slotExecute2: program : <" << program << ">" <<endl; + + appFrontend()->startAppCommand(runDirectory(), program, inTerminal); + m_executeAfterBuild=false; + m_runProg.truncate(0); +} + + +void AutoProjectPart::slotAddTranslation() +{ + AddTranslationDialog dlg(this, m_widget); + dlg.exec(); +} + + +void AutoProjectPart::slotBuildConfigChanged(const QString &config) +{ + DomUtil::writeEntry(*projectDom(), "/kdevautoproject/general/useconfiguration", config); + kdDebug(9020) << "Changed used configuration to " << config << endl; +} + + +void AutoProjectPart::slotBuildConfigAboutToShow() +{ + QStringList l = allBuildConfigs(); + buildConfigAction->setItems(l); + buildConfigAction->setCurrentItem(l.findIndex(currentBuildConfig())); +} + +void AutoProjectPart::restorePartialProjectSession ( const QDomElement* el ) +{ + m_widget->restoreSession ( el ); +} + +void AutoProjectPart::savePartialProjectSession ( QDomElement* el ) +{ + QDomDocument domDoc = el->ownerDocument(); + + KMessageBox::information ( 0, "Hallo, Welt!" ); + + kdDebug ( 9020 ) << k_funcinfo << "1" << endl; + + if ( domDoc.isNull() ) + { + kdDebug ( 9020 ) << k_funcinfo << "2" << endl; + return; + } + + kdDebug ( 9020 ) << k_funcinfo << "3" << endl; + + m_widget->saveSession ( el ); +} + +void AutoProjectPart::slotCommandFinished( const QString& command ) +{ + kdDebug(9020) << k_funcinfo << endl; + + if( m_buildCommand != command ) + return; + + m_buildCommand = QString::null; + + m_timestamp.clear(); + QStringList fileList = allFiles(); + QStringList::Iterator it = fileList.begin(); + while( it != fileList.end() ){ + QString fileName = *it; + ++it; + + m_timestamp[ fileName ] = QFileInfo( projectDirectory(), fileName ).lastModified(); + } + + emit projectCompiled(); + + // reset the "last compilation has failed" flag + m_lastCompilationFailed = false; + + if( m_executeAfterBuild ){ + slotExecute(); + } +} + +void AutoProjectPart::slotCommandFailed( const QString& /*command*/ ) +{ + kdDebug(9020) << "slotCommandFinished " << k_funcinfo << endl; + + m_lastCompilationFailed = true; + m_executeAfterBuild=false; +} + +bool AutoProjectPart::isDirty() +{ + if (m_lastCompilationFailed) return true; + + QStringList fileList = allFiles(); + QStringList::Iterator it = fileList.begin(); + while( it != fileList.end() ){ + QString fileName = *it; + ++it; + + QMap<QString, QDateTime>::Iterator it = m_timestamp.find( fileName ); + QDateTime t = QFileInfo( projectDirectory(), fileName ).lastModified(); + if( it == m_timestamp.end() || *it != t ){ + return true; + } + } + + return false; +} + +void AutoProjectPart::needMakefileCvs( ) +{ + m_needMakefileCvs = true; +} + +bool AutoProjectPart::isKDE() const +{ + return m_isKDE; +} + +KDevProject::Options AutoProjectPart::options() const +{ + return UsesAutotoolsBuildSystem; +} + +QStringList recursiveATFind( const QString &currDir, const QString &baseDir ) +{ + kdDebug(9020) << "Dir " << currDir << endl; + QStringList fileList; + + if( !currDir.contains( "/..") && !currDir.contains("/.") ) + { + QDir dir(currDir); + QStringList dirList = dir.entryList(QDir::Dirs ); + QStringList::Iterator idx = dirList.begin(); + for( ; idx != dirList.end(); ++idx ) + { + fileList += recursiveATFind( currDir + "/" + (*idx),baseDir ); + } + QStringList newFiles = dir.entryList("*.am *.in"); + idx = newFiles.begin(); + for( ; idx != newFiles.end(); ++idx ) + { + QString file = currDir + "/" + (*idx); + fileList.append( file.remove( baseDir ) ); + } + } + + + return fileList; +} + +/*! + \fn AutoProjectPart::distFiles() const + */ +QStringList AutoProjectPart::distFiles() const +{ + QStringList sourceList = allFiles(); + // Scan current source directory for any .pro files. + QString projectDir = projectDirectory(); + QDir dir(projectDir); + QDir admin(projectDir +"/admin"); + QStringList files = dir.entryList( "Makefile.cvs Makefile.am configure* INSTALL README NEWS TODO ChangeLog COPYING AUTHORS stamp-h.in acinclude.m4 config.h.in Makefile.in install-sh config.sub config.guess mkinstalldirs missing ltmain.sh depcomp"); + QStringList adminFiles = admin.entryList(QDir::Files); + QStringList::Iterator idx = adminFiles.begin(); + for( ; idx != adminFiles.end(); ++idx) + { + files.append( "admin/" + (*idx) ); + } + QStringList srcDirs = dir.entryList(QDir::Dirs); + idx = srcDirs.begin(); + for(; idx != srcDirs.end(); ++idx) + { + sourceList += recursiveATFind( projectDirectory() + "/" + (*idx), projectDirectory()); + } + return sourceList + files; +} + +void AutoProjectPart::startSimpleMakeCommand( const QString & dir, const QString & command, bool withKdesu ) +{ + if (partController()->saveAllFiles()==false) + return; //user cancelled + + // m_buildCommand = constructMakeCommandLine(dir, target); + + QString cmdline = command; + cmdline.prepend(makeEnvironment()); + + QString dircmd = "cd "; + dircmd += KProcess::quote(dir); + dircmd += " && "; + + m_buildCommand = dircmd + cmdline; + + if (withKdesu) + m_buildCommand = "kdesu -t -c '" + m_buildCommand + "'"; + + if (!m_buildCommand.isNull()) + makeFrontend()->queueCommand(dir, m_buildCommand); +} + +QString AutoProjectPart::getAutoConfFile(const QString& dir){ + + QFile inFile(dir + "/configure.in"); + QFile acFile(dir + "/configure.ac"); + if ( inFile.exists()){ + return inFile.name(); + }else if (acFile.exists()){ + return acFile.name(); + } + return acFile.name();; +} + +#include "autoprojectpart.moc" + +// kate: space-indent on; indent-width 4; diff --git a/buildtools/autotools/autoprojectpart.h b/buildtools/autotools/autoprojectpart.h new file mode 100644 index 00000000..d0862cc3 --- /dev/null +++ b/buildtools/autotools/autoprojectpart.h @@ -0,0 +1,153 @@ +/*************************************************************************** +* Copyright (C) 2001-2002 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* Copyright (C) 2002 by Victor R�er * +* victor_roeder@gmx.de * +* * +* 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 _AUTOPROJECTPART_H_ +#define _AUTOPROJECTPART_H_ + +#include <qdict.h> +#include <qguardedptr.h> +#include <qmap.h> +#include <qdatetime.h> +#include <qdir.h> +#include <kdevgenericfactory.h> +#include "kdevbuildtool.h" + +class QDomElement; +class QStringList; +class KDialogBase; +class AutoProjectWidget; +class KSelectAction; +class TargetItem; +class ConfigWidgetProxy; + +class AutoProjectPart : public KDevBuildTool +{ + Q_OBJECT + +public: + AutoProjectPart( QObject *parent, const char *name, const QStringList &args ); + virtual ~AutoProjectPart(); + + /** + * Implementation of the KDevProject interface. + */ + virtual QString projectDirectory() const; + virtual QString projectName() const; + virtual DomUtil::PairList runEnvironmentVars() const; + virtual QString runDirectory() const; + virtual QString mainProgram() const; + virtual QString debugArguments() const; + virtual QString runArguments() const; + virtual QString environString() const; + virtual QString activeDirectory() const; + virtual QStringList allFiles() const; + virtual void addFile( const QString &fileName ); + virtual void addFiles ( const QStringList& fileList ); + virtual void removeFile( const QString &fileName ); + virtual void removeFiles ( const QStringList& fileList ); + virtual QString buildDirectory() const; + virtual Options options() const; + + /** + * Implementation of the KDevPlugin interface. + */ + virtual void restorePartialProjectSession ( const QDomElement* el ); + virtual void savePartialProjectSession ( QDomElement* el ); + + /** + * automake specific methods. + */ + QStringList allBuildConfigs() const; + QString currentBuildConfig() const; + QString topsourceDirectory() const; + void startMakeCommand( const QString &dir, const QString &target, bool withKdesu = false ); + void startSimpleMakeCommand( const QString &dir, const QString &command, bool withKdesu = false ); + void buildTarget( QString relpath, TargetItem* titem ); + void executeTarget( const QDir& dir, const TargetItem* titem ); + + void needMakefileCvs(); + bool isDirty(); + bool isKDE() const; + QStringList distFiles() const; + QString getAutoConfFile(const QString& dir); + +protected: + /** + * Reimplemented from KDevProject. These methods are only + * for use by the application core. + */ + virtual void openProject( const QString &dirName, const QString &projectName ); + virtual void closeProject(); + +private slots: + // void projectConfigWidget(KDialogBase *dlg); + void slotAddTranslation(); + void slotBuild(); + void slotBuildActiveTarget(); + void slotCompileFile(); + void slotClean(); + void slotDistClean(); + void slotInstall(); + void slotInstallWithKdesu(); + void slotMakefilecvs(); + void slotMakeMessages(); + void slotConfigure(); + void slotExecute(); + void slotExecute2(); + void slotExecuteTargetAfterBuild( const QString& command ); + void slotNotExecuteTargetAfterBuildFailed( const QString& command ); + void slotBuildConfigChanged( const QString &config ); + void slotBuildConfigAboutToShow(); + void slotCommandFinished( const QString& command ); + void slotCommandFailed( const QString& command ); + //void slotImportExisting(); + void insertConfigWidget( const KDialogBase* dlg, QWidget * page, unsigned int ); + + +private: + QGuardedPtr<AutoProjectWidget> m_widget; + QString m_projectName; + QString m_projectPath; + KSelectAction *buildConfigAction; + + QString makeEnvironment() const; + void setWantautotools(); + QString makefileCvsCommand() const; + QString configureCommand() const; + + QMap<QString, QDateTime> m_timestamp; + bool m_executeAfterBuild; + QString m_buildCommand; + bool m_needMakefileCvs; + bool m_lastCompilationFailed; + bool m_isKDE; + QPair<QDir, TargetItem*> m_executeTargetAfterBuild; + QString m_runProg; + + ConfigWidgetProxy * _configProxy; + + // Enble AutoProjectWidget to emit our signals + friend class AutoProjectWidget; + friend class AddSubprojectDialog; + friend class FileItem; + + // For make commands queuing + QString constructMakeCommandLine( const QString &dir, const QString &target ) const; + bool queueInternalLibDependenciesBuild( TargetItem* titem, QStringList& list ); +}; + +typedef KDevGenericFactory<AutoProjectPart> AutoProjectFactory; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/autoprojectviewbase.ui b/buildtools/autotools/autoprojectviewbase.ui new file mode 100644 index 00000000..ad5142ba --- /dev/null +++ b/buildtools/autotools/autoprojectviewbase.ui @@ -0,0 +1,123 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>AutoProjectViewBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>AutoProjectViewBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>245</width> + <height>334</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>4</number> + </property> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="spacing"> + <number>2</number> + </property> + <widget class="QToolButton"> + <property name="name"> + <cstring>m_button1</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="QToolButton"> + <property name="name"> + <cstring>m_button2</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="QToolButton"> + <property name="name"> + <cstring>m_button3</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="QToolButton"> + <property name="name"> + <cstring>m_button4</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <widget class="QToolButton"> + <property name="name"> + <cstring>m_button5</cstring> + </property> + <property name="text"> + <string></string> + </property> + </widget> + <spacer> + <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>40</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QToolButton"> + <property name="name"> + <cstring>m_optionsButton</cstring> + </property> + <property name="text"> + <string></string> + </property> + <property name="toolTip" stdset="0"> + <string>Options</string> + </property> + </widget> + </hbox> + </widget> + <widget class="KListView" row="1" column="0"> + <property name="name"> + <cstring>m_listView</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + <property name="fullWidth"> + <bool>false</bool> + </property> + </widget> + </grid> +</widget> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/buildtools/autotools/autoprojectwidget.cpp b/buildtools/autotools/autoprojectwidget.cpp new file mode 100644 index 00000000..c3248504 --- /dev/null +++ b/buildtools/autotools/autoprojectwidget.cpp @@ -0,0 +1,748 @@ +/* + KDevelop Autotools Support + Copyright (c) 2001-2002 by Bernd Gehrmann <bernd@kdevelop.org> + Copyright (c) 2002 by Victor Roeder <victor_roeder@gmx.de> + Copyright (c) 2005 by Matt Rogers <mattr@kde.org> + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + *************************************************************************** +*/ + + +#include "autoprojectwidget.h" + +#include <qcheckbox.h> +#include <qdom.h> +#include <qfile.h> +#include <qheader.h> +#include <qpainter.h> +#include <qptrstack.h> +#include <qregexp.h> +#include <qsplitter.h> +#include <qstringlist.h> +#include <qtextstream.h> +#include <qtoolbutton.h> +#include <qtooltip.h> +#include <qwhatsthis.h> +#include <qtimer.h> + +#include <kdebug.h> +#include <kfiledialog.h> +#include <klistview.h> +#include <kmessagebox.h> +#include <kregexp.h> +#include <kurl.h> +#include <kfile.h> +#include <kxmlguiclient.h> +#include <kaction.h> + +#include "kdevcore.h" +#include "domutil.h" +#include "misc.h" +#include "choosetargetdialog.h" + +#include "autolistviewitems.h" + +#include "autoprojectpart.h" +#include "autosubprojectview.h" +#include "autodetailsview.h" +#include "urlutil.h" +#include "makefilehandler.h" + +static QString nicePrimary( const QString &primary ) +{ + if ( primary == "PROGRAMS" ) + return i18n( "Program" ); + else if ( primary == "LIBRARIES" ) + return i18n( "Library" ); + else if ( primary == "LTLIBRARIES" ) + return i18n( "Libtool Library" ); + else if ( primary == "SCRIPTS" ) + return i18n( "Script" ); + else if ( primary == "HEADERS" ) + return i18n( "Header" ); + else if ( primary == "DATA" ) + return i18n( "Data" ); + else if ( primary == "JAVA" ) + return i18n( "Java" ); + else + return QString::null; +} + + +AutoProjectWidget::AutoProjectWidget( AutoProjectPart *part, bool kde ) + : QVBox( 0, "auto project widget" ) +{ + m_part = part; + m_kdeMode = kde; + m_activeSubproject = 0; + m_activeTarget = 0; + m_shownSubproject = 0; + m_choosenTarget = 0; + m_makefileHandler = new MakefileHandler(); + + QSplitter *splitter = new QSplitter(Vertical, this); + + initOverview ( splitter ); + initDetailview ( splitter ); + + initActions (); +} + + +AutoProjectWidget::~AutoProjectWidget() +{ + delete m_makefileHandler; +} + +void AutoProjectWidget::initOverview ( QWidget* parent ) +{ + m_subprojectView = new AutoSubprojectView( this, m_part, parent, "project overview widget" ); +} + +void AutoProjectWidget::initDetailview ( QWidget* parent ) +{ + m_detailView = new AutoDetailsView( this, m_part, parent, "project details widget" ); +} + +void AutoProjectWidget::initActions() +{ + connect( m_subprojectView, SIGNAL( selectionChanged( QListViewItem* ) ), + this, SLOT( slotOverviewSelectionChanged( QListViewItem* ) ) ); +} + +AutoSubprojectView* AutoProjectWidget::getSubprojectView () +{ + return m_subprojectView; +} + +AutoDetailsView* AutoProjectWidget::getDetailsView () +{ + return m_detailView; +} + +void AutoProjectWidget::openProject( const QString &dirName ) +{ + m_subprojectView->loadMakefileams ( dirName ); + MakefileHandler mfh; + mfh.parse( m_part->projectDirectory(), true ); + +} + + +void AutoProjectWidget::closeProject() +{ + m_shownSubproject = 0; + m_subprojectView->listView()->clear(); + m_detailView->listView()->clear(); +} + +SubprojectItem* AutoProjectWidget::activeSubproject () +{ + return m_activeSubproject; +} + +TargetItem* AutoProjectWidget::activeTarget () +{ + return m_activeTarget; +} + +QStringList AutoProjectWidget::allSubprojects() +{ + int prefixlen = m_part->projectDirectory().length() + 1; + QStringList res; + + QListViewItemIterator it( m_subprojectView->listView() ); + for ( ; it.current(); ++it ) + { + // Skip root subproject + // if ( it.current() == m_subprojectView->firstChild() ) + // continue; + QString path = static_cast<SubprojectItem*>( it.current() ) ->path; + res.append( path.mid( prefixlen ) ); + } + + return res; +} + +QPtrList <SubprojectItem> AutoProjectWidget::allSubprojectItems() +{ + QPtrList <SubprojectItem> res; + + QListViewItemIterator it ( m_subprojectView->listView() ); + + for ( ; it.current(); ++it ) + { + // Skip root subproject + // if ( it.current() == m_subprojectView->firstChild() ) + // continue; + + SubprojectItem* spitem = static_cast <SubprojectItem*> ( it.current() ); + res.append ( spitem ); + } + + return res; +} + +SubprojectItem* AutoProjectWidget::subprojectItemForPath(const QString & path, bool pathIsAbsolute) +{ + kdDebug(9020) << "Looking for path " << path << endl; + + int prefixLen = m_part->projectDirectory().length() + 1; + QListViewItemIterator it( m_subprojectView->listView() ); + for(; it.current(); ++it) + { + SubprojectItem* spitem = static_cast<SubprojectItem*>(it.current() ); + QString relpath = (spitem->path).mid(prefixLen); + kdDebug(9020) << " ... checking -" << spitem->path << "-" << endl; + kdDebug(9020) << " ... (tailored: -" << relpath << "- against -" << (pathIsAbsolute ? path.mid(prefixLen) : path) << "- )" << endl; + if ( relpath == (pathIsAbsolute ? path.mid(prefixLen) : path)) + { + kdDebug(9020) << "Found it!" << endl; + return spitem; + } + } + kdDebug(9020) << "Not found" << endl; + return NULL; +} + +QString AutoProjectWidget::pathForTarget(const TargetItem *titem) const +{ + + if (!titem) + return QString::null; + + kdDebug(9020) << "Looking for target " << titem->name << endl; + int prefixLen = m_part->projectDirectory().length() + 1; + QListViewItemIterator it( m_subprojectView->listView() ); + for(; it.current(); ++it) + { + SubprojectItem* spitem = static_cast<SubprojectItem*>(it.current() ); + kdDebug(9020) << "Checking: " << spitem->path << endl; + if (spitem->targets.containsRef(titem)) + { + kdDebug(9020) << "Found it!" << endl; + QString relpath = (spitem->path).mid(prefixLen); + return relpath; + } + } + kdDebug(9020) << "Not found" << endl; + return QString::null; +} + +QStringList AutoProjectWidget::allLibraries() +{ + int prefixlen = m_part->projectDirectory().length() + 1; + QStringList res; + + QListViewItemIterator it( m_subprojectView->listView() ); + for ( ; it.current(); ++it ) + { + SubprojectItem *spitem = static_cast<SubprojectItem*>( it.current() ); + QString path = spitem->path; + QPtrListIterator<TargetItem> tit( spitem->targets ); + for ( ; tit.current(); ++tit ) + { + QString primary = ( *tit ) ->primary; + if ( primary == "LIBRARIES" || primary == "LTLIBRARIES" ) + { + QString fullname = path + "/" + ( *tit ) ->name; + res.append( fullname.mid( prefixlen ) ); + } + } + } + + return res; +} + + +QStringList AutoProjectWidget::allFiles() +{ + QPtrStack<QListViewItem> s; + QMap<QString, bool> dict; + + for ( QListViewItem * item = m_subprojectView->listView()->firstChild(); item; + item = item->nextSibling() ? item->nextSibling() : s.pop() ) + { + if ( item->firstChild() ) + s.push( item->firstChild() ); + + SubprojectItem *spitem = static_cast<SubprojectItem*>( item ); + // use URLUtil so paths in root project dir are worked out correctly + QString relPath = URLUtil::relativePath(m_part->projectDirectory(), spitem->path, URLUtil::SLASH_SUFFIX); + QPtrListIterator<TargetItem> tit( spitem->targets ); + for ( ; tit.current(); ++tit ) + { + QPtrListIterator<FileItem> fit( tit.current() ->sources ); + for ( ; fit.current(); ++fit ) + { + + if((*fit)->is_subst) + continue; + + QFileInfo fileInfo( (*fit)->name ); + if( fileInfo.extension() == "ui" ) + { + dict.insert( relPath + fileInfo.baseName() + ".h", true ); + dict.insert( relPath + fileInfo.baseName() + ".cpp", true ); + } + + dict.insert( relPath + ( *fit ) ->name, true ); + } + } + } + + // Files may be in multiple targets, so we have to remove + // duplicates + QStringList res; + QMap<QString, bool>::Iterator it = dict.begin(); + while( it != dict.end() ){ + res << it.key(); + ++it; + } + + return res; +} + + +QString AutoProjectWidget::subprojectDirectory() +{ + if ( !selectedSubproject() ) + return QString::null; + + return selectedSubproject()->path; +} + + +void AutoProjectWidget::setActiveTarget( const QString &targetPath ) +{ + int prefixlen = m_part->projectDirectory().length() + 1; + QString olddir = m_part->activeDirectory(); + m_activeSubproject = 0; + m_activeTarget = 0; + + QListViewItemIterator it( m_subprojectView->listView() ); + for ( ; it.current(); ++it ) + { + SubprojectItem *spitem = static_cast<SubprojectItem*>( it.current() ); + QString path = spitem->path; + QPtrListIterator<TargetItem> tit( spitem->targets ); + for ( ; tit.current(); ++tit ) + { + QString primary = ( *tit ) ->primary; + if ( primary != "PROGRAMS" && primary != "LIBRARIES" + && primary != "LTLIBRARIES" && primary != "JAVA" ) + continue; + + QString currentTargetPath = ( path + "/" + ( *tit ) ->name ).mid( prefixlen ); + + bool hasTarget = ( targetPath == currentTargetPath ); + ( *tit )->setBold( hasTarget ); + if ( hasTarget ) + { + spitem->setBold( true ); + m_activeSubproject = spitem; + m_activeTarget = ( *tit ); + m_subprojectView->listView()->setSelected( m_activeSubproject, true ); + m_subprojectView->listView()->ensureItemVisible ( m_activeSubproject ); + m_subprojectView->listView()->viewport()->update(); + m_detailView->listView()->setSelected ( m_activeTarget, true ); + m_detailView->listView()->ensureItemVisible ( m_activeTarget ); + m_detailView->listView()->viewport()->update(); + } + else + { + // to avoid a setBold ( false ) if there's another target in the current Subproject (i.e. spitem) ... + spitem->setBold ( ( m_activeSubproject == spitem ) ); + m_detailView->listView()->viewport()->update(); + } + } + } + if( olddir != m_part->activeDirectory() ) + { + emit m_part->activeDirectoryChanged( olddir, m_part->activeDirectory() ); + } + + if ( m_activeSubproject == 0 && m_activeTarget == 0 ) + { + m_subprojectView->listView()->setSelected ( m_subprojectView->listView()->firstChild(), true ); + m_subprojectView->listView()->ensureItemVisible ( m_subprojectView->listView()->firstChild() ); + m_subprojectView->listView()->viewport()->update(); + } +} + + +QString AutoProjectWidget::activeDirectory() +{ + if ( m_activeSubproject ) + return m_activeSubproject->path.mid( m_part->projectDirectory().length() + 1 ); + else + { +/* if ( selectedSubproject() ) + return selectedSubproject()->path; + else*/ + return QString::null; + } +} + + +void AutoProjectWidget::addFiles( const QStringList &list ) +{ + QDomDocument &dom = *m_part->projectDom(); + QStringList fileList = list; + + if ( DomUtil::readBoolEntry( dom, "/kdevautoproject/general/useactivetarget" ) ) + { + QStringList::iterator it; + + QString fileName; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) + { + int pos = ( *it ).findRev('/'); + if (pos != -1) + fileName = ( *it ).mid(pos+1); + else + fileName = ( *it ); + + //FileItem * fitem = createFileItem( fileName,m_activeSubproject ); + //m_activeTarget->sources.append( fitem ); + //m_activeTarget->insertItem( fitem ); + + /// @todo Merge with code in addfiledlg.cpp + // Check wether a selected subproject+target exists and matches this file + // If so use that as target. + if( m_detailView->listView()->selectedItem() && m_subprojectView->listView()->selectedItem() ) + { + TargetItem *titem = dynamic_cast <TargetItem*> ( m_detailView->listView()->selectedItem() ); + SubprojectItem * subitem = dynamic_cast <SubprojectItem*> ( m_subprojectView->listView()->selectedItem() ); + QString relativeDir = URLUtil::directory(*it); + SubprojectItem* spitem = subprojectItemForPath(relativeDir); + + if( titem && subitem && subitem == spitem ) + { + addToTarget(fileName, subitem, titem); + }else + { + addToTarget(fileName, m_activeSubproject, m_activeTarget); + } + }else + { + addToTarget(fileName, m_activeSubproject, m_activeTarget); + } + +// QString canontargetname = AutoProjectTool::canonicalize( m_activeTarget->name ); +// QString varname = canontargetname + "_SOURCES"; +// m_activeSubproject->variables[ varname ] += ( " " + fileName ); +// +// QMap<QString, QString> replaceMap; +// replaceMap.insert( varname, m_activeSubproject->variables[ varname ] ); +// +// AutoProjectTool::addToMakefileam( m_activeSubproject->path + "/Makefile.am", replaceMap ); + } + + emitAddedFiles ( list ); + } + else + { + QStringList doManually, doneAutomatically; + // First check wether the detail view has a selected target and the subproject + // view selected subproject matches the path of the new file. Then + // we can assume the user used the right-click option on the target + for( QStringList::iterator it = fileList.begin(); it != fileList.end(); ++it) + { + bool autoAdded = false; + if( m_detailView->listView()->selectedItem() && m_subprojectView->listView()->selectedItem() ) + { + TargetItem *titem = dynamic_cast <TargetItem*> ( m_detailView->listView()->selectedItem() ); + SubprojectItem * subitem = dynamic_cast <SubprojectItem*> ( m_subprojectView->listView()->selectedItem() ); + QString relativeDir = URLUtil::directory(*it); + SubprojectItem* spitem = subprojectItemForPath(relativeDir); + if( titem && subitem && subitem == spitem ) + { + addToTarget(URLUtil::filename(*it), subitem, titem); + autoAdded = true; + doneAutomatically << *it; + } + } + if(!autoAdded) doManually << *it; + } + + // See if we can figure out the target for each file without asking the user + // I think it's a valid assumption that if a directory contains only one target + // the file can be added to that target (Julian Rockey linux at jrockey.com) + QStringList temp = doManually; + doManually.clear(); + for(QStringList::iterator it = temp.begin();it!=temp.end();++it) + { + bool autoAdded = false; + QString relativeDir = URLUtil::directory(*it); + SubprojectItem* spitem = subprojectItemForPath(relativeDir); + if (spitem) + { + QPtrList<TargetItem> titemList = spitem->targets; + if (titemList.count()==1) { + addToTarget( URLUtil::filename(*it), spitem, titemList.first() ); + doneAutomatically.append(*it); + autoAdded = true; + } + } + + // add to manual list if this file wasn't auto-added + if (!autoAdded) doManually.append(*it); + } + if (doneAutomatically.count()>0) emitAddedFiles(doneAutomatically); + + // raise dialog for any files that weren't added automatically + if (doManually.count()>0) { + ChooseTargetDialog chooseTargetDlg ( this, m_part, doManually, this, "choose target dialog" ); + + //chooseTargetDlg = new ChooseTargetDialog ( this, this, "choose target dialog" ); + + if ( chooseTargetDlg.exec() && chooseTargetDlg.alwaysUseActiveTarget() ) + DomUtil::writeBoolEntry( dom, "/kdevautoproject/general/useactivetarget", true ); + } + } +} + +void AutoProjectWidget::addToTarget(const QString & fileName, SubprojectItem* spitem, TargetItem* titem) +{ + QString varname; + /// \FIXME a quick hack to prevent adding header files to _SOURCES and display them in noinst_HEADERS + if (AutoProjectPrivate::isHeader(fileName) && + ( titem->primary == "PROGRAMS" || titem->primary == "LIBRARIES" || titem->primary == "LTLIBRARIES" ) ) + { + kdDebug ( 9020 ) << "Ignoring header file and adding it to noinst_HEADERS: " << fileName << endl; + TargetItem* noinst_HEADERS_item = getSubprojectView()->findNoinstHeaders(spitem); + FileItem *fitem = createFileItem( fileName, spitem ); + noinst_HEADERS_item->sources.append( fitem ); + noinst_HEADERS_item->insertItem( fitem ); + varname = "noinst_HEADERS"; + } + else + { + FileItem * fitem = createFileItem( fileName, spitem ); + titem->sources.append( fitem ); + titem->insertItem( fitem ); + + QString canontargetname = AutoProjectTool::canonicalize( titem->name ); + varname = canontargetname + "_SOURCES"; + } + spitem->variables[ varname ] += ( " " + fileName ); + + QMap<QString, QString> replaceMap; + replaceMap.insert( varname, spitem->variables[ varname ] ); + + AutoProjectTool::addToMakefileam( spitem->path + "/Makefile.am", replaceMap ); + + m_detailView->slotSelectionChanged( spitem ); +} + +void AutoProjectWidget::removeFiles( const QStringList &list ) +{ + Q_UNUSED( list ) +} + +void AutoProjectWidget::slotOverviewSelectionChanged( QListViewItem *item ) +{ + if ( !item ) + return; + + // Delete the items from the details view first. + if ( m_shownSubproject ) + { + // Remove all TargetItems and all of their children from the view + kdDebug ( 9020 ) << "m_shownSubproject (before takeItem()): " << m_shownSubproject->subdir << endl; + + QListViewItem* i = m_detailView->listView()->firstChild(); + while( i ) + { + QListViewItem* o = i; + i = i->nextSibling(); + m_detailView->listView()->takeItem(o); + } + } + + // We assume here that ALL items in the over list view + // are SubprojectItem's + m_shownSubproject = dynamic_cast<SubprojectItem*>( item ); + if ( !m_shownSubproject) return; + kdDebug ( 9020 ) << "m_shownSubproject (after takeItem()): " << selectedSubproject()->subdir << endl; + + // Insert all TargetItems and all of their children into the view + QPtrListIterator<TargetItem> it2( selectedSubproject()->targets ); + for ( ; it2.current(); ++it2 ) + { + kdDebug ( 9020 ) << "insertItem in detail " << ( *it2 )->name << endl; + m_detailView->listView()->insertItem( *it2 ); + QPtrListIterator<FileItem> it3( ( *it2 ) ->sources ); + for ( ; it3.current(); ++it3 ) + ( *it2 )->insertItem( *it3 ); + QString primary = ( *it2 ) ->primary; + if ( primary == "PROGRAMS" || primary == "LIBRARIES" || + primary == "LTLIBRARIES" || primary == "JAVA" ) + ( *it2 ) ->setOpen( true ); + } +} + +TargetItem *AutoProjectWidget::selectedTarget() +{ + ProjectItem * pvitem = static_cast<ProjectItem*>( m_detailView->listView()->selectedItem() ); + if ( !pvitem || ( pvitem->type() != ProjectItem::Target ) ) + return 0; + + return static_cast<TargetItem*>( pvitem ); +} + + +FileItem *AutoProjectWidget::selectedFile() +{ + ProjectItem * pvitem = static_cast<ProjectItem*>( m_detailView->listView()->selectedItem() ); + if ( !pvitem || ( pvitem->type() != ProjectItem::File ) ) + return 0; + + return static_cast<FileItem*>( pvitem ); +} + +SubprojectItem* AutoProjectWidget::selectedSubproject() +{ + ProjectItem * pvitem = static_cast <SubprojectItem*> ( m_subprojectView->listView()->selectedItem() ); + + if ( !pvitem || ( pvitem->type() != ProjectItem::Subproject ) ) + return 0; + + return static_cast <SubprojectItem*> ( pvitem ); +} + +TargetItem *AutoProjectWidget::createTargetItem( const QString &name, + const QString &prefix, const QString &primary, + bool take ) +{ + bool docgroup = ( primary == "KDEDOCS" ); + bool icongroup = ( primary == "KDEICON" ); + bool group = !(docgroup || icongroup); + + QString text; + if ( docgroup ) + text = i18n( "Documentation data" ); + else if ( icongroup ) + text = i18n( "KDE Icon data" ).arg( prefix ); + else + text = i18n( "%1 (%2 in %3)" ).arg( name ).arg( nicePrimary( primary ) ).arg( prefix ); + + // Workaround because of QListView not being able to create + // items without actually inserting them + TargetItem *titem = new TargetItem( m_detailView->listView(), group, text ); + titem->name = name; + titem->prefix = prefix; + titem->primary = primary; + if( take ) + m_detailView->listView()->takeItem( titem ); + + return titem; +} + + +FileItem *AutoProjectWidget::createFileItem( const QString &name, SubprojectItem *subproject ) +{ + bool is_subst; + if(name.find("$(") == 0 || name.find("${") == 0) + is_subst = true; + else + is_subst = false; + + FileItem * fitem = new FileItem( m_subprojectView->listView(), name, is_subst ); + fitem->uiFileLink = m_detailView->getUiFileLink(subproject->relativePath()+"/", name ); + m_subprojectView->listView()->takeItem( fitem ); + fitem->name = name; + + return fitem; +} + + +void AutoProjectWidget::emitAddedFiles( const QStringList &fileList ) +{ + emit m_part->addedFilesToProject( fileList ); +} + +void AutoProjectWidget::emitAddedFile( const QString &name ) +{ + QStringList fileList; + fileList.append ( name ); + emit m_part->addedFilesToProject( fileList ); +} + +void AutoProjectWidget::emitRemovedFiles( const QStringList &fileList ) +{ + emit m_part->removedFilesFromProject( fileList ); +} + +void AutoProjectWidget::emitRemovedFile( const QString &name ) +{ + QStringList fileList; + fileList.append ( name ); + emit m_part->removedFilesFromProject( fileList ); +} + +void AutoProjectWidget::restoreSession ( const QDomElement* el ) +{ + Q_UNUSED( el ); +} + +void AutoProjectWidget::saveSession ( QDomElement* el ) +{ + if ( m_activeTarget && m_activeSubproject ) + { + QDomDocument domDoc = el->ownerDocument(); + + QString activeTargetPath = m_activeSubproject->path.mid ( m_part->project()->projectDirectory().length() + 1 ); + activeTargetPath = activeTargetPath + "/" + m_activeTarget->name; + + QDomElement generalEl = domDoc.createElement("general"); + + kdDebug ( 9020 ) << k_funcinfo << "Saving session data of AutoProjectWidget: " << activeTargetPath << endl; + + generalEl.setAttribute("activetarget", activeTargetPath); + el->appendChild(generalEl); + } +} + +void AutoProjectWidget::setActiveSubproject( SubprojectItem * spitem ) +{ + QString olddir = m_part->activeDirectory(); + m_activeSubproject = spitem; + emit m_part->activeDirectoryChanged( olddir, m_part->activeDirectory() ); +} + +void AutoProjectWidget::focusInEvent( QFocusEvent */*e*/ ) +{ + switch (m_lastFocusedView) + { + case DetailsView: + m_detailView->listView()->setFocus(); + break; + case SubprojectView: + default: + m_subprojectView->listView()->setFocus(); + } +} + +void AutoProjectWidget::setLastFocusedView( AutoProjectView view ) +{ + m_lastFocusedView = view; +} + +#include "autoprojectwidget.moc" + +MakefileHandler* AutoProjectWidget::makefileHandler() +{ + return m_makefileHandler; +} +//kate: indent-mode csands; tab-width 4; space-indent off; + diff --git a/buildtools/autotools/autoprojectwidget.h b/buildtools/autotools/autoprojectwidget.h new file mode 100644 index 00000000..0f4a8b13 --- /dev/null +++ b/buildtools/autotools/autoprojectwidget.h @@ -0,0 +1,229 @@ +/* + KDevelop Autotools Support + Copyright (c) 2001-2002 by Bernd Gehrmann <bernd@kdevelop.org> + Copyright (c) 2002 by Victor Roeder <victor_roeder@gmx.de> + Copyright (c) 2005 by Matt Rogers <mattr@kde.org> + +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +*************************************************************************** +*/ + +#ifndef _AUTOPROJECTWIDGET_H_ +#define _AUTOPROJECTWIDGET_H_ + +#include <qdict.h> +#include <qlistview.h> +#include <qmap.h> +#include <qvbox.h> +#include <qhbox.h> +#include <qlayout.h> +#include <qtoolbutton.h> +#include <kiconloader.h> +#include <klocale.h> + +#include "domutil.h" +#include "makefilehandler.h" + +class AutoProjectPart; +class AutoSubprojectView; +class AutoDetailsView; +class SubprojectItem; +class TargetItem; +class FileItem; +class KAction; +class QDomElement; +class QToolButton; +class QStringList; +class QFocusEvent; +class KListViewItem; +class QListViewItem; +class MakefileHandler; + +class AutoProjectWidget : public QVBox +{ + Q_OBJECT + friend class RemoveFileDialog; + friend class TargetOptionsDialog; // to access projectDom() via m_part->projectDom() +public: + AutoProjectWidget( AutoProjectPart *part, bool kde ); + ~AutoProjectWidget(); + + void openProject( const QString &dirName ); + void closeProject(); + + /** + * A list of the (relative) names of all subprojects (== subdirectories) + */ + QStringList allSubprojects(); + /** + * A list of all Subproject items in the overview KListView + */ + QPtrList <SubprojectItem> allSubprojectItems(); + /** + * A list of the (relative) names of all libraries + */ + QStringList allLibraries(); + /** + * A list of all files that belong to the project + **/ + QStringList allFiles(); + /** + * The top level directory of the project. + **/ + QString projectDirectory() const; + /** + * The directory of the currently shown subproject. + */ + QString subprojectDirectory(); + /** + * Are we in KDE mode? + */ + bool kdeMode() const + { + return m_kdeMode; + } + + /** + * Sets the given target active. The argument is given + * relative to the project directory. + */ + void setActiveTarget( const QString &targetPath ); + /** + * Returns the active target as path relative to + * the project directory. + */ + QString activeDirectory(); + + /** + * Adds a file to the active target. + * If the file does not contain a "/" character, it is added + * to the active target. + * If it does contain "/" character(s), ... @todo .. add to appropriate target + */ + void addFiles( const QStringList &list ); + /** + * Removes the file fileName from the directory directory. + * (not implemented currently) + */ + void removeFiles( const QStringList &list ); + + /** + * Returns the currently selected target. Returns 0 if + * no target is selected. + */ + TargetItem *selectedTarget(); + + /** + * Returns the currently selected file. Returns 0 if + * no file is selected. + */ + FileItem *selectedFile(); + + /** + * Returns the currently selected subproject (directory with Makefile.am). Returns 0 if + * no subproject is selected. + */ + SubprojectItem* selectedSubproject(); + + /** + * Creates a TargetItem instance without a parent item. + */ + TargetItem *createTargetItem( const QString &name, + const QString &prefix, const QString &primary, + bool take = true ); + /** + * Creates a FileItem instance without a parent item. + */ + FileItem *createFileItem( const QString &name, SubprojectItem *subproject ); + + /** + * Returns the Subproject that contains the Active Target. The Active Target is a special target + * to which e.g. all files are added to. + */ + SubprojectItem* activeSubproject (); + void setActiveSubproject( SubprojectItem* spitem ); + + /** + * Returns the Active Target. The Active Target is a special target + * to which e.g. all files are added to. + */ + TargetItem* activeTarget(); + + /** + * Returns the sub project item, if any, for a given path. The path supplied can be either + * absolute, or relative to the project directory. If no subproject item is found for the + * path, null is returned. + */ + SubprojectItem* subprojectItemForPath( const QString & path, bool pathIsAbsolute = false ); + + /** + * Returns the projectdir-relative path for a target item + */ + QString pathForTarget( const TargetItem *item ) const; + + /** + * Adds file fileName to target titem in subproject spitem + */ + void addToTarget( const QString & fileName, SubprojectItem* spitem, TargetItem* titem ); + + /** + * Restores the last settings of the AutoProjectWidget + */ + void restoreSession ( const QDomElement* el ); + + /** + * Saves the latest changes of the AutoProjectWidget to the session file. + */ + void saveSession ( QDomElement* el ); + + AutoSubprojectView* getSubprojectView (); + AutoDetailsView* getDetailsView (); + + + void emitAddedFile ( const QString& name ); + void emitAddedFiles( const QStringList &fileList ); + void emitRemovedFile ( const QString& name ); + void emitRemovedFiles( const QStringList &fileList ); + + void parse( SubprojectItem *item ); + + enum AutoProjectView { SubprojectView, DetailsView }; + void setLastFocusedView( AutoProjectView view ); + + MakefileHandler* makefileHandler(); + +public slots: + void slotOverviewSelectionChanged( QListViewItem *item ); + +protected: + void initOverview ( QWidget* parent ); + void initDetailview ( QWidget* parent ); + void initActions (); + + virtual void focusInEvent( QFocusEvent *e ); + +private: + + AutoSubprojectView* m_subprojectView; + AutoDetailsView* m_detailView; + + bool m_kdeMode; + AutoProjectPart *m_part; + SubprojectItem *m_activeSubproject; + TargetItem *m_activeTarget; + TargetItem *m_choosenTarget; + SubprojectItem *m_shownSubproject; + + AutoProjectView m_lastFocusedView; + + MakefileHandler *m_makefileHandler; +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/autosubprojectview.cpp b/buildtools/autotools/autosubprojectview.cpp new file mode 100644 index 00000000..efa3a358 --- /dev/null +++ b/buildtools/autotools/autosubprojectview.cpp @@ -0,0 +1,1137 @@ +/* + KDevelop Autotools Support + Copyright (c) 2002 by Victor Roeder <victor_roeder@gmx.de> + Copyright (c) 2005 by Matt Rogers <mattr@kde.org> + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + *************************************************************************** +*/ + +/** Qt */ +#include <qregexp.h> +#include <qcheckbox.h> +#include <qstringlist.h> +#include <qtable.h> +#include <qlayout.h> + +/** KDE Libs */ +#include <kxmlguiclient.h> +#include <kaction.h> +#include <kdebug.h> +#include <klocale.h> +#include <kpopupmenu.h> +#include <kmessagebox.h> +#include <kapplication.h> +#include <kprocess.h> +#include <ksqueezedtextlabel.h> +#include <kdialogbase.h> +#include <klistview.h> + +/** KDevelop */ +#include <kdevmainwindow.h> +#include <kdevmakefrontend.h> +#include <kdevappfrontend.h> +#include <kdevcore.h> +#include <urlutil.h> + +/** AutoProject */ +#include "subprojectoptionsdlg.h" +#include "addsubprojectdlg.h" +#include "addtargetdlg.h" +#include "addservicedlg.h" +#include "addapplicationdlg.h" +#include "addexistingdirectoriesdlg.h" +#include "autolistviewitems.h" +#include "autoprojectwidget.h" +#include "autoprojectpart.h" +#include "autosubprojectview.h" +#include "autotoolsaction.h" +#include "removesubprojectdialog.h" +#include "managecustomcommand.h" + +namespace AutoProjectPrivate +{ + +bool isHeader( const QString& fileName ) +{ + return QStringList::split( ";", "h;H;hh;hxx;hpp;tcc;h++" ).contains( QFileInfo(fileName).extension(false) ); +} + +static QString cleanWhitespace( const QString &str ) +{ + QString res; + + QStringList l = QStringList::split( QRegExp( "[ \t]" ), str ); + QStringList::ConstIterator it; + for ( it = l.begin(); it != l.end(); ++it ) + { + res += *it; + res += " "; + } + + return res.left( res.length() - 1 ); +} + +static void removeDir( const QString& dirName ) +{ + QDir d( dirName ); + const QFileInfoList* fileList = d.entryInfoList(); + if( !fileList ) + return; + + QFileInfoListIterator it( *fileList ); + while( it.current() ){ + const QFileInfo* fileInfo = it.current(); + ++it; + + if( fileInfo->fileName() == "." || fileInfo->fileName() == ".." ) + continue; + + if( fileInfo->isDir() && !fileInfo->isSymLink() ) + removeDir( fileInfo->absFilePath() ); + + kdDebug(9020) << "remove " << fileInfo->absFilePath() << endl; + d.remove( fileInfo->fileName(), false ); + } + + kdDebug(9020) << "remove dir " << dirName << endl; + d.rmdir( d.absPath(), true ); +} + +} + + +AutoSubprojectView::AutoSubprojectView(AutoProjectWidget* widget, AutoProjectPart* part, QWidget *parent, const char *name) +: AutoProjectViewBase(parent, name) +{ + + m_widget = widget; + m_part = part; + + m_listView->setSorting(-1); + m_listView->header()->hide(); + m_listView->addColumn( QString::null ); + + connect( m_listView, SIGNAL( selectionChanged( QListViewItem* ) ), + this, SLOT( slotSelectionChanged( QListViewItem* ) ) ); + + initActions(); +} + + +AutoSubprojectView::~AutoSubprojectView() +{ +} + +void AutoSubprojectView::slotSelectionChanged( QListViewItem* item ) +{ + if ( m_listView->selectedItems().count() <= 0 ) + { + subProjectOptionsAction->setEnabled( false ); + addSubprojectAction->setEnabled( false ); + addTargetAction->setEnabled( false ); + addServiceAction->setEnabled( false ); + addApplicationAction->setEnabled( false ); + buildSubprojectAction->setEnabled( false ); + } + else + { + subProjectOptionsAction->setEnabled( true ); + addSubprojectAction->setEnabled( true ); + addTargetAction->setEnabled( true ); + addServiceAction->setEnabled( true ); + addApplicationAction->setEnabled( true ); + buildSubprojectAction->setEnabled( true ); + } + + emit selectionChanged( item ); +} + +void AutoSubprojectView::loadMakefileams ( const QString& dir ) +{ + SubprojectItem * item = new SubprojectItem( m_listView, m_part->projectName() ); + item->setPixmap ( 0, SmallIcon ( "kdevelop" ) ); + item->subdir = "/"; + item->path = dir; + parse( item ); + item->setOpen( true ); + + //setSelected( item, true ); + + expandCollapseFirst( m_listView->firstChild(), false ); +} + + +void AutoSubprojectView::initActions() +{ + KActionCollection * actions = new KActionCollection( this ); + + subProjectOptionsAction = new AutoToolsAction( i18n( "Options..." ), "configure", 0, + this, SLOT( slotSubprojectOptions() ), actions, "subproject options" ); + subProjectOptionsAction->setWhatsThis(i18n("<qt><b>Options</b><p>Shows subproject options dialog " + "that provides settings for compiler, include paths, " + "prefixes and build order.</qt>")); + subProjectOptionsAction->plug( m_optionsButton ); + + QToolTip::add( m_button1, tr2i18n( "Add new subproject...")); + addSubprojectAction = new AutoToolsAction( i18n( "Add new subproject..." ), "folder_new", 0, + this, SLOT( slotAddSubproject() ), actions, "add subproject" ); + addSubprojectAction->setWhatsThis(i18n("<qt><b>Add new subproject</b><p>Creates a new " + "subproject in currently selected subproject.</qt>")); + addSubprojectAction->plug( m_button1 ); + + removeSubprojectAction = new KAction( i18n( "Remove Subproject..." ), "remove_subdir", 0, + this, SLOT( slotRemoveSubproject() ), actions, "remove subproject" ); + removeSubprojectAction->setWhatsThis(i18n("<qt><b>Remove subproject</b><p>Removes the subproject. Asks if the " + "subproject should be also removed from disk. Only subprojects " + "which do not hold other subprojects can be removed.</qt>")); + addExistingSubprojectAction = new KAction( i18n( "Add Existing Subprojects..." ), "fileimport", 0, + this, SLOT( slotAddExistingSubproject() ), actions, "add existing subproject" ); + addExistingSubprojectAction->setWhatsThis(i18n("<qt><b>Add existing subprojects</b><p>Imports existing " + "subprojects containing Makefile.am.</qt>")); + + QToolTip::add( m_button2, tr2i18n( "Add Target...")); + addTargetAction = new AutoToolsAction( i18n( "Add Target..." ), "targetnew_kdevelop", 0, + this, SLOT( slotAddTarget() ), actions, "add target" ); + addTargetAction->setWhatsThis(i18n( "<qt><b>Add target</b><p>Adds a new target to " + "the currently selected subproject. Target can be a " + "binary program, library, script, also a collection of " + "data or header files.</qt>")); + addTargetAction->plug( m_button2 ); + + QToolTip::add( m_button3, tr2i18n( "Add Service...")); + addServiceAction = new AutoToolsAction( i18n( "Add Service..." ), "servicenew_kdevelop", 0, this, + SLOT( slotAddService() ), actions, "add service" ); + addServiceAction->setWhatsThis(i18n("<qt><b>Add service</b><p>Creates a .desktop file describing the service.</qt>")); + addServiceAction->plug( m_button3 ); + + QToolTip::add( m_button4, tr2i18n( "Add Application...")); + addApplicationAction = new AutoToolsAction( i18n( "Add Application..." ), "window_new", 0, this, + SLOT( slotAddApplication() ), actions, "add application" ); + addApplicationAction->setWhatsThis(i18n("<qt><b>Add application</b><p>Creates an application .desktop file.</qt>")); + addApplicationAction->plug( m_button4 ); + + QToolTip::add( m_button5, tr2i18n( "Build")); + buildSubprojectAction = new AutoToolsAction( i18n( "Build" ), "launch", 0, this, + SLOT( slotBuildSubproject() ), actions, "build subproject" ); + buildSubprojectAction->setWhatsThis(i18n("<qt><b>Build</b><p>Runs <b>make</b> from the directory of " + "the selected subproject.<br> Environment variables and " + "make arguments can be specified in the project settings " + "dialog, <b>Make Options</b> tab.</qt>")); + buildSubprojectAction->plug( m_button5 ); + + forceReeditSubprojectAction = new KAction( i18n( "Force Reedit" ), 0, 0, this, + SLOT( slotForceReeditSubproject() ), actions, "force-reedit subproject" ); + forceReeditSubprojectAction->setWhatsThis(i18n("<qt><b>Force Reedit</b><p>Runs <b>make force-reedit</b> " + "from the directory of the selected subproject.<br>This " + "recreates makefile (tip: and solves most of .moc related " + "problems)<br>Environment variables and make arguments can " + "be specified in the project settings dialog, " + "<b>Make Options</b> tab.</qt>")); + + if (!m_part->isKDE()) + forceReeditSubprojectAction->setEnabled(false); + + cleanSubprojectAction = new KAction( i18n( "Clean" ), 0, 0, this, + SLOT( slotCleanSubproject() ), actions, "clean subproject" ); + cleanSubprojectAction->setWhatsThis(i18n("<qt><b>Clean</b><p>Runs <b>make clean</b> from the directory of " + "the selected subproject.<br> Environment variables and make " + "arguments can be specified in the project settings dialog, " + "<b>Make Options</b> tab.</qt>")); + + installSubprojectAction = new KAction( i18n( "Install" ), 0, 0, this, + SLOT( slotInstallSubproject() ), actions, "install subproject" ); + installSubprojectAction->setWhatsThis(i18n("<qt><b>Install</b><p>Runs <b>make install</b> from the directory " + "of the selected subproject.<br> Environment variables and " + "make arguments can be specified in the project settings " + "dialog, <b>Make Options</b> tab.</qt>")); + installSuSubprojectAction = new KAction( i18n( "Install (as root user)" ), 0, 0, + this, SLOT( slotInstallSuSubproject() ), actions, "install subproject as root" ); + installSuSubprojectAction->setWhatsThis(i18n("<qt><b>Install as root user</b><p>Runs <b>make install</b> " + "command from the directory of the selected subproject " + "with root privileges.<br> It is executed via kdesu " + "command.<br> Environment variables and make arguments " + "can be specified in the project settings dialog, " + "<b>Make Options</b> tab.</qt>")); + + expandAction = new KAction( i18n( "Expand Subtree" ), 0, 0, this, + SLOT(slotExpandTree()), actions, "expandAction" ); + collapseAction = new KAction( i18n( "Collapse Subtree" ), 0, 0, this, + SLOT(slotCollapseTree()), actions, "collapseAction" ); + + otherAction = new KAction( i18n( "Manage Custom Commands..." ), 0, 0, this, + SLOT( slotManageBuildCommands() ), actions, "manage custom commands" ); + otherAction->setWhatsThis(i18n("<qt><b>Manage custom commands</b><p>Allows to create, edit and " + "delete custom build commands which appears in the subproject " + "context menu.<br></qt>")); + + connect( m_listView, SIGNAL( contextMenu( KListView*, QListViewItem*, const QPoint& ) ), + this, SLOT( slotContextMenu( KListView*, QListViewItem*, const QPoint& ) ) ); +} + +void AutoSubprojectView::slotContextMenu( KListView *, QListViewItem *item, const QPoint &p ) +{ + if ( !item ) + return ; + + KPopupMenu popup( i18n( "Subproject: %1" ).arg( item->text( 0 ) ), this ); + + subProjectOptionsAction->plug( &popup ); + popup.insertSeparator(); + addSubprojectAction->plug( &popup ); + addTargetAction->plug( &popup ); + addServiceAction->plug( &popup ); + addApplicationAction->plug( &popup ); + popup.insertSeparator(); + addExistingSubprojectAction->plug( &popup ); + popup.insertSeparator(); + removeSubprojectAction->plug( &popup ); + popup.insertSeparator(); + buildSubprojectAction->plug( &popup ); + popup.insertSeparator(); + forceReeditSubprojectAction->plug( &popup ); + cleanSubprojectAction->plug( &popup ); + popup.insertSeparator(); + installSubprojectAction->plug( &popup ); + installSuSubprojectAction->plug( &popup ); + popup.insertSeparator(); + collapseAction->plug( &popup ); + expandAction->plug( &popup ); + + KConfig *config = m_part->instance()->config(); + bool separate = true; + QMap<QString,QString> customBuildCommands = config->entryMap("CustomCommands"); + for (QMap<QString,QString>::const_iterator it = customBuildCommands.constBegin(); + it != customBuildCommands.constEnd(); ++it) + { + if (separate) + { + popup.insertSeparator(); + separate = false; + } + int id = popup.insertItem(it.key(), this, SLOT(slotCustomBuildCommand(int))); + m_commandList.append(it.data()); + popup.setItemParameter(id, m_commandList.findIndex(it.data())); + } + + popup.insertSeparator(); + otherAction->plug( &popup ); + + KURL::List urls; + urls.append(m_widget->selectedSubproject()->path); + FileContext context(urls); + m_part->core()->fillContextMenu( &popup, &context ); + + popup.exec( p ); +} + +void AutoSubprojectView::slotSubprojectOptions() +{ + kdDebug( 9020 ) << "AutoSubprojectView::slotSubprojectOptions()" << endl; + + SubprojectItem* spitem = dynamic_cast<SubprojectItem*>( m_listView->selectedItem() ); + if ( !spitem ) return; + + SubprojectOptionsDialog dlg( m_part, m_widget, spitem, this, "subproject options dialog" ); + dlg.exec(); +} + + +void AutoSubprojectView::slotAddSubproject() +{ + SubprojectItem* spitem = dynamic_cast<SubprojectItem*>( m_listView->selectedItem() ); + if ( !spitem ) return; + + AddSubprojectDialog dlg( m_part, this, spitem, this, "add subproject dialog" ); + + dlg.setCaption ( i18n ( "Add New Subproject to '%1'" ).arg ( spitem->subdir ) ); + dlg.exec(); +} + + +void AutoSubprojectView::slotAddExistingSubproject() +{ + SubprojectItem* spitem = dynamic_cast<SubprojectItem*>( m_listView->selectedItem() ); + if ( !spitem ) return; + + AddExistingDirectoriesDialog dlg ( m_part, m_widget, spitem, this, "add existing subprojects" ); + + dlg.setCaption ( i18n ( "Add Existing Subproject to '%1'" ).arg ( spitem->subdir ) ); + dlg.targetLabel->setText(""); + dlg.directoryLabel->setText(spitem->path); + + if ( dlg.exec() ) + emit selectionChanged ( spitem ); +} + +void AutoSubprojectView::slotAddTarget() +{ + SubprojectItem* spitem = dynamic_cast<SubprojectItem*>( m_listView->selectedItem() ); + if ( !spitem ) return; + + AddTargetDialog dlg( m_widget, spitem, this, "add target dialog" ); + + dlg.setCaption ( i18n ( "Add New Target to '%1'" ).arg ( spitem->subdir ) ); + + // Update the details view if a target was added + if ( dlg.exec() ) + emit selectionChanged( spitem ); +} + + +void AutoSubprojectView::slotAddService() +{ + SubprojectItem* spitem = dynamic_cast<SubprojectItem*>( m_listView->selectedItem() ); + if ( !spitem ) return; + + AddServiceDialog dlg( m_widget, spitem, this, "add service dialog" ); + + dlg.setCaption ( i18n ( "Add New Service to '%1'" ).arg ( spitem->subdir ) ); + + // Update the details view if a service was added + if ( dlg.exec() ) + emit selectionChanged( spitem ); +} + + +void AutoSubprojectView::slotAddApplication() +{ + SubprojectItem* spitem = dynamic_cast<SubprojectItem*>( m_listView->selectedItem() ); + if ( !spitem ) return; + + AddApplicationDialog dlg( m_widget, spitem, this, "add application dialog" ); + + dlg.setCaption ( i18n ( "Add New Application to '%1'" ).arg ( spitem->subdir ) ); + + // Update the details view if an application was added + if ( dlg.exec() ) + emit selectionChanged( spitem ); +} + + +void AutoSubprojectView::slotBuildSubproject() +{ + SubprojectItem* spitem = dynamic_cast<SubprojectItem*>( m_listView->selectedItem() ); + if ( !spitem ) return; + + QString relpath = "/" + URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + spitem->path.mid( m_part->projectDirectory().length() ); + + m_part->startMakeCommand( m_part->buildDirectory() + relpath, QString::fromLatin1( "" ) ); +} + +void AutoSubprojectView::slotRemoveSubproject() +{ + kdDebug(9020) << "AutoSubprojectView::slotRemoveSubproject()" << endl; + + SubprojectItem* spitem = static_cast<SubprojectItem*>( m_listView->selectedItem() ); + if( !spitem ) + return; + + SubprojectItem* parent = static_cast<SubprojectItem*>( spitem->parent() ); + if( !parent || !parent->listView() || spitem->childCount() != 0 ){ + KMessageBox::error( 0, i18n("This item cannot be removed"), i18n("Automake Manager") ); + return; + } + + QStringList list = QStringList::split( QRegExp("[ \t]"), parent->variables["SUBDIRS"] ); + QStringList::Iterator it = list.find( spitem->subdir ); + QString subdirToRemove = spitem->subdir; + bool topsubdirs = true; + if ((parent->variables["SUBDIRS"].find("$(TOPSUBDIRS)") == -1) + && (parent->variables["SUBDIRS"].find("$(AUTODIRS)") == -1)) + { + topsubdirs = false; + if( it == list.end() ){ + KMessageBox::sorry(this, i18n("There is no subproject %1 in SUBDIRS").arg(spitem->subdir)); + return; + } + } + + RemoveSubprojectDialog dlg(i18n("Remove Subproject %1").arg(spitem->text(0)), + i18n("Do you really want to remove subproject %1 with all targets and files?").arg(spitem->text(0))); + if( dlg.exec() ){ + + bool removeSources = dlg.removeFromDisk(); + + if (!topsubdirs) + { + list.remove( it ); + parent->variables[ "SUBDIRS" ] = list.join( " " ); + } + + parent->listView()->setSelected( parent, true ); + kapp->processEvents( 500 ); + + + if( removeSources ){ + kdDebug(9020) << "remove dir " << spitem->path << endl; + AutoProjectPrivate::removeDir( spitem->path ); + } + + if( m_widget->activeSubproject() == spitem ){ + m_widget->setActiveSubproject( 0 ); + } + + // Adjust AC_OUTPUT in configure.in + if ( !m_part->isKDE() ) { + + QString projroot = m_part->projectDirectory() + "/"; + QString subdirectory = spitem->path; + QString relpath = subdirectory.replace(0, projroot.length(),""); + + QString configureFile = m_part->getAutoConfFile(projroot); + + QStringList list = AutoProjectTool::configureinLoadMakefiles(configureFile); + + QStringList::iterator it; + + for ( it = list.begin(); it != list.end(); it++ ) { + QString current = (QString) (*it); + QRegExp path_regex(relpath); + if ( path_regex.search(current) >= 0) { + list.remove(it); + break; + } + } + AutoProjectTool::configureinSaveMakefiles(configureFile, list); + + } + + // remove all targets + spitem->targets.setAutoDelete( true ); + spitem->targets.clear(); + delete( spitem ); + spitem = 0; + + // Adjust SUBDIRS variable in containing Makefile.am + + if (parent->variables["SUBDIRS"].find("$(TOPSUBDIRS)") != -1) + { + QFile subdirsfile( parent->path + "/subdirs" ); + QStringList topdirs; + if ( subdirsfile.open( IO_ReadOnly ) ) + { + QTextStream subdirsstream( &subdirsfile ); + while (!subdirsstream.atEnd()) + topdirs.append(subdirsstream.readLine()); + subdirsfile.close(); + } + topdirs.remove(subdirToRemove); + if ( subdirsfile.open( IO_WriteOnly | IO_Truncate ) ) + { + QTextStream subdirsstream( &subdirsfile ); + for (QStringList::const_iterator it = topdirs.begin(); it != topdirs.end(); ++it) + subdirsstream << *it << endl; + subdirsfile.close(); + } + } + + QMap<QString,QString> replaceMap; + replaceMap.insert( "SUBDIRS", subdirToRemove ); + AutoProjectTool::removeFromMakefileam( parent->path + "/Makefile.am", replaceMap ); + + QString relmakefile = ( parent->path + "/Makefile" ).mid( m_part->projectDirectory().length()+1 ); + kdDebug(9020) << "Relative makefile path: " << relmakefile << endl; + + // check for config.status + if( !QFileInfo(m_part->buildDirectory(), "config.status").exists() ){ + return; + } + + QString cmdline = "cd "; + cmdline += KProcess::quote(m_part->projectDirectory()); + cmdline += " && automake "; + cmdline += KProcess::quote(relmakefile); + cmdline += " && cd "; + cmdline += KProcess::quote(m_part->buildDirectory()); + cmdline += " && CONFIG_HEADERS=config.h CONFIG_FILES="; + cmdline += KProcess::quote(relmakefile); + cmdline += " ./config.status"; + m_part->makeFrontend()->queueCommand( m_part->projectDirectory(), cmdline ); + } +} + + +void AutoSubprojectView::parsePrimary( SubprojectItem *item, + const QString &lhs, const QString &rhs ) +{ + // Parse line foo_bar = bla bla + + int pos = lhs.findRev( '_' ); + QString prefix = lhs.left( pos ); + QString primary = lhs.right( lhs.length() - pos - 1 ); + // kdDebug(9020) << "Prefix:" << prefix << ",Primary:" << primary << endl; + + +#if 0 + + QStrList prefixes; + prefixes.append( "bin" ); + prefixes.append( "pkglib" ); + prefixes.append( "pkgdata" ); + prefixes.append( "noinst" ); + prefixes.append( "check" ); + prefixes.append( "sbin" ); + QStrList primaries; + primaries.append( "PROGRAMS" ); + primaries.append( "LIBRARIES" ); + primaries.append( "LTLIBRARIES" ); + primaries.append( "SCRIPTS" ); + primaries.append( "HEADERS" ); + primaries.append( "DATA" ); +#endif + + // Not all combinations prefix/primary are possible, so this + // could also be checked... not trivial because the list of + // possible prefixes can be extended dynamically (see below) + if ( primary == "PROGRAMS" || primary == "LIBRARIES" || primary == "LTLIBRARIES" ) + { + QStringList l = QStringList::split( QRegExp( "[ \t\n]" ), rhs ); + QStringList::Iterator it1; + for ( it1 = l.begin(); it1 != l.end(); ++it1 ) + { + TargetItem *titem = m_widget->createTargetItem( *it1, prefix, primary ); + item->targets.append( titem ); + + QString canonname = AutoProjectTool::canonicalize( *it1 ); + titem->ldflags = AutoProjectPrivate::cleanWhitespace( item->variables[ canonname + "_LDFLAGS" ] ); + titem->ldadd = AutoProjectPrivate::cleanWhitespace( item->variables[ canonname + "_LDADD" ] ); + titem->libadd = AutoProjectPrivate::cleanWhitespace( item->variables[ canonname + "_LIBADD" ] ); + titem->dependencies = AutoProjectPrivate::cleanWhitespace( item->variables[ canonname + "_DEPENDENCIES" ] ); + + QString sources = item->variables[ canonname + "_SOURCES" ]; + QStringList sourceList = QStringList::split( QRegExp( "[ \t\n]" ), sources ); + QMap<QString, bool> dict; + QStringList::Iterator it = sourceList.begin(); + while( it != sourceList.end() ){ + dict.insert( *it, true ); + ++it; + } + + QMap<QString, bool>::Iterator dictIt = dict.begin(); + while( dictIt != dict.end() ){ + QString fname = dictIt.key(); + ++dictIt; + + FileItem *fitem = m_widget->createFileItem( fname, item ); + titem->sources.append( fitem ); + + if( AutoProjectPrivate::isHeader(fname) ) + headers += fname; + } + } + } + else if ( primary == "SCRIPTS" || primary == "HEADERS" || primary == "DATA" ) + { + // See if we have already such a group + for ( uint i = 0; i < item->targets.count(); ++i ) + { + TargetItem *titem = item->targets.at( i ); + if ( primary == titem->primary && prefix == titem->prefix ) + { + item->targets.remove( i ); + break; + } + } + // Create a new one + TargetItem *titem = m_widget->createTargetItem( "", prefix, primary ); + item->targets.append( titem ); + + QStringList l = QStringList::split( QRegExp( "[ \t]" ), rhs ); + QStringList::Iterator it3; + for ( it3 = l.begin(); it3 != l.end(); ++it3 ) + { + QString fname = *it3; + FileItem *fitem = m_widget->createFileItem( fname, item ); + titem->sources.append( fitem ); + + if( AutoProjectPrivate::isHeader(fname) ) + headers += fname; + + } + } + else if ( primary == "JAVA" ) + { + QStringList l = QStringList::split( QRegExp( "[ \t\n]" ), rhs ); + QStringList::Iterator it1; + TargetItem *titem = m_widget->createTargetItem( "", prefix, primary ); + item->targets.append( titem ); + + for ( it1 = l.begin(); it1 != l.end(); ++it1 ) + { + FileItem *fitem = m_widget->createFileItem( *it1, item ); + titem->sources.append( fitem ); + } + } +} + + +void AutoSubprojectView::parseKDEDOCS( SubprojectItem *item, + const QString & /*lhs*/, const QString & /*rhs*/ ) +{ + // Handle the line KDE_ICON = + // (actually, no parsing is involved here) + + QString prefix = "kde_docs"; + QString primary = "KDEDOCS"; + + TargetItem *titem = m_widget->createTargetItem( "", prefix, primary ); + item->targets.append( titem ); + + QDir d( item->path ); + QStringList l = d.entryList( QDir::Files ); + + QRegExp re( "Makefile.*|\\..*|.*~|index.cache.bz2" ); + + QStringList::ConstIterator it; + for ( it = l.begin(); it != l.end(); ++it ) + { + if ( !re.exactMatch( *it ) ) + { + QString fname = *it; + FileItem * fitem = m_widget->createFileItem( fname, item ); + titem->sources.append( fitem ); + } + } +} + + +void AutoSubprojectView::parseKDEICON( SubprojectItem *item, + const QString &lhs, const QString &rhs ) +{ + // Parse a line foo_ICON = bla bla + + int pos = lhs.find( "_ICON" ); + QString prefix = lhs.left( pos ); + if ( prefix == "KDE" ) + prefix = "kde_icon"; + + QString primary = "KDEICON"; + + TargetItem *titem = m_widget->createTargetItem( "", prefix, primary ); + item->targets.append( titem ); + + QDir d( item->path ); + QStringList l = d.entryList( QDir::Files ); + + QString regexp; + + if ( rhs == "AUTO" ) + { + regexp = ".*\\.(png|mng|xpm)"; + } + else + { + QStringList appNames = QStringList::split( QRegExp( "[ \t\n]" ), rhs ); + regexp = ".*(-" + appNames.join( "|-" ) + ")\\.(png|mng|xpm)"; + } + + QRegExp re( regexp ); + + QStringList::ConstIterator it; + for ( it = l.begin(); it != l.end(); ++it ) + { + if ( re.exactMatch( *it ) ) + { + FileItem * fitem = m_widget->createFileItem( *it, item ); + titem->sources.append( fitem ); + } + } +} + + +void AutoSubprojectView::parsePrefix( SubprojectItem *item, + const QString &lhs, const QString &rhs ) +{ + // Parse a line foodir = bla bla + QString name = lhs.left( lhs.length() - 3 ); + QString dir = rhs; + item->prefixes.insert( name, dir ); +} + + +void AutoSubprojectView::parseSUBDIRS( SubprojectItem *item, + const QString & /*lhs*/, const QString &rhs ) +{ + // Parse a line SUBDIRS = bla bla + QString subdirs = rhs; + kdDebug( 9020 ) << "subdirs are " << subdirs << endl; + + // Take care of KDE hacks: + // TOPSUBDIRS is an alias for all directories + // listed in the subdirs file + if ( subdirs.find( "$(TOPSUBDIRS)" ) != -1 ) + { + QStringList dirs; + QFile subdirsfile( item->path + "/subdirs" ); + if( subdirsfile.exists() ) + { + if ( subdirsfile.open( IO_ReadOnly ) ) + { + QTextStream subdirsstream( &subdirsfile ); + while ( !subdirsstream.atEnd() ) + dirs.append( subdirsstream.readLine() ); + subdirsfile.close(); + } + } else + { + QDir d( item->path ); + QStringList l = d.entryList( QDir::Dirs ); + for( QStringList::const_iterator it = l.begin(); it != l.end(); ++it ) + { + if( (*it) != "CVS" && (*it) != "admin" && (*it) != ".svn" && (*it) != "." && (*it) != ".." ) + { + QDir subdir = d; + subdir.cd( *it, false ); + if( subdir.exists( "Makefile.am" ) ) + dirs.append( *it ); + } + } + + } + subdirs.replace( QRegExp( "\\$\\(TOPSUBDIRS\\)" ), dirs.join( " " ) ); + } + + // AUTODIRS is an alias for all subdirectories + if ( subdirs.find( "$(AUTODIRS)" ) != -1 ) + { + QDir d( item->path ); + QStringList dirs = d.entryList( QDir::Dirs ); + dirs.remove( "." ); + dirs.remove( ".." ); + dirs.remove( "CVS" ); + subdirs.replace( QRegExp( "\\$\\(AUTODIRS\\)" ), dirs.join( " " ) ); + } + + // If there are any variables in the subdirs line then search + // the Makefile(.am?) for its definition. Unfortunately, it may be + // defined outside this file in which case those dirs won't be added. + QRegExp varre( "\\$\\(\\s*(.*)\\s*\\)" ); + varre.setMinimal( true ); + while ( varre.search( subdirs ) != -1 ) + { + QString varname = varre.cap( 1 ); + QString varvalue; + + // Search the whole Makefile(.am?) + // Note that if the variable isn't found it just disappears + // (Perhaps we should add it back in this case?) + QMap<QString, QString>::ConstIterator varit = item->variables.find( varname ); + if ( varit != item->variables.end() ) + { + kdDebug( 9020 ) << "Found Makefile var " << varname << ", adding dirs <" << varit.data() << ">" << endl; + varvalue = varit.data(); + } + else + { + kdDebug( 9020 ) << "Not found Makefile var " << varname << endl; + } + subdirs.replace( QRegExp( "\\$\\(\\s*" + varname + "\\s*\\)" ), varvalue ); + } + + //search for AC_SUBST variables and try to replace them with variables + //that have been already defined e.g. in a "kdevelop hint" + varre = QRegExp( "\\@(.*)\\@" ); + varre.setMinimal( true ); + while ( varre.search( subdirs ) != -1 ) + { + QString varname = varre.cap( 1 ); + QString varvalue; + + // Search the whole Makefile(.am?) + // Note that if the variable isn't found it just disappears + // (Perhaps we should add it back in this case?) + QMap<QString, QString>::ConstIterator varit = item->variables.find( varname ); + if ( varit != item->variables.end() ) + { + kdDebug( 9020 ) << "Found Makefile var " << varname << ", adding dirs <" << varit.data() << ">" << endl; + varvalue = varit.data(); + } + else + { + kdDebug( 9020 ) << "Not found Makefile var " << varname << endl; + } + subdirs.replace( QRegExp( "\\@" + varname + "\\@" ), varvalue ); + } + + QStringList l = QStringList::split( QRegExp( "[ \t]" ), subdirs ); + l.sort(); + QStringList::Iterator it; + for ( it = l.begin(); it != l.end(); ++it ) + { + if ( *it == "." ) + continue; + SubprojectItem *newitem = new SubprojectItem( item, ( *it ) ); + newitem->subdir = ( *it ); + newitem->path = item->path + "/" + ( *it ); + parse( newitem ); + // Experience tells me this :-) + bool open = true; + if ( newitem->subdir == "doc" ) + open = false; + if ( newitem->subdir == "po" ) + open = false; + if ( newitem->subdir == "pics" ) + open = false; + if ( newitem && static_cast<SubprojectItem*>( newitem->parent() ) + ->subdir == "doc" ) + open = false; + if ( newitem && static_cast<SubprojectItem*> + ( newitem->parent() ) ->subdir == "po" ) + open = false; + if ( newitem && static_cast<SubprojectItem*> + ( newitem->parent() ) ->subdir == "pics" ) + open = false; + newitem->setOpen( open ); + + // Move to the bottom of the list + QListViewItem *lastItem = item->firstChild(); + while ( lastItem->nextSibling() + ) + lastItem = lastItem->nextSibling(); + if ( lastItem != newitem ) + newitem->moveItem( lastItem ); + } +} + +void AutoSubprojectView::parse( SubprojectItem *item ) +{ + headers.clear(); + AutoProjectTool::parseMakefileam( item->path + "/Makefile.am", &item->variables ); + + QMap<QString, QString>::ConstIterator it; + for ( it = item->variables.begin(); it != item->variables.end(); ++it ) + { + QString lhs = it.key(); + QString rhs = it.data(); + if ( lhs == "KDE_DOCS" ) + parseKDEDOCS( item, lhs, rhs ); + else if ( lhs.right( 5 ) == "_ICON" ) + parseKDEICON( item, lhs, rhs ); + else if ( lhs.find( '_' ) > 0 ) + parsePrimary( item, lhs, rhs ); + else if ( lhs.right( 3 ) == "dir" ) + parsePrefix( item, lhs, rhs ); + else if ( lhs == "SUBDIRS" ) + parseSUBDIRS( item, lhs, rhs ); + } + + /// @todo only if in a c++ project + TargetItem* noinst_HEADERS_item = findNoinstHeaders(item); + + QDir dir( item->path ); + QStringList headersList = QStringList::split( QRegExp("[ \t]"), item->variables[ "noinst_HEADERS" ] ); + + headersList += dir.entryList( "*.h;*.H;*.hh;*.hxx;*.hpp;*.tcc", QDir::Files ); + headersList.sort(); + headersList = QStringList::split(QRegExp("[ \t]"), headersList.join( " " )); + + QStringList::Iterator fileIt = headersList.begin(); + while( fileIt != headersList.end() ){ + QString fname = *fileIt; + ++fileIt; + + if( AutoProjectPrivate::isHeader(fname) && !headers.contains(fname) ){ + FileItem *fitem = m_widget->createFileItem( fname, item ); + noinst_HEADERS_item->sources.append( fitem ); + } + } +} + +void AutoSubprojectView::slotForceReeditSubproject( ) +{ + SubprojectItem* spitem = dynamic_cast <SubprojectItem*>( m_listView->selectedItem() ); + if ( !spitem ) return; + + QString relpath = "/" + URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + spitem->path.mid( m_part->projectDirectory().length() ); + + m_part->startMakeCommand( m_part->buildDirectory() + relpath, "force-reedit" ); +} + +void AutoSubprojectView::slotInstallSubproject( ) +{ + SubprojectItem* spitem = dynamic_cast<SubprojectItem*>( m_listView->selectedItem() ); + if ( !spitem ) return; + + QString relpath = "/" + URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + spitem->path.mid( m_part->projectDirectory().length() ); + + m_part->startMakeCommand( m_part->buildDirectory() + relpath, "install" ); +} + +void AutoSubprojectView::slotInstallSuSubproject( ) +{ + SubprojectItem* spitem = dynamic_cast<SubprojectItem*>( m_listView->selectedItem() ); + if ( !spitem ) return; + + QString relpath = "/" + URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + spitem->path.mid( m_part->projectDirectory().length() ); + + m_part->startMakeCommand( m_part->buildDirectory() + relpath, "install", true ); +} + +TargetItem * AutoSubprojectView::findNoinstHeaders( SubprojectItem *item ) +{ + TargetItem* noinst_HEADERS_item = 0; + QPtrListIterator<TargetItem> itemIt( item->targets ); + while( itemIt.current() ){ + TargetItem* titem = itemIt.current(); + ++itemIt; + + if( titem->prefix == "noinst" && titem->primary == "HEADERS" ){ + noinst_HEADERS_item = titem; + break; + } + } + + if( !noinst_HEADERS_item ){ + noinst_HEADERS_item = m_widget->createTargetItem( "", "noinst", "HEADERS" ); + item->targets.append( noinst_HEADERS_item ); + } + + return noinst_HEADERS_item; +} + +void AutoSubprojectView::slotCleanSubproject( ) +{ + SubprojectItem* spitem = dynamic_cast<SubprojectItem*>( m_listView->selectedItem() ); + if ( !spitem ) return; + + QString relpath = "/" + URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + spitem->path.mid( m_part->projectDirectory().length() ); + + m_part->startMakeCommand( m_part->buildDirectory() + relpath, "clean" ); +} + +void AutoSubprojectView::focusOutEvent( QFocusEvent */* e*/ ) +{ + m_widget->setLastFocusedView(AutoProjectWidget::SubprojectView); +} + +void AutoSubprojectView::slotManageBuildCommands( ) +{ + KConfig *config = m_part->instance()->config(); + //menu item name <-> command + QMap<QString, QString> customBuildCommands = config->entryMap("CustomCommands"); + + KDialogBase dlg(KDialogBase::Plain, i18n("Manage Custom Commands"), KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok); + dlg.plainPage()->setMargin(0); + (new QVBoxLayout(dlg.plainPage(), 0, 0))->setAutoAdd(true); + + ManageCustomCommand *widget = new ManageCustomCommand(dlg.plainPage()); + + for (QMap<QString,QString>::const_iterator it = customBuildCommands.constBegin(); + it != customBuildCommands.constEnd(); ++it) + { + widget->commandsTable->insertRows(widget->commandsTable->numRows()); + widget->setRowProperties(widget->commandsTable->numRows()-1); + widget->commandsTable->setText(widget->commandsTable->numRows() - 1, 0, it.key()); + widget->commandsTable->setText(widget->commandsTable->numRows() - 1, 1, + it.data().section(":::", 0, 0)); + static_cast<QComboTableItem*>(widget->commandsTable-> + item(widget->commandsTable->numRows() - 1, 2))-> + setCurrentItem(it.data().section(":::", 1, 1).toInt()); + } + + widget->commandsTable->setFocus(); + if (dlg.exec() == QDialog::Accepted) + { + config->deleteGroup("CustomCommands"); + config->setGroup("CustomCommands"); + for (int i = 0; i < widget->commandsTable->numRows(); ++i) + { + config->writeEntry(widget->commandsTable->text(i, 0), + widget->commandsTable->text(i, 1)+":::"+ + QString("%1").arg(static_cast<QComboTableItem*>(widget-> + commandsTable->item(i, 2))->currentItem())); + } + config->sync(); + } + +} + +void AutoSubprojectView::slotCustomBuildCommand(int val) +{ + QString cmd = m_commandList[val].section(":::", 0, 0); + int type = m_commandList[val].section(":::", 1, 1).toInt(); + + SubprojectItem* spitem = dynamic_cast<SubprojectItem*>( m_listView->selectedItem() ); + if ( !spitem ) return; + + QString relpath = "/" + URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + spitem->path.mid( m_part->projectDirectory().length() ); + switch (type) + { + case 0: //make target + m_part->startMakeCommand( m_part->buildDirectory() + relpath, cmd ); + break; + case 1: //make target as root + m_part->startMakeCommand( m_part->buildDirectory() + relpath, cmd, true ); + break; + case 2: //make command + m_part->startSimpleMakeCommand( m_part->buildDirectory() + relpath, cmd ); + break; + case 3: //make command as root + m_part->startSimpleMakeCommand( m_part->buildDirectory() + relpath, cmd, true ); + break; + case 4: //command + m_part->appFrontend()->startAppCommand(m_part->buildDirectory() + relpath, + cmd, false); + break; + case 5: //command as root + m_part->appFrontend()->startAppCommand(m_part->buildDirectory() + relpath, + "kdesu -t -c ' cd " + + KProcess::quote(m_part->buildDirectory() + relpath) + " && " + + cmd + "'", false); + break; + } +} + +void AutoSubprojectView::slotExpandTree() +{ + expandCollapseFirst( m_listView->currentItem(), true ); +} + +void AutoSubprojectView::slotCollapseTree() +{ + expandCollapseFirst( m_listView->currentItem(), false ); +} + +void AutoSubprojectView::expandCollapseFirst( QListViewItem * item, bool expand ) +{ + if ( !item ) return; + + if ( item == m_listView->firstChild() ) // special case for root node + { + item = item->firstChild(); + while ( item ) + { + expandCollapse( item, expand ); + item = item->nextSibling(); + } + } + else + { + expandCollapse( item, expand ); + } +} + +void AutoSubprojectView::expandCollapse( QListViewItem * item, bool expand ) +{ + if ( !item ) return; + + item->setOpen( expand ); + + item = item->firstChild(); + while ( item ) + { + expandCollapse( item, expand ); + item = item->nextSibling(); + } +} + +#include "autosubprojectview.moc" + +// kate: indent-mode csands; tab-width 4; space-indent off; diff --git a/buildtools/autotools/autosubprojectview.h b/buildtools/autotools/autosubprojectview.h new file mode 100644 index 00000000..e49caddd --- /dev/null +++ b/buildtools/autotools/autosubprojectview.h @@ -0,0 +1,130 @@ +/* + KDevelop Autotools Support + Copyright (c) 2002 by Victor Roeder <victor_roeder@gmx.de> + Copyright (c) 2005 by Matt Rogers <mattr@kde.org> + +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +*************************************************************************** +*/ + +#ifndef AUTOSUBPROJECTVIEW_H +#define AUTOSUBPROJECTVIEW_H + +#include <qwidget.h> +#include "autoprojectviewbase.h" + + +class KAction; +class AutoToolsAction; +class AutoProjectWidget; +class AutoProjectPart; +class TargetItem; +class SubprojectItem; +class KListViewItem; +class KListView; + +namespace AutoProjectPrivate +{ + bool isHeader( const QString& fileName ); +} + + +//with protected inheritance gcc 3.2.3 complains in autoprojectwidget.cpp, line 116 +//that it cannot access the base class QObject (for the connect() call), +//so in order to be able to compile this file I made the inheritance public again, Alex +class AutoSubprojectView : public AutoProjectViewBase +{ + Q_OBJECT + +public: + AutoSubprojectView( AutoProjectWidget* widget, AutoProjectPart* part, QWidget *parent, const char *name ); + virtual ~AutoSubprojectView(); + +public: + void loadMakefileams ( const QString& dir ); + + void parse( SubprojectItem *item ); + KListView* listView() const + { + return m_listView; + } + + TargetItem *findNoinstHeaders( SubprojectItem *item ); + +signals: + void selectionChanged( QListViewItem* ); + +protected: + void initActions (); + + void parseKDEDOCS( SubprojectItem *item, + const QString &lhs, const QString &rhs ); + void parseKDEICON( SubprojectItem *item, + const QString &lhs, const QString &rhs ); + void parsePrimary( SubprojectItem *item, + const QString &lhs, const QString &rhs ); + void parsePrefix( SubprojectItem *item, + const QString &lhs, const QString &rhs ); + void parseSUBDIRS( SubprojectItem *item, + const QString &lhs, const QString &rhs ); + virtual void focusOutEvent( QFocusEvent *e ); + void expandCollapse( QListViewItem * item, bool expand ); + void expandCollapseFirst( QListViewItem * item, bool expand ); + +private: + AutoProjectWidget* m_widget; + AutoProjectPart* m_part; + QStringList headers; + + bool m_kdeMode; + + AutoToolsAction* addApplicationAction; + AutoToolsAction* subProjectOptionsAction; + AutoToolsAction* addSubprojectAction; + KAction* addExistingSubprojectAction; + AutoToolsAction* addTargetAction; + AutoToolsAction* addServiceAction; + AutoToolsAction* buildSubprojectAction; + KAction* removeSubprojectAction; + KAction* cleanSubprojectAction; + KAction* forceReeditSubprojectAction; + KAction* installSubprojectAction; + KAction* installSuSubprojectAction; + KAction* otherAction; + KAction* expandAction; + KAction* collapseAction; + + QStringList m_commandList; + QValueList<int> m_commandTypeList; + +private slots: + void slotContextMenu( KListView *, QListViewItem *item, const QPoint &p ); + //void slotSubprojectExecuted(QListViewItem* item); + void slotSelectionChanged( QListViewItem* item ); + void slotAddApplication(); + void slotSubprojectOptions(); + void slotAddSubproject(); + void slotAddExistingSubproject(); + void slotAddTarget(); + void slotAddService(); + void slotBuildSubproject(); + void slotRemoveSubproject(); + void slotForceReeditSubproject(); + void slotInstallSubproject(); + void slotInstallSuSubproject(); + void slotCleanSubproject(); + void slotManageBuildCommands(); + void slotCustomBuildCommand( int ); + void slotExpandTree(); + void slotCollapseTree(); +}; + +#endif + +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/autotoolsaction.cpp b/buildtools/autotools/autotoolsaction.cpp new file mode 100644 index 00000000..63b38762 --- /dev/null +++ b/buildtools/autotools/autotoolsaction.cpp @@ -0,0 +1,156 @@ +/* + KDevelop Autotools Support + Copyright (c) 2005 by Matt Rogers <mattr@kde.org> + + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + *************************************************************************** +*/ +#include "autotoolsaction.h" + +#include <qtoolbutton.h> +#include <qtooltip.h> +#include <qwhatsthis.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kiconloader.h> + +AutoToolsAction::~AutoToolsAction() +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const KShortcut& cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ) +: KAction( text, cut, receiver, slot, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const QIconSet& pix, const KShortcut& cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ) +: KAction( text, pix, cut, receiver, slot, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const QString& pix, const KShortcut& cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ) +: KAction( text, pix, cut, receiver, slot, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const KGuiItem& item, const KShortcut & cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ) +: KAction( item, cut, receiver, slot, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const KShortcut& cut, + QObject* parent, const char* name ) +: KAction( text, cut, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const KShortcut& cut, + const QObject* receiver, const char* slot, + QObject* parent, const char* name ) +: KAction( text, cut, receiver, slot, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const QIconSet& pix, + const KShortcut& cut, QObject* parent, const char* name ) +: KAction( text, pix, cut, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const QString& pix, + const KShortcut& cut, QObject* parent, const char* name ) +: KAction( text, pix, cut, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const QIconSet& pix, + const KShortcut& cut, const QObject* receiver, + const char* slot, QObject* parent, const char * name ) +: KAction( text, pix, cut, receiver, slot, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const QString& pix, + const KShortcut & cut, const QObject* receiver, + const char* slot, QObject* parent, const char * name ) +: KAction( text, pix, cut, receiver, slot, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( QObject * parent, const char * name ) +: KAction( parent, name ) +{ +} + +int AutoToolsAction::plug( QWidget* w, int index ) +{ + if ( !w ) { + kdWarning(129) << "KAction::plug called with 0 argument\n"; + return -1; + } + + // Check if action is permitted + if (kapp && !kapp->authorizeKAction(name())) + return -1; + + if ( ::qt_cast<QToolButton*>( w ) ) + { + QToolButton* tb = static_cast<QToolButton*>( w ); + connect( tb, SIGNAL( clicked() ), this, SLOT( activate() ) ); + int id = getToolButtonID(); + + if ( !icon().isEmpty() ) + tb->setPixmap( SmallIcon( icon() ) ); + else + tb->setText( text() ); + + if ( !isEnabled() ) + tb->setEnabled( false ); + + if ( !whatsThis().isEmpty() ) + { + QWhatsThis::remove( tb ); + QWhatsThis::add( tb, whatsThisWithIcon() ); + } + + if ( !toolTip().isEmpty() ) + { + QToolTip::remove( tb ); + QToolTip::add( tb, toolTip() ); + } + + addContainer( tb, id ); + + return containerCount() - 1; + } + + return KAction::plug( w, index ); +} + +void AutoToolsAction::updateEnabled( int i ) +{ + QWidget* w = container( i ); + + if ( ::qt_cast<QToolButton*>( w ) ) + static_cast<QToolButton*>( w )->setEnabled( isEnabled() ); + else + KAction::updateEnabled( i ) ; +} + + + +//kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/autotoolsaction.h b/buildtools/autotools/autotoolsaction.h new file mode 100644 index 00000000..97c8e79e --- /dev/null +++ b/buildtools/autotools/autotoolsaction.h @@ -0,0 +1,70 @@ +/* + KDevelop Autotools Support + Copyright (c) 2005 by Matt Rogers <mattr@kde.org> + +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +*************************************************************************** +*/ +#ifndef AUTOTOOLSACTION_H +#define AUTOTOOLSACTION_H + +#include <kxmlguiclient.h> +#include <kaction.h> + +class QObject; +class KActionCollection; + +/** + * A KAction derivative that will work with the QToolButtons used in + * the Automake Manager + * @author Matt Rogers + */ +class AutoToolsAction : public KAction +{ +public: + virtual ~AutoToolsAction(); + + AutoToolsAction( const QString& text, const KShortcut& cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ); + + AutoToolsAction( const QString& text, const QIconSet& pix, const KShortcut& cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ); + + AutoToolsAction( const QString& text, const QString& pix, const KShortcut& cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ); + + AutoToolsAction( const KGuiItem& item, const KShortcut& cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ); + + AutoToolsAction( const QString& text, const KShortcut& cut = KShortcut(), QObject* parent = 0, const char* name = 0 ); + AutoToolsAction( const QString& text, const KShortcut& cut, + const QObject* receiver, const char* slot, QObject* parent, const char* name = 0 ); + AutoToolsAction( const QString& text, const QIconSet& pix, const KShortcut& cut = KShortcut(), + QObject* parent = 0, const char* name = 0 ); + AutoToolsAction( const QString& text, const QString& pix, const KShortcut& cut = KShortcut(), + QObject* parent = 0, const char* name = 0 ); + AutoToolsAction( const QString& text, const QIconSet& pix, const KShortcut& cut, + const QObject* receiver, const char* slot, QObject* parent, const char* name = 0 ); + AutoToolsAction( const QString& text, const QString& pix, const KShortcut& cut, + const QObject* receiver, const char* slot, QObject* parent, + const char* name = 0 ); + AutoToolsAction( QObject* parent = 0, const char* name = 0 ); + + virtual int plug( QWidget *widget, int index = -1 ); + + virtual void updateEnabled( int i ); +}; + +#endif + +//kate: indent-mode csands; tab-width 4; auto-insert-doxygen on; diff --git a/buildtools/autotools/choosetargetdialog.cpp b/buildtools/autotools/choosetargetdialog.cpp new file mode 100644 index 00000000..b35c5c75 --- /dev/null +++ b/buildtools/autotools/choosetargetdialog.cpp @@ -0,0 +1,348 @@ +/*************************************************************************** + ------------------- + begin : 29.11.2002 + copyright : (C) 2002 by Victor Rder + email : victor_roeder@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 "choosetargetdialog.h" + +#include <qcheckbox.h> +#include <qwidget.h> +#include <qgroupbox.h> +#include <qheader.h> +#include <qlistview.h> +#include <qptrlist.h> +#include <qradiobutton.h> +#include <qstringlist.h> +#include <qfileinfo.h> + +#include <kcombobox.h> +#include <kdialog.h> +#include <kdebug.h> +#include <klistview.h> +#include <kmessagebox.h> +#include <kprocess.h> +#include <ksqueezedtextlabel.h> +#include <kurl.h> + +#include "choosetargetdlgbase.h" +#include "autodetailsview.h" +#include "autolistviewitems.h" +#include "autosubprojectview.h" +#include "misc.h" +#include "autoprojectwidget.h" +#include "autoprojectpart.h" + +#include "kdevpartcontroller.h" + +class ChooseTargetDialog::Private +{ +public: + AutoProjectWidget* widget; + AutoProjectPart* part; + QStringList fileList; + QPtrList<SubprojectItem> subprojectList; + SubprojectItem* chosenSubproject; + TargetItem* chosenTarget; + ChooseTargetDlgBase* baseUI; +}; + +ChooseTargetDialog::ChooseTargetDialog ( AutoProjectWidget* widget, AutoProjectPart* part, + QStringList fileList, QWidget* parent, const char* name ) +: KDialogBase( parent, name, false, i18n("Automake Manager - Choose Target"), + Ok | Cancel, KDialogBase::Ok, true /* seperator */ ) + +{ + Q_UNUSED( parent ); + Q_UNUSED( name ); + d = new ChooseTargetDialog::Private; + d->widget = widget; + d->part = part; + d->fileList = fileList; + d->subprojectList = widget->allSubprojectItems(); + d->baseUI = new ChooseTargetDlgBase( this, "base ui" ); + setMainWidget( d->baseUI ); + + d->baseUI->subprojectComboBox->setAutoCompletion( true ); + d->baseUI->targetComboBox->setAutoCompletion( true ); + d->baseUI->newFileList->header()->hide(); + d->baseUI->newFileList->addColumn( QString::null ); + d->baseUI->newFileList->setSorting(-1); + + setIcon ( SmallIcon ( "target_kdevelop" ) ); + + + QPtrListIterator<SubprojectItem> sit(d->subprojectList); + for ( ; (*sit); ++sit ) + { + QPtrList<TargetItem> targetList = (*sit)->targets; + QPtrListIterator<TargetItem> targetIt(targetList); + + // Only insert Subproject which have a "regular" target + for ( ; (*targetIt); ++targetIt ) + { + QString titemPrimary = (*targetIt)->primary; + if ( titemPrimary == "PROGRAMS" || titemPrimary == "LIBRARIES" || + titemPrimary == "LTLIBRARIES" || titemPrimary == "JAVA" ) + { + d->baseUI->subprojectComboBox->insertItem ( SmallIcon ( "folder" ), (*sit)->subdir ); + } + } + } + + if ( d->widget->activeTarget() && d->widget->activeSubproject() ) + { + d->chosenTarget = d->widget->activeTarget(); + //kdDebug ( 9020 ) << "1) Chosen target is " << d->chosenTarget->name << endl; + d->chosenSubproject = widget->activeSubproject(); + d->baseUI->chosenTargetLabel->setText( ( widget->activeSubproject()->path + "/<b>" + + d->widget->activeTarget()->name + "</b>" ) + .mid( d->part->projectDirectory().length() + 1 ) ); + d->baseUI->subprojectComboBox->setEnabled( false ); + d->baseUI->targetComboBox->setEnabled( false ); + + d->baseUI->subprojectComboBox->setCurrentItem( widget->activeSubproject()->subdir ); + slotSubprojectChanged( widget->activeSubproject()->subdir ); + } + else + { + d->baseUI->activeTargetRadioButton->toggle(); + d->baseUI->activeTargetRadioButton->setEnabled ( false ); + d->baseUI->neverAskAgainCheckbox->setEnabled ( false ); + + slotSubprojectChanged ( d->baseUI->subprojectComboBox->text(0) ); + } + + QStringList::iterator it; + QString fileName; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) + { + int pos = ( *it ).findRev('/'); + if (pos != -1) + fileName = ( *it ).mid(pos+1); + else + fileName = ( *it ); + + + d->baseUI->newFileList->insertItem( new QListViewItem( d->baseUI->newFileList, fileName ) ); + } + + connect ( d->baseUI->subprojectComboBox, SIGNAL ( activated ( const QString& ) ), + this, SLOT( slotSubprojectChanged ( const QString& ) ) ); + connect ( d->baseUI->targetComboBox, SIGNAL ( activated ( const QString& ) ), + this, SLOT( slotTargetChanged ( const QString& ) ) ); +} + + +ChooseTargetDialog::~ChooseTargetDialog() +{ +} + +void ChooseTargetDialog::slotSubprojectChanged ( const QString& name ) +{ + d->chosenTarget = 0; + SubprojectItem* spitem = d->subprojectList.first(); + + for ( ; spitem; spitem = d->subprojectList.next() ) + { + if ( spitem->subdir == name ) + { + QPtrList <TargetItem> targetList = spitem->targets; + TargetItem* titem = targetList.first(); + + d->baseUI->targetComboBox->clear(); + +/* choosenSubprojectLabel->setText ( ( spitem->path + "<b>" + ->name + "</b>" ).mid ( d->widget->projectDirectory().length() + 1 ) );*/ + + d->chosenSubproject = spitem; + + for ( ; titem; titem = targetList.next() ) + { + if ( titem->primary == "PROGRAMS" || titem->primary == "LIBRARIES" || + titem->primary == "LTLIBRARIES" || titem->primary == "JAVA" ) + { + d->baseUI->targetComboBox->insertItem ( SmallIcon ( "target_kdevelop" ), titem->name ); + + //d->baseUI->targetComboBox->addToHistory ( titem->name ); + + // if the Active Target is in the currently selected Subproject + if ( d->widget->activeTarget() && + titem->name == d->widget->activeTarget()->name ) + { + d->baseUI->targetComboBox->setCurrentItem( titem->name ); + d->baseUI->chosenTargetLabel->setText( ( spitem->path + "/<b>" + titem->name + "</b>" ).mid( d->part->projectDirectory().length() + 1 ) ); + d->chosenTarget = titem; + //kdDebug ( 9020 ) << "2) Chosen target is " << d->chosenTarget->name << endl; + } + else + { + //d->baseUI->targetComboBox->setCurrentItem ( 0 ); + if ( !d->chosenTarget ) + { + d->baseUI->chosenTargetLabel->setText( ( spitem->path + "/<b>" + titem->name + "</b>") + .mid( d->part->projectDirectory().length() + 1 ) ); + //choosenSubprojectLabel->setText ( ( spitem->path + "<b>" + titem->name + "</b>" ).mid ( d->widget->projectDirectory().length() + 1 ) ); + + d->chosenTarget = titem; + } + //kdDebug ( 9020 ) << "2a) Chosen target is " << d->chosenTarget->name << endl; + } + } + } + + break; + } + } +} + +void ChooseTargetDialog::slotTargetChanged( const QString& name ) +{ + d->baseUI->chosenTargetLabel->setText( ( d->chosenSubproject->path + "/<b>" + name + "</b>" ) + .mid( d->part->projectDirectory().length() + 1 ) ); + + QPtrList <TargetItem> targetList = d->chosenSubproject->targets; + TargetItem* titem = targetList.first(); + + for ( ; titem; titem = targetList.next() ) + { + if ( titem->name == name ) + { + d->chosenTarget = titem; + //kdDebug ( 9020 ) << "4) Chosen target is " << d->chosenTarget->name << endl; + + break; + } + } +} + +void ChooseTargetDialog::slotOk() +{ + if ( d->baseUI->activeTargetRadioButton->isChecked() ) + { + d->chosenTarget = d->widget->activeTarget(); + d->chosenSubproject = d->widget->activeSubproject(); + } + if ( !d->chosenSubproject || !d->chosenTarget ) + return; + + //kdDebug ( 9020 ) << "3) Chosen target is " << d->chosenTarget->name << endl; + + QStringList newFileList; + QStringList::iterator it; + QString directory, fileName; + + for ( it = d->fileList.begin(); it != d->fileList.end(); ++it ) + { + bool found = false; + + int pos = ( *it ).findRev('/'); + if (pos != -1) + { + directory = ( *it ).left(pos); + fileName = ( *it ).mid(pos+1); + } + else + { + fileName = ( *it ); + } + + FileItem * fitem = d->chosenTarget->sources.first(); + for ( ; fitem; fitem = d->chosenTarget->sources.next() ) + { + if ( fitem->name == fileName ) + { + KMessageBox::error ( this, i18n ( "The file %1 already exists in the chosen target.\nThe file will be created but will not be added to the target.\n" + "Rename the file and select 'Add Existing Files' from the Automake Manager." ).arg ( fitem->name ), + i18n ( "Error While Adding Files" ) ); + found = true; + } + } + + if ( !found ) + { + /// \FIXME a quick hack to prevent adding header files to _SOURCES + /// and display them in noinst_HEADERS + if (AutoProjectPrivate::isHeader(fileName) && + ( d->chosenTarget->primary == "PROGRAMS" || d->chosenTarget->primary == "LIBRARIES" || d->chosenTarget->primary == "LTLIBRARIES" ) ) + { + kdDebug ( 9020 ) << "Ignoring header file and adding it to noinst_HEADERS: " << fileName << endl; + TargetItem* noinst_HEADERS_item = d->widget->getSubprojectView()->findNoinstHeaders(d->chosenSubproject); + FileItem *fitem = d->widget->createFileItem( fileName, d->chosenSubproject ); + noinst_HEADERS_item->sources.append( fitem ); + noinst_HEADERS_item->insertItem( fitem ); + + QString varname = "noinst_HEADERS"; + d->chosenSubproject->variables[ varname ] += ( " " + fileName ); + + QMap<QString, QString> replaceMap; + replaceMap.insert( varname, d->chosenSubproject->variables[ varname ] ); + + AutoProjectTool::addToMakefileam( d->chosenSubproject->path + "/Makefile.am", replaceMap ); + } + else + { + fitem = d->widget->createFileItem( fileName,d->chosenSubproject ); + d->chosenTarget->sources.append( fitem ); + d->chosenTarget->insertItem( fitem ); + + QString canontargetname = AutoProjectTool::canonicalize( d->chosenTarget->name ); + QString varname = canontargetname + "_SOURCES"; + d->chosenSubproject->variables[ varname ] += ( " " + fileName ); + + QMap<QString, QString> replaceMap; + replaceMap.insert( varname, d->chosenSubproject->variables[ varname ] ); + + AutoProjectTool::addToMakefileam( d->chosenSubproject->path + "/Makefile.am", replaceMap ); + } + newFileList.append ( d->chosenSubproject->path.mid ( d->part->projectDirectory().length() + 1 ) + "/" + fileName ); + } + + if ( directory.isEmpty() || directory != d->chosenSubproject->subdir ) + { + KShellProcess proc("/bin/sh"); + + proc << "mv"; + proc << KShellProcess::quote( d->part->projectDirectory() + "/" + directory + "/" + fileName ); + proc << KShellProcess::quote( d->chosenSubproject->path + "/" + fileName ); + proc.start(KProcess::DontCare); + } + + // why open the files?! +// d->part->partController()->editDocument ( KURL ( d->chosenSubproject->path + "/" + fileName ) ); + + found = false; + } + + d->widget->emitAddedFiles( newFileList ); + KDialogBase::slotOk(); +} + +TargetItem* ChooseTargetDialog::chosenTarget() +{ + return d->chosenTarget; +} + +SubprojectItem* ChooseTargetDialog::chosenSubproject() +{ + return d->chosenSubproject; +} + +bool ChooseTargetDialog::alwaysUseActiveTarget() const +{ + return d->baseUI->neverAskAgainCheckbox->isChecked(); +} + + +#include "choosetargetdialog.moc" +//kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/choosetargetdialog.h b/buildtools/autotools/choosetargetdialog.h new file mode 100644 index 00000000..44825ce5 --- /dev/null +++ b/buildtools/autotools/choosetargetdialog.h @@ -0,0 +1,57 @@ +/*************************************************************************** + ------------------- + begin : 29.11.2002 + copyright : (C) 2002 by Victor Rder + email : victor_roeder@gmx.de +***************************************************************************/ + +/*************************************************************************** + * * + * 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 _CHOOSETARGETDIALOG_H_ +#define _CHOOSETARGETDIALOG_H_ + +#include <kdialogbase.h> + +class AutoProjectWidget; +class AutoProjectPart; +class SubprojectItem; +class TargetItem; +class QStringList; +class QWidget; + +class ChooseTargetDialog : public KDialogBase +{ +Q_OBJECT +public: + ChooseTargetDialog( AutoProjectWidget* widget, AutoProjectPart* part, + QStringList fileList, QWidget* parent = 0, + const char* name = 0 ); + ~ChooseTargetDialog(); + +public: + TargetItem* chosenTarget(); + SubprojectItem* chosenSubproject(); + + bool alwaysUseActiveTarget() const; + +public slots: + void slotSubprojectChanged ( const QString& ); + void slotTargetChanged ( const QString& ); + +protected: + virtual void slotOk(); + +private: + class Private; + ChooseTargetDialog::Private* d; +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/choosetargetdlgbase.ui b/buildtools/autotools/choosetargetdlgbase.ui new file mode 100644 index 00000000..3581e595 --- /dev/null +++ b/buildtools/autotools/choosetargetdlgbase.ui @@ -0,0 +1,222 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ChooseTargetDlgBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ChooseTargetDlgBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>444</width> + <height>306</height> + </rect> + </property> + <property name="minimumSize"> + <size> + <width>444</width> + <height>306</height> + </size> + </property> + <property name="caption"> + <string>Automake Manager - Choose Target</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>buttonGroup1</cstring> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>Plain</enum> + </property> + <property name="lineWidth"> + <number>1</number> + </property> + <property name="title"> + <string></string> + </property> + <property name="flat"> + <bool>false</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>activeTargetRadioButton</cstring> + </property> + <property name="text"> + <string>Add new files to m&y active target</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>chooseTargetRadioButton</cstring> + </property> + <property name="text"> + <string>Choose &another target</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>chosenTargetGroupBox</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="title"> + <string>Choose &Target</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KHistoryCombo" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>subprojectComboBox</cstring> + </property> + <property name="duplicatesEnabled"> + <bool>false</bool> + </property> + </widget> + <widget class="KHistoryCombo" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>targetComboBox</cstring> + </property> + <property name="duplicatesEnabled"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>targetStaticLabel</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Target:</string> + </property> + </widget> + <widget class="QLabel" row="2" column="1"> + <property name="name"> + <cstring>chosenTargetLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>[TARGET]</string> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="title"> + <string>&New Files</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KListView"> + <property name="name"> + <cstring>newFileList</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>cancelNoticeLabel</cstring> + </property> + <property name="text"> + <string><qt><b>Note:</b> If you cancel, your files will be created but will <b>not</b> be added to the project.</qt></string> + </property> + <property name="alignment"> + <set>AlignVCenter</set> + </property> + </widget> + </vbox> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>neverAskAgainCheckbox</cstring> + </property> + <property name="text"> + <string>Do &not ask me again and use always my active target</string> + </property> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>activeTargetRadioButton</sender> + <signal>toggled(bool)</signal> + <receiver>chosenTargetGroupBox</receiver> + <slot>setDisabled(bool)</slot> + </connection> + <connection> + <sender>activeTargetRadioButton</sender> + <signal>toggled(bool)</signal> + <receiver>subprojectComboBox</receiver> + <slot>setDisabled(bool)</slot> + </connection> + <connection> + <sender>activeTargetRadioButton</sender> + <signal>toggled(bool)</signal> + <receiver>targetComboBox</receiver> + <slot>setDisabled(bool)</slot> + </connection> +</connections> +<tabstops> + <tabstop>activeTargetRadioButton</tabstop> + <tabstop>chooseTargetRadioButton</tabstop> + <tabstop>subprojectComboBox</tabstop> + <tabstop>targetComboBox</tabstop> + <tabstop>newFileList</tabstop> + <tabstop>neverAskAgainCheckbox</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<slots> + <slot access="protected">slotActiveTargetToggled(bool)</slot> + <slot access="protected">slotChooseTargetToggled(bool)</slot> + <slot access="private">slotSubprojectChanged(const QString&)</slot> + <slot access="private">slotTargetChanged(const QString&)</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kcombobox.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kcombobox.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/buildtools/autotools/configureoptionswidget.cpp b/buildtools/autotools/configureoptionswidget.cpp new file mode 100644 index 00000000..7e2db214 --- /dev/null +++ b/buildtools/autotools/configureoptionswidget.cpp @@ -0,0 +1,431 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "configureoptionswidget.h" + +#include <qcombobox.h> +#include <qdir.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qgroupbox.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qtimer.h> +#include <qvalidator.h> +#include <klineedit.h> +#include <kdebug.h> +#include <kfiledialog.h> +#include <klibloader.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kservice.h> +#include <ktrader.h> + +#include "kdevcompileroptions.h" +#include "autoprojectpart.h" +#include "environmentvariableswidget.h" + + +class ServiceComboBox +{ +public: + static void insertStringList(QComboBox *combo, const QValueList<KService::Ptr> &list, + QStringList *names, QStringList *execs) + { + QValueList<KService::Ptr>::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + combo->insertItem((*it)->comment()); + (*names) << (*it)->desktopEntryName(); + (*execs) << (*it)->exec(); + kdDebug(9020) << "insertStringList item " << (*it)->name() << "," << (*it)->exec() << endl; + } + } + static QString currentText(QComboBox *combo, const QStringList &names) + { + if (combo->currentItem() == -1) + return QString::null; + return names[combo->currentItem()]; + } + static void setCurrentText(QComboBox *combo, const QString &str, const QStringList &names) + { + QStringList::ConstIterator it; + int i = 0; + for (it = names.begin(); it != names.end(); ++it) { + if (*it == str) { + combo->setCurrentItem(i); + break; + } + ++i; + } + } +}; + + +ConfigureOptionsWidget::ConfigureOptionsWidget(AutoProjectPart *part, QWidget *parent, const char *name) + : ConfigureOptionsWidgetBase(parent, name) +{ + config_combo->setValidator(new QRegExpValidator(QRegExp("^\\D.*"), this)); + + m_part = part; + env_groupBox->setColumnLayout( 1, Qt::Vertical ); + QDomDocument &dom = *part->projectDom(); + m_environmentVariablesWidget = new EnvironmentVariablesWidget(dom, "/kdevautoproject/general/envvars", env_groupBox); + + coffers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'C'"); + cxxoffers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'C++'"); + f77offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Fortran'"); + + ServiceComboBox::insertStringList(cservice_combo, coffers, &cservice_names, &cservice_execs); + ServiceComboBox::insertStringList(cxxservice_combo, cxxoffers, &cxxservice_names, &cxxservice_execs); + ServiceComboBox::insertStringList(f77service_combo, f77offers, &f77service_names, &f77service_execs); + + if (coffers.isEmpty()) + cflags_button->setEnabled(false); + if (cxxoffers.isEmpty()) + cxxflags_button->setEnabled(false); + if (f77offers.isEmpty()) + f77flags_button->setEnabled(false); + + allConfigs = part->allBuildConfigs(); + config_combo->insertStringList(allConfigs); + + dirty = false; + currentConfig = QString::null; + configChanged(part->currentBuildConfig()); + + fixLayout(); +} + + +ConfigureOptionsWidget::~ConfigureOptionsWidget() +{} + + +void ConfigureOptionsWidget::fixLayout() +{ + int w1 = ccompiler_label->sizeHint().width(); + int w2 = cbinary_label->sizeHint().width(); + int w3 = cflags_label->sizeHint().width(); + int w4 = cxxcompiler_label->sizeHint().width(); + int w5 = cxxbinary_label->sizeHint().width(); + int w6 = cxxflags_label->sizeHint().width(); + int w7 = f77compiler_label->sizeHint().width(); + int w8 = f77binary_label->sizeHint().width(); + int w9 = f77flags_label->sizeHint().width(); + + int w = QMAX(w1, QMAX(w2, w3)); + w = QMAX(w, QMAX(w4, w5)); + w = QMAX(w, QMAX(w6, w7)); + w = QMAX(w, QMAX(w8, w9)); + + ccompiler_label->setMinimumWidth(w); + cxxcompiler_label->setMinimumWidth(w); + f77compiler_label->setMinimumWidth(w); +} + + +void ConfigureOptionsWidget::readSettings(const QString &config) +{ + QDomDocument dom = *m_part->projectDom(); + QString prefix = "/kdevautoproject/configurations/" + config + "/"; + kdDebug(9020) << "Reading config from " << prefix << endl; + + configargs_edit->setText(DomUtil::readEntry(dom, prefix + "configargs")); + QString builddir = DomUtil::readEntry(dom, prefix + "builddir"); + if (builddir.isEmpty() && config != "default") + builddir = config; + builddir_edit->setText(builddir); + + topsourcedir_edit->setText(DomUtil::readEntry(dom, prefix + "topsourcedir")); + + cppflags_edit->setText(DomUtil::readEntry(dom, prefix + "cppflags")); + ldflags_edit->setText(DomUtil::readEntry(dom, prefix + "ldflags")); + + QString ccompiler = DomUtil::readEntry(dom, prefix + "ccompiler"); + QString cxxcompiler = DomUtil::readEntry(dom, prefix + "cxxcompiler"); + QString f77compiler = DomUtil::readEntry(dom, prefix + "f77compiler"); + + if (ccompiler.isEmpty()) { + kdDebug(9020) << "No c compiler set" << endl; + QValueList<KService::Ptr>::ConstIterator it; + for (it = coffers.begin(); it != coffers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + kdDebug(9020) << "Found default " << (*it)->name() << endl; + ccompiler = (*it)->name(); + break; + } + } + } + if (cxxcompiler.isEmpty()) { + kdDebug(9020) << "No cxx compiler set" << endl; + QValueList<KService::Ptr>::ConstIterator it; + for (it = cxxoffers.begin(); it != cxxoffers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + kdDebug(9020) << "Found default " << (*it)->name() << endl; + cxxcompiler = (*it)->name(); + break; + } + } + } + if (f77compiler.isEmpty()) { + kdDebug(9020) << "No c compiler set" << endl; + QValueList<KService::Ptr>::ConstIterator it; + for (it = f77offers.begin(); it != f77offers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + kdDebug(9020) << "Found default " << (*it)->name() << endl; + f77compiler = (*it)->name(); + break; + } + } + } + + ServiceComboBox::setCurrentText(cservice_combo, ccompiler, cservice_names); + ServiceComboBox::setCurrentText(cxxservice_combo, cxxcompiler, cxxservice_names); + ServiceComboBox::setCurrentText(f77service_combo, f77compiler, f77service_names); + + cbinary_edit->setText(DomUtil::readEntry(dom, prefix + "ccompilerbinary")); + cxxbinary_edit->setText(DomUtil::readEntry(dom, prefix + "cxxcompilerbinary")); + f77binary_edit->setText(DomUtil::readEntry(dom, prefix + "f77compilerbinary")); + + cflags_edit->setText(DomUtil::readEntry(dom, prefix + "cflags")); + cxxflags_edit->setText(DomUtil::readEntry(dom, prefix + "cxxflags")); + f77flags_edit->setText(DomUtil::readEntry(dom, prefix + "f77flags")); + + m_environmentVariablesWidget->readEnvironment(dom, prefix + "envvars"); +} + + +void ConfigureOptionsWidget::saveSettings(const QString &config) +{ + m_environmentVariablesWidget->accept(); + QDomDocument dom = *m_part->projectDom(); + QString prefix = "/kdevautoproject/configurations/" + config + "/"; + kdDebug(9020) << "Saving config under " << prefix << endl; + + DomUtil::writeEntry(dom, prefix + "configargs", configargs_edit->text()); + DomUtil::writeEntry(dom, prefix + "builddir", builddir_edit->text()); + DomUtil::writeEntry(dom, prefix + "topsourcedir", topsourcedir_edit->text()); + + DomUtil::writeEntry(dom, prefix + "cppflags", cppflags_edit->text()); + DomUtil::writeEntry(dom, prefix + "ldflags", ldflags_edit->text()); + + QFileInfo fi(m_part->buildDirectory()); + QDir dir(fi.dir()); + dir.mkdir(fi.fileName()); + + DomUtil::writeEntry(dom, prefix + "ccompiler", + ServiceComboBox::currentText(cservice_combo, cservice_names)); + DomUtil::writeEntry(dom, prefix + "cxxcompiler", + ServiceComboBox::currentText(cxxservice_combo, cxxservice_names)); + DomUtil::writeEntry(dom, prefix + "f77compiler", + ServiceComboBox::currentText(f77service_combo, f77service_names)); + + DomUtil::writeEntry(dom, prefix + "ccompilerbinary", cbinary_edit->text()); + DomUtil::writeEntry(dom, prefix + "cxxcompilerbinary", cxxbinary_edit->text()); + DomUtil::writeEntry(dom, prefix + "f77compilerbinary", f77binary_edit->text()); + + DomUtil::writeEntry(dom, prefix + "cflags", cflags_edit->text()); + DomUtil::writeEntry(dom, prefix + "cxxflags", cxxflags_edit->text()); + DomUtil::writeEntry(dom, prefix + "f77flags", f77flags_edit->text()); + + if (KMessageBox::questionYesNo(this, i18n("Re-run configure for %1 now?").arg(config), QString::null, i18n("Rerun"), i18n("Do Not Run")) == KMessageBox::Yes) + QTimer::singleShot(0, m_part, SLOT(slotConfigure())); + +} + + +void ConfigureOptionsWidget::setDirty() +{ + kdDebug(9020) << "config dirty" << endl; + dirty = true; +} + + +void ConfigureOptionsWidget::builddirClicked() +{ + QString dir = builddir_edit->text(); + dir = KFileDialog::getExistingDirectory(dir, this); + if (!dir.isNull()) + builddir_edit->setText(dir); +} + +void ConfigureOptionsWidget::topsourcedirClicked() +{ + QString dir = topsourcedir_edit->text(); + dir = KFileDialog::getExistingDirectory(dir, this); + if (!dir.isNull()) + topsourcedir_edit->setText(dir); +} + +void ConfigureOptionsWidget::configComboTextChanged(const QString &config) +{ + bool canAdd = !allConfigs.contains(config) && !config.contains("/") && !config.isEmpty(); + bool canRemove = allConfigs.contains(config) && config != "default"; + addconfig_button->setEnabled(canAdd); + removeconfig_button->setEnabled(canRemove); +} + + +void ConfigureOptionsWidget::configChanged(const QString &config) +{ + if (config == currentConfig || !allConfigs.contains(config)) + return; + + if (!currentConfig.isNull() && dirty) + saveSettings(currentConfig); + + currentConfig = config; + readSettings(config); + dirty = false; + + config_combo->blockSignals(true); + config_combo->setEditText(config); + config_combo->blockSignals(false); +} + + +void ConfigureOptionsWidget::configAdded() +{ + QString config = config_combo->currentText(); + + allConfigs.append(config); + + config_combo->clear(); + config_combo->insertStringList(allConfigs); + configChanged(config); + setDirty(); // force saving +} + + +void ConfigureOptionsWidget::configRemoved() +{ + QString config = config_combo->currentText(); + + QDomDocument dom = *m_part->projectDom(); + QDomNode node = dom.documentElement().namedItem("kdevautoproject").namedItem("configurations"); + node.removeChild(node.namedItem(config)); + allConfigs.remove(config); + + config_combo->clear(); + config_combo->insertStringList(allConfigs); + + currentConfig = QString::null; + configChanged("default"); +} + + +void ConfigureOptionsWidget::cserviceChanged() +{ + QString exec = ServiceComboBox::currentText(cservice_combo, cservice_execs); + cbinary_edit->setText(exec); + kdDebug(9020) << "exec: " << exec << endl; +} + + +void ConfigureOptionsWidget::cxxserviceChanged() +{ + QString exec = ServiceComboBox::currentText(cxxservice_combo, cxxservice_execs); + cxxbinary_edit->setText(exec); +} + + +void ConfigureOptionsWidget::f77serviceChanged() +{ + QString exec = ServiceComboBox::currentText(f77service_combo, f77service_execs); + f77binary_edit->setText(exec); + kdDebug(9020) << "exec: " << exec << endl; +} + + +void ConfigureOptionsWidget::cflagsClicked() +{ + QString name = ServiceComboBox::currentText(cservice_combo, cservice_names); + KDevCompilerOptions *plugin = createCompilerOptions(name); + + if (plugin) { + QString flags = plugin->exec(this, cflags_edit->text()); + cflags_edit->setText(flags); + delete plugin; + } +} + + +void ConfigureOptionsWidget::cxxflagsClicked() +{ + QString name = ServiceComboBox::currentText(cxxservice_combo, cxxservice_names); + KDevCompilerOptions *plugin = createCompilerOptions(name); + + if (plugin) { + QString flags = plugin->exec(this, cxxflags_edit->text()); + cxxflags_edit->setText(flags); + delete plugin; + } +} + + +void ConfigureOptionsWidget::f77flagsClicked() +{ + QString name = ServiceComboBox::currentText(f77service_combo, f77service_names); + KDevCompilerOptions *plugin = createCompilerOptions(name); + + if (plugin) { + QString flags = plugin->exec(this, f77flags_edit->text()); + f77flags_edit->setText(flags); + delete plugin; + } +} + + +KDevCompilerOptions *ConfigureOptionsWidget::createCompilerOptions(const QString &name) +{ + KService::Ptr service = KService::serviceByDesktopName(name); + if (!service) { + kdDebug(9020) << "Can't find service " << name; + return 0; + } + + KLibFactory *factory = KLibLoader::self()->factory(QFile::encodeName(service->library())); + if (!factory) { + QString errorMessage = KLibLoader::self()->lastErrorMessage(); + KMessageBox::error(0, i18n("There was an error loading the module %1.\n" + "The diagnostics is:\n%2").arg(service->name()).arg(errorMessage)); + exit(1); + } + + QStringList args; + QVariant prop = service->property("X-KDevelop-Args"); + if (prop.isValid()) + args = QStringList::split(" ", prop.toString()); + + QObject *obj = factory->create(this, service->name().latin1(), + "KDevCompilerOptions", args); + + if (!obj->inherits("KDevCompilerOptions")) { + kdDebug(9020) << "Component does not inherit KDevCompilerOptions" << endl; + return 0; + } + KDevCompilerOptions *dlg = (KDevCompilerOptions*) obj; + + return dlg; +} + + +void ConfigureOptionsWidget::accept() +{ + DomUtil::writeEntry(*m_part->projectDom(), "/kdevautoproject/general/useconfiguration", currentConfig); + m_environmentVariablesWidget->accept(); + if (dirty) + { + saveSettings(currentConfig); + } +} + +#include "configureoptionswidget.moc" diff --git a/buildtools/autotools/configureoptionswidget.h b/buildtools/autotools/configureoptionswidget.h new file mode 100644 index 00000000..a973ce7d --- /dev/null +++ b/buildtools/autotools/configureoptionswidget.h @@ -0,0 +1,69 @@ +/*************************************************************************** +* Copyright (C) 2001-2002 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#ifndef _CONFIGUREOPTIONSWIDGET_H_ +#define _CONFIGUREOPTIONSWIDGET_H_ + +#include "configureoptionswidgetbase.h" + +#include <ktrader.h> +#include "domutil.h" + + +class KDevCompilerOptions; +class AutoProjectPart; +class EnvironmentVariablesWidget; + +class ConfigureOptionsWidget : public ConfigureOptionsWidgetBase +{ + Q_OBJECT + +public: + ConfigureOptionsWidget( AutoProjectPart *part, QWidget *parent = 0, const char *name = 0 ); + ~ConfigureOptionsWidget(); + +public slots: + void accept(); + +private: + virtual void builddirClicked(); + virtual void topsourcedirClicked(); + virtual void setDirty(); + virtual void configChanged( const QString &config ); + virtual void configComboTextChanged( const QString &config ); + virtual void configAdded(); + virtual void configRemoved(); + virtual void cflagsClicked(); + virtual void cxxflagsClicked(); + virtual void f77flagsClicked(); + virtual void cserviceChanged(); + virtual void cxxserviceChanged(); + virtual void f77serviceChanged(); + + void fixLayout(); + void readSettings( const QString &config ); + void saveSettings( const QString &config ); + + KDevCompilerOptions *createCompilerOptions( const QString &lang ); + KTrader::OfferList coffers, cxxoffers, f77offers; + QStringList cservice_names, cservice_execs; + QStringList cxxservice_names, cxxservice_execs; + QStringList f77service_names, f77service_execs; + QStringList allConfigs; + QString currentConfig; + bool dirty; + + AutoProjectPart *m_part; + EnvironmentVariablesWidget* m_environmentVariablesWidget; +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/configureoptionswidgetbase.ui b/buildtools/autotools/configureoptionswidgetbase.ui new file mode 100644 index 00000000..0eb47ac7 --- /dev/null +++ b/buildtools/autotools/configureoptionswidgetbase.ui @@ -0,0 +1,1040 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ConfigureOptionsWidgetBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>configure_options_widget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>628</width> + <height>607</height> + </rect> + </property> + <property name="caption"> + <string>Configure Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>config_label</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Configuration:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>config_combo</cstring> + </property> + </widget> + <widget class="QComboBox"> + <property name="name"> + <cstring>config_combo</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Different build profiles</string> + </property> + <property name="whatsThis" stdset="0"> + <string>profiles</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer17_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>8</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>addconfig_button</cstring> + </property> + <property name="text"> + <string>&Add</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>removeconfig_button</cstring> + </property> + <property name="text"> + <string>&Remove</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer18_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QTabWidget"> + <property name="name"> + <cstring>tabwidget</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>general_tab</cstring> + </property> + <attribute name="title"> + <string>&General</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KLineEdit" row="1" column="1" rowspan="1" colspan="4"> + <property name="name"> + <cstring>configargs_edit</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Options to pass to configure, e.g. --prefix=<install dir></string> + </property> + <property name="whatsThis" stdset="0"> + <string>Options to pass to configure, e.g. --prefix=<install dir></string> + </property> + </widget> + <widget class="QLabel" row="3" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>builddir_label</cstring> + </property> + <property name="text"> + <string>&Build directory (must be different for every different configuration):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>builddir_edit</cstring> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>Spacer23</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="5" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>topsourcedir_label</cstring> + </property> + <property name="text"> + <string>Top source &directory:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>topsourcedir_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="4" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>builddir_edit</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>The build process will place the object +files and binary in this directory. + +If the name does not have a leading / +then it is relative to the project directory. +(in the General page) + +The build process also checks here for +a Makefile and a configure script. + +If you have imported a project and you were +building in the project directory, you +probably want this to be blank.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>The build process will place the object +files and binary in this directory. + +If the name does not have a leading / +then it is relative to the project directory. +(in the General page) + +The build process also checks here for +a Makefile and a configure script. + +If you have imported a project and you were +building in the project directory, you +probably want this to be blank.</string> + </property> + </widget> + <widget class="QPushButton" row="4" column="4"> + <property name="name"> + <cstring>builddir_button</cstring> + </property> + <property name="minimumSize"> + <size> + <width>30</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + <spacer row="4" column="0"> + <property name="name"> + <cstring>Spacer24</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="6" column="4"> + <property name="name"> + <cstring>topsourcedir_button</cstring> + </property> + <property name="minimumSize"> + <size> + <width>30</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + <widget class="KLineEdit" row="6" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>topsourcedir_edit</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Where to start looking for the src files. +If the name does not have a leading / +then it is relative to the project directory. +(in the General page)</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Where to start looking for the src files. +If the name does not have a leading / +then it is relative to the project directory. +(in the General page)</string> + </property> + </widget> + <spacer row="6" column="0"> + <property name="name"> + <cstring>spacer17</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="10" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>ldflags_label</cstring> + </property> + <property name="text"> + <string>Li&nker flags (LDFLAGS):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>ldflags_edit</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>Linker flags, e.g. -L<lib dir> if you have libraries in a +nonstandard directory <lib dir></string> + </property> + </widget> + <spacer row="11" column="0"> + <property name="name"> + <cstring>spacer17_2_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KLineEdit" row="11" column="1" rowspan="1" colspan="4"> + <property name="name"> + <cstring>ldflags_edit</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Linker flags, e.g. -L<lib dir> if you have libraries in a +nonstandard directory <lib dir></string> + </property> + <property name="whatsThis" stdset="0"> + <string>Linker flags, e.g. -L<lib dir> if you have libraries in a +nonstandard directory <lib dir></string> + </property> + </widget> + <widget class="KLineEdit" row="9" column="1" rowspan="1" colspan="4"> + <property name="name"> + <cstring>cppflags_edit</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>C/C++ preprocessor flags, e.g. -I<include dir> if you have +headers in a nonstandard directory <include dir></string> + </property> + <property name="whatsThis" stdset="0"> + <string>C/C++ preprocessor flags, e.g. -I<include dir> if you have +headers in a nonstandard directory <include dir></string> + </property> + </widget> + <spacer row="9" column="0"> + <property name="name"> + <cstring>spacer17_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="8" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>cppflags_label</cstring> + </property> + <property name="text"> + <string>C/C++ &preprocessor flags (CPPFLAGS):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cppflags_edit</cstring> + </property> + <property name="whatsThis" stdset="0"> + <string>C/C++ preprocessor flags, e.g. -I<include dir> if you have +headers in a nonstandard directory <include dir></string> + </property> + </widget> + <widget class="QLabel" row="0" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>configargs_label</cstring> + </property> + <property name="text"> + <string>Configure argu&ments:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>configargs_edit</cstring> + </property> + </widget> + <widget class="QGroupBox" row="12" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>env_groupBox</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Environment &Variables</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + </grid> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>c_tab</cstring> + </property> + <attribute name="title"> + <string>C</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>ccompiler_label</cstring> + </property> + <property name="text"> + <string>C com&piler:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cservice_combo</cstring> + </property> + </widget> + <widget class="QComboBox" row="0" column="1"> + <property name="name"> + <cstring>cservice_combo</cstring> + </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>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>cflags_label</cstring> + </property> + <property name="text"> + <string>Compiler f&lags (CFLAGS):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cflags_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="4" column="1"> + <property name="name"> + <cstring>cflags_edit</cstring> + </property> + </widget> + <widget class="QPushButton" row="4" column="2"> + <property name="name"> + <cstring>cflags_button</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>30</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + <spacer row="5" column="1"> + <property name="name"> + <cstring>Spacer10</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>168</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>cbinary_label</cstring> + </property> + <property name="text"> + <string>Compiler co&mmand (CC):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cbinary_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>cbinary_edit</cstring> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>Spacer12</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>cxx_tab</cstring> + </property> + <attribute name="title"> + <string>C++</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>cxxcompiler_label</cstring> + </property> + <property name="text"> + <string>C++ com&piler:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cxxservice_combo</cstring> + </property> + </widget> + <widget class="QComboBox" row="0" column="1"> + <property name="name"> + <cstring>cxxservice_combo</cstring> + </property> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>Spacer13</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>cxxbinary_label</cstring> + </property> + <property name="text"> + <string>Compiler co&mmand (CXX):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cxxbinary_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>cxxbinary_edit</cstring> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>Spacer13_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>cxxflags_label</cstring> + </property> + <property name="text"> + <string>Compiler flags (C&XXFLAGS):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cxxflags_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="4" column="1"> + <property name="name"> + <cstring>cxxflags_edit</cstring> + </property> + </widget> + <widget class="QPushButton" row="4" column="2"> + <property name="name"> + <cstring>cxxflags_button</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>30</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + <spacer row="5" column="1"> + <property name="name"> + <cstring>Spacer16</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>fortran_tab</cstring> + </property> + <attribute name="title"> + <string>F&ortran</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>f77compiler_label</cstring> + </property> + <property name="text"> + <string>Fortra&n compiler:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>f77service_combo</cstring> + </property> + </widget> + <widget class="QComboBox" row="0" column="1"> + <property name="name"> + <cstring>f77service_combo</cstring> + </property> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>Spacer16_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>f77binary_label</cstring> + </property> + <property name="text"> + <string>Compiler co&mmand (F77):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>f77binary_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>f77binary_edit</cstring> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>Spacer17</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>f77flags_label</cstring> + </property> + <property name="text"> + <string>Compiler f&lags (FFLAGS):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>f77flags_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="4" column="1"> + <property name="name"> + <cstring>f77flags_edit</cstring> + </property> + </widget> + <widget class="QPushButton" row="4" column="2"> + <property name="name"> + <cstring>f77flags_button</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>30</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + <spacer row="5" column="1"> + <property name="name"> + <cstring>Spacer18</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>cflags_button</sender> + <signal>clicked()</signal> + <receiver>configure_options_widget</receiver> + <slot>cflagsClicked()</slot> + </connection> + <connection> + <sender>f77flags_button</sender> + <signal>clicked()</signal> + <receiver>configure_options_widget</receiver> + <slot>f77flagsClicked()</slot> + </connection> + <connection> + <sender>cservice_combo</sender> + <signal>activated(int)</signal> + <receiver>configure_options_widget</receiver> + <slot>cserviceChanged()</slot> + </connection> + <connection> + <sender>f77service_combo</sender> + <signal>activated(int)</signal> + <receiver>configure_options_widget</receiver> + <slot>f77serviceChanged()</slot> + </connection> + <connection> + <sender>cxxflags_button</sender> + <signal>clicked()</signal> + <receiver>configure_options_widget</receiver> + <slot>cxxflagsClicked()</slot> + </connection> + <connection> + <sender>cxxservice_combo</sender> + <signal>activated(int)</signal> + <receiver>configure_options_widget</receiver> + <slot>cxxserviceChanged()</slot> + </connection> + <connection> + <sender>addconfig_button</sender> + <signal>clicked()</signal> + <receiver>configure_options_widget</receiver> + <slot>configAdded()</slot> + </connection> + <connection> + <sender>removeconfig_button</sender> + <signal>clicked()</signal> + <receiver>configure_options_widget</receiver> + <slot>configRemoved()</slot> + </connection> + <connection> + <sender>config_combo</sender> + <signal>activated(const QString&)</signal> + <receiver>configure_options_widget</receiver> + <slot>configChanged(const QString&)</slot> + </connection> + <connection> + <sender>config_combo</sender> + <signal>textChanged(const QString&)</signal> + <receiver>configure_options_widget</receiver> + <slot>configComboTextChanged(const QString&)</slot> + </connection> + <connection> + <sender>builddir_button</sender> + <signal>clicked()</signal> + <receiver>configure_options_widget</receiver> + <slot>builddirClicked()</slot> + </connection> + <connection> + <sender>configargs_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>configure_options_widget</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>builddir_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>configure_options_widget</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>cbinary_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>configure_options_widget</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>cflags_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>configure_options_widget</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>cxxbinary_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>configure_options_widget</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>cxxflags_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>configure_options_widget</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>f77binary_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>configure_options_widget</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>f77flags_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>configure_options_widget</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>topsourcedir_button</sender> + <signal>clicked()</signal> + <receiver>configure_options_widget</receiver> + <slot>topsourcedirClicked()</slot> + </connection> + <connection> + <sender>topsourcedir_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>configure_options_widget</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>cppflags_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>configure_options_widget</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>ldflags_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>configure_options_widget</receiver> + <slot>setDirty()</slot> + </connection> +</connections> +<tabstops> + <tabstop>configargs_edit</tabstop> + <tabstop>builddir_edit</tabstop> + <tabstop>builddir_button</tabstop> + <tabstop>topsourcedir_edit</tabstop> + <tabstop>topsourcedir_button</tabstop> + <tabstop>cppflags_edit</tabstop> + <tabstop>ldflags_edit</tabstop> + <tabstop>tabwidget</tabstop> + <tabstop>config_combo</tabstop> + <tabstop>addconfig_button</tabstop> + <tabstop>removeconfig_button</tabstop> + <tabstop>cservice_combo</tabstop> + <tabstop>cbinary_edit</tabstop> + <tabstop>cflags_edit</tabstop> + <tabstop>cflags_button</tabstop> + <tabstop>cxxservice_combo</tabstop> + <tabstop>cxxbinary_edit</tabstop> + <tabstop>cxxflags_edit</tabstop> + <tabstop>cxxflags_button</tabstop> + <tabstop>f77service_combo</tabstop> + <tabstop>f77binary_edit</tabstop> + <tabstop>f77flags_edit</tabstop> + <tabstop>f77flags_button</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<slots> + <slot access="protected">builddirClicked()</slot> + <slot access="protected">cflagsClicked()</slot> + <slot access="protected">configAdded()</slot> + <slot access="protected">configChanged(const QString&)</slot> + <slot access="protected">configComboTextChanged(const QString&)</slot> + <slot access="protected">configRemoved()</slot> + <slot access="protected">cserviceChanged()</slot> + <slot access="protected">cxxflagsClicked()</slot> + <slot access="protected">cxxserviceChanged()</slot> + <slot access="protected">f77flagsClicked()</slot> + <slot access="protected">f77serviceChanged()</slot> + <slot access="protected">setDirty()</slot> + <slot access="protected">topsourcedirClicked()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/buildtools/autotools/fileselectorwidget.cpp b/buildtools/autotools/fileselectorwidget.cpp new file mode 100644 index 00000000..65b87bf7 --- /dev/null +++ b/buildtools/autotools/fileselectorwidget.cpp @@ -0,0 +1,243 @@ +/**************************************************************************** + * Copyright (C) 2001 by Hugo Varotto * + * hugo@varotto-usa.com * + * * + * Based on Kate's fileselector widget by * + * Matt Newell * + * (C) 2001 by Matt Newell * + * newellm@proaxis.com * + * * + * 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 <qlayout.h> +#include <qpushbutton.h> +#include <qhbox.h> +#include <qlabel.h> +#include <qstrlist.h> +#include <qtooltip.h> +#include <qregexp.h> + +#include <kxmlguiclient.h> +#include <kiconloader.h> +#include <kurlcombobox.h> +#include <kurlcompletion.h> +#include <kprotocolinfo.h> +#include <kconfig.h> +#include <klocale.h> +#include <kcombobox.h> + +#include <kdebug.h> + +#include "fileselectorwidget.h" +#include <kdiroperator.h> +#include <kcombiview.h> +#include <kfilepreview.h> +#include <kfileview.h> +#include <kfileitem.h> +#include <kimagefilepreview.h> + +#include "autoprojectwidget.h" +#include "autoprojectpart.h" +#include "kdevlanguagesupport.h" + +#include "kfilednddetailview.h" +#include "kfiledndiconview.h" + +KDnDDirOperator::KDnDDirOperator ( const KURL &urlName, QWidget* parent, const char* name ) : KDirOperator ( urlName, parent, name ) +{ + +} + +KFileView* KDnDDirOperator::createView( QWidget* parent, KFile::FileView view ) +{ + KFileView* new_view = 0L; + + if( (view & KFile::Detail) == KFile::Detail ) { + new_view = new KFileDnDDetailView( parent, "detail view"); + } + else if ((view & KFile::Simple) == KFile::Simple ) { + new_view = new KFileDnDIconView( parent, "simple view"); + new_view->setViewName( i18n("Short View") ); + } + + return new_view; +} + + +FileSelectorWidget::FileSelectorWidget(AutoProjectPart* part, KFile::Mode mode, QWidget* parent, const char* name ) : QWidget(parent, name) +{ + m_part = part; + + // widgets and layout + QVBoxLayout* lo = new QVBoxLayout(this); + + QHBox *hlow = new QHBox (this); + lo->addWidget(hlow); + + home = new QPushButton( hlow ); + home->setPixmap(SmallIcon("gohome")); + QToolTip::add(home, i18n("Home directory")); + up = new QPushButton( /*i18n("&Up"),*/ hlow ); + up->setPixmap(SmallIcon("up")); + QToolTip::add(up, i18n("Up one level")); + back = new QPushButton( /*i18n("&Back"),*/ hlow ); + back->setPixmap(SmallIcon("back")); + QToolTip::add(back, i18n("Previous directory")); + forward = new QPushButton( /*i18n("&Next"),*/ hlow ); + forward->setPixmap(SmallIcon("forward")); + QToolTip::add(forward, i18n("Next directory")); + + // HACK + QWidget* spacer = new QWidget(hlow); + hlow->setStretchFactor(spacer, 1); + hlow->setMaximumHeight(up->height()); + + cmbPath = new KURLComboBox( KURLComboBox::Directories, true, this, "path combo" ); + cmbPath->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed )); + KURLCompletion* cmpl = new KURLCompletion(); + cmbPath->setCompletionObject( cmpl ); + lo->addWidget(cmbPath); + + dir = new KDnDDirOperator(KURL(), this, "operator"); + dir->setView(KFile::Simple); + dir->setMode(mode); + + lo->addWidget(dir); + lo->setStretchFactor(dir, 2); + + QHBox* filterBox = new QHBox(this); + filterIcon = new QLabel(filterBox); + filterIcon->setPixmap( BarIcon("filter") ); + filter = new KHistoryCombo(filterBox, "filter"); + filter->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed )); + filterBox->setStretchFactor(filter, 2); + lo->addWidget(filterBox); + + // slots and signals + connect( filter, SIGNAL( textChanged(const QString&) ), SLOT( slotFilterChanged(const QString&) ) ); + connect( filter, SIGNAL( activated(const QString&) ), SLOT( slotFilterChanged(const QString&) ) ); + connect( filter, SIGNAL( returnPressed(const QString&) ), SLOT( filterReturnPressed(const QString&) ) ); + + connect( home, SIGNAL( clicked() ), dir, SLOT( home() ) ); + connect( up, SIGNAL( clicked() ), dir, SLOT( cdUp() ) ); + connect( back, SIGNAL( clicked() ), dir, SLOT( back() ) ); + connect( forward, SIGNAL( clicked() ), dir, SLOT( forward() ) ); + + connect( cmbPath, SIGNAL( urlActivated( const KURL& )), this, SLOT( cmbPathActivated( const KURL& ) )); + //connect( cmbPath, SIGNAL( returnPressed( const QString& )), this, SLOT( cmbPathReturnPressed( const QString& ) )); + connect( dir, SIGNAL(urlEntered(const KURL&)), this, SLOT(dirUrlEntered(const KURL&)) ); + + connect( dir, SIGNAL(finishedLoading()), this, SLOT(dirFinishedLoading()) ); + +// dirUrlEntered( dir->url() ); + + QStringList list; + + /* read the file patterns from the project DOM */ + QDomElement docEl = m_part->projectDom()->documentElement(); + QDomElement fileviewEl = docEl.namedItem("kdevfileview").toElement(); + QDomElement groupsEl = fileviewEl.namedItem("groups").toElement(); + QDomElement groupEl = groupsEl.firstChild().toElement(); + + while ( !groupEl.isNull() ) + { + if (groupEl.tagName() == "group") + { + list << groupEl.attribute("pattern").replace ( QRegExp ( ";" ), " " ) + " (" + groupEl.attribute("name") + ")"; + } + groupEl = groupEl.nextSibling().toElement(); + } + + filter->setHistoryItems ( list ); + +} + + +FileSelectorWidget::~FileSelectorWidget() +{ +} + +void FileSelectorWidget::dragEnterEvent ( QDragEnterEvent* /*ev*/ ) +{ +} + +void FileSelectorWidget::dropEvent ( QDropEvent* /*ev*/ ) +{ + kdDebug ( 9020 ) << "Dropped" << endl; + + QString path = "Something was dropped in the Destination directory file-selector"; + + emit dropped ( path ); + +} + +void FileSelectorWidget::filterReturnPressed ( const QString& nf ) +{ + // KURL u ( m_part->project()->projectDirectory() ); + setDir ( nf ); +} + +void FileSelectorWidget::slotFilterChanged( const QString & nf ) +{ + dir->setNameFilter( nf ); + dir->updateDir(); +} + +void FileSelectorWidget::cmbPathActivated( const KURL& u ) +{ + dir->setURL( u, true ); +} + +void FileSelectorWidget::cmbPathReturnPressed( const QString& u ) +{ + dir->setFocus(); + dir->setURL( KURL(u), true ); +} + + +void FileSelectorWidget::dirUrlEntered( const KURL& u ) +{ + cmbPath->removeURL( u ); + QStringList urls = cmbPath->urls(); + urls.prepend( u.url() ); + while ( urls.count() >= (uint)cmbPath->maxItems() ) + urls.remove( urls.last() ); + cmbPath->setURLs( urls ); +} + + +void FileSelectorWidget::dirFinishedLoading() +{ + // HACK - enable the nav buttons + // have to wait for diroperator... + up->setEnabled( dir->actionCollection()->action( "up" )->isEnabled() ); + back->setEnabled( dir->actionCollection()->action( "back" )->isEnabled() ); + forward->setEnabled( dir->actionCollection()->action( "forward" )->isEnabled() ); + home->setEnabled( dir->actionCollection()->action( "home" )->isEnabled() ); +} + + +void FileSelectorWidget::focusInEvent(QFocusEvent*) +{ + dir->setFocus(); +} + +void FileSelectorWidget::setDir( KURL u ) +{ + dir->setURL(u, true); +} + +void FileSelectorWidget::setDir(const QString& path) +{ + KURL u ( path ); + dir->setURL ( u, true ); +} + + +#include "fileselectorwidget.moc" + diff --git a/buildtools/autotools/fileselectorwidget.h b/buildtools/autotools/fileselectorwidget.h new file mode 100644 index 00000000..7a981194 --- /dev/null +++ b/buildtools/autotools/fileselectorwidget.h @@ -0,0 +1,96 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#ifndef _FILESELECTORWIDGET_H_ +#define _FILESELECTORWIDGET_H_ + +#include <qlayout.h> +#include <qpushbutton.h> +#include <qhbox.h> +#include <qlabel.h> +#include <qstrlist.h> +#include <qtooltip.h> + +#include <klistview.h> +#include <qvbox.h> +#include <qwidget.h> +#include <kfile.h> +#include <kurlcombobox.h> +#include <kurlcompletion.h> +#include <kcombobox.h> +#include <kprotocolinfo.h> + +#include <kfileview.h> +#include <kfileitem.h> + +#include <kdiroperator.h> + +class AutoProjectPart; +class SubprojectItem; +class KFile; + +class KDnDDirOperator : public KDirOperator +{ + Q_OBJECT + +public: + KDnDDirOperator ( const KURL& urlName = KURL(), QWidget *parent = 0, const char* name = 0 ); + +protected: + virtual KFileView* createView( QWidget* parent, KFile::FileView view ); +}; + +class FileSelectorWidget : public QWidget +{ + Q_OBJECT + +public: + FileSelectorWidget( AutoProjectPart* part, KFile::Mode, QWidget* parent = 0, const char* name = 0 ); + ~FileSelectorWidget(); + + KDnDDirOperator * dirOperator() + { + return dir; + } + +public slots: + void slotFilterChanged( const QString& ); + void setDir( KURL ); + void setDir( const QString& ); + +private slots: + void cmbPathActivated( const KURL& u ); + void cmbPathReturnPressed( const QString& u ); + void dirUrlEntered( const KURL& u ); + void dirFinishedLoading(); + void filterReturnPressed( const QString& nf ); + +protected: + void focusInEvent( QFocusEvent* ); + void dragEnterEvent ( QDragEnterEvent* ev ); + void dropEvent ( QDropEvent* ev ); + +private: + KURLComboBox *cmbPath; + KHistoryCombo * filter; + QLabel* filterIcon; + KDnDDirOperator * dir; + QPushButton *home, *up, *back, *forward; + AutoProjectPart* m_part; + +signals: + void dropped ( const QString& ); + +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/kdevautoproject.desktop b/buildtools/autotools/kdevautoproject.desktop new file mode 100644 index 00000000..bc366556 --- /dev/null +++ b/buildtools/autotools/kdevautoproject.desktop @@ -0,0 +1,97 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=Automake Project +Comment[br]=Raktres Automake +Comment[ca]=Projecte Automake +Comment[da]=Automake-projekt +Comment[de]=Automake-Projekt für KDevelop +Comment[el]=Έργο Automake +Comment[es]=Proyecto de Automake +Comment[et]=Automake'i project +Comment[eu]=Automake proiektua +Comment[fa]=پروژۀ Automake +Comment[fr]=Projet avec Automake +Comment[ga]=Comhad tionscadail Automake +Comment[gl]=Proxecto Automake +Comment[hi]=ऑटोमेक परियोजना +Comment[hu]=Automake-projekt +Comment[is]=Automake verkefni +Comment[it]=Progetto per automake +Comment[ja]=Automake プロジェクト +Comment[ms]=Projek Automake +Comment[nds]=Automake-Projekt +Comment[ne]=स्वत: निर्माण परियोजना +Comment[nl]=Automake-project +Comment[pa]=ਆਟੋਮੈਕ ਪ੍ਰੋਜੈਕਟ +Comment[pl]=Projekt: Automake +Comment[pt]=Projecto Automake +Comment[pt_BR]=Projeto Automake +Comment[ru]=Проект Automake +Comment[sk]=Automake projekt +Comment[sl]=Projekt automake +Comment[sr]=Automake пројекат +Comment[sr@Latn]=Automake projekat +Comment[sv]=Automake-projekt +Comment[ta]=ஆட்டோமேக் பிராஜக்ட் +Comment[tg]=Лоиҳаи Automake +Comment[tr]=Automake Projesi +Comment[uz]=Automake loyihasi +Comment[uz@cyrillic]=Automake лойиҳаси +Comment[zh_CN]=Automake 工程 +Comment[zh_TW]=Automake 專案 +Name=KDevAutoProject +Name[da]=KDevelop Automake-projekt +Name[de]=Automake-Projekt (KDevelop) +Name[hi]=के-डेव-ऑटो-परियोजना +Name[nds]=Automake-Projekt (KDevelop) +Name[ne]=केडीई विकास स्वत: परियोजना +Name[pl]=KDevProjektAuto +Name[pt_BR]=KDevAutoProjeto +Name[sk]=KDevAutoProjekt +Name[sv]=KDevelop autoprojekt +Name[ta]=கெடெவ்ஆட்டோ பிராஜக்ட் +Name[tg]=Лоиҳаи KDevAuto +Name[zh_TW]=KDevelop Automake 專案 +GenericName=Automake Project +GenericName[br]=Raktres Automake +GenericName[ca]=Projecte Automake +GenericName[da]=Automake-projekt +GenericName[de]=Automake-Projekt +GenericName[el]=Έργο Automake +GenericName[es]=Proyecto de Automake +GenericName[et]=Automake'i projekt +GenericName[eu]=Automake proiektua +GenericName[fa]=پروژۀ Automake +GenericName[fr]=Projet avec Automake +GenericName[ga]=Comhad tionscadail Automake +GenericName[gl]=Proxecto Automake +GenericName[hi]=ऑटोमेक परियोजना +GenericName[hu]=Automake-projekt +GenericName[it]=Progetto Automake +GenericName[ja]=Automake プロジェクト +GenericName[ms]=Projek Automake +GenericName[nds]=Automake-Projekt +GenericName[ne]=स्वत: निर्माण परियोजना +GenericName[nl]=Automake-project +GenericName[pl]=Projekt: Automake +GenericName[pt]=Projecto de Automake +GenericName[pt_BR]=Projeto Automake +GenericName[ru]=Проект Automake +GenericName[sk]=Automake projekt +GenericName[sl]=Projekt automake +GenericName[sr]=Automake пројекат +GenericName[sr@Latn]=Automake projekat +GenericName[sv]=Automake-projekt +GenericName[ta]=ஆட்டோமேக் பிராஜக்ட் +GenericName[tg]=Лоиҳаи Automake +GenericName[tr]=Automake Projesi +GenericName[uz]=Automake loyihasi +GenericName[uz@cyrillic]=Automake лойиҳаси +GenericName[zh_CN]=Automake 工程 +GenericName[zh_TW]=Automake 專案 +ServiceTypes=KDevelop/Project +Icon=make +X-KDE-Library=libkdevautoproject +X-KDevelop-Version=5 +X-KDevelop-Args= diff --git a/buildtools/autotools/kdevautoproject.rc b/buildtools/autotools/kdevautoproject.rc new file mode 100644 index 00000000..89571c11 --- /dev/null +++ b/buildtools/autotools/kdevautoproject.rc @@ -0,0 +1,30 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KDevAutoProject" version="2"> +<MenuBar> + <Menu name="project" > + <Action name="project_addtranslation" /> + <Action name="project_configuration" /> + </Menu> + <Menu name="build" > + <Action name="build_build" /> + <Action name="build_buildactivetarget" /> + <Action name="build_compilefile" /> + <Action name="build_configure" /> + <Action name="build_makefilecvs" /> + <Action name="build_install" /> + <Action name="build_install_kdesu" /> + <Separator/> + <Action name="build_clean" /> + <Action name="build_distclean" /> + <Action name="build_messages" /> + <Separator/> + <Action name="build_execute" /> + </Menu> +</MenuBar> +<ToolBar name="buildToolBar" noMerge="1"> + <Action name="build_build" group="build_operations" /> + <Action name="build_buildactivetarget" group="build_operations" /> + <Action name="build_execute" group="build_operations" /> +</ToolBar> +</kpartgui> + diff --git a/buildtools/autotools/kdevkdeautoproject.desktop b/buildtools/autotools/kdevkdeautoproject.desktop new file mode 100644 index 00000000..235f3071 --- /dev/null +++ b/buildtools/autotools/kdevkdeautoproject.desktop @@ -0,0 +1,92 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=KDE Automake Project +Comment[br]=Raktres KDE Automake +Comment[ca]=Projecte Automake per al KDE +Comment[da]=KDE Automake-projekt +Comment[de]=KDE-Automake-Projekt für KDevelop +Comment[el]=Έργο KDE Automake +Comment[es]=Proyecto de Automake de KDE +Comment[et]=KDE automake'i projekt +Comment[eu]=KDE automake proiektua +Comment[fa]=پروژۀ KDE Automake +Comment[fr]=Projet Automake pour KDE +Comment[ga]=Tionscadal Automake KDE +Comment[gl]=Proxecto Automake de KDE +Comment[hi]=केडीई ऑटोमेक परियोजना +Comment[hu]=KDE Automake-projekt +Comment[is]=KDE Automake verkefni +Comment[it]=Progetto KDE per automake +Comment[ja]=KDE Automake プロジェクト +Comment[ms]=Projek Automake KDE +Comment[nds]=Automake-Projekt vun KDE +Comment[ne]=केडीई स्वत: निर्माण परियोजना +Comment[nl]=KDE Automake-project +Comment[pt]=Projecto Automake do KDE +Comment[pt_BR]=Projeto Automake do KDE +Comment[ru]=Проект KDE Automake +Comment[sk]=KDE Automake projekt +Comment[sl]=Projekt KDE Automake +Comment[sr]=KDE-ов Automake пројекат +Comment[sr@Latn]=KDE-ov Automake projekat +Comment[sv]=KDE Automake-projekt +Comment[ta]=KDE ஆட்டோமேக் பிராஜக்ட் +Comment[tg]=Лоиҳаи KDE Automake +Comment[tr]=KDE Automake Projesi +Comment[zh_CN]=KDE Automake 工程 +Comment[zh_TW]=KDE Automake 專案 +Name=KDevKDEAutoProject +Name[da]=KDevelop KDE Automake-projekt +Name[de]=KDE-Automake-Projekt (KDevelop) +Name[hi]=के-डेव-केडीई-ऑटो-परियोजना +Name[nds]=Automake-Projekt (KDE/KDevelop) +Name[ne]=केडीई विकास केडीई स्वत: परियोजना +Name[pl]=KDevProjektKDEAuto +Name[pt_BR]=KDevKDEAutoProjeto +Name[sk]=KDevAutoProjekt +Name[sv]=KDevelop KDE-autoprojekt +Name[ta]=கெடெவ்ஆட்டோ பிராஜக்ட் +Name[tg]=Лоиҳаи худкори KDevKDEAuto +Name[zh_TW]=KDevelop KDE Automake 專案 +GenericName=KDE Automake Project +GenericName[br]=Raktres KDE Automake +GenericName[ca]=Projecte Automake per al KDE +GenericName[cs]=KDE Automake projekt +GenericName[da]=KDE Automake-projekt +GenericName[de]=KDE-Automake-Projekt +GenericName[el]=Έργο KDE Automake +GenericName[es]=Proyecto de Automake de KDE +GenericName[et]=KDE automake'i projekt +GenericName[eu]=KDE automake proiektua +GenericName[fa]=پروژۀ KDE Automake +GenericName[fr]=Projet avec Automake pour KDE +GenericName[ga]=Tionscadal Automake KDE +GenericName[gl]=Proxecto Automake de KDE +GenericName[hi]=केडीई ऑटोमेक परियोजना +GenericName[hu]=KDE Automake-projekt +GenericName[it]=Progetto KDE Automake +GenericName[ja]=KDE Automake プロジェクト +GenericName[ms]=Projek Automake KDE +GenericName[nds]=Automake-Projekt vun KDE +GenericName[ne]=केडीई स्वत: निर्माण परियोजना +GenericName[nl]=KDE Automake-project +GenericName[pl]=Projekt: KDE Automake +GenericName[pt]=Projecto KDE com Automake +GenericName[pt_BR]=Projeto Automake do KDE +GenericName[ru]=Проект KDE Automake +GenericName[sk]=KDE Automake projekt +GenericName[sl]=Projekt KDE Automake +GenericName[sr]=KDE-ов Automake пројекат +GenericName[sr@Latn]=KDE-ov Automake projekat +GenericName[sv]=KDE Automake-projekt +GenericName[ta]=KDE ஆட்டோமேக் பிராஜக்ட் +GenericName[tg]=Лоиҳаи KDE Automake +GenericName[tr]=KDE Automake Projesi +GenericName[zh_CN]=KDE Automake 工程 +GenericName[zh_TW]=KDE Automake 專案 +ServiceTypes=KDevelop/Project +Icon=make +X-KDE-Library=libkdevautoproject +X-KDevelop-Version=5 +X-KDevelop-Args=kde diff --git a/buildtools/autotools/kfilednddetailview.cpp b/buildtools/autotools/kfilednddetailview.cpp new file mode 100644 index 00000000..c75022fb --- /dev/null +++ b/buildtools/autotools/kfilednddetailview.cpp @@ -0,0 +1,212 @@ +/*************************************************************************** +* kfilednddetailview.cpp - description +* ------------------- +* begin : Wed Nov 1 2000 +* copyright : (C) 2000 by Bj�n Sahlstr� +* email : kbjorn@users.sourceforge.net +***************************************************************************/ + +/*************************************************************************** +* * +* 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 specific includes +#include <qptrlist.h> +#include <qapplication.h> +////////////////////////////////////////////////////// +// KDE specific includes +#include <kfileitem.h> +#include <kiconloader.h> +#include <kdebug.h> +////////////////////////////////////////////////////// +// Application specific includes +#include "kfilednddetailview.h" + +#ifndef AUTO_OPEN_TIME +#define AUTO_OPEN_TIME + static int autoOpenTime = 750; +#endif +//----------------------------------------------- +KFileDnDDetailView::KFileDnDDetailView(QWidget *parent, const char *name ) + : KFileDetailView(parent,name), m_autoOpenTimer( this ), + m_autoOpenTime( autoOpenTime ), m_useAutoOpenTimer( true ), + m_dropItem(0), m_dndEnabled( true ) +{ + setAutoUpdate( true ); + setDnDEnabled( true ); + useAutoOpenTimer( true ); +} +//----------------------------------------------- +KFileDnDDetailView::~KFileDnDDetailView(){ +} +//----------------------------------------------- +void KFileDnDDetailView::readConfig( KConfig* config, const QString& group ) { + KConfigGroupSaver cs( config, group ); + bool dnd = config->readBoolEntry("DragAndDrop", true ); + setDnDEnabled( dnd ); + KFileDetailView::readConfig( config, group ); +} +//----------------------------------------------- +void KFileDnDDetailView::writeConfig( KConfig* config, const QString& group ) { + KConfigGroupSaver cs( config, group ); + config->writeEntry("DragAndDrop", m_dndEnabled ); + KFileDetailView::writeConfig( config, group ); +} +//----------------------------------------------- +void KFileDnDDetailView::slotOpenFolder(){ + if( m_useAutoOpenTimer ) { + m_autoOpenTimer.stop(); + if( !m_dropItem ) + return; + } + KFileItemListIterator it( * KFileView::items() ); + for( ; it.current() ;++it ){ + if( (*it)->name() == m_dropItem->text(0) ) { + if( (*it)->isFile() ) + return; + else if( (*it)->isDir() || (*it)->isLink()) { + sig->activate( (*it) ); + return; + } + } + } +} +//----------------------------------------------- +void KFileDnDDetailView::contentsDragEnterEvent( QDragEnterEvent *e ) { + + kdDebug (9020) << "KFileDnDDetailView::contentsDragEnterEvent" << endl; + + if ( ! acceptDrag( e ) ) { + e->accept( false ); + return; + } + e->acceptAction(); + QListViewItem *i = itemAt( contentsToViewport( e->pos() ) ); + if ( i && m_useAutoOpenTimer ) { + m_dropItem = i; + m_autoOpenTimer.start( m_autoOpenTime ); + } +} +//----------------------------------------------- +void KFileDnDDetailView::contentsDragMoveEvent( QDragMoveEvent *e ) { + + kdDebug (9020) << "KFileDnDDetailView::contentsDragMoveEvent" << endl; + + if ( ! acceptDrag( e ) ) { + e->accept( false ); + return; + } + e->acceptAction(); + QListViewItem *i = itemAt( contentsToViewport( e->pos() ) ); + if( ! m_useAutoOpenTimer ) + return; + if ( i ) { + if ( i != m_dropItem ) { + m_autoOpenTimer.stop(); + m_dropItem = i; + m_autoOpenTimer.start( m_autoOpenTime ); + } + } + else + m_autoOpenTimer.stop(); +} +//----------------------------------------------- +void KFileDnDDetailView::contentsDragLeaveEvent( QDragLeaveEvent* ) { + + kdDebug (9020) << "KFileDnDDetailView::contentsDragLeaveEvent" << endl; + + if( m_useAutoOpenTimer ) { + m_autoOpenTimer.stop(); + m_dropItem = 0L; + } +} +//----------------------------------------------- +void KFileDnDDetailView::contentsDropEvent( QDropEvent* e ) { + + kdDebug (9020) << "KFileDndDetailView::contentsDropEvent" << endl; + + if( m_useAutoOpenTimer ) { + m_autoOpenTimer.stop(); + m_dropItem = 0L; + } + if( ! acceptDrag( e ) ) { + e->acceptAction( false ); + return; + } + e->acceptAction(); + // the drop was accepted so lets emit this to the outside world + KURL::List urls; + KURLDrag::decode( e, urls ); + emit dropped( e ); + emit dropped( this, e ); + emit dropped( this, urls ); +} +//----------------------------------------------- +void KFileDnDDetailView::startDrag(){ + + kdDebug (9020) << "KFileDnDDetailView::startDrag()" << endl; + + // create a list of the URL:s that we want to drag + KURL::List urls; + KFileItemListIterator it( * KFileView::selectedItems() ); + for ( ; it.current(); ++it ){ + urls.append( (*it)->url() ); + } + QPixmap pixmap; + if( urls.count() > 1 ){ + pixmap = DesktopIcon( "kmultiple", 16 ); + } + if( pixmap.isNull() ) + pixmap = currentFileItem()->pixmap( 16 ); + QPoint hotspot; + hotspot.setX( pixmap.width() / 2 ); + hotspot.setY( pixmap.height() / 2 ); + m_dragObject = KURLDrag::newDrag( urls, widget() ); + m_dragObject->setPixmap( pixmap, hotspot ); + m_dragObject->drag(); // start the drag +} +//----------------------------------------------- +QDragObject* KFileDnDDetailView::dragObject() const { + return m_dragObject; +} +//----------------------------------------------- +bool KFileDnDDetailView::acceptDrag(QDropEvent* e ) const { + return KURLDrag::canDecode( e ) && + ( e->action() == QDropEvent::Copy + || e->action() == QDropEvent::Move + || e->action() == QDropEvent::Link ); +} +//----------------------------------------------- +void KFileDnDDetailView::setAutoOpenTime( const int& time ){ + m_autoOpenTime = time; + useAutoOpenTimer(); +} +//----------------------------------------------- +void KFileDnDDetailView::useAutoOpenTimer( bool use ){ + m_useAutoOpenTimer = use; + if( use ) + connect( &m_autoOpenTimer, SIGNAL( timeout() ),this, SLOT( slotOpenFolder() ) ); + else { + disconnect( &m_autoOpenTimer, SIGNAL( timeout() ),this, SLOT( slotOpenFolder() ) ); + m_dropItem = 0L; + m_autoOpenTimer.stop(); + } +} +//----------------------------------------------- +void KFileDnDDetailView::setDnDEnabled( bool useDnD ){ + m_dndEnabled = useDnD; + setDragEnabled( useDnD ); + setDropVisualizer( useDnD ); + setAcceptDrops( useDnD ); + viewport()->setAcceptDrops( useDnD ); +} +//----------------------------------------------- +#ifndef NO_INCLUDE_MOCFILES +#include "kfilednddetailview.moc" +#endif diff --git a/buildtools/autotools/kfilednddetailview.h b/buildtools/autotools/kfilednddetailview.h new file mode 100644 index 00000000..ecb232c6 --- /dev/null +++ b/buildtools/autotools/kfilednddetailview.h @@ -0,0 +1,136 @@ +/*************************************************************************** +* kfilednddetailview.h - description +* ------------------- +* begin : Wed Nov 1 2000 +* copyright : (C) 2000 by Bjrn Sahlstrm +* email : kbjorn@users.sourceforge.net +***************************************************************************/ + +/*************************************************************************** +* * +* 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 KFILEDNDDETAILVIEW_H +#define KFILEDNDDETAILVIEW_H + +////////////////////////////////////////////////////////////////////// +// Qt specific include files +#include <qwidget.h> +#include <qtimer.h> +////////////////////////////////////////////////////////////////////// +// KDE specific include files +#include <kfiledetailview.h> +#include <kurldrag.h> + + +/** + *This is a fileview inherited from @ref KFileDetailView. + *It adds "drag and drop" handling to the view suitable for a @ref KFileDetailView. + * No special setup is needed, just connect to the @ref dropped signals + * and the view will take care of the rest. + *@short "Drag and drop" aware @ref KFileDetailView + *@author Bjrn Sahlstrm + */ + +class KFileDnDDetailView : public KFileDetailView +{ + Q_OBJECT +public: + /** */ + KFileDnDDetailView( QWidget *parent = 0, const char *name = 0 ); + /** */ + virtual ~KFileDnDDetailView(); + /** + * Set this to true if Drag'n drop should be enabled or not, default is enabled + */ + void setDnDEnabled( bool ); + /** + * @returns wether DnD is enabled or not. + */ + bool isDnDEnabled() const + { + return m_dndEnabled; + } + /** + *Sets the auto open time, which means the time that will + *elapse before a directory is automatically opened after entered by DnD. + *Only need to call this if you want to change the predefined time that is 750 ms. + *This also calls @ref #useAutoOpenTimer so no need to call this to. + */ + void setAutoOpenTime( const int& time ); + /** + *Set this to true if you want the view to use it's auto open functionallity otherwhise set it to false. + *By default this is turned ON. + */ + void useAutoOpenTimer( bool on = true ); + /** + *@returns true if auto open functionallity is turned ON (default), otherwhise false + *@see #useAutoOpenTimer + *@see #setAutoOpenTime + */ + bool isAutoOpening() const + { + return m_useAutoOpenTimer; + } + /** */ + virtual void readConfig( KConfig*, const QString& group = QString::null ); + /** */ + virtual void writeConfig( KConfig*, const QString& group = QString::null ); +signals: // Signals + /** + * Emitted whenever an decodable item is dropped in the view. + * Note: The @ref QDropEvent contains a @ref KURLDrag object. + */ + void dropped( QDropEvent* ); + /** + * Emitted whenever an decodable item is dropped in the view + * Note: The @ref QDropEvent contains a @ref KURLDrag object. + */ + void dropped( KFileView*, QDropEvent* ); + /** + * Emitted whenever an decodable item is dropped in the view. + *@param urls contains a list of all dropped @ref KURL + */ + void dropped( KFileView*, KURL::List& urls ); +protected slots: // Protected slots + /** + * Called when the auto timer times out. Open the current folder. + */ + void slotOpenFolder(); +protected: //Protected Methods + /** */ + virtual void contentsDragEnterEvent( QDragEnterEvent *e ); + /** */ + virtual void contentsDragMoveEvent( QDragMoveEvent *e ); + /** */ + virtual void contentsDragLeaveEvent( QDragLeaveEvent *e ); + /** */ + virtual void contentsDropEvent( QDropEvent* e ); + /** + * Create dragobject encoding the current selection and starts the drag + */ + virtual void startDrag(); + /** + * @returns the dragObject + */ + virtual QDragObject* dragObject() const; + /** + * @returns true if we can decode the drag and support the action + */ + virtual bool acceptDrag( QDropEvent* event ) const; +protected: // Private attributes + QTimer m_autoOpenTimer; + int m_autoOpenTime; + bool m_useAutoOpenTimer; + QListViewItem* m_dropItem; + KURLDrag* m_dragObject; + bool m_dndEnabled; +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/kfiledndiconview.cpp b/buildtools/autotools/kfiledndiconview.cpp new file mode 100644 index 00000000..47bb32a9 --- /dev/null +++ b/buildtools/autotools/kfiledndiconview.cpp @@ -0,0 +1,194 @@ +/*************************************************************************** +* kfiledndiconview.cpp - description +* ------------------- +* begin : Wed Nov 1 2000 +* copyright : (C) 2000 by Bjrn Sahlstrm +* email : kbjorn@users.sourceforge.net +***************************************************************************/ + +/*************************************************************************** +* * +* 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 specific includes +#include <qptrlist.h> +#include <qapplication.h> +////////////////////////////////////////////////////// +// KDE specific includes +#include <kfileitem.h> +#include <kiconloader.h> +#include <kdebug.h> +////////////////////////////////////////////////////// +// Application specific includes +#include "kfiledndiconview.h" + +#ifndef AUTO_OPEN_TIME +#define AUTO_OPEN_TIME + static int autoOpenTime = 750; +#endif +//----------------------------------------------- +KFileDnDIconView::KFileDnDIconView( QWidget *parent, const char *name ) + : KFileIconView(parent,name), m_autoOpenTimer( this ), + m_autoOpenTime( autoOpenTime ), m_useAutoOpenTimer( true ), + m_dropItem(0), m_dndEnabled( true ) +{ + setDnDEnabled( true ); + setAutoUpdate( true ); + useAutoOpenTimer( true ); +} +//----------------------------------------------- +KFileDnDIconView::~KFileDnDIconView(){ +} +//----------------------------------------------- +void KFileDnDIconView::readConfig( KConfig* config, const QString& group ) { + KConfigGroupSaver cs( config, group ); + bool dnd = config->readBoolEntry("EnableDND", true ); + setDnDEnabled( dnd ); + KFileIconView::readConfig( config, group ); +} +//----------------------------------------------- +void KFileDnDIconView::writeConfig( KConfig* config, const QString& group ) { + KConfigGroupSaver cs( config, group ); + config->writeEntry("EnableDND", m_dndEnabled ); + KFileIconView::writeConfig( config, group ); +} +//----------------------------------------------- +void KFileDnDIconView::slotOpenFolder(){ + if( m_useAutoOpenTimer ) { + m_autoOpenTimer.stop(); + if( !m_dropItem ) + return; + } + KFileItemListIterator it( * KFileView::items() ); + for( ; it.current() ;++it ){ + if( (*it)->name() == m_dropItem->text() ) { + if( (*it)->isFile() ) + return; + else if( (*it)->isDir() || (*it)->isLink()) { + sig->activate( (*it) ); + return; + } + } + } +} +//----------------------------------------------- +void KFileDnDIconView::contentsDragEnterEvent( QDragEnterEvent *e ) { + if ( ! acceptDrag( e ) ) { // can we decode this ? + e->accept( false ); // No + return; + } + e->acceptAction(); // Yes + QIconViewItem *i = findItem( contentsToViewport( e->pos() ) ); + if ( i && m_useAutoOpenTimer) { // are we over an item ? + m_dropItem = i; // set new m_dropItem + m_autoOpenTimer.start( m_autoOpenTime ); // restart timer + } +} +//----------------------------------------------- +void KFileDnDIconView::contentsDragMoveEvent( QDragMoveEvent *e ) { + if ( ! acceptDrag( e ) ) { // can we decode this ? + e->accept( false ); // No + return; + } + e->acceptAction(); // Yes + QIconViewItem *i = findItem( contentsToViewport( e->pos() ) ); + if( ! m_useAutoOpenTimer ) + return; + if ( i ) { // are we over an item ? + if ( i != m_dropItem ) { // if so, is it a new one ? + m_autoOpenTimer.stop(); // stop timer + m_dropItem = i; // set new m_dropItem + m_autoOpenTimer.start( m_autoOpenTime ); // restart timer + } + } + else + m_autoOpenTimer.stop(); // stop timer +} +//----------------------------------------------- +void KFileDnDIconView::contentsDragLeaveEvent( QDragLeaveEvent* ) { + if( m_useAutoOpenTimer ) { + m_autoOpenTimer.stop(); + m_dropItem = 0L; + } +} +//----------------------------------------------- +void KFileDnDIconView::contentsDropEvent( QDropEvent* e ) { + if( m_useAutoOpenTimer ) { + m_autoOpenTimer.stop(); + m_dropItem = 0L; + } + if( ! acceptDrag( e ) ) { + e->acceptAction( false ); + return; + } + e->acceptAction(); + // the drop was accepted so lets emit this + KURL::List urls; + KURLDrag::decode( e, urls ); + emit dropped( e ); +} +//----------------------------------------------- +void KFileDnDIconView::startDrag(){ + if ( ! currentItem() ) // is there any selected items ? + return; // nope + dragObject()->dragCopy(); // start the drag +} +//----------------------------------------------- +QDragObject* KFileDnDIconView::dragObject() { + // create a list of the URL:s that we want to drag + KURL::List urls; + KFileItemListIterator it( * KFileView::selectedItems() ); + for ( ; it.current(); ++it ){ + urls.append( (*it)->url() ); + } + QPixmap pixmap; + if( urls.count() > 1 ) + pixmap = DesktopIcon( "kmultiple", iconSize() ); + if( pixmap.isNull() ) + pixmap = currentFileItem()->pixmap( iconSize() ); + QPoint hotspot; + hotspot.setX( pixmap.width() / 2 ); + hotspot.setY( pixmap.height() / 2 ); + QDragObject* myDragObject = KURLDrag::newDrag( urls, widget() ); + myDragObject->setPixmap( pixmap, hotspot ); + return myDragObject; +} +//----------------------------------------------- +void KFileDnDIconView::setAutoOpenTime( const int& time ){ + m_autoOpenTime = time; + useAutoOpenTimer(); +} +//----------------------------------------------- +void KFileDnDIconView::useAutoOpenTimer( bool use ){ + m_useAutoOpenTimer = use; + if ( use ) + connect( &m_autoOpenTimer, SIGNAL( timeout() ),this, SLOT( slotOpenFolder() ) ); + else { + disconnect( &m_autoOpenTimer, SIGNAL( timeout() ),this, SLOT( slotOpenFolder() ) ); + m_dropItem = 0L; + m_autoOpenTimer.stop(); + } +} +//----------------------------------------------- +void KFileDnDIconView::setDnDEnabled( bool useDnD ){ + m_dndEnabled = useDnD; + setAcceptDrops( useDnD ); + viewport()->setAcceptDrops( useDnD ); +} +//----------------------------------------------- +bool KFileDnDIconView::acceptDrag(QDropEvent* e ) const { + return KURLDrag::canDecode( e ) && + ( e->action() == QDropEvent::Copy + || e->action() == QDropEvent::Move + || e->action() == QDropEvent::Link ); +} +//----------------------------------------------- +#ifndef NO_INCLUDE_MOCFILES +#include "kfiledndiconview.moc" +#endif diff --git a/buildtools/autotools/kfiledndiconview.h b/buildtools/autotools/kfiledndiconview.h new file mode 100644 index 00000000..65edd91a --- /dev/null +++ b/buildtools/autotools/kfiledndiconview.h @@ -0,0 +1,128 @@ +/************************************************************************** +* kfiledndiconview.h - description +* ------------------- +* begin : Wed Nov 1 2000 +* copyright : (C) 2000 by Bjrn Sahlstrm +* email : kbjorn@users.sourceforge.net +***************************************************************************/ + +/*************************************************************************** +* * +* 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 KFILEDNDICONVIEW_H +#define KFILEDNDICONVIEW_H + +#include <qwidget.h> +#include <qtimer.h> +#include <kfileiconview.h> +#include <kurldrag.h> + +/** + * This is a fileview inherited from @ref KFileIconView. + * It adds "drag and drop" suitable for a @ref KFileIconView + * No special setup is needed, just connect to the @ref dropped signals + * and the view will take care of the rest. + * @short Drag and drop" aware @ref KFileIconView + * @author Bjrn Sahlstrm +*/ + +class KFileDnDIconView : public KFileIconView +{ + Q_OBJECT +public: // Public methods + + KFileDnDIconView( QWidget *parent = 0, const char *name = 0 ); + virtual ~KFileDnDIconView(); + + /** + * Set if Drag'n drop should be enabled or not, default is enabled. + */ + void setDnDEnabled( bool ); + + /** + * @returns wether DnD is enabled or not. + */ + bool isDnDEnabled() const + { + return m_dndEnabled; + } + + /** + * Sets the auto open time, which means the time that will + * elapse before a directory is automatically opened after entered by DnD. + * Only need to call this if you want to change the predefined time that is 750 ms. + * This also calls @ref #useAutoOpenTimer so no need to call this to. + */ + void setAutoOpenTime( const int& time ); + + /** + * Set this to true if you want the view to use it's auto open functionallity otherwhise set it to false. + * By default this is turned ON. + */ + void useAutoOpenTimer( bool on = true ); + + /** + * @returns true if auto open functionallity is turned ON (default), otherwhise false + * @see #useAutoOpenTimer + * @see #setAutoOpenTime + */ + bool isAutoOpening() const + { + return m_useAutoOpenTimer; + } + + virtual void readConfig( KConfig*, const QString& group = QString::null ); + virtual void writeConfig( KConfig*, const QString& group = QString::null ); +signals: + + /** + * Emitted whenever an decodable item is dropped in the view. + * Note: The @ref QDropEvent contains a @ref KURLDrag object. + */ + void dropped( QDropEvent* ); + +protected slots: + /** + * Called when the auto timer times out. Open the current folder. + */ + void slotOpenFolder(); + +protected: + virtual void contentsDragEnterEvent( QDragEnterEvent *e ); + virtual void contentsDragMoveEvent( QDragMoveEvent *e ); + virtual void contentsDragLeaveEvent( QDragLeaveEvent *e ); + virtual void contentsDropEvent( QDropEvent* e ); + + /** + * Creates a @ref QDragObject containing all urls of the selected @ref KFileItem of the view, + * @returns the @ref QDragObject + */ + virtual QDragObject* dragObject(); + + /** + *Creates the drag item and starts the drag + */ + virtual void startDrag(); + + /** + *@returns true if we can decode the drag and support the action + */ + virtual bool acceptDrag( QDropEvent* event ) const; + +protected: + + QTimer m_autoOpenTimer; + int m_autoOpenTime; + bool m_useAutoOpenTimer; + QIconViewItem* m_dropItem; + bool m_dndEnabled; +}; +#endif +// kate: indent-mode csands; tab-width 4; auto-insert-doxygen on; + diff --git a/buildtools/autotools/kimporticonview.cpp b/buildtools/autotools/kimporticonview.cpp new file mode 100644 index 00000000..9b64d3ee --- /dev/null +++ b/buildtools/autotools/kimporticonview.cpp @@ -0,0 +1,87 @@ +/*************************************************************************** + ------------------- + begin : 19.01.2003 + copyright : (C) 2002 by Victor Rder + email : victor_roeder@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 <qfontmetrics.h> +#include <qpainter.h> +#include <qrect.h> +#include <qwidget.h> + +#include <kglobalsettings.h> +#include <klocale.h> +#include <kwordwrap.h> + +#include "kimporticonview.h" + + +KImportIconView::KImportIconView(const QString& strIntro, QWidget *parent, const char *name) + : KFileDnDIconView(parent, name) +{ + m_strIntro = strIntro; + m_bDropped = false; + + setAcceptDrops ( true ); +} + + +KImportIconView::~KImportIconView() +{ +} + +void KImportIconView::drawContents ( QPainter *p, int cx, int cy, int cw, int ch ) +{ + if ( !m_bDropped) + { + QIconView::drawContents ( p, cx, cy, cw, ch ); + + p->save(); + QFont font ( p->font() ); + font.setBold ( true ); + font.setFamily ( "Helvetica [Adobe]" ); + font.setPointSize ( 10 ); + p->setFont ( font ); + p->setPen ( QPen ( KGlobalSettings::highlightColor() ) ); + + QRect rect = frameRect(); + QFontMetrics fm ( p->font() ); + rect.setLeft ( rect.left() + 30 ); + rect.setRight ( rect.right() - 30 ); + + resizeContents ( contentsWidth(), contentsHeight() ); + + // word-wrap the string + KWordWrap* wordWrap1 = KWordWrap::formatText( fm, rect, AlignHCenter | WordBreak, m_strIntro ); + KWordWrap* wordWrap2 = KWordWrap::formatText( fm, rect, AlignHCenter | WordBreak, i18n("Or just use the buttons.") ); + + QRect introRect1 = wordWrap1->boundingRect(); + QRect introRect2 = wordWrap2->boundingRect(); + + wordWrap1->drawText ( p, ( ( frameRect().right() - introRect1.right() ) / 2 ), ( ( frameRect().bottom() - introRect1.bottom() ) / 2 ) - 20, AlignHCenter | AlignVCenter ); + wordWrap2->drawText ( p, ( ( frameRect().right() - introRect2.right() ) / 2 ), ( ( frameRect().bottom() - introRect2.bottom() ) / 2 ) + introRect1.bottom(), AlignHCenter | AlignVCenter ); + + p->restore(); + } + else + { + QIconView::drawContents ( p, cx, cy, cw, ch ); + } +} + +void KImportIconView::somethingDropped ( bool dropped ) +{ + m_bDropped = dropped; +} + +#include "kimporticonview.moc" diff --git a/buildtools/autotools/kimporticonview.h b/buildtools/autotools/kimporticonview.h new file mode 100644 index 00000000..100fc33e --- /dev/null +++ b/buildtools/autotools/kimporticonview.h @@ -0,0 +1,44 @@ +/*************************************************************************** + ------------------- + begin : 19.01.2003 + copyright : (C) 2002 by Victor Rder + email : victor_roeder@gmx.de +***************************************************************************/ + +/*************************************************************************** + * * + * 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 KIMPORTICONVIEW_H +#define KIMPORTICONVIEW_H + +#include <qwidget.h> + +#include "kfiledndiconview.h" + +class KImportIconView : public KFileDnDIconView +{ + Q_OBJECT + +public: + KImportIconView( const QString& strIntro, QWidget *parent, const char *name ); + virtual ~KImportIconView(); + + void somethingDropped ( bool dropped ); + +protected: + void drawContents ( QPainter *p, int cx, int cy, int cw, int ch ); + +private: + QString m_strIntro; + bool m_bDropped; +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/makefilehandler.cpp b/buildtools/autotools/makefilehandler.cpp new file mode 100644 index 00000000..03ad5277 --- /dev/null +++ b/buildtools/autotools/makefilehandler.cpp @@ -0,0 +1,166 @@ +/* + KDevelop Autotools Support + Copyright (c) 2005 by Matt Rogers <mattr@kde.org> + +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +*************************************************************************** +*/ + +#include <qdir.h> +#include <qglobal.h> +#include <qmap.h> +#include <qregexp.h> +#include <qstring.h> +#include <qvaluelist.h> + +#include <kdebug.h> + +#include <autotoolsast.h> +#include <autotoolsdriver.h> + +#include "makefilehandler.h" + +typedef QValueList<AutoTools::AST*> ASTList; + +class MakefileHandler::Private +{ +public: + QMap<QString, AutoTools::ProjectAST*> projects; + QMap<QString, QString> folderToFileMap; +}; + +MakefileHandler::MakefileHandler() +{ + d = new MakefileHandler::Private; +} + +MakefileHandler::~MakefileHandler() +{ + delete d; +} + +void MakefileHandler::parse( const QString& folder, bool recursive ) +{ + //look for either Makefile.am.in, Makefile.am, or Makefile.in, in that order + AutoTools::ProjectAST* ast; + int ret = -1; + QString filePath = folder + "/Makefile.am.in"; + if ( QFile::exists( filePath ) ) + ret = AutoTools::Driver::parseFile( filePath, &ast ); + else + { + filePath = folder + "/Makefile.am"; + if ( QFile::exists( filePath ) ) + ret = AutoTools::Driver::parseFile( filePath, &ast ); + else + { + filePath = folder + "/Makefile.in"; + if ( QFile::exists( filePath ) ) + ret = AutoTools::Driver::parseFile( filePath, &ast ); + else + kdDebug(9020) << k_funcinfo << "no appropriate file to parse in " + << folder << endl; + } + } + + if ( ret != 0 ) + { + return; + } + + kdDebug(9020) << k_funcinfo << filePath << " was parsed correctly. Adding information" << endl; + Q_ASSERT( ast != 0 ); + d->projects[filePath] = ast; + d->folderToFileMap[folder] = filePath; + + if ( recursive && ast && ast->hasChildren() ) + { + QValueList<AutoTools::AST*> astChildList = ast->children(); + QValueList<AutoTools::AST*>::iterator it(astChildList.begin()), clEnd(astChildList.end()); + for ( ; it != clEnd; ++it ) + { + if ( (*it)->nodeType() == AutoTools::AST::AssignmentAST ) + { + AutoTools::AssignmentAST* assignment = static_cast<AutoTools::AssignmentAST*>( (*it) ); + if ( assignment->scopedID == "SUBDIRS" ) + { + QString list = assignment->values.join( QString::null ); + list.simplifyWhiteSpace(); + kdDebug(9020) << k_funcinfo << "subdirs is " << list << endl; + QStringList subdirList = QStringList::split( " ", list ); + QStringList::iterator vit = subdirList.begin(); + for ( ; vit != subdirList.end(); ++vit ) + { + QString realDir = ( *vit ); + if ( realDir.startsWith( "\\" ) ) + realDir.remove( 0, 1 ); + + realDir = realDir.stripWhiteSpace(); + if ( realDir != "." && realDir != ".." && !realDir.isEmpty() ) + { + if ( isVariable( realDir ) ) + { + kdDebug(9020) << k_funcinfo << "'" << realDir << "' is a variable" << endl; + realDir = resolveVariable( realDir, ast ); + } + + kdDebug(9020) << k_funcinfo << "Beginning parsing of '" << realDir << "'" << endl; + parse( folder + '/' + realDir, recursive ); + } + } + } + } + } + } +} + +AutoTools::ProjectAST* MakefileHandler::astForFolder( const QString& folderPath ) +{ + if ( d->folderToFileMap.contains( folderPath ) ) + { + QString filePath = d->folderToFileMap[folderPath]; + return d->projects[filePath]; + } + else + return 0; +} + +bool MakefileHandler::isVariable( const QString& item ) const +{ + if ( item.contains( QRegExp( "(\\$\\([a-zA-Z0-9_-]*\\)|@[a-zA-Z0-9_-]*@)" ) ) ) + return true; + else + return false; +} + +QString MakefileHandler::resolveVariable( const QString& variable, AutoTools::ProjectAST* ast ) +{ + if ( !ast ) + return variable; + + kdDebug(9020) << k_funcinfo << "attempting to resolve '" << variable << "'"<< endl; + ASTList childList = ast->children(); + ASTList::iterator it( childList.begin() ), clEnd( childList.end() ); + for ( ; it != clEnd; ++it ) + { + if ( ( *it )->nodeType() == AutoTools::AST::AssignmentAST ) + { + AutoTools::AssignmentAST* assignment = static_cast<AutoTools::AssignmentAST*>( ( *it ) ); + if ( variable.find( assignment->scopedID ) != -1 ) + { + kdDebug(9020) << k_funcinfo << "Resolving variable '" << variable << "' to '" + << assignment->values.join( QString::null ).stripWhiteSpace() << "'" << endl; + return assignment->values.join( QString::null ).stripWhiteSpace(); + } + } + } + + return variable; +} +//kate: space-indent on; indent-width 4; diff --git a/buildtools/autotools/makefilehandler.h b/buildtools/autotools/makefilehandler.h new file mode 100644 index 00000000..77045fe9 --- /dev/null +++ b/buildtools/autotools/makefilehandler.h @@ -0,0 +1,76 @@ +/* + KDevelop Autotools Support + Copyright (c) 2005 by Matt Rogers <mattr@kde.org> + +*************************************************************************** +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +*************************************************************************** +*/ +#ifndef MAKEFILEHANDLER_H +#define MAKEFILEHANDLER_H + +/** + * This class is responsible for taking the data from the Makefile.am parser + * and providing various data list view items can use in the automake manager + * widget + * @author Matt Rogers + */ +namespace AutoTools { +class ProjectAST; +} + +class MakefileHandler +{ +public: + MakefileHandler(); + ~MakefileHandler(); + + /** + * Parse a folder that has supported makefiles in it. The following files + * will be looked for in the following order: + * \li Makefile.am.in + * \li Makefile.am + * \li Makefile.in + * + * \param folder, the folder to parse + * \param recursive if true, subfolders will be parsed - defaults to true + */ + void parse( const QString& folder, bool recursive = true ); + + /** + * Get the AST for a certain path + * \param folderPath the path of the folder to get an AST for + * \return the AST that represents a particular folder + */ + AutoTools::ProjectAST* astForFolder( const QString& folderPath ); + + /** + * Check if a string is an automake variable + * \return true if it is an automake variable, false otherwise + */ + bool isVariable( const QString& item ) const; + + /** + * Find the value for the variable specified by \p variable + * \param variable The name of the variable to look for + * \param ast the AST to use to look for the variable in + * \return the value to substitute for the variable + */ + QString resolveVariable( const QString& variable, + AutoTools::ProjectAST* ast ); + + +private: + class Private; + Private* d; +}; + +#endif + +//kate: space-indent on; indent-width 4; + diff --git a/buildtools/autotools/managecustomcommand.cpp b/buildtools/autotools/managecustomcommand.cpp new file mode 100644 index 00000000..7d111965 --- /dev/null +++ b/buildtools/autotools/managecustomcommand.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo <adymo@kdevelop.org> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "managecustomcommand.h" + +#include <qtable.h> + +#include <klocale.h> + +ManageCustomCommand::ManageCustomCommand(QWidget *parent, const char *name) + :ManageCustomBuildCommandsBase(parent, name) +{ +} + +void ManageCustomCommand::addButton_clicked() +{ + commandsTable->setNumRows(commandsTable->numRows() + 1); + setRowProperties(commandsTable->numRows()-1); +} + +void ManageCustomCommand::removeButton_clicked() +{ + commandsTable->removeRow(commandsTable->currentRow()); +} + +void ManageCustomCommand::setRowProperties(int row) +{ + commandsTable->setItem(row, 2, + new QComboTableItem(commandsTable, QStringList::split(",", + i18n("this is a list of items in the combobox", + "Make target,Make target (as root),Make command,Make command (as root),Command,Command (as root)")))); +} + +#include "managecustomcommand.moc" diff --git a/buildtools/autotools/managecustomcommand.h b/buildtools/autotools/managecustomcommand.h new file mode 100644 index 00000000..cda5e54a --- /dev/null +++ b/buildtools/autotools/managecustomcommand.h @@ -0,0 +1,37 @@ +/*************************************************************************** +* Copyright (C) 2004 by Alexander Dymo <adymo@kdevelop.org> * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU Library General Public License as * +* published by the Free Software Foundation; either version 2 of the * +* License, or (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public * +* License along with this program; if not, write to the * +* Free Software Foundation, Inc., * +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +***************************************************************************/ +#ifndef MANAGECUSTOMCOMMAND_H +#define MANAGECUSTOMCOMMAND_H + +#include "managecustomcommandsbase.h" + +class ManageCustomCommand: public ManageCustomBuildCommandsBase +{ + Q_OBJECT +public: + ManageCustomCommand( QWidget *parent = 0, const char *name = 0 ); + + void setRowProperties( int row ); +public slots: + virtual void addButton_clicked(); + virtual void removeButton_clicked(); +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/managecustomcommandsbase.ui b/buildtools/autotools/managecustomcommandsbase.ui new file mode 100644 index 00000000..43164ef5 --- /dev/null +++ b/buildtools/autotools/managecustomcommandsbase.ui @@ -0,0 +1,125 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>ManageCustomBuildCommandsBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ManageCustomBuildCommandsBase</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>435</width> + <height>218</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>addButton</cstring> + </property> + <property name="text"> + <string>&Add</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>removeButton</cstring> + </property> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + <widget class="QTable" row="0" column="0" rowspan="3" colspan="1"> + <column> + <property name="text"> + <string>Menu Text</string> + </property> + <property name="pixmap"> + <pixmap></pixmap> + </property> + </column> + <column> + <property name="text"> + <string>Command</string> + </property> + <property name="pixmap"> + <pixmap></pixmap> + </property> + </column> + <column> + <property name="text"> + <string>Command Type</string> + </property> + <property name="pixmap"> + <pixmap></pixmap> + </property> + </column> + <property name="name"> + <cstring>commandsTable</cstring> + </property> + <property name="numRows"> + <number>0</number> + </property> + <property name="numCols"> + <number>3</number> + </property> + <property name="rowMovingEnabled"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>SingleRow</enum> + </property> + </widget> + <spacer row="2" column="1"> + <property name="name"> + <cstring>spacer4</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>addButton</sender> + <signal>clicked()</signal> + <receiver>ManageCustomBuildCommandsBase</receiver> + <slot>addButton_clicked()</slot> + </connection> + <connection> + <sender>removeButton</sender> + <signal>clicked()</signal> + <receiver>ManageCustomBuildCommandsBase</receiver> + <slot>removeButton_clicked()</slot> + </connection> +</connections> +<tabstops> + <tabstop>commandsTable</tabstop> + <tabstop>addButton</tabstop> + <tabstop>removeButton</tabstop> +</tabstops> +<slots> + <slot>addButton_clicked()</slot> + <slot>removeButton_clicked()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/buildtools/autotools/misc.cpp b/buildtools/autotools/misc.cpp new file mode 100644 index 00000000..97c449e7 --- /dev/null +++ b/buildtools/autotools/misc.cpp @@ -0,0 +1,999 @@ +/*************************************************************************** +* Copyright (C) 2001-2002 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#include <qdir.h> +#include <qfile.h> +#include <qregexp.h> +#include <qtextstream.h> +#include <qdict.h> + +#include <kdebug.h> +#include <kparts/componentfactory.h> +#include <kservice.h> + +#include "misc.h" + +#include "kdevcompileroptions.h" + + +static KDevCompilerOptions *createCompilerOptions( const QString &name, QObject *parent ) +{ + KService::Ptr service = KService::serviceByDesktopName( name ); + if ( !service ) + { + kdDebug( 9020 ) << "Can't find service " << name << endl; + return 0; + } + + + KLibFactory *factory = KLibLoader::self()->factory(QFile::encodeName(service->library())); + if (!factory) { + QString errorMessage = KLibLoader::self()->lastErrorMessage(); + kdDebug(9020) << "There was an error loading the module " << service->name() << endl << + "The diagnostics is:" << endl << errorMessage << endl; + exit(1); + } + + QStringList args; + QVariant prop = service->property("X-KDevelop-Args"); + if (prop.isValid()) + args = QStringList::split(" ", prop.toString()); + + QObject *obj = factory->create(parent, service->name().latin1(), + "KDevCompilerOptions", args); + + if (!obj->inherits("KDevCompilerOptions")) { + kdDebug(9020) << "Component does not inherit KDevCompilerOptions" << endl; + return 0; + } + KDevCompilerOptions *dlg = (KDevCompilerOptions*) obj; + + return dlg; + +/* + QStringList args; + QVariant prop = service->property( "X-KDevelop-Args" ); + if ( prop.isValid() ) + args = QStringList::split( " ", prop.toString() ); + + return KParts::ComponentFactory + ::createInstanceFromService<KDevCompilerOptions>( service, parent, + service->name().latin1(), args );*/ +} + + +QString AutoProjectTool::execFlagsDialog( const QString &compiler, const QString &flags, QWidget *parent ) +{ + KDevCompilerOptions * plugin = createCompilerOptions( compiler, parent ); + + if ( plugin ) + { + QString newflags = plugin->exec( parent, flags ); + delete plugin; + return newflags; + } + return QString::null; +} + + +QString AutoProjectTool::canonicalize( const QString &str ) +{ + QString res; + for ( uint i = 0; i < str.length(); ++i ) + res += ( str[ i ].isLetterOrNumber() || str[ i ] == '@' ) ? str[ i ] : QChar( '_' ); + + kdDebug(9020) << k_funcinfo << "normalized '" << str << "' to '" << res << "'" << endl; + return res; +} + + +/** + * Read the Makefile.am and return a map of all the variables. + * Will take notice of backslash and += constructs. + * @param fileName + * @param variables + */ +void AutoProjectTool::parseMakefileam(const QString &fileName, QMap<QString, QString> *variables) +{ + QFile f(fileName); + if (!f.open(IO_ReadOnly)) + { + return ; + } + QTextStream stream(&f); + + QRegExp re("^(#kdevelop:[ \t]*)?([A-Za-z][@A-Za-z0-9_]*)[ \t]*([:\\+]?=)[ \t]*(.*)$"); + + QString last; + bool multiLine = false; + while (!stream.atEnd()) + { + QString s = stream.readLine().stripWhiteSpace(); + if (re.exactMatch(s)) + { + QString lhs = re.cap(2); + QString rhs = re.cap(4); + if (rhs[ rhs.length() - 1 ] == '\\') + { + multiLine = true; + last = lhs; + rhs[rhs.length() - 1] = ' '; + } + + // The need for stripWhiteSpace seems to be a Qt bug. + // make our list nice and neat. + QStringList bits = QStringList::split(" ", rhs); + rhs = bits.join(" "); + if (re.cap(3) == "+=") + { + ((*variables)[lhs] += ' ') += rhs; + } + else + { + variables->insert(lhs, rhs); + } + } + else if (multiLine) + { + if (s[s.length()-1] == '\\') + { + s[s.length()-1] = ' '; + } + else + { + multiLine = false; + } + QStringList bits = QStringList::split(" ", s); + ((*variables)[last] += ' ') += bits.join(" "); + } + } + f.close(); + + QMap<QString, QString> list; + + for (QMap<QString, QString>::iterator iter = variables->begin();iter != variables->end();iter++) + { + QStringList items = QStringList::split(" ", iter.data()); + QMap<QString, QString> unique; + for (uint i = 0;i < items.size();i++) + { + unique.insert(items[i], ""); + } + QString line; + for (QMap<QString, QString>::iterator it = unique.begin();it != unique.end();it++) + { + line += it.key() + ' '; + } + if (line.length() > 1) + { + line.setLength(line.length() - 1); + } + + list.insert(iter.key(), line); + } + *variables = list; +} + +/** + * Add entries to a variable. Will just add the variables to the existing line, removing duplicates + * Will preserve += constructs and make sure that the variable only has one copy of the value across + * all += constructs + * @param fileName + * @param variables key=value string of entries to add + */ +void AutoProjectTool::addToMakefileam(const QString &fileName, QMap<QString, QString> variables) +{ + AutoProjectTool::addRemoveMakefileam(fileName, variables, true); +} + +/** + * Set entries to a variable. Will set the variables to the existing line, removing duplicates + * Will preserve += constructs and make sure that the variable only has one copy of the value across + * all += constructs + * Adds line if it does not exist. + * @param fileName + * @param variables key=value string of entries to add + */ +void AutoProjectTool::setMakefileam ( const QString &fileName, QMap<QString, QString> variables ) +{ + for ( QMap<QString, QString>::Iterator it0 = variables.begin(); it0 != variables.end(); ++it0 ) + { + kdDebug ( 9020 ) << "key (set): " << it0.key() << "=" << it0.data() << endl; + } + + // input file reading + QFile fin ( fileName ); + if ( !fin.open ( IO_ReadOnly ) ) + { + return ; + } + QTextStream ins ( &fin ); + + // output file writing. + QFile fout ( fileName + "#" ); + if ( !fout.open ( IO_WriteOnly ) ) + { + fin.close(); + return ; + } + QTextStream outs ( &fout ); + + // variables + QRegExp re ( "^(#kdevelop:[ \t]*)?([A-Za-z][@A-Za-z0-9_]*)[ \t]*([:\\+]?=)[ \t]*(.*)$" ); + + bool multiLine = false; + QString lastLhs; + QMap<QString, QString> seenLhs; + while ( !fin.atEnd() ) + { + QString s = ins.readLine(); + if ( re.exactMatch ( s ) ) + { + QString lhs = re.cap ( 2 ); + bool notFound = ( variables.find ( lhs ) == variables.end() ); + + if ( notFound ) + { + if ( seenLhs.find ( lhs ) == seenLhs.end() ) + { + // not interested in this line at all + // write it out as is.. + outs << s << endl; + } + // we have seen this variable, but since we are setting the + // whole line - we skip this as it will be a += line. + } + else + { + // we are interested in this line.. + QString rhs = re.cap ( 4 ).stripWhiteSpace(); + if ( rhs[ rhs.length() - 1 ] == '\\' ) + { + // save it for when we have the whole line.. + multiLine = true; + lastLhs = lhs; + } + else + { + // deal with it now - a single line + // we are adding our interested values to this line and writing it + // now write the line out if it is not going to be empty. + QString newLine ( lhs ); + newLine += " = "; + bool added = false; + int len = newLine.length(); + QStringList variableList = QStringList::split ( ' ', variables[lhs] ); + for ( uint count = 0; count < variableList.size(); count++ ) + { + len += variableList[count].length() + 1; + if ( len > 80 ) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += variableList[count]; + newLine += ' '; + added = true; + + } + // only print it out if there was a value to add.. + if ( added ) + { + newLine.setLength ( newLine.length() - 1 ); + outs << newLine << endl; + } + seenLhs[lhs] = "done"; + variables.erase ( lhs ); + } + } + } + else if ( multiLine ) + { + s = s.stripWhiteSpace(); + // we are only here if were interested in this line.. + if ( s[s.length()-1] == '\\' ) + { + s.setLength ( s.length() - 1 ); + // still more multi line we wait for.. + } + else + { + // end of the multi line.. + multiLine = false; + } + + if ( !multiLine ) + { + // we are adding our interested values to this line and writing it + // now write the line out if it is not going to be empty. + QString newLine ( lastLhs ); + newLine += " = "; + bool added = false; + int len = newLine.length(); + QStringList variableList = QStringList::split ( ' ', variables[lastLhs] ); + for ( uint count = 0; count < variableList.size(); count++ ) + { + len += variableList[count].length() + 1; + if ( len > 80 ) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += variableList[count]; + newLine += ' '; + added = true; + } + // only print it out if there was a value to add.. + if ( added ) + { + newLine.setLength ( newLine.length() - 1 ); + outs << newLine << endl; + } + seenLhs[lastLhs] = "done"; + variables.erase ( lastLhs ); + lastLhs.setLength ( 0 ); + } + } + else + { + // can write this line out.. + // not a match, not a multi line, + outs << s << endl; + } + } + + for ( QMap<QString, QString>::Iterator it0 = variables.begin(); it0 != variables.end(); ++it0 ) + { + QString newLine ( it0.key() ); + newLine += " = "; + bool added = false; + int len = newLine.length(); + QStringList variableList = QStringList::split ( ' ', it0.data() ); + for ( uint count = 0; count < variableList.size(); count++ ) + { + len += variableList[count].length() + 1; + if ( len > 80 ) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += variableList[count]; + newLine += ' '; + added = true; + + } + // only print it out if there was a value to add.. + if ( added ) + { + newLine.setLength ( newLine.length() - 1 ); + outs << newLine << endl; + } + } + + fin.close(); + fout.close(); + + QDir().rename ( fileName + "#", fileName ); +} + + +/** + * Add entries to a variable. Will just add the variables to the existing line, removing duplicates + * Will preserve += constructs and make sure that the variable only has one copy of the value across + * all += constructs + * @param fileName + * @param variables key=value string of entries to add + * @param add true= add these key,value pairs, false = remove. You can have empty values for an add - the whole line is + * removed. For adding, we will not add an empty line. + */ +void AutoProjectTool::addRemoveMakefileam(const QString &fileName, QMap<QString, QString> variables, bool add) +{ + // input file reading + QFile fin(fileName); + if (!fin.open(IO_ReadOnly)) + { + return ; + } + QTextStream ins(&fin); + + // output file writing. + QFile fout(fileName + "#"); + if (!fout.open(IO_WriteOnly)) + { + fin.close(); + return ; + } + QTextStream outs(&fout); + + // variables + QRegExp re("^(#kdevelop:[ \t]*)?([A-Za-z][@A-Za-z0-9_]*)[ \t]*([:\\+]?=)[ \t]*(.*)$"); + + // build key=map of values to add + // map can be empty.we never add an empty key, but do remove empty keys from the file.. + QDict< QMap<QString, bool> > interest; + for (QMap<QString, QString>::Iterator it0 = variables.begin(); it0 != variables.end(); ++it0) + { + kdDebug(9020) << "key (" << add<<"): " << it0.key() << "="<< it0.data() << endl; + + QMap<QString, bool>* set = new QMap<QString, bool>(); + if (!it0.data().stripWhiteSpace().isEmpty()) + { + QStringList variableList = QStringList::split(' ', it0.data()); + + for (uint i = 0; i < variableList.count(); i++) + { + set->insert(variableList[i], true); + } + } + interest.insert(it0.key(), set); + } + + bool multiLine = false; + QString lastLhs; + QStringList lastRhs; + QMap<QString, QString> seenLhs; + while (!fin.atEnd()) + { + QString s = ins.readLine(); + if (re.exactMatch(s)) + { + QString lhs = re.cap(2); + QMap<QString, bool>* ourRhs = interest.find(lhs); + + if (!ourRhs) + { + // not interested in this line at all + // write it out as is.. + outs << s << endl; + } + else + { + // we are interested in this line.. + QString rhs = re.cap(4).stripWhiteSpace(); + if (rhs[ rhs.length() - 1 ] == '\\') + { + // save it for when we have the whole line.. + multiLine = true; + lastLhs = lhs; + rhs.setLength(rhs.length() - 1); + lastRhs += QStringList::split(" ", rhs); + } + else + { + // deal with it now. + + QStringList bits = QStringList::split(" ", rhs); + if (add) + { + // we are adding our interested values to this line and writing it + + // add this line to we we want to add to remove duplicates. + for (uint index = 0; index < bits.size(); index++) + { + QMap<QString, bool>::iterator findEntry = ourRhs->find(bits[index]); + if (findEntry == ourRhs->end()) + { + // we haven't seen it, so add it, so we don't add it again later.. + ourRhs->insert(bits[index], true); + } + // else we have this value in our 'to add list' , it is either already been + // added, so we don't want to add it again, or it hasn't been added, in which + // case we will do so soon. so we can ignore this now.. + } + // now write the line out if it is not going to be empty. + QString newLine(lhs); + if (seenLhs.find(lhs) == seenLhs.end()) + { + newLine += " = "; + seenLhs[lhs] = ""; + } + else + { + newLine += " += "; + } + + int len = newLine.length(); + bool added = false; + QValueList<QString> keys = ourRhs->keys(); + for (uint count = 0; count < keys.size(); count++) + { + // if out entry is true, add it.. + if ((*ourRhs)[keys[count]]) + { + added = true; + len += keys[count].length() + 1; + if (len > 80) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += keys[count]; + newLine += ' '; + // set our value so we don't add it again. + (*ourRhs)[keys[count]] = false; + } + } + // only print it out if there was a value to add.. + if (added) + { + newLine.setLength(newLine.length() - 1); + outs << newLine << endl; + } + } + else + { + // we are removing our interested values from this line + + // special case - no values, remove the line.. + if (!ourRhs->empty()) + { + // check if any of these values are down to remove. + QString newLine(lhs); + if (seenLhs.find(lhs) == seenLhs.end()) + { + newLine += " = "; + seenLhs[lhs] = ""; + } + else + { + newLine += " += "; + } + + int len = newLine.length(); + bool added = false; + for (QStringList::Iterator posIter = bits.begin(); posIter != bits.end();posIter++) + { + QMap<QString, bool>::iterator findEntry = ourRhs->find(*posIter); + if (findEntry == ourRhs->end()) + { + // we do not want to remove it.. + added = true; + len += (*posIter).length() + 1; + if (len > 80) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += (*posIter); + newLine += ' '; + } + // else we have this value in our 'to remove list', so don't add it. + } + // only print it out if there was a value on it.. + if (added) + { + newLine.setLength(newLine.length() - 1); + outs << newLine << endl; + } + } + }//if (add) + }//if ( rhs[ rhs.length() - 1 ] == '\\' ) + }//if ( found == interest.end()) + } + else if (multiLine) + { + s = s.stripWhiteSpace(); + // we are only here if were interested in this line.. + if (s[s.length()-1] == '\\') + { + s.setLength(s.length() - 1); + // still more multi line we wait for.. + } + else + { + // end of the multi line.. + multiLine = false; + } + lastRhs += QStringList::split(" ", s); + + if (!multiLine) + { + // now we have to deal with this multiLine value.. + // ourRhs will always be a value, as we only get multiLine if we're interested in it.. + QMap<QString, bool>* ourRhs = interest.find(lastLhs); + + if (add) + { + // we are adding our interested values to this line and writing it + + // add this line to we we want to add to remove duplicates. + for (uint index = 0; index < lastRhs.size(); index++) + { + QMap<QString, bool>::iterator findEntry = ourRhs->find(lastRhs[index]); + if (findEntry == ourRhs->end()) + { + // we haven't seen it, so add it, so we don't add it again later.. + ourRhs->insert(lastRhs[index], true); + } + // else we have this value in our 'to add list' , it is either already been + // added, so we don't want to add it again, or it hasn't been added, in which + // case we will do so soon. so we can ignore this now.. + } + // now write the line out if it is not going to be empty. + QString newLine(lastLhs); + if (seenLhs.find(lastLhs) == seenLhs.end()) + { + newLine += " = "; + seenLhs[lastLhs] = ""; + } + else + { + newLine += " += "; + } + + int len = newLine.length(); + bool added = false; + QValueList<QString> keys = ourRhs->keys(); + for (uint count = 0; count < keys.size(); count++) + { + // if out entry is true, add it.. + if ((*ourRhs)[keys[count]]) + { + added = true; + len += keys[count].length() + 1; + if (len > 80) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += keys[count]; + newLine += ' '; + // set our value so we don't add it again. + (*ourRhs)[keys[count]] = false; + } + } + // only print it out if there was a value to add.. + if (added) + { + newLine.setLength(newLine.length() - 1); + outs << newLine << endl; + } + } + else + { + // we are removing our interested values from this line + // special case - no values, remove the line.. + if (!ourRhs->empty()) + { + // check if any of these values are down to remove. + QString newLine(lastLhs); + if (seenLhs.find(lastLhs) == seenLhs.end()) + { + newLine += " = "; + seenLhs[lastLhs] = ""; + } + else + { + newLine += " += "; + } + int len = newLine.length(); + bool added = false; + for (QStringList::Iterator posIter = lastRhs.begin(); posIter != lastRhs.end();posIter++) + { + QMap<QString, bool>::iterator findEntry = ourRhs->find(*posIter); + if (findEntry == ourRhs->end()) + { + // we do not want to remove it.. + added = true; + len += (*posIter).length() + 1; + if (len > 80) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += (*posIter); + newLine += ' '; + } + // else we have this value in our 'to remove list', so don't add it. + } + // only print it out if there was a value on it.. + if (added) + { + newLine.setLength(newLine.length() - 1); + outs << newLine << endl; + } + } + } + + lastLhs.setLength(0); + lastRhs.clear(); + } + } + else + { + // can write this line out.. + // not a match, not a multi line, + outs << s << endl; + } + } + + if (add) + { + QDictIterator<QMap<QString, bool> > it(interest); + for (; it.current(); ++it) + { + QString lhs = it.currentKey(); + QMap<QString, bool>* ourRhs = it.current(); + + QString newLine(lhs); + if (seenLhs.find(lhs) == seenLhs.end()) + { + newLine += " = "; + seenLhs[lastLhs] = ""; + } + else + { + newLine += " += "; + } + int len = newLine.length(); + bool added = false; + QValueList<QString> keys = ourRhs->keys(); + for (uint count = 0; count < keys.size(); count++) + { + if ((*ourRhs)[keys[count]]) + { + added = true; + len += keys[count].length() + 1; + if (len > 80) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += keys[count]; + newLine += ' '; + // set our value so we don't add it again. + (*ourRhs)[keys[count]] = false; + } + } + // only print it out if there was a value to add.. + if (added) + { + newLine.setLength(newLine.length() - 1); + outs << newLine << endl; + } + } + } + interest.setAutoDelete(true); + interest.clear(); + + fin.close(); + fout.close(); + + QDir().rename(fileName + "#", fileName); +} + +/** + * Any items in the map will be removed from the Makefile.am + * Empty lines are removed. eg. foo_LDDADD if empty is removed. + * @param fileName full path to Makefile.am + * @param variables lines to remove items from. + */ +void AutoProjectTool::removeFromMakefileam(const QString &fileName, QMap <QString, QString> variables) +{ + AutoProjectTool::addRemoveMakefileam(fileName, variables, false); +} + + +/** + * Open the file and parse out the AC_OUTPUT line. following backslash continue lines.. + * @param configureinpath + * @return list of all the values + */ +QStringList AutoProjectTool::configureinLoadMakefiles(QString configureinpath) +{ + QFile configurein(configureinpath); + + if (!configurein.open(IO_ReadOnly)) + { + kdDebug(9020) << k_funcinfo << " - couldn't open file: " << configureinpath << endl; + return QStringList(); + } + + QTextStream stream(&configurein); + QStringList list; + + QString ac_match("^AC_OUTPUT"); + + QRegExp ac_regex(ac_match); + bool multiLine = false; + QChar cont('\\'); + QRegExp close("\\)"); + QRegExp open("\\("); + while (!stream.eof()) + { + QString line = stream.readLine().stripWhiteSpace(); + if (multiLine) + { + if (close.search(line) >= 0) + { + line = line.replace(close.search(line), 1, ""); + list += QStringList::split(" ", line); + break; + } + else + { + if (line.endsWith(cont)) + { + line.setLength(line.length() - 1); + } + list += QStringList::split(" ", line); + } + } + else if (ac_regex.search(line) >= 0) + { + line = line.replace(ac_regex.search(line), ac_match.length() - 1, ""); + + if (open.search(line) >= 0) + { + line = line.replace(open.search(line), 1, ""); + } + + if (line.endsWith(cont)) + { + line.setLength(line.length() - 1); + multiLine = true; + } + else + { + if (close.search(line) >= 0) + { + line = line.replace(close.search(line), 1, ""); + } + } + + list = QStringList::split(" ", line); + + if (!multiLine) + { + break; + } + } + } + + configurein.close(); + + // make a new object on the heap + return list; + +} + +/** + * Write the items to the AC_OUTPUT line. This replaces the exiting line. + * @param configureinpath + * @param makefiles + */ +void AutoProjectTool::configureinSaveMakefiles(QString fileName, QStringList makefiles) +{ + // input file reading + QFile fin(fileName); + if (!fin.open(IO_ReadOnly)) + { + return ; + } + QTextStream ins(&fin); + + // output file writing. + QFile fout(fileName + "#"); + if (!fout.open(IO_WriteOnly)) + { + fin.close(); + return ; + } + QTextStream outs(&fout); + + // remove duplicates if any.. + QMap<QString, QString> toAdd; + for (uint i = 0; i < makefiles.size();i++) + { + toAdd.insert(makefiles[i].stripWhiteSpace(), ""); + } + + QString ac_match("^AC_OUTPUT"); + QRegExp ac_regex(ac_match); + bool multiLine = false; + QChar cont('\\'); + QRegExp close("\\)"); + QRegExp open("\\("); + bool done = false; + while (!fin.atEnd()) + { + QString line = ins.readLine(); + if (done) + { + outs << line << endl; + } + else + { + if (multiLine) + { + line = line.stripWhiteSpace(); + if (close.search(line) >= 0) + { + int len = 10; + QString acline("AC_OUTPUT("); + for (QMap<QString, QString>::iterator iter = toAdd.begin();iter != toAdd.end();iter++) + { + len += iter.key().length(); + if (len > 80) + { + acline += "\\\n\t"; + len = 8; + } + acline += iter.key(); + acline += ' '; + } + acline.setLength(acline.length() - 1); + acline = acline.append(")"); + outs << acline << endl; + done = true; + } + else + { + if (line.endsWith(cont)) + { + line.setLength(line.length() - 1); + } + } + } + else if (ac_regex.search(line) >= 0) + { + line = line.stripWhiteSpace(); + line = line.replace(ac_regex.search(line), ac_match.length() - 1, ""); + if (line.endsWith(cont)) + { + line.setLength(line.length() - 1); + multiLine = true; + } + if (open.search(line) >= 0) + { + line = line.replace(open.search(line), 1, ""); + } + if (close.search(line) >= 0) + { + line = line.replace(close.search(line), 1, ""); + } + + if (!multiLine) + { + int len = 10; + QString acline("AC_OUTPUT("); + for (QMap<QString, QString>::iterator iter = toAdd.begin();iter != toAdd.end();iter++) + { + len += iter.key().length(); + if (len > 80) + { + acline += "\\\n\t"; + len = 8; + } + acline += iter.key(); + acline += ' '; + } + acline.setLength(acline.length() - 1); + acline = acline.append(")"); + outs << acline << endl; + done = true; + } + } + else + { + outs << line << endl; + } + } + } + + fin.close(); + fout.close(); + + QDir().rename(fileName + "#", fileName); + +} + +//kate: indent-mode csands; space-indent off; tab-width 4; diff --git a/buildtools/autotools/misc.h b/buildtools/autotools/misc.h new file mode 100644 index 00000000..9db9919e --- /dev/null +++ b/buildtools/autotools/misc.h @@ -0,0 +1,65 @@ +/*************************************************************************** +* Copyright (C) 2001-2002 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#ifndef _MISC_H_ +#define _MISC_H_ + +#include <qcstring.h> +#include <qmap.h> +#include <qwidget.h> + +/** + * Very small helper class. It has just static methods. + */ +class AutoProjectTool +{ +public: + + /** + * Loads the compiler options plugin for the given compiler, executes the dialog + * with some initial flags, and returns the new flags. + */ + static QString execFlagsDialog( const QString &compiler, const QString &flags, QWidget *parent ); + + /** + * Returns the canonicalized version of a file name, i.e. + * the file name with special characters replaced by underscores + */ + static QString canonicalize( const QString &str ); + + /** + * Parses a Makefile.am and stores its variable assignments + * in a map. + */ + static void parseMakefileam( const QString &filename, QMap<QString, QString> *variables ); + + static void addToMakefileam( const QString &filename, QMap<QString, QString> variables ); + static void removeFromMakefileam( const QString &filename, QMap<QString, QString> variables ); + static void setMakefileam ( const QString &fileName, QMap<QString, QString> variables ); + + static void addRemoveMakefileam(const QString &fileName, QMap<QString, QString> variables, bool add); + + /** + * Parses configure.in and splits AC_OUTPUT into a QStringList + */ + static QStringList configureinLoadMakefiles( QString configureinpath ); + + /** + * Receives a QStringList and puts it into + * configure.in as arguments to AC_OUTPUT + */ + static void configureinSaveMakefiles( QString configureinpath, QStringList makefiles ); + +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/removefiledlg.cpp b/buildtools/autotools/removefiledlg.cpp new file mode 100644 index 00000000..2c3bc37f --- /dev/null +++ b/buildtools/autotools/removefiledlg.cpp @@ -0,0 +1,182 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "removefiledlg.h" + +#include <qcheckbox.h> +#include <qgroupbox.h> +#include <qfile.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qregexp.h> + +#include <kbuttonbox.h> +#include <kdebug.h> +#include <kdialog.h> +#include <ksqueezedtextlabel.h> + +#include "autolistviewitems.h" + +#include "misc.h" +#include "autoprojectpart.h" +#include "autoprojectwidget.h" +#include "autodetailsview.h" + +static bool fileListContains(const QPtrList<FileItem> &list, const QString &name) +{ + QPtrListIterator<FileItem> it(list); + for (; it.current(); ++it) + if ((*it)->text(0) == name) + return true; + return false; +} + + +RemoveFileDialog::RemoveFileDialog(AutoProjectWidget *widget, AutoProjectPart* part, SubprojectItem *spitem, + TargetItem *item, const QString &filename, + QWidget *parent, const char *name) + : RemoveFileDlgBase(parent, name, true) +{ + removeFromTargetsCheckBox = 0; + + QStringList targets; + + QPtrListIterator<TargetItem> it(spitem->targets); + for (; it.current(); ++it) + if (fileListContains((*it)->sources, filename)) + targets.append((*it)->name); + + if (targets.count() > 1) + { + removeFromTargetsCheckBox = new QCheckBox( fileGroupBox, "removeFromTargetsCheckBox" ); + removeFromTargetsCheckBox->setMinimumSize( QSize( 0, 45 ) ); + fileLayout->addWidget( removeFromTargetsCheckBox ); + + QString joinedtargets = " *" + targets.join("\n *"); + removeFromTargetsCheckBox->setText ( i18n ( "The file %1 is still used by the following targets:\n%2\n" + "Remove it from all of them?").arg(filename).arg(joinedtargets) ); + setMinimumSize(QSize(size().width(), size().height() + removeFromTargetsCheckBox->size().height()*2) ); + } + + removeLabel->setText ( i18n ( "Do you really want to remove <b>%1</b>?" ).arg ( filename ) ); + + directoryLabel->setText ( spitem->path ); + if ( item->name.isEmpty() ) + targetLabel->setText ( i18n ( "%1 in %2" ).arg ( item->primary ).arg ( item->prefix ) ); + else + targetLabel->setText ( item->name ); + + connect ( removeButton, SIGNAL ( clicked() ), this, SLOT ( accept() ) ); + connect ( cancelButton, SIGNAL ( clicked() ), this, SLOT ( reject() ) ); + + setIcon ( SmallIcon ( "editdelete.png" ) ); + + m_widget = widget; + m_part = part; + subProject = spitem; + target = item; + fileName = filename; +} + + +RemoveFileDialog::~RemoveFileDialog() +{} + + +void RemoveFileDialog::accept() +{ + m_widget->emitRemovedFile ( subProject->path.mid ( m_part->projectDirectory().length() + 1 ) + "/" + fileName ); + + QMap<QString,QString> replaceMap; + + if (removeFromTargetsCheckBox && removeFromTargetsCheckBox->isChecked()) { + QPtrListIterator<TargetItem> it(subProject->targets); + for (; it.current(); ++it) { + if ((*it) != target && fileListContains((*it)->sources, fileName)) { + FileItem *fitem = static_cast<FileItem*>((*it)->firstChild()); + while (fitem) { + FileItem *nextitem = static_cast<FileItem*>(fitem->nextSibling()); + if (fitem->text(0) == fileName) { + QListView *lv = fitem->listView(); + lv->setSelected(fitem, false); + (*it)->sources.remove(fitem); + } + fitem = nextitem; + } + QString canontargetname = AutoProjectTool::canonicalize((*it)->name); + QString varname; + if( (*it)->primary == "PROGRAMS" || (*it)->primary == "LIBRARIES" || (*it)->primary == "LTLIBRARIES" ) + varname = canontargetname + "_SOURCES"; + else + varname = (*it)->prefix + "_" + (*it)->primary; + QStringList sources = QStringList::split(QRegExp("[ \t\n]"), subProject->variables[varname]); + sources.remove(fileName); + subProject->variables[varname] = sources.join(" "); + replaceMap.insert(varname, fileName); + } + } + } + + QString fileItemName; + FileItem *fitem = static_cast<FileItem*>(target->firstChild()); + while (fitem) { + if (fitem->text(0) == fileName) { + QListView *lv = fitem->listView(); + lv->setSelected(fitem, false); + fileItemName = fitem->name; + target->sources.remove(fitem); + break; + } + fitem = static_cast<FileItem*>(fitem->nextSibling()); + } + QString canontargetname = AutoProjectTool::canonicalize(target->name); + QString varname; + if( target->primary == "PROGRAMS" || target->primary == "LIBRARIES" || target->primary == "LTLIBRARIES" ) + varname = canontargetname + "_SOURCES"; + else + varname = target->prefix + "_" + target->primary; + QStringList sources = QStringList::split(QRegExp("[ \t\n]"), subProject->variables[varname]); + sources.remove(fileName); + subProject->variables[varname] = sources.join(" "); + replaceMap.insert(varname, fileName); + + AutoProjectTool::removeFromMakefileam(subProject->path + "/Makefile.am", replaceMap); + +// review configuration cleanup in the project file after removing subclassing related source + QDomDocument &dom = *(m_part->projectDom()); + + QDomElement el = dom.documentElement(); + QDomNode el2 = el.namedItem("kdevautoproject"); + QDomNode el3 = el2.namedItem("subclassing"); + + QDomNode n = el3.firstChild(); + QValueList<QDomNode> nodesToRemove; + while ( !n.isNull() ) { + QDomNamedNodeMap attr = n.attributes(); + QString fpath = subProject->path + QString("/") + fileItemName; + QString relpath = fpath.remove(0, m_part->projectDirectory().length()); + if ((attr.item(0).nodeValue() == relpath) + || (attr.item(1).nodeValue() == relpath) ) + nodesToRemove.append(n); + n = n.nextSibling(); + } + QValueList<QDomNode>::iterator it; + for ( it = nodesToRemove.begin(); it != nodesToRemove.end(); ++it ) + el3.removeChild(*it); + + if (removeCheckBox->isChecked()) + QFile::remove(subProject->path + "/" + fileName); + + QDialog::accept(); +} + +#include "removefiledlg.moc" diff --git a/buildtools/autotools/removefiledlg.h b/buildtools/autotools/removefiledlg.h new file mode 100644 index 00000000..ab843dda --- /dev/null +++ b/buildtools/autotools/removefiledlg.h @@ -0,0 +1,51 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#ifndef _REMOVEFILEDLG_H_ +#define _REMOVEFILEDLG_H_ + +#include <qdialog.h> + +#include "removefiledlgbase.h" + +class QCheckBox; +class AutoProjectWidget; +class AutoProjectPart; +class SubprojectItem; +class TargetItem; + + +class RemoveFileDialog : public RemoveFileDlgBase +{ + Q_OBJECT + +public: + RemoveFileDialog( AutoProjectWidget *widget, AutoProjectPart* part, SubprojectItem *spitem, + TargetItem *item, const QString &filename, + QWidget *parent = 0, const char *name = 0 ); + ~RemoveFileDialog(); + +protected: + virtual void accept(); + +private: + QCheckBox *removeFromTargetsCheckBox; + //QCheckBox *removefromdisk_box; + + AutoProjectWidget* m_widget; + AutoProjectPart *m_part; + SubprojectItem *subProject; + TargetItem *target; + QString fileName; +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/removefiledlgbase.ui b/buildtools/autotools/removefiledlgbase.ui new file mode 100644 index 00000000..d7b66011 --- /dev/null +++ b/buildtools/autotools/removefiledlgbase.ui @@ -0,0 +1,233 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>RemoveFileDlgBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>RemoveFileDlgBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>447</width> + <height>284</height> + </rect> + </property> + <property name="caption"> + <string>Remove File From This Target</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="2" column="0"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>buttonSpacer</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>247</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>removeButton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelButton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QGroupBox" row="1" column="0"> + <property name="name"> + <cstring>fileGroupBox</cstring> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="title"> + <string>&File Information</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>fileLayout</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>removeLabel</cstring> + </property> + <property name="text"> + <string>[REMOVE QUESTION]</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>removeCheckBox</cstring> + </property> + <property name="text"> + <string>Also &remove it from disk</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>noticeLabel</cstring> + </property> + <property name="minimumSize"> + <size> + <width>200</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string><b>Note:</b> You will not be able to undelete the file.</string> + </property> + </widget> + </vbox> + </widget> + </vbox> + </widget> + <widget class="QGroupBox" row="0" column="0"> + <property name="name"> + <cstring>targetBox</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Subproject Information</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="1" column="1"> + <property name="name"> + <cstring>targetLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>[TARGET NAME]</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>directoryStaticLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Directory:</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>targetStaticLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Target:</string> + </property> + </widget> + <widget class="QLabel" row="0" column="1"> + <property name="name"> + <cstring>directoryLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>[DIRECTORY NAME]</string> + </property> + </widget> + </grid> + </widget> + </grid> +</widget> +<tabstops> + <tabstop>removeCheckBox</tabstop> + <tabstop>removeButton</tabstop> + <tabstop>cancelButton</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">ksqueezedtextlabel.h</include> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +</UI> diff --git a/buildtools/autotools/removetargetdlg.cpp b/buildtools/autotools/removetargetdlg.cpp new file mode 100644 index 00000000..6104e404 --- /dev/null +++ b/buildtools/autotools/removetargetdlg.cpp @@ -0,0 +1,279 @@ +/*************************************************************************** + ------------------- + begin : 21.11.2002 + copyright : (C) 2002 by Victor R�er + email : victor_roeder@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 "removetargetdlg.h" + +#include <qapplication.h> +#include <qcheckbox.h> +#include <qgroupbox.h> +#include <qfile.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <qregexp.h> + +#include <kbuttonbox.h> +#include <kdebug.h> +#include <kdialog.h> +#include <klistbox.h> +#include <kprogress.h> +#include <ksqueezedtextlabel.h> +#include <klocale.h> + +#include "autolistviewitems.h" + +#include "misc.h" + +#include "autoprojectpart.h" +#include "autoprojectwidget.h" + + +RemoveTargetDialog::RemoveTargetDialog( AutoProjectWidget *widget, AutoProjectPart* part, SubprojectItem *spitem, + TargetItem *titem, QWidget* parent, const char* name ) + : RemoveTargetDlgBase ( parent, name, true, 0 ) +{ + removeLabel->setText ( i18n ( "Do you really want to remove <b>%1</b><br>with <b>all files</b> that are attached to it<br>and <b>all dependencies</b>?" ).arg ( titem->name ) ); + directoryLabel->setText ( spitem->path ); + + if ( titem->name.isEmpty() ) + targetLabel->setText ( i18n ( "%1 in %2" ).arg ( titem->primary ).arg ( titem->prefix ) ); + else + targetLabel->setText ( titem->name ); + + connect ( removeButton, SIGNAL ( clicked() ), this, SLOT ( accept() ) ); + connect ( cancelButton, SIGNAL ( clicked() ), this, SLOT ( reject() ) ); + + setIcon ( SmallIcon ( "editdelete" ) ); + + progressBar->hide(); + + m_spitem = spitem; + m_titem = titem; + m_widget = widget; + m_part = part; + + //kdDebug ( 9020 ) << "+++++ " << titem->primary << " " << titem->prefix << " " << titem->name << endl; + + init(); +} + + +RemoveTargetDialog::~RemoveTargetDialog() +{ +} + +void RemoveTargetDialog::init() +{ + QPtrList <SubprojectItem> subprojectItems = m_widget->allSubprojectItems(); + + TargetItem* titem = 0; + + for ( SubprojectItem* spitem = subprojectItems.first(); spitem; spitem = subprojectItems.next() ) + { + if ( m_titem->name.isEmpty() ) + break; + + for ( titem = spitem->targets.first(); titem; titem = spitem->targets.next() ) + { + if ( m_titem->name == titem->name ) + continue; + + if ( titem->primary == "LTLIBRARIES" || titem->primary == "PROGRAMS" + || titem->primary == "LIBRARIES" || titem->primary == "JAVA" ) + { + QString canonname = AutoProjectTool::canonicalize ( titem->name ); + + if ( spitem->variables[canonname + "_LIBADD"].contains ( m_titem->name ) > 0 || + spitem->variables[canonname + "_LDADD"].contains ( m_titem->name ) > 0 ) + { + dependencyListBox->insertItem ( SmallIcon ( "target_kdevelop" ), spitem->path + " (" + titem->name + ")" ); + + dependentSubprojects.append ( spitem ); + } + } + } + } + + if ( dependencyListBox->count() == 0 ) + dependencyListBox->insertItem ( i18n("no dependency", "<none>") ); +} + +void RemoveTargetDialog::accept () +{ + progressBar->show(); + progressBar->setFormat ( i18n ( "Removing Target... %p%" ) ); + + qApp->processEvents(); + + QString canonname = AutoProjectTool::canonicalize ( m_titem->name ); + QString varname = m_titem->prefix + "_" + m_titem->primary; + + SubprojectItem* spitem = 0; + TargetItem* titem = 0; + + QMap <QString, QString> removeMap; + QMap <QString, QString> replaceMap; + + // Remove dependencies to other targets first (stored by init() in 'dependentTargets') + for ( spitem = dependentSubprojects.first(); spitem; spitem = dependentSubprojects.next() ) + { + for ( titem = spitem->targets.first(); titem; titem = spitem->targets.next() ) + { + QString curVarname; + QString curCanonname = AutoProjectTool::canonicalize ( titem->name ); + QStringList dependencies; + + if ( spitem->variables[curCanonname + "_LIBADD"].contains ( m_titem->name ) ) + curVarname = curCanonname + "_LIBADD"; + else + curVarname = curCanonname + "_LDADD"; + + dependencies = QStringList::split(QRegExp("[ \t\n]"), spitem->variables[curVarname]); + + //QStringList::Iterator it = dependencies.begin(); + + for ( uint i = 0; i < dependencies.size(); ++i ) + { + QString s = dependencies[i]; + if ( s.contains ( m_titem->name ) > 0 ) + dependencies.remove ( s ); + } + + // if we removed the last entry of "blabla_LDADD" or "blabla_LIBADD", remove the complete line + if ( dependencies.count() == 0 ) + { + removeMap.insert ( curVarname, "" ); + AutoProjectTool::removeFromMakefileam ( spitem->path + "/Makefile.am", removeMap ); + removeMap.clear(); + } + else + { + spitem->variables[curVarname] = dependencies.join ( " " ); + replaceMap.insert ( curVarname, spitem->variables[curVarname] ); + AutoProjectTool::addToMakefileam ( spitem->path + "/Makefile.am", replaceMap ); + replaceMap.clear(); + } + } + } + + // handling am_edit stuff + if ( m_titem->primary == "KDEICON" ) + removeMap.insert ( "KDE_ICON", "" ); + else if ( m_titem->primary == "KDEDOCS" ) + removeMap.insert ( "KDE_DOCS", "" ); + else + { + // if we have bin_PROGRAMS = [target to be deleted] [other target] + // delete only the [target to be deleted], not the whole line! + QStringList targets = QStringList::split(QRegExp("[ \t\n]"), m_spitem->variables[varname]); + + if ( targets.count() > 1 ) + { + targets.remove ( m_titem->name ); + m_spitem->variables[varname] = targets.join ( " " ); + replaceMap.insert ( varname, m_spitem->variables[varname] ); + AutoProjectTool::addToMakefileam ( m_spitem->path + "/Makefile.am", replaceMap ); + replaceMap.clear(); + } + else + { + removeMap.insert ( varname, m_titem->name ); + } + } + + // if we have no such line containing blabla_SOURCES, blabla_LDFLAGS, etc. + // they are ignored + removeMap.insert ( canonname + "_SOURCES", "" ); + + // remove from our internal list + m_spitem->variables.erase(canonname+"_SOURCES"); + + if ( m_titem->primary == "PROGRAMS" || m_titem->primary == "LTLIBRARIES" ) + { + removeMap.insert ( canonname + "_LDFLAGS", "" ); + removeMap.insert ( canonname + "_DEPENDENCIES", "" ); + removeMap.insert ( canonname + "_LDADD", "" ); + removeMap.insert ( canonname + "_LIBADD", "" ); + } + + AutoProjectTool::removeFromMakefileam ( m_spitem->path + "/Makefile.am", removeMap ); + + removeMap.clear(); + + // if we have another "blabla_PROGRAMS" or "blabla_LTLIBRARIES" target in the same subproject + // check if it has an empty "blabla_LIBADD"-entry + if ( m_titem->primary == "PROGRAMS" || m_titem->primary == "LTLIBRARIES" ) + { + for ( titem = m_spitem->targets.first(); titem; titem = m_spitem->targets.next() ) + { + //kdDebug (9020) << "******** " << m_spitem->subdir << endl; + if ( titem->primary == "PROGRAMS" || titem->primary == "LTLIBRARIES" ) + { + QString curCanonname = AutoProjectTool::canonicalize ( titem->name ); + + if ( m_spitem->variables[curCanonname + "_LIBADD"].isEmpty() ) + { + removeMap.insert ( curCanonname + "_LIBADD", "" ); + + //kdDebug (9020) << "Removing from " << m_spitem->subdir << " " << curCanonname << "_LIBADD" << endl; + + AutoProjectTool::removeFromMakefileam ( m_spitem->path + "/Makefile.am", removeMap ); + + removeMap.clear(); + } + } + } + } + + + progressBar->setTotalSteps ( m_titem->sources.count() ); + + QStringList fileList; + + for ( FileItem* fitem = m_titem->sources.first(); fitem; fitem = m_titem->sources.next() ) + { + if (removeCheckBox->isChecked()) + { + // before removing the files, check if they are mentioned in "noinst_HEADERS = blabla1.h blabla2.h" + QStringList noInstHeaders = QStringList::split ( QRegExp ( "[ \t\n]" ), m_spitem->variables["noinst_HEADERS"] ); + + if ( noInstHeaders.contains ( fitem->name ) ) + { + noInstHeaders.remove ( fitem->name ); + + m_spitem->variables["noinst_HEADERS"] = noInstHeaders.join ( " " ); + replaceMap.insert ( "noinst_HEADERS", m_spitem->variables["noinst_HEADERS"] ); + AutoProjectTool::addToMakefileam ( m_spitem->path + "/Makefile.am", replaceMap ); + replaceMap.clear(); + } + + QFile::remove(m_spitem->path + "/" + fitem->name); + } + + fileList.append ( m_spitem->path.mid ( m_part->projectDirectory().length() + 1 ) + "/" + fitem->name ); + + qApp->processEvents(); + + progressBar->setValue ( progressBar->value() + 1 ); + } + + m_widget->emitRemovedFiles ( fileList ); + + m_spitem->targets.remove ( m_titem ); + + + QDialog::accept(); +} diff --git a/buildtools/autotools/removetargetdlg.h b/buildtools/autotools/removetargetdlg.h new file mode 100644 index 00000000..6953d2bf --- /dev/null +++ b/buildtools/autotools/removetargetdlg.h @@ -0,0 +1,55 @@ +/*************************************************************************** + ------------------- + begin : 21.11.2002 + copyright : (C) 2002 by Victor Rder + email : victor_roeder@gmx.de +***************************************************************************/ + +/*************************************************************************** + * * + * 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 _REMOVETARGETDLG_H_ +#define _REMOVETARGETDLG_H_ + +#include "removetargetdlgbase.h" + +#include <qptrlist.h> + +class AutoProjectWidget; +class AutoProjectPart; +class SubprojectItem; +class TargetItem; + +/** + * + * KDevelop Authors + **/ +class RemoveTargetDialog : public RemoveTargetDlgBase +{ + +public: + RemoveTargetDialog( AutoProjectWidget *widget, AutoProjectPart* part, SubprojectItem *spitem, + TargetItem *titem, QWidget* parent = 0, const char* name = 0 ); + ~RemoveTargetDialog(); + +private: + SubprojectItem* m_spitem; + TargetItem* m_titem; + AutoProjectWidget* m_widget; + AutoProjectPart* m_part; + + QPtrList <SubprojectItem> dependentSubprojects; + +protected: + void init (); + virtual void accept(); +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/removetargetdlgbase.ui b/buildtools/autotools/removetargetdlgbase.ui new file mode 100644 index 00000000..8e3660d3 --- /dev/null +++ b/buildtools/autotools/removetargetdlgbase.ui @@ -0,0 +1,264 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>RemoveTargetDlgBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>RemoveTargetDlgBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>472</width> + <height>477</height> + </rect> + </property> + <property name="caption"> + <string>Remove Target From [SUBPROJECT]</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox" row="0" column="0"> + <property name="name"> + <cstring>targetBox</cstring> + </property> + <property name="title"> + <string>Subproject Information</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KSqueezedTextLabel" row="0" column="1"> + <property name="name"> + <cstring>directoryLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>[TARGET DIRECTORY]</string> + </property> + </widget> + <widget class="QLabel" row="1" column="1"> + <property name="name"> + <cstring>targetLabel</cstring> + </property> + <property name="text"> + <string>[TARGET NAME]</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>directoryStaticLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Directory:</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>targetStaticLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Target:</string> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox" row="1" column="0"> + <property name="name"> + <cstring>fileGroupBox</cstring> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>140</height> + </size> + </property> + <property name="title"> + <string>&Target Information</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>removeLabel</cstring> + </property> + <property name="text"> + <string>[REMOVE QUESTION]</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="0"> + <property name="name"> + <cstring>removeCheckBox</cstring> + </property> + <property name="text"> + <string>Also &remove it from disk</string> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel</cstring> + </property> + <property name="minimumSize"> + <size> + <width>200</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string><b>Note:</b> You will not be able to undo this operation. Please check your Makefile.am afterwards.</string> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox" row="2" column="0"> + <property name="name"> + <cstring>groupBox3</cstring> + </property> + <property name="title"> + <string>&Dependencies to Other Subprojects</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KListBox" row="0" column="0"> + <property name="name"> + <cstring>dependencyListBox</cstring> + </property> + <property name="dragAutoScroll"> + <bool>false</bool> + </property> + <property name="selectionMode"> + <enum>NoSelection</enum> + </property> + </widget> + </grid> + </widget> + <widget class="KProgress" row="3" column="0"> + <property name="name"> + <cstring>progressBar</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + </widget> + <spacer row="4" column="0"> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget" row="5" column="0"> + <property name="name"> + <cstring>buttonLayout</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>buttonSpacer</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>30</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>removeButton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelButton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>ksqueezedtextlabel.h</includehint> + <includehint>klistbox.h</includehint> + <includehint>kprogress.h</includehint> +</includehints> +</UI> diff --git a/buildtools/autotools/subprojectoptionsdlg.cpp b/buildtools/autotools/subprojectoptionsdlg.cpp new file mode 100644 index 00000000..5ad6bf10 --- /dev/null +++ b/buildtools/autotools/subprojectoptionsdlg.cpp @@ -0,0 +1,404 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "subprojectoptionsdlg.h" + +#include <qdom.h> +#include <qheader.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qlineedit.h> +#include <qpushbutton.h> +#include <qcheckbox.h> +#include <qregexp.h> +#include <kbuttonbox.h> +#include <kdebug.h> +#include <kdialog.h> +#include <keditlistbox.h> +#include <kinputdialog.h> +#include <klocale.h> +#include <knotifyclient.h> +#include <kservice.h> +#include <kurlrequesterdlg.h> +#include <kurlrequester.h> +#include <kurlcompletion.h> +#include <kfiledialog.h> +#include "domutil.h" +#include "misc.h" +#include "addprefixdlg.h" + +#include "autolistviewitems.h" + +#include "autoprojectpart.h" +#include "autoprojectwidget.h" + + +SubprojectOptionsDialog::SubprojectOptionsDialog(AutoProjectPart *part, AutoProjectWidget *widget, + SubprojectItem *item, QWidget *parent, const char *name) + : SubprojectOptionsDialogBase(parent, name, true) +{ + setCaption(i18n("Subproject Options for '%1'").arg(item->subdir)); + + subProject = item; + m_part = part; + + QFontMetrics fm(cflags_edit->fontMetrics()); + int wid = fm.width('X')*35; + cflags_edit->setMinimumWidth(wid); + cxxflags_edit->setMinimumWidth(wid); + fflags_edit->setMinimumWidth(wid); + + QDomDocument &dom = *part->projectDom(); + QString prefix = "/kdevautoproject/configurations/" + m_part->currentBuildConfig() + "/"; + + ccompiler = DomUtil::readEntry(dom, prefix + "ccompiler", "kdevgccoptions"); + cxxcompiler = DomUtil::readEntry(dom, prefix + "cxxcompiler", "kdevgppoptions"); + f77compiler = DomUtil::readEntry(dom, prefix + "f77compiler", "kdevg77options"); + + if (!KService::serviceByDesktopName(ccompiler)) + cflags_button->setEnabled(false); + if (!KService::serviceByDesktopName(cxxcompiler)) + cxxflags_button->setEnabled(false); + if (!KService::serviceByDesktopName(f77compiler)) + fflags_button->setEnabled(false); + + insideinc_listview->header()->hide(); + outsideinc_listview->header()->hide(); + buildorder_listview->header()->hide(); + + insideinc_listview->setSorting(-1); + outsideinc_listview->setSorting(-1); + prefix_listview->setSorting(-1); + buildorder_listview->setSorting(-1); + + connect( prefix_listview, SIGNAL( doubleClicked ( QListViewItem *, const QPoint &, int ) ), this, SLOT( editPrefixClicked() ) ); + + // Insert all subdirectories as possible include directories + QStringList l = widget->allSubprojects(); + QCheckListItem *lastItem = 0; + QStringList::ConstIterator it; + for (it = l.begin(); it != l.end(); ++it) { + kdDebug(9020) << "----------> subproject = " << (*it) << endl; + QString subProjectName = *it; + + if( subProjectName.isEmpty() ){ + subProjectName = QString::fromLatin1( "." ); + } + QCheckListItem *clitem = new QCheckListItem(insideinc_listview, subProjectName, QCheckListItem::CheckBox); + if (lastItem) + clitem->moveItem(lastItem); + lastItem = clitem; + } + + setIcon ( SmallIcon ( "configure" ) ); + + readConfig(); +} + + +SubprojectOptionsDialog::~SubprojectOptionsDialog() +{} + + +void SubprojectOptionsDialog::readConfig() +{ + + cflags_edit->setText(subProject->variables["AM_CFLAGS"]); + cxxflags_edit->setText(subProject->variables["AM_CXXFLAGS"]); + fflags_edit->setText(subProject->variables["AM_FFLAGS"]); + + metasources_checkbox->setChecked(subProject->variables["METASOURCES"].stripWhiteSpace() == "AUTO"); + + QString includes = subProject->variables["INCLUDES"]; + QStringList includeslist = QStringList::split(QRegExp("[ \t]"), QString(includes)); + + QListViewItem *lastItem = 0; + QStringList::Iterator it; + for (it = includeslist.begin(); it != includeslist.end(); ++it) { + QCheckListItem *clitem = static_cast<QCheckListItem*>(insideinc_listview->firstChild()); + while (clitem) { + if (*it == ("-I$(top_srcdir)/" + clitem->text())) { + clitem->setOn(true); + break; + } + clitem = static_cast<QCheckListItem*>(clitem->nextSibling()); + } + if (!clitem) { + QListViewItem *item = new QListViewItem(outsideinc_listview, *it); + if (lastItem) + item->moveItem(lastItem); + lastItem = item; + } + } + + QMap<QString, QString>::ConstIterator it2; + for (it2 = subProject->prefixes.begin(); it2 != subProject->prefixes.end(); ++it2) + new QListViewItem(prefix_listview, it2.key(), it2.data()); + + QString subdirs = subProject->variables["SUBDIRS"]; + kdDebug(9020) << "Subdirs variable: " << subdirs << endl; + QStringList subdirslist = QStringList::split(QRegExp("[ \t]"), QString(subdirs)); + lastItem = 0; + for (it = subdirslist.begin(); it != subdirslist.end(); ++it) { + QListViewItem *item = new QListViewItem(buildorder_listview, *it); + if (lastItem) + item->moveItem(lastItem); + lastItem = item; + } +} + + +void SubprojectOptionsDialog::storeConfig() +{ + QMap<QString, QString> replaceMap; + + QString old_cflags = subProject->variables["AM_CFLAGS"]; + QString new_cflags = cflags_edit->text(); + if (new_cflags != old_cflags) { + subProject->variables["AM_CFLAGS"] = new_cflags; + replaceMap.insert("AM_CFLAGS", new_cflags); + } + + QString old_cxxflags = subProject->variables["AM_CXXFLAGS"]; + QString new_cxxflags = cxxflags_edit->text(); + if (new_cxxflags != old_cxxflags) { + subProject->variables["AM_CXXFLAGS"] = new_cxxflags; + replaceMap.insert("AM_CXXFLAGS", new_cxxflags); + } + + QString old_fflags = subProject->variables["AM_FFLAGS"]; + QString new_fflags = fflags_edit->text(); + if (new_fflags != old_fflags) { + subProject->variables["AM_FFLAGS"] = new_fflags; + replaceMap.insert("AM_FFLAGS", new_fflags); + } + + QString old_metasources = subProject->variables["METASOURCES"]; + QString new_metasources = metasources_checkbox->isChecked() ? QString::fromLatin1("AUTO") : QString::null; + if (new_metasources != old_metasources) { + subProject->variables["METASOURCES"] = new_metasources; + replaceMap.insert("METASOURCES", new_metasources); + } + + QStringList includeslist; + QCheckListItem *clitem = static_cast<QCheckListItem*>(insideinc_listview->firstChild()); + while (clitem) { + if (clitem->isOn()) + includeslist.append("-I$(top_srcdir)/" + clitem->text()); + clitem = static_cast<QCheckListItem*>(clitem->nextSibling()); + } + clitem = static_cast<QCheckListItem*>(outsideinc_listview->firstChild()); + while (clitem) { + includeslist.append(clitem->text()); + clitem = static_cast<QCheckListItem*>(clitem->nextSibling()); + } + QString includes = includeslist.join(" "); + subProject->variables["INCLUDES"] = includes; + replaceMap.insert("INCLUDES", includes); + + subProject->prefixes.clear(); + for (QListViewItem *item = prefix_listview->firstChild(); + item; item = item->nextSibling()) { + QString key = item->text(0); + QString data = item->text(1); + subProject->prefixes[key] = data; + replaceMap.insert(key + "dir", data); + } + /// \FIXME take removed prefixes into account + + QStringList subdirslist; + for (QListViewItem *item = buildorder_listview->firstChild(); + item; item = item->nextSibling()) + subdirslist.append(item->text(0)); + QString subdirs = subdirslist.join(" "); + kdDebug() << "New subdirs variable: " << subdirs << endl; + subProject->variables["SUBDIRS"] = subdirs; + replaceMap.insert("SUBDIRS", subdirs); + + AutoProjectTool::setMakefileam(subProject->path + "/Makefile.am", replaceMap); +} + + +void SubprojectOptionsDialog::cflagsClicked() +{ + QString new_cflags = AutoProjectTool::execFlagsDialog(ccompiler, cflags_edit->text(), this); +// if (!new_cflags.isNull()) + cflags_edit->setText(new_cflags); +} + + +void SubprojectOptionsDialog::cxxFlagsClicked() +{ + QString new_cxxflags = AutoProjectTool::execFlagsDialog(cxxcompiler, cxxflags_edit->text(), this); +// if (!new_cxxflags.isNull()) + cxxflags_edit->setText(new_cxxflags); +} + + +void SubprojectOptionsDialog::fflagsClicked() +{ + QString new_fflags = AutoProjectTool::execFlagsDialog(f77compiler, fflags_edit->text(), this); +// if (!new_fflags.isNull()) + fflags_edit->setText(new_fflags); +} + + +void SubprojectOptionsDialog::insideMoveUpClicked() +{ + if (insideinc_listview->currentItem() == insideinc_listview->firstChild()) { + KNotifyClient::beep(); + return; + } + + QListViewItem *item = insideinc_listview->firstChild(); + while (item->nextSibling() != insideinc_listview->currentItem()) + item = item->nextSibling(); + item->moveItem(insideinc_listview->currentItem()); +} + + +void SubprojectOptionsDialog::insideMoveDownClicked() +{ + if (insideinc_listview->currentItem() == 0 || insideinc_listview->currentItem()->nextSibling() == 0) { + KNotifyClient::beep(); + return; + } + + insideinc_listview->currentItem()->moveItem(insideinc_listview->currentItem()->nextSibling()); +} + + +void SubprojectOptionsDialog::outsideMoveUpClicked() +{ + if (outsideinc_listview->currentItem() == outsideinc_listview->firstChild()) { + KNotifyClient::beep(); + return; + } + + QListViewItem *item = outsideinc_listview->firstChild(); + while (item->nextSibling() != outsideinc_listview->currentItem()) + item = item->nextSibling(); + item->moveItem(outsideinc_listview->currentItem()); +} + + +void SubprojectOptionsDialog::outsideMoveDownClicked() +{ + if (outsideinc_listview->currentItem() == 0 || outsideinc_listview->currentItem()->nextSibling() == 0) { + KNotifyClient::beep(); + return; + } + + outsideinc_listview->currentItem()->moveItem(outsideinc_listview->currentItem()->nextSibling()); +} + +void SubprojectOptionsDialog::outsideAddClicked() +{ + KURLRequesterDlg dialog( "", i18n( "Add Include directory: Choose directory, give -Idirectory or use a variable with -I$(FOOBAR)" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + dialog.urlRequester() ->setURL( QString::null ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString file = dialog.urlRequester() ->url(); + if ( !file.isEmpty() ) + { + if ( !file.isEmpty() ) + { + if( file.startsWith("-I") ) + new QListViewItem( outsideinc_listview, file ); + else + { + new QListViewItem( outsideinc_listview, "-I"+file ); + } + } + } +} + + +void SubprojectOptionsDialog::outsideEditClicked() +{ + if ( (outsideinc_listview->childCount()==0) || (outsideinc_listview->currentItem() == 0) ) + return; + bool ok; + QString dir = KInputDialog::getText(i18n("Edit Include Directory"), i18n("Edit include directory:"), + outsideinc_listview->currentItem()-> text(0), &ok, 0); + if (ok && !dir.isEmpty()) + outsideinc_listview->currentItem()-> setText(0, dir); +} + + +void SubprojectOptionsDialog::outsideRemoveClicked() +{ + delete outsideinc_listview->currentItem(); +} + + +void SubprojectOptionsDialog::addPrefixClicked() +{ + AddPrefixDialog dlg; + if (!dlg.exec() || dlg.name().isEmpty() || dlg.path().isEmpty() ) + return; + + new QListViewItem(prefix_listview, dlg.name(), dlg.path()); +} + + +void SubprojectOptionsDialog::editPrefixClicked() +{ + QListViewItem* lvItem = prefix_listview->currentItem(); + if ( (prefix_listview->childCount()==0) || (lvItem == 0) ) + return; + AddPrefixDialog dlg(lvItem-> text(0), lvItem-> text(1)); + dlg.setCaption(i18n("Edit Prefix")); + if (!dlg.exec() || dlg.name().isEmpty() || dlg.path().isEmpty() ) + return; + lvItem-> setText(0, dlg.name()); + lvItem-> setText(1, dlg.path()); +} + +void SubprojectOptionsDialog::removePrefixClicked() +{ + delete prefix_listview->currentItem(); +} + + +void SubprojectOptionsDialog::buildorderMoveUpClicked() +{ + if (buildorder_listview->currentItem() == buildorder_listview->firstChild()) { + KNotifyClient::beep(); + return; + } + + QListViewItem *item = buildorder_listview->firstChild(); + while (item->nextSibling() != buildorder_listview->currentItem()) + item = item->nextSibling(); + item->moveItem(buildorder_listview->currentItem()); +} + + +void SubprojectOptionsDialog::buildorderMoveDownClicked() +{ + if (buildorder_listview->currentItem() == 0 || buildorder_listview->currentItem()->nextSibling() == 0) { + KNotifyClient::beep(); + return; + } + + buildorder_listview->currentItem()->moveItem(buildorder_listview->currentItem()->nextSibling()); +} + + +void SubprojectOptionsDialog::accept() +{ + storeConfig(); + QDialog::accept(); +} + +#include "subprojectoptionsdlg.moc" diff --git a/buildtools/autotools/subprojectoptionsdlg.h b/buildtools/autotools/subprojectoptionsdlg.h new file mode 100644 index 00000000..7ec1fbf0 --- /dev/null +++ b/buildtools/autotools/subprojectoptionsdlg.h @@ -0,0 +1,63 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#ifndef _SUBPROJECTOPTIONSDLG_H_ +#define _SUBPROJECTOPTIONSDLG_H_ + +#include "subprojectoptionsdlgbase.h" + +class AutoProjectPart; +class AutoProjectWidget; +class SubprojectItem; + + +class SubprojectOptionsDialog : public SubprojectOptionsDialogBase +{ + Q_OBJECT + +public: + SubprojectOptionsDialog( AutoProjectPart *part, AutoProjectWidget *widget, + SubprojectItem *item, QWidget *parent = 0, const char *name = 0 ); + ~SubprojectOptionsDialog(); + +private: + virtual void cflagsClicked(); + virtual void cxxFlagsClicked(); + virtual void fflagsClicked(); + virtual void insideMoveUpClicked(); + virtual void insideMoveDownClicked(); + virtual void outsideMoveUpClicked(); + virtual void outsideMoveDownClicked(); + virtual void outsideAddClicked(); + virtual void outsideRemoveClicked(); + virtual void outsideEditClicked(); + virtual void addPrefixClicked(); + virtual void editPrefixClicked(); + virtual void removePrefixClicked(); + virtual void buildorderMoveUpClicked(); + virtual void buildorderMoveDownClicked(); + virtual void accept(); + + void readConfig(); + void storeConfig(); + + SubprojectItem *subProject; + AutoProjectWidget *m_widget; + AutoProjectPart *m_part; + + QString ccompiler; + QString cxxcompiler; + QString f77compiler; +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/subprojectoptionsdlgbase.ui b/buildtools/autotools/subprojectoptionsdlgbase.ui new file mode 100644 index 00000000..f2723e5a --- /dev/null +++ b/buildtools/autotools/subprojectoptionsdlgbase.ui @@ -0,0 +1,989 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>SubprojectOptionsDialogBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>sub project options widget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>442</width> + <height>437</height> + </rect> + </property> + <property name="caption"> + <string>Subproject Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QTabWidget"> + <property name="name"> + <cstring>subprojectoptions_tabwidget</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>Co&mpiler</string> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>cflags_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Compiler flags for C compiler (CFLA&GS):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cflags_edit</cstring> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="KLineEdit"> + <property name="name"> + <cstring>cflags_edit</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cflags_button</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>30</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <property name="name"> + <cstring>cxxflags_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Compiler flags for C++ compiler (C&XXFLAGS):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>cxxflags_edit</cstring> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="KLineEdit"> + <property name="name"> + <cstring>cxxflags_edit</cstring> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cxxflags_button</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <property name="name"> + <cstring>fflags_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Compiler flags for Fortran compiler (&FFLAGS):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>fflags_edit</cstring> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="KLineEdit"> + <property name="name"> + <cstring>fflags_edit</cstring> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>fflags_button</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>30</width> + <height>25</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>&Includes</string> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout11</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>metasources_checkbox</cstring> + </property> + <property name="text"> + <string>Automatically &generate metasources</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout9</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="1" column="1"> + <property name="name"> + <cstring>Layout9</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer2_3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>insidemoveup_button</cstring> + </property> + <property name="text"> + <string>Move &Up</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>insidemovedown_button</cstring> + </property> + <property name="text"> + <string>Move &Down</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer3_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>insideinc_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Directories in&side project:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>insideinc_listview</cstring> + </property> + </widget> + <widget class="QListView" row="1" column="0"> + <column> + <property name="text"> + <string></string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>insideinc_listview</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout10</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="0" column="1" rowspan="2" colspan="1"> + <property name="name"> + <cstring>Layout10</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer1_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>outsideadd_button</cstring> + </property> + <property name="text"> + <string>&Add...</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>outsideedit_button</cstring> + </property> + <property name="text"> + <string>&Edit...</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>outsideremove_button</cstring> + </property> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>outsidemoveup_button</cstring> + </property> + <property name="text"> + <string>Move U&p</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>outsidemovedown_button</cstring> + </property> + <property name="text"> + <string>Move Dow&n</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel2_2</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Directories ou&tside project:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>outsideinc_listview</cstring> + </property> + </widget> + <widget class="QListView" row="1" column="0"> + <column> + <property name="text"> + <string></string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>outsideinc_listview</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + </grid> + </widget> + </vbox> + </widget> + </vbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>&Prefixes</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QListView" row="1" column="0"> + <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>Path</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>prefix_listview</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="resizeMode"> + <enum>AllColumns</enum> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>prefixes_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>C&ustom prefixes:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>prefix_listview</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="1"> + <property name="name"> + <cstring>Layout6</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>addprefix_button</cstring> + </property> + <property name="text"> + <string>&Add...</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>editprefix_button</cstring> + </property> + <property name="text"> + <string>&Edit...</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>removeprefix_button</cstring> + </property> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer6</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>&Build Order</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="1" column="1"> + <property name="name"> + <cstring>Layout9_2</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer2_3_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buildmoveup_button</cstring> + </property> + <property name="text"> + <string>Move &Up</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buildmovedown_button</cstring> + </property> + <property name="text"> + <string>Move &Down</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer3_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QListView" row="1" column="0"> + <column> + <property name="text"> + <string></string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>buildorder_listview</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>buildorder_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>O&rder in which sub projects are built:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>buildorder_listview</cstring> + </property> + </widget> + </grid> + </widget> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <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>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>okbutton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelbutton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>cflags_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>cflagsClicked()</slot> + </connection> + <connection> + <sender>cxxflags_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>cxxFlagsClicked()</slot> + </connection> + <connection> + <sender>removeprefix_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>removePrefixClicked()</slot> + </connection> + <connection> + <sender>insidemoveup_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>insideMoveUpClicked()</slot> + </connection> + <connection> + <sender>insidemovedown_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>insideMoveDownClicked()</slot> + </connection> + <connection> + <sender>outsideadd_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>outsideAddClicked()</slot> + </connection> + <connection> + <sender>outsideedit_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>outsideEditClicked()</slot> + </connection> + <connection> + <sender>outsidemovedown_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>outsideMoveDownClicked()</slot> + </connection> + <connection> + <sender>outsidemoveup_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>outsideMoveUpClicked()</slot> + </connection> + <connection> + <sender>outsideremove_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>outsideRemoveClicked()</slot> + </connection> + <connection> + <sender>okbutton</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>cancelbutton</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>fflags_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>fflagsClicked()</slot> + </connection> + <connection> + <sender>buildmovedown_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>buildorderMoveDownClicked()</slot> + </connection> + <connection> + <sender>buildmoveup_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>buildorderMoveUpClicked()</slot> + </connection> + <connection> + <sender>addprefix_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>addPrefixClicked()</slot> + </connection> + <connection> + <sender>editprefix_button</sender> + <signal>clicked()</signal> + <receiver>sub project options widget</receiver> + <slot>editPrefixClicked()</slot> + </connection> +</connections> +<tabstops> + <tabstop>cflags_edit</tabstop> + <tabstop>cflags_button</tabstop> + <tabstop>cxxflags_edit</tabstop> + <tabstop>cxxflags_button</tabstop> + <tabstop>fflags_edit</tabstop> + <tabstop>fflags_button</tabstop> + <tabstop>subprojectoptions_tabwidget</tabstop> + <tabstop>metasources_checkbox</tabstop> + <tabstop>insideinc_listview</tabstop> + <tabstop>insidemoveup_button</tabstop> + <tabstop>insidemovedown_button</tabstop> + <tabstop>outsideinc_listview</tabstop> + <tabstop>outsideadd_button</tabstop> + <tabstop>outsideedit_button</tabstop> + <tabstop>outsideremove_button</tabstop> + <tabstop>outsidemoveup_button</tabstop> + <tabstop>outsidemovedown_button</tabstop> + <tabstop>prefix_listview</tabstop> + <tabstop>addprefix_button</tabstop> + <tabstop>editprefix_button</tabstop> + <tabstop>removeprefix_button</tabstop> + <tabstop>buildorder_listview</tabstop> + <tabstop>buildmoveup_button</tabstop> + <tabstop>buildmovedown_button</tabstop> + <tabstop>okbutton</tabstop> + <tabstop>cancelbutton</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<slots> + <slot access="protected">buildorderMoveDownClicked()</slot> + <slot access="protected">cflagsClicked()</slot> + <slot access="protected">cxxFlagsClicked()</slot> + <slot access="protected">fflagsClicked()</slot> + <slot access="protected">insideMoveDownClicked()</slot> + <slot access="protected">insideMoveUpClicked()</slot> + <slot access="protected">buildorderMoveUpClicked()</slot> + <slot access="protected">outsideAddClicked()</slot> + <slot access="protected">outsideEditClicked()</slot> + <slot access="protected">outsideMoveDownClicked()</slot> + <slot access="protected">outsideMoveUpClicked()</slot> + <slot access="protected">outsideRemoveClicked()</slot> + <slot access="protected">removePrefixClicked()</slot> + <slot access="private">addPrefixClicked()</slot> + <slot access="private">editPrefixClicked()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +</UI> diff --git a/buildtools/autotools/targetoptionsdlg.cpp b/buildtools/autotools/targetoptionsdlg.cpp new file mode 100644 index 00000000..c8d49c55 --- /dev/null +++ b/buildtools/autotools/targetoptionsdlg.cpp @@ -0,0 +1,357 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "targetoptionsdlg.h" + +#include <qcheckbox.h> +#include <qheader.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qregexp.h> +#include <klineedit.h> +#include <kbuttonbox.h> +#include <kdialog.h> +#include <kinputdialog.h> +#include <kurlrequesterdlg.h> +#include <kurlrequester.h> +#include <kurlcompletion.h> +#include <klocale.h> +#include <knotifyclient.h> +#include <kfiledialog.h> +#include "autolistviewitems.h" + +#include "misc.h" +#include "autoprojectpart.h" +#include "autoprojectwidget.h" +#include "urlutil.h" + +TargetOptionsDialog::TargetOptionsDialog(AutoProjectWidget *widget, TargetItem *item, + QWidget *parent, const char *name) + : TargetOptionsDialogBase(parent, name, true) +{ + setCaption( i18n("Target Options for '%1'").arg(item->name) ); + setIcon( SmallIcon("configure") ); + + target = item; + m_widget = widget; + + if (item->primary == "PROGRAMS") { + insidelib_label->setText(i18n("Link convenience libraries inside project (LDADD)")); + outsidelib_label->setText(i18n("Link libraries outside project (LDADD)")); + } + else + argumentBox->setEnabled( false ); +// run_arguments_edit->setEnabled(false); + + insidelib_listview->header()->hide(); + outsidelib_listview->header()->hide(); + insidelib_listview->setSorting(-1); + outsidelib_listview->setSorting(-1); + + + m_cwdEdit->completionObject()->setMode(KURLCompletion::DirCompletion); + m_cwdEdit->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + + // Insert all convenience libraries as possible linked libraries + QStringList l = widget->allLibraries(); + QStringList::ConstIterator it; + QString fulltargetname = m_widget->subprojectDirectory() + "/" + item->name; + for (it = l.begin(); it != l.end(); ++it) + // Do not list the target itself (a target can not link with itself) + if ( !fulltargetname.endsWith(*it) ) + (void) new QCheckListItem(insidelib_listview, *it, QCheckListItem::CheckBox); + readConfig(); +} + + +TargetOptionsDialog::~TargetOptionsDialog() +{} + + +void TargetOptionsDialog::readConfig() +{ + QString flagsstr = target->ldflags; + flagsstr.replace(QRegExp("$(KDE_PLUGIN)"), "-avoid-version -module -no-undefined $(KDE_RPATH)"); + QStringList l1 = QStringList::split(QRegExp("[ \t]"), flagsstr); + QStringList::Iterator l1it; + + l1it = l1.find("-all-static"); + if (l1it != l1.end()) { + allstatic_box->setChecked(true); + l1.remove(l1it); + } + l1it = l1.find("-avoid-version"); + if (l1it != l1.end()) { + avoidversion_box->setChecked(true); + l1.remove(l1it); + } + l1it = l1.find("-module"); + if (l1it != l1.end()) { + module_box->setChecked(true); + l1.remove(l1it); + } + l1it = l1.find("-no-undefined"); + if (l1it != l1.end()) { + noundefined_box->setChecked(true); + l1.remove(l1it); + } + ldflagsother_edit->setText(l1.join(" ")); + dependencies_edit->setText(target->dependencies); + + QString addstr = (target->primary == "PROGRAMS")? target->ldadd : target->libadd; + QStringList l2 = QStringList::split(QRegExp("[ \t]"), addstr); + + kdDebug(9020) << "ls=: " << addstr << endl; + + bool inlistItem; + QListViewItem *lastItem = 0; + QStringList::Iterator l2it; + QCheckListItem *flitem = static_cast<QCheckListItem*>(insidelib_listview->firstChild()); + for (l2it = l2.begin(); l2it != l2.end(); ++l2it) { + inlistItem = false; + QCheckListItem *clitem = static_cast<QCheckListItem*>(insidelib_listview->firstChild()); + if (flitem) { + while (clitem) { + if (*l2it == ("$(top_builddir)/" + clitem->text())) { + clitem->setOn(true); + // move this item to the "top of the list" + if (flitem != clitem) + clitem->moveItem(flitem); + // move the "top of the list" one item down + flitem = static_cast<QCheckListItem*>(flitem->nextSibling()); + inlistItem = true; + break; + } + clitem = static_cast<QCheckListItem*>(clitem->nextSibling()); + } + } + if ( inlistItem == false ) { + QListViewItem *item = new QListViewItem(outsidelib_listview, *l2it); + if (lastItem) + item->moveItem(lastItem); + lastItem = item; + } + } + + if (target->primary == "PROGRAMS") + { + run_arguments_edit->setText(DomUtil::readEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/runarguments/" + target->name)); + if( DomUtil::readEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/cwd/" + target->name).isEmpty() ) + { + m_cwdEdit->setURL( m_widget->m_part->buildDirectory()+"/"+URLUtil::getRelativePath(m_widget->m_part->topsourceDirectory(), m_widget->m_part->projectDirectory())+"/"+m_widget->activeDirectory() ); + m_cwdEdit->fileDialog()->setURL( KURL::fromPathOrURL( m_widget->m_part->buildDirectory()+"/"+URLUtil::getRelativePath(m_widget->m_part->topsourceDirectory(), m_widget->m_part->projectDirectory())+"/"+m_widget->activeDirectory() ) ); + }else + { + m_cwdEdit->setURL( DomUtil::readEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/cwd/" + target->name) ); + m_cwdEdit->fileDialog()->setURL( KURL::fromPathOrURL( DomUtil::readEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/cwd/" + target->name) ) ); + } + debug_arguments_edit->setText(DomUtil::readEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/debugarguments/" + target->name)); + } +} + + +void TargetOptionsDialog::storeConfig() +{ + QStringList flagslist; + if (allstatic_box->isChecked()) + flagslist.append("-all-static"); + if (avoidversion_box->isChecked()) + flagslist.append("-avoid-version"); + if (module_box->isChecked()) + flagslist.append("-module"); + if (noundefined_box->isChecked()) + flagslist.append("-no-undefined"); + flagslist.append(ldflagsother_edit->text()); + QString new_ldflags = flagslist.join(" "); + + QStringList liblist; + QCheckListItem *clitem = static_cast<QCheckListItem*>(insidelib_listview->firstChild()); + while (clitem) { + if( clitem->isOn() ) + liblist.append("$(top_builddir)/" + clitem->text()); + clitem = static_cast<QCheckListItem*>(clitem->nextSibling()); + } + clitem = static_cast<QCheckListItem*>(outsidelib_listview->firstChild()); + while (clitem) { + liblist.append(clitem->text()); + clitem = static_cast<QCheckListItem*>(clitem->nextSibling()); + } + QString new_addstr = liblist.join(" "); + + QString canonname = AutoProjectTool::canonicalize(target->name); + QMap<QString, QString> replaceMap; + + if (target->primary == "PROGRAMS") { + QString old_ldadd = target->ldadd; + if (new_addstr != old_ldadd) { + target->ldadd = new_addstr; + replaceMap.insert(canonname + "_LDADD", new_addstr); + } + } + + if (target->primary == "LIBRARIES" || target->primary == "LTLIBRARIES") { + QString old_libadd = target->libadd; + if (new_addstr != old_libadd) { + target->libadd = new_addstr; + replaceMap.insert(canonname + "_LIBADD", new_addstr); + } + } + + QString old_ldflags = target->ldflags; + if (new_ldflags != old_ldflags) { + target->ldflags = new_ldflags; + replaceMap.insert(canonname + "_LDFLAGS", new_ldflags); + } + + QString new_dependencies = dependencies_edit->text(); + QString old_dependencies = target->dependencies; + if (new_dependencies != old_dependencies) { + target->dependencies = new_dependencies; + if (!new_dependencies.isEmpty()) + replaceMap.insert(canonname + "_DEPENDENCIES", new_dependencies); + } + + // We can safely assume that this target is in the active sub project + AutoProjectTool::setMakefileam(m_widget->subprojectDirectory() + "/Makefile.am", replaceMap); + + if (target->primary == "PROGRAMS") + { + DomUtil::writeEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/runarguments/" + target->name, run_arguments_edit->text()); + DomUtil::writeEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/debugarguments/" + target->name, debug_arguments_edit->text()); + DomUtil::writeEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/cwd/" + target->name, m_cwdEdit->url()); + } +} + + +void TargetOptionsDialog::insideMoveUpClicked() +{ + if (!insidelib_listview->currentItem()) + return; + if (insidelib_listview->currentItem() == insidelib_listview->firstChild()) { + KNotifyClient::beep(); + return; + } + + QListViewItem *item = insidelib_listview->firstChild(); + while (item->nextSibling() != insidelib_listview->currentItem()) + item = item->nextSibling(); + item->moveItem(insidelib_listview->currentItem()); +} + + +void TargetOptionsDialog::insideMoveDownClicked() +{ + if (!insidelib_listview->currentItem()) + return; + + if (insidelib_listview->currentItem()->nextSibling() == 0) { + KNotifyClient::beep(); + return; + } + + insidelib_listview->currentItem()->moveItem(insidelib_listview->currentItem()->nextSibling()); +} + + +void TargetOptionsDialog::outsideMoveUpClicked() +{ + if (!outsidelib_listview->currentItem()) + return; + if (outsidelib_listview->currentItem() == outsidelib_listview->firstChild()) { + KNotifyClient::beep(); + return; + } + + QListViewItem *item = outsidelib_listview->firstChild(); + while (item->nextSibling() != outsidelib_listview->currentItem()) + item = item->nextSibling(); + item->moveItem(outsidelib_listview->currentItem()); +} + + +void TargetOptionsDialog::outsideMoveDownClicked() +{ + if (!outsidelib_listview->currentItem()) + return; + if (outsidelib_listview->currentItem()->nextSibling() == 0) { + KNotifyClient::beep(); + return; + } + + outsidelib_listview->currentItem()->moveItem(outsidelib_listview->currentItem()->nextSibling()); +} + + +void TargetOptionsDialog::outsideAddClicked() +{ + KURLRequesterDlg dialog( "", i18n( "Add Library: Choose the .a/.so file, give -l<libname> or use a variable with $(FOOBAR)" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly ); + dialog.urlRequester() ->setFilter( "*.so|"+i18n("Shared Library (*.so)")+"\n*.a|"+i18n("Static Library (*.a)") ); + dialog.urlRequester() ->setURL( QString::null ); + dialog.urlRequester() ->completionObject() ->setDir( m_widget->selectedSubproject()->path ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL::fromPathOrURL( m_widget->selectedSubproject()->path ) ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString file = dialog.urlRequester() ->url(); + if ( !file.isEmpty() ) + { + if ( !file.isEmpty() ) + { + if( file.startsWith("-l") ) + new QListViewItem( outsidelib_listview, file ); + else + { + QFileInfo fi(file); + if( !fi.exists() ) + new QListViewItem( outsidelib_listview, file ); + if( fi.extension(false) == "a" ) + { + new QListViewItem( outsidelib_listview, file ); + }else if ( fi.extension(false) == "so" ) + { + QString name = fi.fileName(); + if( name.startsWith( "lib" ) ) + name = name.mid(3); + name = "-l"+name.left( name.length() - 3 ); + new QListViewItem( outsidelib_listview, name ); + } + } + } + } +} + + +void TargetOptionsDialog::outsideEditClicked() +{ + if ( (outsidelib_listview->childCount()==0) || (outsidelib_listview->currentItem() == 0) ) + return; + bool ok; + QString dir = KInputDialog::getText(i18n("Edit External Library"), i18n("Edit external library:"), + outsidelib_listview->currentItem()-> text(0), &ok, 0); + if (ok && !dir.isEmpty()) + outsidelib_listview->currentItem()-> setText(0, dir); +} + + +void TargetOptionsDialog::outsideRemoveClicked() +{ + delete outsidelib_listview->currentItem(); +} + + +void TargetOptionsDialog::accept() +{ + storeConfig(); + QDialog::accept(); +} + +#include "targetoptionsdlg.moc" +// kate: indent-mode csands; space-indent on; indent-width 4; replace-tabs on; diff --git a/buildtools/autotools/targetoptionsdlg.h b/buildtools/autotools/targetoptionsdlg.h new file mode 100644 index 00000000..c1dea20a --- /dev/null +++ b/buildtools/autotools/targetoptionsdlg.h @@ -0,0 +1,49 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU General Public License as published by * +* the Free Software Foundation; either version 2 of the License, or * +* (at your option) any later version. * +* * +***************************************************************************/ + +#ifndef _TARGETOPTIONSDLG_ +#define _TARGETOPTIONSDLG_ + +#include "targetoptionsdlgbase.h" + +class AutoProjectWidget; +class TargetItem; + + +class TargetOptionsDialog : public TargetOptionsDialogBase +{ + Q_OBJECT + +public: + TargetOptionsDialog( AutoProjectWidget *widget, TargetItem *item, + QWidget *parent = 0, const char *name = 0 ); + ~TargetOptionsDialog(); + +private: + virtual void insideMoveUpClicked(); + virtual void insideMoveDownClicked(); + virtual void outsideMoveUpClicked(); + virtual void outsideMoveDownClicked(); + virtual void outsideAddClicked(); + virtual void outsideEditClicked(); + virtual void outsideRemoveClicked(); + virtual void accept(); + + void readConfig(); + void storeConfig(); + + TargetItem *target; + AutoProjectWidget *m_widget; +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/targetoptionsdlgbase.ui b/buildtools/autotools/targetoptionsdlgbase.ui new file mode 100644 index 00000000..07487ac2 --- /dev/null +++ b/buildtools/autotools/targetoptionsdlgbase.ui @@ -0,0 +1,726 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>TargetOptionsDialogBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>target_options_dialog</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>627</width> + <height>474</height> + </rect> + </property> + <property name="caption"> + <string>Target Options</string> + </property> + <property name="sizeGripEnabled"> + <bool>false</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QTabWidget"> + <property name="name"> + <cstring>tabWidget</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>Widget5</cstring> + </property> + <attribute name="title"> + <string>Fl&ags</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Li&nker flags (LDFLAGS):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>allstatic_box</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout12</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>allstatic_box</cstring> + </property> + <property name="text"> + <string>&Do not link against shared libraries (-all-static)</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>avoidversion_box</cstring> + </property> + <property name="text"> + <string>Do not &assign version numbers to libraries (-avoid-version)</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>module_box</cstring> + </property> + <property name="text"> + <string>Create a library that can &be dynamically loaded (-module)</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>noundefined_box</cstring> + </property> + <property name="text"> + <string>Library does not depend on external symbols (-no-&undefined)</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout11</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>ldflagsother_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>O&ther:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>ldflagsother_edit</cstring> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>ldflagsother_edit</cstring> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <spacer row="2" column="2"> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Preferred</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="1" column="0"> + <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>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KLineEdit" row="4" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>dependencies_edit</cstring> + </property> + </widget> + <widget class="QLabel" row="3" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>dependencies_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>E&xplicit dependencies (DEPENDENCIES):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>dependencies_edit</cstring> + </property> + </widget> + <spacer row="4" 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>20</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="5" column="2"> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>Widget6</cstring> + </property> + <attribute name="title"> + <string>Li&braries</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>insidelib_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Lin&k convenience libraries inside project (LIBADD):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>insidelib_listview</cstring> + </property> + </widget> + <spacer row="2" column="0"> + <property name="name"> + <cstring>Spacer9</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>7</height> + </size> + </property> + </spacer> + <widget class="QListView" row="4" column="0"> + <column> + <property name="text"> + <string></string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>outsidelib_listview</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>outsidelib_label</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>Link libraries ou&tside project (LIBADD):</string> + </property> + <property name="buddy" stdset="0"> + <cstring>outsidelib_listview</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="1"> + <property name="name"> + <cstring>Layout9_3</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer5</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>insidemoveup_button</cstring> + </property> + <property name="text"> + <string>Move &Up</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>insidemovedown_button</cstring> + </property> + <property name="text"> + <string>Move &Down</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer6</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QListView" row="1" column="0"> + <column> + <property name="text"> + <string></string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>insidelib_listview</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QLayoutWidget" row="4" column="1"> + <property name="name"> + <cstring>Layout10_4</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer7</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>outsideadd_button</cstring> + </property> + <property name="text"> + <string>&Add...</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>outsideedit_button</cstring> + </property> + <property name="text"> + <string>&Edit...</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>outsideremove_button</cstring> + </property> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>outsidemoveup_button</cstring> + </property> + <property name="text"> + <string>Mo&ve Up</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>outsidemovedown_button</cstring> + </property> + <property name="text"> + <string>Move Dow&n</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer8</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>arguments_page</cstring> + </property> + <attribute name="title"> + <string>Ar&guments</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox" row="0" column="0"> + <property name="name"> + <cstring>argumentBox</cstring> + </property> + <property name="title"> + <string>Program Arguments (only valid for executable targets)</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>run_arguments_edit</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>arguments_label_1</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&Run arguments:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>run_arguments_edit</cstring> + </property> + </widget> + <widget class="KURLRequester" row="3" column="1"> + <property name="name"> + <cstring>m_cwdEdit</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0" rowspan="2" colspan="1"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Working Directory:</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>arguments_label_2</cstring> + </property> + <property name="font"> + <font> + </font> + </property> + <property name="text"> + <string>&Debug arguments:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>run_arguments_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="1" column="1" rowspan="2" colspan="1"> + <property name="name"> + <cstring>debug_arguments_edit</cstring> + </property> + </widget> + </grid> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>Spacer4_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>120</height> + </size> + </property> + </spacer> + </grid> + </widget> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer10</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>okbutton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelbutton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>okbutton</sender> + <signal>clicked()</signal> + <receiver>target_options_dialog</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>cancelbutton</sender> + <signal>clicked()</signal> + <receiver>target_options_dialog</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>insidemoveup_button</sender> + <signal>clicked()</signal> + <receiver>target_options_dialog</receiver> + <slot>insideMoveUpClicked()</slot> + </connection> + <connection> + <sender>outsidemoveup_button</sender> + <signal>clicked()</signal> + <receiver>target_options_dialog</receiver> + <slot>outsideMoveUpClicked()</slot> + </connection> + <connection> + <sender>outsidemovedown_button</sender> + <signal>clicked()</signal> + <receiver>target_options_dialog</receiver> + <slot>outsideMoveDownClicked()</slot> + </connection> + <connection> + <sender>outsideadd_button</sender> + <signal>clicked()</signal> + <receiver>target_options_dialog</receiver> + <slot>outsideAddClicked()</slot> + </connection> + <connection> + <sender>outsideedit_button</sender> + <signal>clicked()</signal> + <receiver>target_options_dialog</receiver> + <slot>outsideEditClicked()</slot> + </connection> + <connection> + <sender>outsideremove_button</sender> + <signal>clicked()</signal> + <receiver>target_options_dialog</receiver> + <slot>outsideRemoveClicked()</slot> + </connection> + <connection> + <sender>insidemovedown_button</sender> + <signal>clicked()</signal> + <receiver>target_options_dialog</receiver> + <slot>insideMoveDownClicked()</slot> + </connection> +</connections> +<tabstops> + <tabstop>allstatic_box</tabstop> + <tabstop>avoidversion_box</tabstop> + <tabstop>module_box</tabstop> + <tabstop>noundefined_box</tabstop> + <tabstop>ldflagsother_edit</tabstop> + <tabstop>dependencies_edit</tabstop> + <tabstop>tabWidget</tabstop> + <tabstop>insidelib_listview</tabstop> + <tabstop>insidemoveup_button</tabstop> + <tabstop>insidemovedown_button</tabstop> + <tabstop>outsidelib_listview</tabstop> + <tabstop>outsideadd_button</tabstop> + <tabstop>outsideedit_button</tabstop> + <tabstop>outsideremove_button</tabstop> + <tabstop>outsidemoveup_button</tabstop> + <tabstop>outsidemovedown_button</tabstop> + <tabstop>okbutton</tabstop> + <tabstop>cancelbutton</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<slots> + <slot access="protected">insideMoveDownClicked()</slot> + <slot access="protected">insideMoveUpClicked()</slot> + <slot access="protected">outsideAddClicked()</slot> + <slot access="protected">outsideEditClicked()</slot> + <slot access="protected">outsideMoveDownClicked()</slot> + <slot access="protected">outsideMoveUpClicked()</slot> + <slot access="protected">outsideRemoveClicked()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/buildtools/custommakefiles/Makefile.am b/buildtools/custommakefiles/Makefile.am new file mode 100644 index 00000000..fab92b8b --- /dev/null +++ b/buildtools/custommakefiles/Makefile.am @@ -0,0 +1,26 @@ +# Here resides the custom project part. + +INCLUDES = -I$(top_srcdir)/buildtools/lib/base \ + -I$(top_srcdir)/buildtools/lib/widgets -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/util $(all_includes) \ + -I$(top_builddir)/buildtools/lib/widgets + +kde_module_LTLIBRARIES = libkdevcustomproject.la +libkdevcustomproject_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevcustomproject_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/buildtools/lib/widgets/libkdevbuildtoolswidgets.la $(top_builddir)/buildtools/lib/base/libkdevbuildbase.la + +libkdevcustomproject_la_SOURCES = selectnewfilesdialog.cpp selectnewfilesdialogbase.ui \ + custombuildoptionswidget.cpp custombuildoptionswidgetbase.ui custommakeconfigwidget.cpp \ + custommakeconfigwidgetbase.ui custommanagerwidget.cpp custommanagerwidgetbase.ui \ + customotherconfigwidget.cpp customotherconfigwidgetbase.ui customprojectpart.cpp + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevcustomproject.desktop + +rcdir = $(kde_datadir)/kdevcustomproject +rc_DATA = kdevcustomproject.rc +noinst_HEADERS = selectnewfilesdialog.h custommanagerwidget.h \ + customotherconfigwidget.h diff --git a/buildtools/custommakefiles/README.dox b/buildtools/custommakefiles/README.dox new file mode 100644 index 00000000..28762d87 --- /dev/null +++ b/buildtools/custommakefiles/README.dox @@ -0,0 +1,47 @@ +/** \class CustomProjectPart +This is the custom build tools part. +Put a more detailed description of your part in these lines. It can span +over several lines. You can even use some html commands in these lines like: +<code>This is code</code>, html links <a href="http://somelocation">link text</a>, +and images. + +\authors <a href="mailto:bernd AT kdevelop.org">Bernd Gehrmann</a> + +\unmaintained This part is currently un-maintained + +\feature Describe the first feature +\feature Describe the second feature +... +\feature Describe the last feature + +\bug bugs in <a href="http://bugs.kde.org/buglist.cgi?product=kdevelop&component=customproject&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&order=Bug+Number">customproject component at Bugzilla database</a> +\bug Describe a the 1st bug that you know of, but probably hasn't been reported yet. +.. +\bug Describe a the nth bug that you know of, but probably hasn't been reported yet. + +\requirement Describe a the 1st requirement of your part. +\requirement Describe a the 2nd requirement of your part. +... +\requirement Describe a the nth requirement of your part. + +\todo Describe a the 1st TODO of your part. +\todo Describe a the 2nd TODO of your part. +... +\todo Describe a the nth TODO of your part. + +\faq <b>First frequenly asked question about your part ?</b> Answer. +\faq <b>Second frequenly asked question about your part ?</b> Answer. +... +\faq <b>Last frequenly asked question about your part ?</b> Answer. + +\note First note text. +\note Second note text. +... +\note Last note text. + +\warning First warning text. +\warning Second warning text. +... +\warning Last warning text. + +*/ diff --git a/buildtools/custommakefiles/custombuildoptionswidget.cpp b/buildtools/custommakefiles/custombuildoptionswidget.cpp new file mode 100644 index 00000000..37b087b2 --- /dev/null +++ b/buildtools/custommakefiles/custombuildoptionswidget.cpp @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (C) 2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "custombuildoptionswidget.h" + +#include <qcheckbox.h> +#include <klineedit.h> +#include <kurlrequester.h> +#include <kurlcompletion.h> +#include <kfiledialog.h> +#include <qradiobutton.h> +#include <qtabwidget.h> +#include "domutil.h" + + +CustomBuildOptionsWidget::CustomBuildOptionsWidget(QDomDocument &dom, + QWidget *parent, const char *name) + : CustomBuildOptionsWidgetBase(parent, name), + m_dom(dom) +{ + ant_button->setChecked(DomUtil::readEntry(dom, "/kdevcustomproject/build/buildtool") == "ant"); + other_button->setChecked(DomUtil::readEntry(dom, "/kdevcustomproject/build/buildtool") == "other"); + if( !DomUtil::readEntry(dom, "/kdevcustomproject/build/builddir").isEmpty() + && QFileInfo( DomUtil::readEntry(dom, "/kdevcustomproject/build/builddir") ).exists() ) + { + builddir_edit->setURL(DomUtil::readEntry(dom, "/kdevcustomproject/build/builddir")); + builddir_edit->fileDialog()->setURL( DomUtil::readEntry(dom, "/kdevcustomproject/build/builddir") ); + } + else + { + builddir_edit->setURL( QString() ); + builddir_edit->fileDialog()->setURL( QString() ); + } + builddir_edit->completionObject()->setMode(KURLCompletion::DirCompletion); + builddir_edit->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + + // This connection must not be made before the ant->setChecked() line, + // because at this time makeToggled() would crash + connect( make_button, SIGNAL(toggled(bool)), + this, SLOT(makeToggled(bool)) ); + connect( other_button, SIGNAL(toggled(bool)), + this, SLOT(otherToggled(bool)) ); +} + + +CustomBuildOptionsWidget::~CustomBuildOptionsWidget() +{} + + +void CustomBuildOptionsWidget::accept() +{ + QString buildtool; + if (ant_button->isChecked()) + { + buildtool = "ant"; + } + else if (other_button->isChecked()) + { + buildtool = "other"; + } + else + { + buildtool = "make"; + } + DomUtil::writeEntry(m_dom, "/kdevcustomproject/build/buildtool", buildtool); + DomUtil::writeEntry(m_dom, "/kdevcustomproject/build/builddir", builddir_edit->url()); +} + + +void CustomBuildOptionsWidget::setMakeOptionsWidget(QTabWidget *tw, QWidget *mow, QWidget* oow) +{ + m_tabWidget = tw; + m_makeOptions = mow; + m_otherOptions = oow; + makeToggled(make_button->isChecked()); + otherToggled(other_button->isChecked()); +} + +void CustomBuildOptionsWidget::otherToggled(bool b) +{ + m_tabWidget->setTabEnabled(m_otherOptions, b); +} + +void CustomBuildOptionsWidget::makeToggled(bool b) +{ + m_tabWidget->setTabEnabled(m_makeOptions, b); +} + +#include "custombuildoptionswidget.moc" + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/custommakefiles/custombuildoptionswidget.h b/buildtools/custommakefiles/custombuildoptionswidget.h new file mode 100644 index 00000000..1b049574 --- /dev/null +++ b/buildtools/custommakefiles/custombuildoptionswidget.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef _CUSTOMBUILDOPTIONSWIDGET_H_ +#define _CUSTOMBUILDOPTIONSWIDGET_H_ + +#include "custombuildoptionswidgetbase.h" +#include <qdom.h> + +class QTabWidget; + + +class CustomBuildOptionsWidget : public CustomBuildOptionsWidgetBase +{ + Q_OBJECT + +public: + CustomBuildOptionsWidget( QDomDocument &dom, QWidget *parent=0, const char *name=0 ); + ~CustomBuildOptionsWidget(); + + void setMakeOptionsWidget(QTabWidget *tw, QWidget *mow, QWidget *oow); + +public slots: + void accept(); + +private: + virtual void makeToggled(bool b); + virtual void otherToggled(bool b); + + QDomDocument &m_dom; + QTabWidget *m_tabWidget; + QWidget *m_makeOptions; + QWidget *m_otherOptions; +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/custommakefiles/custombuildoptionswidgetbase.ui b/buildtools/custommakefiles/custombuildoptionswidgetbase.ui new file mode 100644 index 00000000..59ca9ba2 --- /dev/null +++ b/buildtools/custommakefiles/custombuildoptionswidgetbase.ui @@ -0,0 +1,164 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>CustomBuildOptionsWidgetBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>configure_options_widget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>592</width> + <height>480</height> + </rect> + </property> + <property name="caption"> + <string>Custom Build Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>buildtool_group</cstring> + </property> + <property name="title"> + <string>Build Tool</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>make_button</cstring> + </property> + <property name="text"> + <string>&Make</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>ant_button</cstring> + </property> + <property name="text"> + <string>A&nt</string> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>other_button</cstring> + </property> + <property name="text"> + <string>Other</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="toolTip" stdset="0"> + <string>other custom build tool, e.g. script</string> + </property> + <property name="whatsThis" stdset="0"> + <string>There are myriads of buildtools out there that are not ant or make. If you use one of them (or have your own scripts), select this option.</string> + </property> + </widget> + </vbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer19</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Minimum</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <property name="name"> + <cstring>builddir_label</cstring> + </property> + <property name="text"> + <string>Run &the build tool in the following directory:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>builddir_edit</cstring> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>Spacer38</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="KURLRequester"> + <property name="name"> + <cstring>builddir_edit</cstring> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer39</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<slots> + <slot access="protected">makeToggled(bool)</slot> + <slot access="protected">otherToggled(bool)</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/buildtools/custommakefiles/custommakeconfigwidget.cpp b/buildtools/custommakefiles/custommakeconfigwidget.cpp new file mode 100644 index 00000000..2af0d137 --- /dev/null +++ b/buildtools/custommakefiles/custommakeconfigwidget.cpp @@ -0,0 +1,134 @@ +/*************************************************************************** + * Copyright (C) 2003 by Hendrik Kueck * + * kueck@cs.ubc.ca * + * * + * 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 "custommakeconfigwidget.h" +#include <custombuildoptionswidgetbase.h> +#include <customprojectpart.h> +#include <qcombobox.h> +#include <qdir.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qlabel.h> +#include <qpushbutton.h> +#include <qcheckbox.h> +#include <qspinbox.h> +#include <qlistview.h> +#include <qgroupbox.h> +#include <qvalidator.h> +#include <klineedit.h> +#include <kdebug.h> +#include <klocale.h> + +#include <environmentvariableswidget.h> + +CustomMakeConfigWidget::CustomMakeConfigWidget(CustomProjectPart* part, const QString& configGroup, QWidget* parent) + : CustomMakeConfigWidgetBase(parent), + m_part(part), m_configGroup(configGroup), m_dom( *part->projectDom() ) +{ + abort_box->setChecked(DomUtil::readBoolEntry(m_dom, m_configGroup + "/make/abortonerror")); + int numjobs = DomUtil::readIntEntry(m_dom, m_configGroup + "/make/numberofjobs"); + jobs_box->setValue(numjobs); + runMultiJobs->setChecked( (numjobs > 0 ) ); + + prio_box->setValue(DomUtil::readIntEntry(m_dom, m_configGroup + "/make/prio")); + dontact_box->setChecked(DomUtil::readBoolEntry(m_dom, m_configGroup + "/make/dontact")); + makebin_edit->setText(DomUtil::readEntry(m_dom, m_configGroup + "/make/makebin")); + defaultTarget_edit->setText(DomUtil::readEntry(m_dom, m_configGroup + "/make/defaulttarget")); + makeoptions_edit->setText(DomUtil::readEntry(m_dom, m_configGroup + "/make/makeoptions")); + + envs_combo->setValidator(new QRegExpValidator(QRegExp("^\\D[^\\s]*"), this)); + m_allEnvironments = m_part->allMakeEnvironments(); + m_currentEnvironment = m_part->currentMakeEnvironment(); + env_var_group->setColumnLayout( 1, Qt::Vertical ); + m_envWidget = new EnvironmentVariablesWidget(m_dom, m_configGroup + "/make/environments/" + m_currentEnvironment, env_var_group); + envs_combo->insertStringList(m_allEnvironments); + envs_combo->setEditText(m_currentEnvironment); +} + + +CustomMakeConfigWidget::~CustomMakeConfigWidget() +{ + +} + +void CustomMakeConfigWidget::envNameChanged(const QString& envName) +{ + QStringList allEnvNames = m_part->allMakeEnvironments(); + bool canAdd = !allEnvNames.contains(envName) && !envName.contains("/") && !envName.isEmpty(); + bool canRemove = allEnvNames.contains(envName) && allEnvNames.count() > 1; + addenvs_button->setEnabled(canAdd); + copyenvs_button->setEnabled(canAdd); + removeenvs_button->setEnabled(canRemove); +} + +void CustomMakeConfigWidget::envChanged(const QString& envName) +{ + if (envName == m_currentEnvironment || !m_allEnvironments.contains(envName)) + return; + + // save settings of previously active environment + if (!m_currentEnvironment.isNull() ) + m_envWidget->accept(); + + m_currentEnvironment = envName; + m_envWidget->readEnvironment(m_dom, m_configGroup + "/make/environments/" + envName); + envs_combo->setEditText(envName); +} + +void CustomMakeConfigWidget::envAdded() +{ + QString env = envs_combo->currentText(); + m_allEnvironments.append(env); + + envs_combo->clear(); + envs_combo->insertStringList(m_allEnvironments); + envChanged(env); +} + +void CustomMakeConfigWidget::envRemoved() +{ + QString env = envs_combo->currentText(); + QDomNode node = DomUtil::elementByPath(m_dom, m_configGroup + "/make/environments"); + node.removeChild(node.namedItem(env)); + m_allEnvironments.remove(env); + envs_combo->clear(); + envs_combo->insertStringList(m_allEnvironments); + m_currentEnvironment = QString::null; + envChanged( m_allEnvironments[0] ); +} + +void CustomMakeConfigWidget::envCopied() +{ + QString env = envs_combo->currentText(); + m_allEnvironments.append(env); + envs_combo->clear(); + envs_combo->insertStringList(m_allEnvironments); + m_currentEnvironment = env; + m_envWidget->changeConfigGroup(m_configGroup + "/make/environments/" + env); + envs_combo->setEditText(env); +} + +void CustomMakeConfigWidget::accept() +{ + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/make/abortonerror", abort_box->isChecked()); + if( runMultiJobs->isChecked() ) + DomUtil::writeIntEntry(m_dom, m_configGroup + "/make/numberofjobs", jobs_box->value()); + else + DomUtil::writeIntEntry(m_dom, m_configGroup + "/make/numberofjobs", 0); + DomUtil::writeIntEntry(m_dom, m_configGroup + "/make/prio", prio_box->value()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/make/dontact", dontact_box->isChecked()); + DomUtil::writeEntry(m_dom, m_configGroup + "/make/makebin", makebin_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/make/defaulttarget", defaultTarget_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/make/makeoptions", makeoptions_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/make/selectedenvironment", m_currentEnvironment); + m_envWidget->accept(); +} + +#include "custommakeconfigwidget.moc" diff --git a/buildtools/custommakefiles/custommakeconfigwidget.h b/buildtools/custommakefiles/custommakeconfigwidget.h new file mode 100644 index 00000000..ae8376c1 --- /dev/null +++ b/buildtools/custommakefiles/custommakeconfigwidget.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2003 by Hendrik Kueck * + * kueck@cs.ubc.ca * + * * + * 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 CUSTOMMAKECONFIGWIDGET_H +#define CUSTOMMAKECONFIGWIDGET_H + +#include "domutil.h" + +#include <custommakeconfigwidgetbase.h> + +class CustomProjectPart; +class EnvironmentVariablesWidget; + +/** +@author KDevelop Authors +*/ +class CustomMakeConfigWidget : public CustomMakeConfigWidgetBase +{ + Q_OBJECT + +public: + CustomMakeConfigWidget(CustomProjectPart* part, const QString& configGroup, QWidget* parent); + + ~CustomMakeConfigWidget(); + +public slots: + void accept(); + +protected: + CustomProjectPart* m_part; + QString m_configGroup; + QDomDocument& m_dom; + + QStringList m_allEnvironments; + QString m_currentEnvironment; + + EnvironmentVariablesWidget* m_envWidget; + + virtual void envNameChanged(const QString& envName); + virtual void envChanged(const QString& envName); + virtual void envAdded(); + virtual void envRemoved(); + virtual void envCopied(); + +}; + +#endif diff --git a/buildtools/custommakefiles/custommakeconfigwidgetbase.ui b/buildtools/custommakefiles/custommakeconfigwidgetbase.ui new file mode 100644 index 00000000..b864a18f --- /dev/null +++ b/buildtools/custommakefiles/custommakeconfigwidgetbase.ui @@ -0,0 +1,395 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>CustomMakeConfigWidgetBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>CustomMakeConfigWidgetBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>659</width> + <height>600</height> + </rect> + </property> + <property name="caption"> + <string>Make Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>abort_box</cstring> + </property> + <property name="text"> + <string>A&bort on first error</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>dontact_box</cstring> + </property> + <property name="text"> + <string>Only di&splay commands without actually executing them</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>defaultTarget_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="1" column="1"> + <property name="name"> + <cstring>makebin_edit</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>makeoptions_label</cstring> + </property> + <property name="text"> + <string>A&dditional make options:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>makeoptions_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>makeoptions_edit</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>makebin_label</cstring> + </property> + <property name="text"> + <string>Name of make e&xecutable:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>makebin_edit</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>defTarget_label</cstring> + </property> + <property name="text"> + <string>Default make &target:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>defaultTarget_edit</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout6</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>runMultiJobs</cstring> + </property> + <property name="text"> + <string>Run multiple jobs</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>jobs_label</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Number of simultaneous &jobs:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>jobs_box</cstring> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>jobs_box</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxValue"> + <number>30</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + </widget> + <spacer> + <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>200</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout5</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>prio_label</cstring> + </property> + <property name="text"> + <string>Make &priority:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>jobs_box</cstring> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>prio_box</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxValue"> + <number>19</number> + </property> + <property name="minValue"> + <number>-20</number> + </property> + <property name="value"> + <number>0</number> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>192</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>envs_label</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>E&nvironment:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>envs_combo</cstring> + </property> + </widget> + <widget class="QComboBox"> + <property name="name"> + <cstring>envs_combo</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>addenvs_button</cstring> + </property> + <property name="text"> + <string>&Add</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>copyenvs_button</cstring> + </property> + <property name="text"> + <string>Co&py</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>removeenvs_button</cstring> + </property> + <property name="text"> + <string>Re&move</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>env_var_group</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Environment &Variables</string> + </property> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>envs_combo</sender> + <signal>textChanged(const QString&)</signal> + <receiver>CustomMakeConfigWidgetBase</receiver> + <slot>envNameChanged(const QString&)</slot> + </connection> + <connection> + <sender>envs_combo</sender> + <signal>activated(const QString&)</signal> + <receiver>CustomMakeConfigWidgetBase</receiver> + <slot>envChanged(const QString&)</slot> + </connection> + <connection> + <sender>copyenvs_button</sender> + <signal>clicked()</signal> + <receiver>CustomMakeConfigWidgetBase</receiver> + <slot>envCopied()</slot> + </connection> + <connection> + <sender>addenvs_button</sender> + <signal>clicked()</signal> + <receiver>CustomMakeConfigWidgetBase</receiver> + <slot>envAdded()</slot> + </connection> + <connection> + <sender>removeenvs_button</sender> + <signal>clicked()</signal> + <receiver>CustomMakeConfigWidgetBase</receiver> + <slot>envRemoved()</slot> + </connection> + <connection> + <sender>runMultiJobs</sender> + <signal>toggled(bool)</signal> + <receiver>jobs_label</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>runMultiJobs</sender> + <signal>toggled(bool)</signal> + <receiver>jobs_box</receiver> + <slot>setEnabled(bool)</slot> + </connection> +</connections> +<tabstops> + <tabstop>abort_box</tabstop> + <tabstop>dontact_box</tabstop> + <tabstop>makebin_edit</tabstop> + <tabstop>makeoptions_edit</tabstop> + <tabstop>jobs_box</tabstop> + <tabstop>envs_combo</tabstop> + <tabstop>addenvs_button</tabstop> + <tabstop>copyenvs_button</tabstop> + <tabstop>removeenvs_button</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<slots> + <slot access="protected">envNameChanged(const QString &)</slot> + <slot access="protected">envChanged(const QString&)</slot> + <slot access="protected">envAdded()</slot> + <slot access="protected">envRemoved()</slot> + <slot access="protected">envCopied()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/buildtools/custommakefiles/custommanagerwidget.cpp b/buildtools/custommakefiles/custommanagerwidget.cpp new file mode 100644 index 00000000..9001480e --- /dev/null +++ b/buildtools/custommakefiles/custommanagerwidget.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2007 by Andreas Pakulat * + * apaku@gmx.de * + * * + * 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 "custommanagerwidget.h" + +#include <qstringlist.h> +#include <qlayout.h> +#include <qlistbox.h> +#include <qwhatsthis.h> +#include <qtooltip.h> + +#include <ktextedit.h> +#include <kurlrequester.h> +#include <kurlcompletion.h> +#include <kfiledialog.h> +#include <keditlistbox.h> +#include <klocale.h> +#include <kdebug.h> + +#include "customprojectpart.h" +#include "domutil.h" + +CustomManagerWidget::CustomManagerWidget( CustomProjectPart* part, QWidget* parent ) + : CustomManagerWidgetBase( parent ), m_part( part), m_dom( *part->projectDom() ) +{ + m_filetypes->insertStringList( DomUtil::readListEntry( m_dom, "kdevcustomproject/filetypes", "filetype" ) ); + KURLRequester* urlselector = new KURLRequester( ); + urlselector->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly ); + urlselector->setURL( QString::null ); + urlselector->completionObject() ->setDir( part->projectDirectory() ); + urlselector->fileDialog() ->setURL( KURL( part->projectDirectory() ) ); + m_blacklistBox = new KEditListBox( i18n("blacklisted files and directories are not" + " considered part of the project, even if they fit one of " + "the wildcard patterns in the project file list", + "Blacklisted files/dirs"), urlselector->customEditor(), this); + m_blacklistBox->setButtons( KEditListBox::Add | KEditListBox::Remove ); + m_blacklistBox->insertStringList( DomUtil::readListEntry( m_dom, "kdevcustomproject/blacklist","path") ); + grid->addWidget( m_blacklistBox, 0, 1 ); + connect(m_blacklistBox, SIGNAL(added(const QString&)), this, SLOT(checkUrl(const QString&))); +} + +void CustomManagerWidget::checkUrl(const QString& url) +{ + kdDebug(9025) << "got file:" << url << endl; + if( !QFileInfo(url).isRelative() ) + { + kdDebug(9025) << "seems to be non-relative" << endl; + QString relpath = m_part->relativeToProject( url ); + QListBoxItem* item = m_blacklistBox->listBox()->findItem( url ); + m_blacklistBox->listBox()->takeItem( item ); + kdDebug(9025) << "relative path:" << relpath << endl; + if( !relpath.isEmpty() ) + m_blacklistBox->insertItem( relpath ); + } +} + +CustomManagerWidget::~CustomManagerWidget() +{ +} + +void CustomManagerWidget::accept() +{ + DomUtil::writeListEntry( m_dom, "kdevcustomproject/filetypes", "filetype", + m_filetypes->items() ); + DomUtil::writeListEntry( m_dom, "kdevcustomproject/blacklist", "path", + m_blacklistBox->items() ); +} + + +#include "custommanagerwidget.moc" + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/custommakefiles/custommanagerwidget.h b/buildtools/custommakefiles/custommanagerwidget.h new file mode 100644 index 00000000..4f15f156 --- /dev/null +++ b/buildtools/custommakefiles/custommanagerwidget.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2007 by Andreas Pakulat * + * apaku@gmx.de * + * * + * 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 CUSTOMMANAGERWIDGET_H +#define CUSTOMMANAGERWIDGET_H + +#include "custommanagerwidgetbase.h" + + +#include <qdom.h> + +class CustomProjectPart; +class KEditListBox; + +class CustomManagerWidget : public CustomManagerWidgetBase +{ +Q_OBJECT + +public: + CustomManagerWidget( CustomProjectPart* part, QWidget* parent ); + ~CustomManagerWidget(); +public slots: + void checkUrl(const QString& url); + void accept(); +private: + CustomProjectPart* m_part; + QDomDocument& m_dom; + KEditListBox* m_blacklistBox; +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/custommakefiles/custommanagerwidgetbase.ui b/buildtools/custommakefiles/custommanagerwidgetbase.ui new file mode 100644 index 00000000..a388b288 --- /dev/null +++ b/buildtools/custommakefiles/custommanagerwidgetbase.ui @@ -0,0 +1,74 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>CustomManagerWidgetBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>CustomManagerWidgetBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>467</width> + <height>393</height> + </rect> + </property> + <property name="caption"> + <string>Custom Manager Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>grid</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KEditListBox" row="0" column="0"> + <property name="name"> + <cstring>m_filetypes</cstring> + </property> + <property name="title"> + <string>Filetypes used in Project</string> + </property> + <property name="buttons"> + <set>Remove|Add</set> + </property> + <property name="toolTip" stdset="0"> + <string>Add filetypes to be used in Projects, can be full filenames or shell wildcards</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Each entry contains a filetype used in the project in the form of a filename or a filename wildcard (using shell wildcards). +This will be used when adding/removing files in directories and re-populating the project</string> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>108</height> + </size> + </property> + </spacer> + </grid> + </widget> + </vbox> +</widget> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>keditlistbox.h</includehint> + <includehint>klineedit.h</includehint> +</includehints> +</UI> diff --git a/buildtools/custommakefiles/customotherconfigwidget.cpp b/buildtools/custommakefiles/customotherconfigwidget.cpp new file mode 100644 index 00000000..47fe4b4d --- /dev/null +++ b/buildtools/custommakefiles/customotherconfigwidget.cpp @@ -0,0 +1,125 @@ +/*************************************************************************** + * Copyright (C) 2005 by Achim Herwig * + * achim.herwig@wodca.de * + * * + * 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 "customotherconfigwidget.h" +#include <custombuildoptionswidgetbase.h> +#include <customprojectpart.h> +#include <qcombobox.h> +#include <qdir.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qlabel.h> +#include <qlineedit.h> +#include <qpushbutton.h> +#include <qcheckbox.h> +#include <qlineedit.h> +#include <qspinbox.h> +#include <qlistview.h> +#include <qgroupbox.h> +#include <qvalidator.h> +#include <kdebug.h> +#include <klocale.h> + +#include <environmentvariableswidget.h> + +CustomOtherConfigWidget::CustomOtherConfigWidget(CustomProjectPart* part, const QString& configGroup, QWidget* parent) + : CustomOtherConfigWidgetBase(parent), + m_part(part), m_configGroup(configGroup), m_dom( *part->projectDom() ) +{ + prio_box->setValue(DomUtil::readIntEntry(m_dom, m_configGroup + "/other/prio")); + makebin_edit->setText(DomUtil::readEntry(m_dom, m_configGroup + "/other/otherbin")); + defaultTarget_edit->setText(DomUtil::readEntry(m_dom, m_configGroup + "/other/defaulttarget")); + makeoptions_edit->setText(DomUtil::readEntry(m_dom, m_configGroup + "/other/otheroptions")); + + envs_combo->setValidator(new QRegExpValidator(QRegExp("^\\D.*"), this)); + m_allEnvironments = m_part->allMakeEnvironments(); + m_currentEnvironment = m_part->currentMakeEnvironment(); + env_var_group->setColumnLayout( 1, Qt::Vertical ); + m_envWidget = new EnvironmentVariablesWidget(m_dom, m_configGroup + "/other/environments/" + m_currentEnvironment, env_var_group); + envs_combo->insertStringList(m_allEnvironments); + envs_combo->setEditText(m_currentEnvironment); +} + + +CustomOtherConfigWidget::~CustomOtherConfigWidget() +{ + +} + +void CustomOtherConfigWidget::envNameChanged(const QString& envName) +{ + QStringList allEnvNames = m_part->allMakeEnvironments(); + bool canAdd = !allEnvNames.contains(envName) && !envName.contains("/") && !envName.isEmpty(); + bool canRemove = allEnvNames.contains(envName) && allEnvNames.count() > 1; + addenvs_button->setEnabled(canAdd); + copyenvs_button->setEnabled(canAdd); + removeenvs_button->setEnabled(canRemove); +} + +void CustomOtherConfigWidget::envChanged(const QString& envName) +{ + if (envName == m_currentEnvironment || !m_allEnvironments.contains(envName)) + return; + + // save settings of previously active environment + if (!m_currentEnvironment.isNull() ) + m_envWidget->accept(); + + m_currentEnvironment = envName; + m_envWidget->readEnvironment(m_dom, m_configGroup + "/other/environments/" + envName); + envs_combo->setEditText(envName); +} + +void CustomOtherConfigWidget::envAdded() +{ + QString env = envs_combo->currentText(); + m_allEnvironments.append(env); + + envs_combo->clear(); + envs_combo->insertStringList(m_allEnvironments); + envChanged(env); +} + +void CustomOtherConfigWidget::envRemoved() +{ + QString env = envs_combo->currentText(); + QDomNode node = DomUtil::elementByPath(m_dom, m_configGroup + "/other/environments"); + node.removeChild(node.namedItem(env)); + m_allEnvironments.remove(env); + envs_combo->clear(); + envs_combo->insertStringList(m_allEnvironments); + m_currentEnvironment = QString::null; + envChanged( m_allEnvironments[0] ); +} + +void CustomOtherConfigWidget::envCopied() +{ + QString env = envs_combo->currentText(); + m_allEnvironments.append(env); + envs_combo->clear(); + envs_combo->insertStringList(m_allEnvironments); + m_currentEnvironment = env; + m_envWidget->changeConfigGroup(m_configGroup + "/other/environments/" + env); + envs_combo->setEditText(env); +} + +void CustomOtherConfigWidget::accept() +{ + DomUtil::writeIntEntry(m_dom, m_configGroup + "/other/prio", prio_box->value()); + DomUtil::writeEntry(m_dom, m_configGroup + "/other/otherbin", makebin_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/other/defaulttarget", defaultTarget_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/other/otheroptions", makeoptions_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/other/selectedenvironment", m_currentEnvironment); + m_envWidget->accept(); +} + +#include "customotherconfigwidget.moc" +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + diff --git a/buildtools/custommakefiles/customotherconfigwidget.h b/buildtools/custommakefiles/customotherconfigwidget.h new file mode 100644 index 00000000..755df98b --- /dev/null +++ b/buildtools/custommakefiles/customotherconfigwidget.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2005 by Achim Herwig * + * achim.herwig@wodca.de * + * * + * 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 CUSTOMOTHERCONFIGWIDGET_H +#define CUSTOMOTHERCONFIGWIDGET_H + +#include "domutil.h" + +#include <customotherconfigwidgetbase.h> + +class CustomProjectPart; +class EnvironmentVariablesWidget; + +/** +@author KDevelop Authors +*/ +class CustomOtherConfigWidget : public CustomOtherConfigWidgetBase +{ + Q_OBJECT + +public: + CustomOtherConfigWidget(CustomProjectPart* part, const QString& configGroup, QWidget* parent); + + ~CustomOtherConfigWidget(); + +public slots: + void accept(); + +protected: + CustomProjectPart* m_part; + QString m_configGroup; + QDomDocument& m_dom; + + QStringList m_allEnvironments; + QString m_currentEnvironment; + + EnvironmentVariablesWidget* m_envWidget; + + virtual void envNameChanged(const QString& envName); + virtual void envChanged(const QString& envName); + virtual void envAdded(); + virtual void envRemoved(); + virtual void envCopied(); + +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + diff --git a/buildtools/custommakefiles/customotherconfigwidgetbase.ui b/buildtools/custommakefiles/customotherconfigwidgetbase.ui new file mode 100644 index 00000000..174391ae --- /dev/null +++ b/buildtools/custommakefiles/customotherconfigwidgetbase.ui @@ -0,0 +1,288 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>CustomOtherConfigWidgetBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>CustomOtherConfigWidgetBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>659</width> + <height>600</height> + </rect> + </property> + <property name="caption"> + <string>Make Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>defaultTarget_edit</cstring> + </property> + </widget> + <widget class="QLineEdit" row="1" column="1"> + <property name="name"> + <cstring>makebin_edit</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>makeoptions_label</cstring> + </property> + <property name="text"> + <string>Add&itional options:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>makeoptions_edit</cstring> + </property> + </widget> + <widget class="QLineEdit" row="2" column="1"> + <property name="name"> + <cstring>makeoptions_edit</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>makebin_label</cstring> + </property> + <property name="text"> + <string>Name of build &script</string> + </property> + <property name="buddy" stdset="0"> + <cstring>makebin_edit</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>defTarget_label</cstring> + </property> + <property name="text"> + <string>Default &target:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>defaultTarget_edit</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>prio_label</cstring> + </property> + <property name="text"> + <string>Run with priority:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>jobs_box</cstring> + </property> + </widget> + <widget class="QSpinBox"> + <property name="name"> + <cstring>prio_box</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxValue"> + <number>19</number> + </property> + <property name="minValue"> + <number>-20</number> + </property> + <property name="value"> + <number>0</number> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>envs_label</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>E&nvironment:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>envs_combo</cstring> + </property> + </widget> + <widget class="QComboBox"> + <property name="name"> + <cstring>envs_combo</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>addenvs_button</cstring> + </property> + <property name="text"> + <string>&Add</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>copyenvs_button</cstring> + </property> + <property name="text"> + <string>&Copy</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>removeenvs_button</cstring> + </property> + <property name="text"> + <string>Re&move</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>env_var_group</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Environment &Variables</string> + </property> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>envs_combo</sender> + <signal>textChanged(const QString&)</signal> + <receiver>CustomOtherConfigWidgetBase</receiver> + <slot>envNameChanged(const QString&)</slot> + </connection> + <connection> + <sender>envs_combo</sender> + <signal>activated(const QString&)</signal> + <receiver>CustomOtherConfigWidgetBase</receiver> + <slot>envChanged(const QString&)</slot> + </connection> + <connection> + <sender>copyenvs_button</sender> + <signal>clicked()</signal> + <receiver>CustomOtherConfigWidgetBase</receiver> + <slot>envCopied()</slot> + </connection> + <connection> + <sender>addenvs_button</sender> + <signal>clicked()</signal> + <receiver>CustomOtherConfigWidgetBase</receiver> + <slot>envAdded()</slot> + </connection> + <connection> + <sender>removeenvs_button</sender> + <signal>clicked()</signal> + <receiver>CustomOtherConfigWidgetBase</receiver> + <slot>envRemoved()</slot> + </connection> +</connections> +<tabstops> + <tabstop>makebin_edit</tabstop> + <tabstop>makeoptions_edit</tabstop> + <tabstop>envs_combo</tabstop> + <tabstop>addenvs_button</tabstop> + <tabstop>copyenvs_button</tabstop> + <tabstop>removeenvs_button</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<slots> + <slot access="protected">envNameChanged(const QString &)</slot> + <slot access="protected">envChanged(const QString&)</slot> + <slot access="protected">envAdded()</slot> + <slot access="protected">envRemoved()</slot> + <slot access="protected">envCopied()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +</UI> diff --git a/buildtools/custommakefiles/customprojectpart.cpp b/buildtools/custommakefiles/customprojectpart.cpp new file mode 100644 index 00000000..f061dadc --- /dev/null +++ b/buildtools/custommakefiles/customprojectpart.cpp @@ -0,0 +1,1669 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2007 by Andreas Pakulat * + * apaku@gmx.de * + * * + * 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 "customprojectpart.h" + +#include <qapplication.h> +#include <kapplication.h> +#include <qdir.h> +#include <qfileinfo.h> +#include <qpopupmenu.h> +#include <qregexp.h> +#include <qstringlist.h> +#include <qtabwidget.h> +#include <qvaluestack.h> +#include <qvbox.h> +#include <qwhatsthis.h> +#include <qdom.h> + +#include <kaction.h> +#include <kconfig.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <keditlistbox.h> +#include <kdevgenericfactory.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kmainwindow.h> +#include <kmessagebox.h> +#include <kparts/part.h> +#include <kpopupmenu.h> +#include <kdeversion.h> +#include <kprocess.h> + +#include "domutil.h" +#include "kdevcore.h" +#include "kdevmainwindow.h" +#include "kdevmakefrontend.h" +#include "kdevappfrontend.h" +#include "kdevpartcontroller.h" +#include "runoptionswidget.h" +#include "makeoptionswidget.h" +#include "custombuildoptionswidget.h" +#include "custommakeconfigwidget.h" +#include "customotherconfigwidget.h" +#include "custommanagerwidget.h" +#include "config.h" +#include "envvartools.h" +#include "urlutil.h" + +#include "selectnewfilesdialog.h" + +#include <kdevplugininfo.h> + +typedef KDevGenericFactory<CustomProjectPart> CustomProjectFactory; +static const KDevPluginInfo data( "kdevcustomproject" ); +K_EXPORT_COMPONENT_FACTORY( libkdevcustomproject, CustomProjectFactory( data ) ) + +CustomProjectPart::CustomProjectPart( QObject *parent, const char *name, const QStringList & ) + : KDevBuildTool( &data, parent, name ? name : "CustomProjectPart" ) + , m_lastCompilationFailed( false ), m_recursive( false ), m_first_recursive( false ) +{ + setInstance( CustomProjectFactory::instance() ); + setXMLFile( "kdevcustomproject.rc" ); + + m_executeAfterBuild = false; + + KAction *action; + + action = new KAction( i18n( "Re-Populate Project" ), 0, this, SLOT( populateProject() ), actionCollection(), "repopulate_project" ); + action->setToolTip( i18n( "Re-Populate Project" ) ); + action->setWhatsThis( i18n( "<b>Re-Populate Project</b><p>Re-Populates the project, searching through the project directory and adding all files that match one of the wildcards set in the custom manager options of the project filelist." ) ); + + action = new KAction( i18n( "&Build Project" ), "make_kdevelop", Key_F8, + this, SLOT( slotBuild() ), + actionCollection(), "build_build" ); + action->setToolTip( i18n( "Build project" ) ); + action->setWhatsThis( i18n( "<b>Build project</b><p>Runs <b>make</b> from the project directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Build Options</b> tab." ) ); + + action = new KAction( i18n( "&Build Active Directory" ), "make_kdevelop", Key_F7, + this, SLOT( slotBuildActiveDir() ), + actionCollection(), "build_buildactivetarget" ); + action->setToolTip( i18n( "Build active directory" ) ); + action->setWhatsThis( i18n( "<b>Build active directory</b><p>Constructs a series of make commands to build the active directory. " + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab." ) ); + + action = new KAction( i18n( "Compile &File" ), "make_kdevelop", + this, SLOT( slotCompileFile() ), + actionCollection(), "build_compilefile" ); + action->setToolTip( i18n( "Compile file" ) ); + action->setWhatsThis( i18n( "<b>Compile file</b><p>Runs <b>make filename.o</b> command from the directory where 'filename' is the name of currently opened file.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Build Options</b> tab." ) ); + + action = new KAction( i18n( "Install" ), 0, + this, SLOT( slotInstall() ), + actionCollection(), "build_install" ); + action->setToolTip( i18n( "Install" ) ); + action->setWhatsThis( i18n( "<b>Install</b><p>Runs <b>make install</b> command from the project directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab." ) ); + + action = new KAction( i18n( "Install Active Directory" ), 0, + this, SLOT( slotInstallActiveDir() ), + actionCollection(), "build_installactivetarget" ); + action->setToolTip( i18n( "Install active directory" ) ); + action->setWhatsThis( i18n( "<b>Install active directory</b><p>Runs <b>make install</b> command from the active directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab." ) ); + + action = new KAction( i18n( "Install (as root user)" ), 0, + this, SLOT( slotInstallWithKdesu() ), + actionCollection(), "build_install_kdesu" ); + action->setToolTip( i18n( "Install as root user" ) ); + action->setWhatsThis( i18n( "<b>Install</b><p>Runs <b>make install</b> command from the project directory with root privileges.<br>" + "It is executed via kdesu command.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab." ) ); + + action = new KAction( i18n( "&Clean Project" ), 0, + this, SLOT( slotClean() ), + actionCollection(), "build_clean" ); + action->setToolTip( i18n( "Clean project" ) ); + action->setWhatsThis( i18n( "<b>Clean project</b><p>Runs <b>make clean</b> command from the project directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Build Options</b> tab." ) ); + + action = new KAction( i18n( "Execute Program" ), "exec", 0, + this, SLOT( slotExecute() ), + actionCollection(), "build_execute" ); + action->setToolTip( i18n( "Execute program" ) ); + action->setWhatsThis( i18n( "<b>Execute program</b><p>Executes the main program specified in project settings, <b>Run Options</b> tab. " + "If it is not specified then the active target is used to determine the application to run." ) ); + + KActionMenu *menu = new KActionMenu( i18n( "Build &Target" ), + actionCollection(), "build_target" ); + m_targetMenu = menu->popupMenu(); + menu->setToolTip( i18n( "Build target" ) ); + menu->setWhatsThis( i18n( "<b>Build target</b><p>Runs <b>make targetname</b> from the project directory (targetname is the name of the target selected).<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Build Options</b> tab." ) ); + + m_targetObjectFilesMenu = new QPopupMenu(); + m_targetOtherFilesMenu = new QPopupMenu(); + + m_makeEnvironmentsSelector = new KSelectAction( i18n( "Make &Environment" ), 0, + actionCollection(), "build_make_environment" ); + m_makeEnvironmentsSelector->setToolTip( i18n( "Make environment" ) ); + m_makeEnvironmentsSelector->setWhatsThis( i18n( "<b>Make Environment</b><p> Choose the set of environment variables to be passed on to make.<br>" + "Environment variables can be specified in the project " + "settings dialog, <b>Build Options</b> tab." ) ); + + connect( m_targetMenu, SIGNAL( aboutToShow() ), + this, SLOT( updateTargetMenu() ) ); + connect( m_targetMenu, SIGNAL( activated( int ) ), + this, SLOT( targetMenuActivated( int ) ) ); + connect( m_targetObjectFilesMenu, SIGNAL( activated( int ) ), + this, SLOT( targetObjectFilesMenuActivated( int ) ) ); + connect( m_targetOtherFilesMenu, SIGNAL( activated( int ) ), + this, SLOT( targetOtherFilesMenuActivated( int ) ) ); + connect( m_makeEnvironmentsSelector->popupMenu(), SIGNAL( aboutToShow() ), + this, SLOT( updateMakeEnvironmentsMenu() ) ); + connect( m_makeEnvironmentsSelector->popupMenu(), SIGNAL( activated( int ) ), + this, SLOT( makeEnvironmentsMenuActivated( int ) ) ); + connect( core(), SIGNAL( projectConfigWidget( KDialogBase* ) ), + this, SLOT( projectConfigWidget( KDialogBase* ) ) ); + connect( core(), SIGNAL( contextMenu( QPopupMenu *, const Context * ) ), + this, SLOT( contextMenu( QPopupMenu *, const Context * ) ) ); + + connect( makeFrontend(), SIGNAL( commandFinished( const QString& ) ), + this, SLOT( slotCommandFinished( const QString& ) ) ); + connect( makeFrontend(), SIGNAL( commandFailed( const QString& ) ), + this, SLOT( slotCommandFailed( const QString& ) ) ); +} + + +CustomProjectPart::~CustomProjectPart() +{} + + +void CustomProjectPart::projectConfigWidget( KDialogBase *dlg ) +{ + QVBox *vbox; + vbox = dlg->addVBoxPage( i18n( "Custom Manager" ), i18n( "Custom Manager" ), BarIcon( "make", KIcon::SizeMedium ) ); + CustomManagerWidget *w0 = new CustomManagerWidget( this, vbox ); + connect( dlg, SIGNAL( okClicked() ), w0, SLOT( accept() ) ); + + vbox = dlg->addVBoxPage( i18n( "Run Options" ), i18n( "Run Options" ), BarIcon( "make", KIcon::SizeMedium ) ); + RunOptionsWidget *w1 = new RunOptionsWidget( *projectDom(), "/kdevcustomproject", buildDirectory(), vbox ); + connect( dlg, SIGNAL( okClicked() ), w1, SLOT( accept() ) ); + vbox = dlg->addVBoxPage( i18n( "Build Options" ), i18n( "Build Options" ), BarIcon( "make", KIcon::SizeMedium ) ); + QTabWidget *buildtab = new QTabWidget( vbox ); + + CustomBuildOptionsWidget *w2 = new CustomBuildOptionsWidget( *projectDom(), buildtab ); + connect( dlg, SIGNAL( okClicked() ), w2, SLOT( accept() ) ); + buildtab->addTab( w2, i18n( "&Build" ) ); + + CustomOtherConfigWidget *w4 = new CustomOtherConfigWidget( this, "/kdevcustomproject", buildtab ); + connect( dlg, SIGNAL( okClicked() ), w4, SLOT( accept() ) ); + buildtab->addTab( w4, i18n( "&Other" ) ); + + CustomMakeConfigWidget *w3 = new CustomMakeConfigWidget( this, "/kdevcustomproject", buildtab ); + buildtab->addTab( w3, i18n( "Ma&ke" ) ); + w2->setMakeOptionsWidget( buildtab, w3, w4 ); + connect( dlg, SIGNAL( okClicked() ), w3, SLOT( accept() ) ); + +} + + +void CustomProjectPart::contextMenu( QPopupMenu *popup, const Context *context ) +{ + if ( !context->hasType( Context::FileContext ) ) + return; + + const FileContext *fcontext = static_cast<const FileContext*>( context ); + + m_contextAddFiles.clear(); + m_contextRemoveFiles.clear(); + + QString popupstr = fcontext->urls().first().fileName(); + + if ( popupstr == QString::null ) + popupstr = "."; + + if ( fcontext->urls().size() == 1 && URLUtil::isDirectory( fcontext->urls().first() ) && !isInBlacklist( fcontext->urls().first().path() ) ) + { + popup->insertSeparator(); + // remember the name of the directory + m_contextDirName = fcontext->urls().first().path(); + m_contextDirName = m_contextDirName.mid( project()->projectDirectory().length() + 1 ); + int id = popup->insertItem( i18n( "Make Active Directory" ), + this, SLOT( slotChooseActiveDirectory() ) ); + popup->setWhatsThis( id, i18n( "<b>Make active directory</b><p>" + "Chooses this directory as the destination for new files created using wizards " + "like the <i>New Class</i> wizard." ) ); + } + + kdDebug( 9025 ) << "context urls: " << fcontext->urls() << endl; + if ( fcontext->urls().size() == 1 && ( isProjectFileType( fcontext->urls().first().path() ) || URLUtil::isDirectory( fcontext->urls().first() ) ) ) + { + popup->insertSeparator(); + m_contextDirName = fcontext->urls().first().path(); + m_contextDirName = m_contextDirName.mid( project()->projectDirectory().length() + 1 ); + int id; + if ( isInBlacklist( m_contextDirName ) ) + { + id = popup->insertItem( i18n( "Remove from blacklist" ), + this, SLOT( slotChangeBlacklist() ) ); + popup->setWhatsThis( id, i18n( "<b>Remove from blacklist</b><p>" + "Removes the given file or directory from the " + "blacklist if it is already in it.<br>The blacklist contains files and" + " directories that should be ignored even if they match a project filetype " + "pattern" ) ); + } + else + { + id = popup->insertItem( i18n( "Add to blacklist" ), + this, SLOT( slotChangeBlacklist() ) ); + popup->setWhatsThis( id, i18n( "<b>Add to blacklist</b><p>" + "Adds the given file or directory to the blacklist.<br>The blacklist contains files and" + " directories that should be ignored even if they match a project filetype " + "pattern" ) ); + } + } + + const KURL::List urls = fcontext->urls(); + + bool dirAddRecursive = false; + bool dirDelRecursive = false; + + for ( KURL::List::ConstIterator it = urls.begin(); it != urls.end(); ++it ) + { + kdDebug( 9025 ) << "Checking URL: " << *it << endl; + QString canPath( URLUtil::canonicalPath(( *it ).path() ) ); + QString relPath = relativeToProject( canPath ); + kdDebug( 9025 ) << "relpath: " << relPath << "|canpath: " << canPath << endl; + if ( isInBlacklist( relPath ) ) + continue; + if ((( *it ).isLocalFile() && isProjectFileType(( *it ).fileName() ) ) ) + { + if ( project()->isProjectFile( canPath ) ) + m_contextRemoveFiles << relPath; + if ( !project()->isProjectFile( canPath ) ) + m_contextAddFiles << relPath; + } + if ( QFileInfo(( *it ).path() ).isDir() ) + { + if ( containsProjectFiles( canPath ) || project()->isProjectFile( canPath ) ) + { + if ( containsProjectFiles( canPath ) ) + dirDelRecursive = true; + m_contextRemoveFiles << relPath; + } + if ( containsNonProjectFiles( canPath ) || !project()->isProjectFile( canPath ) ) + { + if ( containsNonProjectFiles( canPath ) ) + dirAddRecursive = true; + m_contextAddFiles << relPath; + } + } + } + + if ( m_contextAddFiles.size() > 0 || m_contextRemoveFiles.size() > 0 ) + popup->insertSeparator(); + if ( m_contextAddFiles.size() > 0 ) + { + int id = popup->insertItem( i18n( "Add Selected File/Dir(s) to Project" ), + this, SLOT( slotAddToProject() ) ); + popup->setWhatsThis( id, i18n( "<b>Add to project</b><p>Adds selected file/dir(s) to the list of files in the project. " + "Note that the files should be manually added to the corresponding makefile or build.xml." ) ); + if ( dirAddRecursive ) + { + int id = popup->insertItem( i18n( "Add Selected Dir(s) to Project (recursive)" ), + this, SLOT( slotAddToProjectRecursive() ) ); + popup->setWhatsThis( id, i18n( "<b>Add to project</b><p>Recursively adds selected dir(s) to the list of files in the project. " + "Note that the files should be manually added to the corresponding makefile or build.xml." ) ); + } + } + + if ( m_contextRemoveFiles.size() > 0 ) + { + int id = popup->insertItem( i18n( "Remove Selected File/Dir(s) From Project" ), + this, SLOT( slotRemoveFromProject() ) ); + popup->setWhatsThis( id, i18n( "<b>Remove from project</b><p>Removes selected file/dir(s) from the list of files in the project. " + "Note that the files should be manually excluded from the corresponding makefile or build.xml." ) ); + + if ( dirDelRecursive ) + { + int id = popup->insertItem( i18n( "Remove Selected Dir(s) From Project (recursive)" ), + this, SLOT( slotRemoveFromProjectRecursive() ) ); + popup->setWhatsThis( id, i18n( "<b>Remove from project</b><p>Recursively removes selected dir(s) from the list of files in the project. " + "Note that the files should be manually excluded from the corresponding makefile or build.xml." ) ); + } + } +} + + +void CustomProjectPart::slotAddToProject() +{ + m_recursive = false; + m_first_recursive = true; + addFiles( m_contextAddFiles ); +} + + +void CustomProjectPart::slotRemoveFromProject() +{ + m_recursive = false; + m_first_recursive = true; + removeFiles( m_contextRemoveFiles ); +} + + +void CustomProjectPart::slotAddToProjectRecursive() +{ + m_recursive = true; + addFiles( m_contextAddFiles ); + m_recursive = false; +} + + +void CustomProjectPart::slotRemoveFromProjectRecursive() +{ + m_recursive = true; + removeFiles( m_contextRemoveFiles ); + m_recursive = false; +} + +void CustomProjectPart::slotChangeBlacklist() +{ + switchBlacklistEntry( m_contextDirName ); +} + +void CustomProjectPart::slotChooseActiveDirectory() +{ + QString olddir = activeDirectory(); + QDomDocument &dom = *projectDom(); + DomUtil::writeEntry( dom, "/kdevcustomproject/general/activedir", m_contextDirName ); + emit activeDirectoryChanged( olddir, activeDirectory() ); +} + + +void CustomProjectPart::openProject( const QString &dirName, const QString &projectName ) +{ + m_projectDirectory = dirName; + m_projectName = projectName; + + QDomDocument &dom = *projectDom(); + // Set the default directory radio to "executable" + if ( DomUtil::readEntry( dom, "/kdevcustomproject/run/directoryradio" ) == "" ) + { + DomUtil::writeEntry( dom, "/kdevcustomproject/run/directoryradio", "executable" ); + } + + if ( filetypes().isEmpty() ) + { + QStringList types; + types << "*.java" << "*.h" << "*.H" << "*.hh" << "*.hxx" << "*.hpp" << "*.c" << "*.C" + << "*.cc" << "*.cpp" << "*.c++" << "*.cxx" << "Makefile" << "CMakeLists.txt"; + DomUtil::writeListEntry( dom, "/kdevcustomproject/filetypes", "filetype", types ); + } + + /*this entry is currently only created by the cmake kdevelop3 project generator + in order to support completely-out-of-source builds, where nothing, not + even the kdevelop project files are created in the source directory, Alex <neundorf@kde.org> + */ + m_filelistDir = DomUtil::readEntry( dom, "/kdevcustomproject/filelistdirectory" ); + if ( m_filelistDir.isEmpty() ) + m_filelistDir = dirName; + + if ( QFileInfo( m_filelistDir + "/" + projectName.lower() + + ".kdevelop.filelist" ).exists() ) + { + QDir( m_filelistDir ).rename( + projectName.lower() + ".kdevelop.filelist", + projectName + ".kdevelop.filelist" ); + } + + QFile f( m_filelistDir + "/" + projectName + ".kdevelop.filelist" ); + if ( f.open( IO_ReadOnly ) ) + { + QTextStream stream( &f ); + while ( !stream.atEnd() ) + { + QString s = stream.readLine(); + // Skip comments. + if ( s.isEmpty() || s.startsWith( "#" ) ) + continue; + // Skip non-existent files. + if ( ! QFileInfo( projectDirectory() + "/" + s ).exists() ) + continue; + // Do not bother with files already in project or on blacklist. + if ( isInProject( s ) || isInBlacklist( s ) ) + continue; + addToProject( s ); + } + QStringList newfiles; + findNewFiles( dirName, newfiles ); + + if ( newfiles.count() > 0 ) + { + addNewFilesToProject( newfiles ); + } + + } + else + { + int r = KMessageBox::questionYesNo( mainWindow()->main(), + i18n( "This project does not contain any files yet.\n" + "Populate it with all C/C++/Java files below " + "the project directory?" ), QString::null, i18n( "Populate" ), i18n( "Do Not Populate" ) ); + if ( r == KMessageBox::Yes ) + populateProject(); + } + + + // check if there is an old envvars entry (from old project file with single make environment) + QString buildtool = DomUtil::readEntry( dom , "/kdevcustomproject/build/buildtool" ); + QDomElement el = + DomUtil::elementByPath( dom , "/kdevcustomproject/" + buildtool + "/envvars" ); + if ( !el.isNull() ) + { + QDomElement envs = DomUtil::createElementByPath( dom , "/kdevcustomproject/" + buildtool + "/environments" ); + DomUtil::makeEmpty( envs ); + el.setTagName( "default" ); + envs.appendChild( el ); + } + KDevProject::openProject( dirName, projectName ); +} + + +/** + * @brief Recursively search given directory searching for files which may be part of this project. + * + * The files found not in a black list, + * and not being already part of our project are gathered. + * + * @param dir directory to scan (and recurse) for potential project files. + * @param[out] fileList the list of files found. + */ +void CustomProjectPart::findNewFiles( const QString& dir, QStringList& filelist ) const +{ + if ( dir.isEmpty() ) + return; + QStringList fileentries = QDir( dir ).entryList( filetypes().join( ";" ) ); + QStringList dirs = QDir( dir ).entryList( QDir::Dirs ); + QStringList entries = fileentries + dirs; + QString relpath = relativeToProject( dir ); + if ( !relpath.isEmpty() ) + relpath += "/"; + for ( QStringList::const_iterator it = entries.begin(); it != entries.end(); ++it ) + { + // Only process genuine entries - files and directories. + if (( *it == "." ) || ( *it == ".." ) ) + continue; + // If the entry (be it a file or a directory) is already part of this project, proceed to next one. + const QString relativeEntry( relpath + *it ); + if ( isInProject( relativeEntry ) ) + continue; + // If the entry is blacklisted, proceed to next one. + // Note that by using generic isInBlacklist(), + // we are actually wasting resources, + // because it also tests whether any parent directory of relativeEntry is blacklisted. + // But by the order we are traversing and processing the directories, + // we know it is not the case, ever. + if ( isInBlacklist( relativeEntry ) ) + continue; + // We have a new, non-blacklisted entry. + // Recurse into it (a directory) or add it to the potential list of new project files. + const QString absoluteEntry( dir + "/" + *it ); + if ( QFileInfo( absoluteEntry ).isFile() ) + { + filelist << relativeEntry; + } + else if ( QFileInfo( absoluteEntry ).isDir() ) + { + bool searchRecursive = true; + QFileInfo fi( absoluteEntry ); + if( fi.isSymLink() ) + { + QString realDir = fi.readLink(); + if( QFileInfo( realDir ).exists() ) + { + for( QStringList::const_iterator it = filelist.constBegin(); it != filelist.constEnd(); ++it ) + { + + if( QFileInfo(projectDirectory()+"/"+*it).absFilePath().startsWith( realDir ) ) + { + searchRecursive = false; + } + } + } else { + searchRecursive = false; + } + } + if( searchRecursive ) + { + findNewFiles( absoluteEntry, filelist ); + } + } + } +} + + +void CustomProjectPart::populateProject() +{ + + KDialogBase* dlg = new KDialogBase( mainWindow()->main(), "typeselector", true, + "Select filetypes of project", KDialogBase::Ok | KDialogBase::Cancel ); + QVBox* box = dlg->makeVBoxMainWidget(); + KEditListBox* lb = new KEditListBox( "Filetypes in the project", box, "selecttypes", + false, KEditListBox::Add | KEditListBox::Remove ); + lb->setItems( filetypes() ); + if ( dlg->exec() == QDialog::Accepted ) + { + setFiletypes( lb->items() ); + } + + QApplication::setOverrideCursor( Qt::waitCursor ); + removeFiles( allFiles() ); + updateBlacklist( QStringList() ); + + QStringList newlist; + + findNewFiles( projectDirectory(), newlist ); + + QApplication::restoreOverrideCursor(); + addNewFilesToProject( newlist ); +} + + +void CustomProjectPart::closeProject() +{ + saveProject(); +} + +void CustomProjectPart::saveProject() +{ + QFile f( m_filelistDir + "/" + m_projectName + ".kdevelop.filelist" ); + if ( !f.open( IO_WriteOnly ) ) + return; + + QTextStream stream( &f ); + stream << "# KDevelop Custom Project File List" << endl; + + ProjectFilesSet::ConstIterator it; + for ( it = m_sourceFilesSet.constBegin(); it != m_sourceFilesSet.constEnd(); ++it ) + stream << it.key() << endl; + f.close(); +} + + +QString CustomProjectPart::projectDirectory() const +{ + return m_projectDirectory; +} + + +QString CustomProjectPart::projectName() const +{ + return m_projectName; +} + + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList CustomProjectPart::runEnvironmentVars() const +{ + return DomUtil::readPairListEntry( *projectDom(), "/kdevcustomproject/run/envvars", "envvar", "name", "value" ); +} + + +/** Retuns the currently selected run directory + * The returned string can be: + * if run/directoryradio == executable + * The directory where the executable is + * if run/directoryradio == build + * The directory where the executable is relative to build directory + * if run/directoryradio == custom + * The custom directory absolute path + */ +QString CustomProjectPart::runDirectory() const +{ + QString cwd = defaultRunDirectory( "kdevcustomproject" ); + if ( cwd.isEmpty() ) + cwd = buildDirectory(); + return cwd; +} + + +/** Retuns the currently selected main program + * The returned string can be: + * if run/directoryradio == executable + * The executable name + * if run/directoryradio == build + * The path to executable relative to build directory + * if run/directoryradio == custom or relative == false + * The absolute path to executable + */ +QString CustomProjectPart::mainProgram() const +{ + QDomDocument * dom = projectDom(); + + if ( !dom ) return QString(); + + QString DomMainProgram = DomUtil::readEntry( *dom, "/kdevcustomproject/run/mainprogram" ); + + if ( DomMainProgram.isEmpty() ) return QString(); + + if ( DomMainProgram.startsWith( "/" ) ) // assume absolute path + { + return DomMainProgram; + } + else // assume project relative path + { + return projectDirectory() + "/" + DomMainProgram; + } + + return QString(); +} + +/** Retuns a QString with the debug command line arguments */ +QString CustomProjectPart::debugArguments() const +{ + return DomUtil::readEntry( *projectDom(), "/kdevcustomproject/run/globaldebugarguments" ); +} + + +/** Retuns a QString with the run command line arguments */ +QString CustomProjectPart::runArguments() const +{ + return DomUtil::readEntry( *projectDom(), "/kdevcustomproject/run/programargs" ); +} + +QString CustomProjectPart::activeDirectory() const +{ + QDomDocument &dom = *projectDom(); + return DomUtil::readEntry( dom, "/kdevcustomproject/general/activedir", "." ); +} + + +QStringList CustomProjectPart::allFiles() const +{ + return m_sourceFilesSet.keys(); +} + + +void CustomProjectPart::addFile( const QString &fileName ) +{ + QStringList fileList; + fileList.append( fileName ); + + this->addFiles( fileList ); +} + +void CustomProjectPart::addFiles( const QStringList& fileList ) +{ + QStringList::ConstIterator it; + QStringList addedFiles; + QStringList myfileList = fileList; + kdDebug( 9025 ) << "Adding files: " << myfileList << endl; + myfileList.remove( "." ); + myfileList.remove( "" ); + myfileList.remove( ".." ); + for ( it = myfileList.begin(); it != myfileList.end(); ++it ) + { + if ( isInBlacklist( *it ) ) + continue; + QString relpath; + kdDebug( 9025 ) << "Checking path: " << *it << endl; + if ( QDir::isRelativePath( *it ) ) + { + kdDebug( 9025 ) << *it << " is relative" << endl; + relpath = *it; + } + else + { + kdDebug( 9025 ) << *it << " is not relative" << endl; + relpath = relativeToProject( *it ); + } + + if ( !QFileInfo( projectDirectory() + "/" + relpath ).exists() ) + continue; + + if ( QFileInfo( projectDirectory() + "/" + relpath ).isDir() && ( m_recursive || m_first_recursive ) ) + { + kdDebug( 9025 ) << "is a dir and " << m_recursive << "|" << m_first_recursive << endl; + m_first_recursive = false; + QStringList fileentries = QDir( projectDirectory() + "/" + relpath ).entryList( filetypes().join( ";" ) ); + QStringList dirs = QDir( projectDirectory() + "/" + relpath ).entryList( QDir::Dirs ); + QStringList subentries = fileentries + dirs; + for ( QStringList::iterator subit = subentries.begin(); subit != subentries.end(); ++subit ) + { + if ( *subit != "." && *subit != ".." ) + *subit = relpath + "/" + ( *subit ); + if (( *subit ).startsWith( "/" ) ) + *subit = ( *subit ).mid( 1, ( *subit ).length() ); + } + addFiles( subentries ); + addedFiles << relpath; + addToProject( relpath ); + m_first_recursive = true; + } + else if ( isProjectFileType( QFileInfo( relpath ).fileName() ) && ( ! isInProject( relpath ) ) ) + { + QStringList paths = QStringList::split( "/", relpath ); + paths.pop_back(); + QString path; + for ( QStringList::const_iterator it = paths.begin(); it != paths.end(); ++it ) + { + path += *it; + if ( ! isInProject( path ) ) + { + addedFiles << path; + addToProject( path ); + } + path += "/"; + } + addedFiles << relpath; + addToProject( relpath ); + } + else + { + kdDebug( 9025 ) << "not adding " << relpath << endl; + } + } + m_first_recursive = false; + saveProject(); + + kdDebug( 9025 ) << "Emitting addedFilesToProject" << addedFiles << endl; + emit addedFilesToProject( addedFiles ); +} + +void CustomProjectPart::removeFile( const QString &fileName ) +{ + QStringList fileList; + fileList.append( fileName ); + + this->removeFiles( fileList ); +} + +void CustomProjectPart::removeFiles( const QStringList& fileList ) +{ + kdDebug( 9025 ) << "Emitting removedFilesFromProject" << fileList << endl; + QStringList removedFiles; + QStringList myfileList = fileList; + QStringList::ConstIterator it; + myfileList.remove( "." ); + myfileList.remove( ".." ); + myfileList.remove( "" ); + + for ( it = myfileList.begin(); it != myfileList.end(); ++it ) + { + QString relpath; + if ( QDir::isRelativePath( *it ) ) + relpath = *it; + else + relpath = relativeToProject( *it ); + + if ( QFileInfo( projectDirectory() + "/" + relpath ).isDir() && ( m_recursive || m_first_recursive ) ) + { + m_first_recursive = false; + QStringList fileentries = QDir( projectDirectory() + "/" + relpath ).entryList( filetypes().join( ";" ) ); + QStringList dirs = QDir( projectDirectory() + "/" + relpath ).entryList( QDir::Dirs ); + QStringList subentries = fileentries + dirs; + for ( QStringList::iterator subit = subentries.begin(); subit != subentries.end(); ++subit ) + if ( *subit != "." && *subit != ".." ) + *subit = relpath + "/" + ( *subit ); + removeFiles( subentries ); + if ( !containsProjectFiles( relpath ) ) + { + removedFiles << relpath; + removeFromProject( relpath ); + } + m_first_recursive = true; + } + else if ( isInProject( relpath ) ) + { + removedFiles << relpath; + removeFromProject( relpath ); + QStringList paths = QStringList::split( "/", relpath ); + QString lastsubentry = paths[paths.size()-1]; + paths.pop_back(); + while ( paths.size() > 0 ) + { + QString dir = paths.join( "/" ); + QStringList projectentries = projectFilesInDir( dir ); + if ( projectentries.size() == 0 ) + { + removedFiles << dir; + removeFromProject( dir ); + } + else + break; + lastsubentry = paths[paths.size()-1]; + paths.pop_back(); + } + } + } + + saveProject(); + emit removedFilesFromProject( removedFiles ); +} + +QString CustomProjectPart::buildDirectory() const +{ + QString dir = DomUtil::readEntry( *projectDom(), "/kdevcustomproject/build/builddir" ); + if ( dir.isEmpty() ) + return projectDirectory(); + if ( QFileInfo( dir ).isRelative() ) + return QDir::cleanDirPath( projectDirectory() + "/" + dir ); + return dir; +} + + +QString CustomProjectPart::makeEnvironment() const +{ + // Get the make environment variables pairs into the environstr string + // in the form of: "ENV_VARIABLE=ENV_VALUE" + // Note that we quote the variable value due to the possibility of + // embedded spaces + QString buildtool = DomUtil::readEntry( *projectDom(), "/kdevcustomproject/build/buildtool" ); + DomUtil::PairList envvars = + DomUtil::readPairListEntry( *projectDom(), "/kdevcustomproject/" + buildtool + "/environments/" + currentMakeEnvironment(), "envvar", "name", "value" ); + + QString environstr; + DomUtil::PairList::ConstIterator it; + for ( it = envvars.begin(); it != envvars.end(); ++it ) + { + environstr += ( *it ).first; + environstr += "="; + environstr += EnvVarTools::quote(( *it ).second ); + environstr += " "; + } + + KConfigGroup grp( kapp->config(), "MakeOutputView" ); + if( grp.readBoolEntry( "ForceCLocale", true ) ) + environstr += "LC_MESSAGES=" + EnvVarTools::quote( "C" )+" "+" "+"LC_CTYPE="+EnvVarTools::quote("C")+" "; + + return environstr; +} + + +void CustomProjectPart::startMakeCommand( const QString &dir, const QString &target, bool withKdesu ) +{ + if ( partController()->saveAllFiles() == false ) + return; //user cancelled + + QDomDocument &dom = *projectDom(); + QString buildtool = DomUtil::readEntry( dom, "/kdevcustomproject/build/buildtool" ); + + QString cmdline; + if ( buildtool == "ant" ) + { + cmdline = "ant"; + } + else if ( buildtool == "other" ) + { + cmdline = DomUtil::readEntry( dom, "/kdevcustomproject/other/otherbin" ); + if ( cmdline.isEmpty() ) + cmdline = "echo"; + else if ( cmdline.find( "/" ) == -1 ) + cmdline = "./" + cmdline; + cmdline += " " + DomUtil::readEntry( dom, "/kdevcustomproject/other/otheroptions" ); + } + else + { + cmdline = DomUtil::readEntry( dom, "/kdevcustomproject/make/makebin" ); + if ( cmdline.isEmpty() ) + cmdline = MAKE_COMMAND; + if ( !DomUtil::readBoolEntry( dom, "/kdevcustomproject/make/abortonerror" ) ) + cmdline += " -k"; + int jobs = DomUtil::readIntEntry( dom, "/kdevcustomproject/make/numberofjobs" ); + if ( jobs != 0 ) + { + cmdline += " -j"; + cmdline += QString::number( jobs ); + } + if ( DomUtil::readBoolEntry( dom, "/kdevcustomproject/make/dontact" ) ) + cmdline += " -n"; + cmdline += " " + DomUtil::readEntry( dom, "/kdevcustomproject/make/makeoptions" ); + } + + cmdline += " "; + if ( !target.isEmpty() ) + cmdline += KProcess::quote( target ); + + QString dircmd = "cd "; + dircmd += KProcess::quote( dir ); + dircmd += " && "; + + int prio = DomUtil::readIntEntry( dom, "/kdevcustomproject/" + buildtool + "/prio" ); + QString nice; + if ( prio != 0 ) + { + nice = QString( "nice -n%1 " ).arg( prio ); + } + + cmdline.prepend( nice ); + cmdline.prepend( makeEnvironment() ); + + if ( withKdesu ) + cmdline = "kdesu -t -c '" + cmdline + "'"; + + m_buildCommand = dircmd + cmdline; + + + makeFrontend()->queueCommand( dir, dircmd + cmdline ); +} + + +void CustomProjectPart::slotBuild() +{ + m_lastCompilationFailed = false; + QString buildtool = DomUtil::readEntry( *projectDom(), "/kdevcustomproject/build/buildtool" ); + startMakeCommand( buildDirectory(), DomUtil::readEntry( *projectDom(), + "/kdevcustomproject/" + buildtool + "/defaulttarget" ) ); +} + +void CustomProjectPart::slotBuildActiveDir() +{ + m_lastCompilationFailed = false; + QString buildtool = DomUtil::readEntry( *projectDom(), "/kdevcustomproject/build/buildtool" ); + startMakeCommand( buildDirectory() + "/" + activeDirectory(), DomUtil::readEntry( *projectDom(), + "/kdevcustomproject/" + buildtool + "/defaulttarget" ) ); +} + + +void CustomProjectPart::slotCompileFile() +{ + KParts::ReadWritePart *part = dynamic_cast<KParts::ReadWritePart*>( partController()->activePart() ); + if ( !part || !part->url().isLocalFile() ) + return; + + QString fileName = part->url().path(); + QFileInfo fi( fileName ); + QString sourceDir = fi.dirPath(); + QString baseName = fi.baseName( true ); + kdDebug( 9025 ) << "Compiling " << fileName + << "in dir " << sourceDir + << " with baseName " << baseName << endl; + + // What would be nice: In case of non-recursive build system, climb up from + // the source dir until a Makefile is found + + QString buildDir = sourceDir; + QString target = baseName + ".o"; + + QString buildtool = DomUtil::readEntry( *projectDom(), "/kdevcustomproject/build/buildtool" ); + + //if there is no Makefile in the directory of the source file + //try to build it from the main build dir + //this works e.g. for non-recursive cmake Makefiles, Alex + if ( buildtool == "make" && ( QFile::exists( sourceDir + "/Makefile" ) == false ) + && ( QFile::exists( sourceDir + "/makefile" ) == false ) ) + { + buildDir = buildDirectory(); + } + + startMakeCommand( buildDir, target ); +} + +void CustomProjectPart::slotInstallActiveDir() +{ + startMakeCommand( buildDirectory() + "/" + activeDirectory(), QString::fromLatin1( "install" ) ); +} + +void CustomProjectPart::slotInstall() +{ + startMakeCommand( buildDirectory(), QString::fromLatin1( "install" ) ); +} + + +void CustomProjectPart::slotInstallWithKdesu() +{ + // First issue "make" to build the entire project with the current user + // This way we make sure all files are up to date before we do the "make install" + slotBuild(); + + // After that issue "make install" with the root user + startMakeCommand( buildDirectory(), QString::fromLatin1( "install" ), true ); +} + +void CustomProjectPart::slotClean() +{ + startMakeCommand( buildDirectory(), QString::fromLatin1( "clean" ) ); +} + + +void CustomProjectPart::slotExecute() +{ + partController()->saveAllFiles(); + + bool _auto = false; + if ( DomUtil::readBoolEntry( *projectDom(), "/kdevcustomproject/run/autocompile", true ) && ( isDirty() || !QFileInfo( mainProgram() ).exists() ) ) + { + m_executeAfterBuild = true; + slotBuild(); + _auto = true; + } + + if ( DomUtil::readBoolEntry( *projectDom(), "/kdevcustomproject/run/autoinstall", false ) && ( isDirty() || !QFileInfo( mainProgram() ).exists() ) ) + { + m_executeAfterBuild = true; + // Use kdesu?? + if ( DomUtil::readBoolEntry( *projectDom(), "/kdevcustomproject/run/autokdesu", false ) ) + //slotInstallWithKdesu assumes that it hasn't just been build... + _auto ? slotInstallWithKdesu() : startMakeCommand( buildDirectory(), QString::fromLatin1( "install" ), true ); + else + slotInstall(); + _auto = true; + } + + if ( _auto ) + return; + + // Get the run environment variables pairs into the environstr string + // in the form of: "ENV_VARIABLE=ENV_VALUE" + // Note that we quote the variable value due to the possibility of + // embedded spaces + DomUtil::PairList envvars = runEnvironmentVars(); + QString environstr; + DomUtil::PairList::ConstIterator it; + for ( it = envvars.begin(); it != envvars.end(); ++it ) + { + environstr += ( *it ).first; + environstr += "="; + environstr += EnvVarTools::quote(( *it ).second ); + environstr += " "; + } + + if ( mainProgram().isEmpty() ) + // Do not execute non executable targets + return; + + QString program = environstr; + program += mainProgram(); + program += " " + runArguments(); + + bool inTerminal = DomUtil::readBoolEntry( *projectDom(), "/kdevcustomproject/run/terminal" ); + + kdDebug( 9025 ) << "runDirectory: <" << runDirectory() << ">" << endl; + kdDebug( 9025 ) << "environstr : <" << environstr << ">" << endl; + kdDebug( 9025 ) << "mainProgram : <" << mainProgram() << ">" << endl; + kdDebug( 9025 ) << "runArguments: <" << runArguments() << ">" << endl; + + appFrontend()->startAppCommand( runDirectory(), program, inTerminal ); +} + +void CustomProjectPart::updateTargetMenu() +{ + m_targets.clear(); + m_targetsObjectFiles.clear(); + m_targetsOtherFiles.clear(); + m_targetMenu->clear(); + m_targetObjectFilesMenu->clear(); + m_targetOtherFilesMenu->clear(); + + QDomDocument &dom = *projectDom(); + bool ant = DomUtil::readEntry( dom, "/kdevcustomproject/build/buildtool" ) == "ant"; + + if ( ant ) + { + QFile f( buildDirectory() + "/build.xml" ); + if ( !f.open( IO_ReadOnly ) ) + { + kdDebug( 9025 ) << "No build file" << endl; + return; + } + QDomDocument dom; + if ( !dom.setContent( &f ) ) + { + kdDebug( 9025 ) << "Build script not valid xml" << endl; + f.close(); + return; + } + f.close(); + + QDomNode node = dom.documentElement().firstChild(); + while ( !node.isNull() ) + { + if ( node.toElement().tagName() == "target" ) + m_targets.append( node.toElement().attribute( "name" ) ); + node = node.nextSibling(); + } + } + else + { + kdDebug( 9025 ) << "Trying to load a makefile... " << endl; + + m_makefileVars.clear(); + m_parsedMakefiles.clear(); + m_makefilesToParse.clear(); + m_makefilesToParse.push( "Makefile" ); + m_makefilesToParse.push( "makefile" ); + putEnvVarsInVarMap(); + while ( !m_makefilesToParse.isEmpty() ) + parseMakefile( m_makefilesToParse.pop() ); + + //free the memory again + m_makefileVars.clear(); + m_parsedMakefiles.clear(); + + m_targets.sort(); + m_targetsObjectFiles.sort(); + m_targetsOtherFiles.sort(); + + } + + m_targetMenu->insertItem( i18n( "Object Files" ), m_targetObjectFilesMenu ); + m_targetMenu->insertItem( i18n( "Other Files" ), m_targetOtherFilesMenu ); + + int id = 0; + QStringList::ConstIterator it; + for ( it = m_targets.begin(); it != m_targets.end(); ++it ) + m_targetMenu->insertItem( *it, id++ ); + + id = 0; + for ( it = m_targetsObjectFiles.begin(); it != m_targetsObjectFiles.end(); ++it ) + m_targetObjectFilesMenu->insertItem( *it, id++ ); + + id = 0; + for ( it = m_targetsOtherFiles.begin(); it != m_targetsOtherFiles.end(); ++it ) + m_targetOtherFilesMenu->insertItem( *it, id++ ); +} + +void CustomProjectPart::putEnvVarsInVarMap() +{ + DomUtil::PairList envvars = + DomUtil::readPairListEntry( *projectDom(), "/kdevcustomproject/make/environments/" + currentMakeEnvironment(), "envvar", "name", "value" ); + + for ( DomUtil::PairList::ConstIterator it = envvars.begin(); it != envvars.end(); ++it ) + m_makefileVars[( *it ).first] = ( *it ).second; //is qouting here required as in makeEnvironment() ?? +} + +void CustomProjectPart::parseMakefile( const QString& filename ) +{ + if ( m_parsedMakefiles.contains( filename ) ) + return; + + m_parsedMakefiles.insert( filename, 1 ); + + QString absFilename = filename; + if ( !filename.startsWith( "/" ) ) + absFilename = buildDirectory() + "/" + filename; + + QFile f( absFilename ); + if ( !f.open( IO_ReadOnly ) ) + { + kdDebug( 9025 ) << "could not open " << absFilename << endl; + return; + } + QRegExp targetRe( "^ *([^\\t$.#]\\S+) *:.*$" ); + targetRe.setMinimal( true ); + + QRegExp variablesRe( "\\$\\(\\s*([^\\)\\s]+)\\s*\\)" ); + QRegExp assignmentRe( "^\\s*(\\S+)\\s*[:\\?]?=\\s*(\\S+)\\s*(#.*)?$" ); + + QRegExp includedMakefilesRe( "^include\\s+(\\S+)" ); + QString str = ""; + while ( !f.atEnd() ) + { + f.readLine( str, 200 ); + + // Replace any variables in the current line + int offset = -1; + while (( offset = variablesRe.search( str, offset + 1 ) ) != -1 ) + { + QString variableName = variablesRe.cap( 1 ).simplifyWhiteSpace(); + if ( m_makefileVars.contains( variableName ) ) + { + str.replace( variablesRe.cap( 0 ), m_makefileVars[variableName] ); + } + } + + // Read all continuation lines + // kdDebug(9025) << "Trying: " << str.simplifyWhiteSpace() << endl; + //while (str.right(1) == "\\" && !stream.atEnd()) { + // str.remove(str.length()-1, 1); + // str += stream.readLine(); + //} + // Find any variables + if ( assignmentRe.search( str ) != -1 ) + { + m_makefileVars[assignmentRe.cap( 1 ).simplifyWhiteSpace()] = assignmentRe.cap( 2 ).simplifyWhiteSpace(); + } + else if ( includedMakefilesRe.search( str ) != -1 ) + { + QString includedMakefile = includedMakefilesRe.cap( 1 ).simplifyWhiteSpace(); + m_makefilesToParse.push( includedMakefile ); + } + else if ( targetRe.search( str ) != -1 ) + { + QString tmpTarget = targetRe.cap( 1 ).simplifyWhiteSpace(); + if ( tmpTarget.endsWith( ".o" ) ) + { + if ( m_targetsObjectFiles.find( tmpTarget ) == m_targetsObjectFiles.end() ) + m_targetsObjectFiles += tmpTarget; + } + else if ( tmpTarget.contains( '.' ) ) + { + if ( m_targetsOtherFiles.find( tmpTarget ) == m_targetsOtherFiles.end() ) + m_targetsOtherFiles += tmpTarget; + } + else + { + if ( m_targets.find( tmpTarget ) == m_targets.end() ) + m_targets += tmpTarget; + } + } + } + f.close(); +} + +void CustomProjectPart::targetMenuActivated( int id ) +{ + QString target = m_targets[id]; + startMakeCommand( buildDirectory(), target ); +} + +void CustomProjectPart::targetObjectFilesMenuActivated( int id ) +{ + QString target = m_targetsObjectFiles[id]; + startMakeCommand( buildDirectory(), target ); +} + +void CustomProjectPart::targetOtherFilesMenuActivated( int id ) +{ + QString target = m_targetsOtherFiles[id]; + startMakeCommand( buildDirectory(), target ); +} + +void CustomProjectPart::updateMakeEnvironmentsMenu() +{ + QDomDocument &dom = *projectDom(); + bool makeUsed = ( DomUtil::readEntry( dom, "/kdevcustomproject/build/buildtool" ) == "make" ); + if ( makeUsed ) + { + QStringList l = allMakeEnvironments(); + m_makeEnvironmentsSelector->setItems( l ); + m_makeEnvironmentsSelector->setCurrentItem( l.findIndex( currentMakeEnvironment() ) ); + } + else + { + m_makeEnvironmentsSelector->clear(); + } + /* + m_makeEnvironmentsMenu->clear(); + QDomDocument &dom = *projectDom(); + + QStringList environments = allMakeEnvironments(); + QStringList::ConstIterator it; + int id = 0; + for (it = environments.begin(); it != environments.end(); ++it) + m_makeEnvironmentsMenu->insertItem(*it, id++); + } + */ +} + +void CustomProjectPart::makeEnvironmentsMenuActivated( int id ) +{ + QDomDocument &dom = *projectDom(); + QString environment = allMakeEnvironments()[id]; + DomUtil::writeEntry( dom, "/kdevcustomproject/make/selectedenvironment", environment ); +} + +void CustomProjectPart::slotCommandFinished( const QString& command ) +{ + kdDebug( 9025 ) << "CustomProjectPart::slotProcessFinished()" << endl; + + if ( m_buildCommand != command ) + return; + + m_buildCommand = QString::null; + + m_timestamp.clear(); + QStringList fileList = allFiles(); + QStringList::Iterator it = fileList.begin(); + while ( it != fileList.end() ) + { + QString fileName = *it; + ++it; + + m_timestamp[ fileName ] = QFileInfo( projectDirectory(), fileName ).lastModified(); + } + + emit projectCompiled(); + + if ( m_executeAfterBuild ) + { + slotExecute(); + m_executeAfterBuild = false; + } +} + +void CustomProjectPart::slotCommandFailed( const QString& /*command*/ ) +{ + m_lastCompilationFailed = true; + m_executeAfterBuild = false; +} + +bool CustomProjectPart::isDirty() +{ + if ( m_lastCompilationFailed ) return true; + + QStringList fileList = allFiles(); + QStringList::Iterator it = fileList.begin(); + while ( it != fileList.end() ) + { + QString fileName = *it; + ++it; + + QMap<QString, QDateTime>::Iterator it = m_timestamp.find( fileName ); + QDateTime t = QFileInfo( projectDirectory(), fileName ).lastModified(); + if ( it == m_timestamp.end() || *it != t ) + { + return true; + } + } + + return false; +} + + +QStringList CustomProjectPart::allMakeEnvironments() const +{ + QDomDocument &dom = *projectDom(); + + QStringList allConfigs; + + QDomNode node = + DomUtil::elementByPath( dom , "/kdevcustomproject/make/environments" ); + // extract the names of the different make environments + QDomElement childEl = node.firstChild().toElement(); + while ( !childEl.isNull() ) + { + QString config = childEl.tagName(); + allConfigs.append( config ); + childEl = childEl.nextSibling().toElement(); + } + if ( allConfigs.isEmpty() ) + allConfigs.append( "default" ); + + return allConfigs; +} + + +QString CustomProjectPart::currentMakeEnvironment() const +{ + QStringList allEnvs = allMakeEnvironments(); + QDomDocument &dom = *projectDom(); + QString environment = DomUtil::readEntry( dom, "/kdevcustomproject/make/selectedenvironment" ); + if ( environment.isEmpty() || !allEnvs.contains( environment ) ) + environment = allEnvs[0]; + return environment; +} + +/*! + \fn CustomProjectPart::distFiles() const + */ +QStringList CustomProjectPart::distFiles() const +{ + QStringList sourceList = allFiles(); + // Scan current source directory for any .pro files. + QString projectDir = projectDirectory(); + QDir dir( projectDir ); + QStringList files = dir.entryList( "*README*" ); + return sourceList + files; +} + +bool CustomProjectPart::containsNonProjectFiles( const QString& dir ) +{ + if ( isInBlacklist( dir ) ) + return false; + QStringList fileentries = QDir( dir ).entryList( filetypes().join( ";" ) ); + QStringList dirs = QDir( dir ).entryList( QDir::Dirs ); + QStringList subentries = fileentries + dirs; + subentries.remove( "." ); + subentries.remove( ".." ); + for ( QStringList::const_iterator it = subentries.begin(); it != subentries.end(); ++it ) + { + if ( isInBlacklist( *it ) ) + continue; + if ( QFileInfo( dir + "/" + *it ).isDir() && !isInBlacklist( *it ) ) + { + if ( containsNonProjectFiles( dir + "/" + *it ) ) + { + return true; + } + } + else if ( !project()->isProjectFile( URLUtil::canonicalPath( dir + "/" + *it ) ) + && !isInBlacklist( *it ) ) + { + return true; + } + } + return false; +} + +bool CustomProjectPart::containsProjectFiles( const QString& dir ) +{ + if ( isInBlacklist( dir ) ) + return false; + + QStringList fileentries = QDir( dir ).entryList( filetypes().join( ";" ) ); + QStringList dirs = QDir( dir ).entryList( QDir::Dirs ); + QStringList subentries = fileentries + dirs; + subentries.remove( "." ); + subentries.remove( ".." ); + for ( QStringList::const_iterator it = subentries.begin(); it != subentries.end(); ++it ) + { + if ( isInBlacklist( *it ) ) + continue; + + if ( QFileInfo( dir + "/" + *it ).isDir() && !isInBlacklist( *it ) ) + { + if ( containsProjectFiles( dir + "/" + *it ) ) + { + return true; + } + } + else if ( project()->isProjectFile( URLUtil::canonicalPath( dir + "/" + *it ) ) && !isInBlacklist( *it ) ) + { + return true; + } + } + return false; +} + +QStringList CustomProjectPart::projectFilesInDir( const QString& dir ) +{ + QStringList result; + QStringList fileentries = QDir( projectDirectory() + "/" + dir ).entryList( filetypes().join( ";" ) ); + QStringList dirs = QDir( projectDirectory() + "/" + dir ).entryList( QDir::Dirs ); + QStringList subentries = fileentries + dirs; + subentries.remove( "." ); + subentries.remove( ".." ); + for ( QStringList::const_iterator it = subentries.begin(); it != subentries.end(); ++it ) + { + if ( isInProject( dir + "/" + *it ) ) + { + result << ( *it ); + } + } + return result; +} + +QStringList CustomProjectPart::filetypes( ) const +{ + return DomUtil::readListEntry( *projectDom(), "/kdevcustomproject/filetypes", "filetype" ); +} + +bool CustomProjectPart::isProjectFileType( const QString& filename ) const +{ + QStringList types = filetypes(); + QRegExp re( "", true, true ); + for ( QStringList::const_iterator it = types.begin(); it != types.end(); ++it ) + { + re.setPattern( *it ); + int pos = re.search( filename ); + uint len = re.matchedLength(); + if ((( *it ).find( "*" ) != -1 || ( *it ).find( "?" ) != -1 ) && pos + len == filename.length() ) + return true; + else if ( filename.find( "/" ) != -1 && filename.find( *it ) != -1 ) + return true; + else if ( filename.find( "/" ) == -1 && filename == *it ) + return true; + } + return false; +} + +void CustomProjectPart::switchBlacklistEntry( const QString& path ) +{ + QStringList blacklist = this->blacklist(); + kdDebug( 9025 ) << "Switching path " << path << endl; + if ( !isInBlacklist( path ) ) + { + blacklist << path; + m_recursive = true; + removeFile( path ); + m_recursive = false; + } + else + { + blacklist.remove( path ); + } + updateBlacklist( blacklist ); +} + +QString CustomProjectPart::relativeToProject( const QString& abspath ) const +{ + QString path = abspath.mid( projectDirectory().length() + 1 ); + kdDebug( 9025 ) << "abspath: " << "|project dir: " << projectDirectory() << "|path: " << path << endl; + if ( path.endsWith( "/" ) ) + path = path.mid( 0, path.length() - 1 ); + if ( path.startsWith( "/" ) ) + path = path.mid( 1, path.length() ); + return path; +} + +bool CustomProjectPart::isInBlacklist( const QString& path ) const +{ + QString relpath = path; + QStringList blacklist = this->blacklist(); + if ( !QFileInfo( relpath ).isRelative() ) + relpath = relativeToProject( path ); + if ( blacklist.find( relpath ) != blacklist.end() ) + return true; + QStringList paths = QStringList::split( "/", relpath ); + QString parentpath; + for ( QStringList::const_iterator it = paths.begin(); it != paths.end(); ++it ) + { + parentpath += *it; + if ( blacklist.find( parentpath ) != blacklist.end() ) + return true; + parentpath = parentpath + "/"; + } + return false; +} + +void CustomProjectPart::updateBlacklist( const QStringList& l ) +{ + DomUtil::writeListEntry( *projectDom(), "kdevcustomproject/blacklist", "path", l ); +} + +QStringList CustomProjectPart::blacklist() const +{ + return DomUtil::readListEntry( *projectDom(), "kdevcustomproject/blacklist", "path" ); +} + +void CustomProjectPart::addNewFilesToProject( const QStringList& filelist ) +{ + QStringList addfiles; + for ( QStringList::const_iterator it = filelist.begin(); it != filelist.end(); ++it ) + { + if (( ! isInProject( *it ) ) && ( isProjectFileType( *it ) || QFileInfo( projectDirectory() + "/" + *it ).isDir() ) && !isInBlacklist( *it ) ) + { + addfiles << *it; + } + } + + if ( addfiles.isEmpty() ) + return; + + SelectNewFilesDialog *dlg = new SelectNewFilesDialog( addfiles, mainWindow()->main() ); + if ( dlg->exec() == KDialog::Accepted ) + { + m_first_recursive = false; + m_recursive = false; + QStringList blacklist = this->blacklist(); + QStringList excludelist = dlg->excludedPaths(); + QStringList removeFromExcludes; + for ( QStringList::const_iterator it = excludelist.begin(); it != excludelist.end(); ++it ) + { + if ( QFileInfo( projectDirectory() + "/" + *it ).isDir() ) + { + for ( ProjectFilesSet::ConstIterator it2 = m_sourceFilesSet.constBegin(); it2 != m_sourceFilesSet.constEnd(); ++it2 ) + { + if ( it2.key().find( *it ) != -1 ) + { + removeFromExcludes << *it; + } + } + } + } + for ( QStringList::const_iterator it = removeFromExcludes.begin(); it != removeFromExcludes.end(); ++it ) + { + excludelist.remove( *it ); + } + blacklist += excludelist; + updateBlacklist( blacklist ); + addFiles( dlg->includedPaths() ); + } +} + +void CustomProjectPart::setFiletypes( const QStringList& l ) +{ + DomUtil::writeListEntry( *projectDom(), "kdevcustomproject/filetypes", "filetype", l ); +} + + +/** + * @brief Is a given file (or a directory) part of this project? + * + * @param fileName + */ +bool CustomProjectPart::isInProject( const QString& fileName ) const +{ + return m_sourceFilesSet.contains( fileName ); +} + + +/** + * @brief Add a file (or a directory) to this project. + * + * @param fileName + * + * @see removeFromProject() + */ +void CustomProjectPart::addToProject( const QString& fileName ) +{ + m_sourceFilesSet.insert( fileName, false ); +} + + +/** + * @brief Remove a file (or a directory) from this project. + * + * @param fileName + */ +void CustomProjectPart::removeFromProject( const QString& fileName ) +{ + m_sourceFilesSet.remove( fileName ); +} + + +#include "customprojectpart.moc" + diff --git a/buildtools/custommakefiles/customprojectpart.h b/buildtools/custommakefiles/customprojectpart.h new file mode 100644 index 00000000..f3fb9ec4 --- /dev/null +++ b/buildtools/custommakefiles/customprojectpart.h @@ -0,0 +1,158 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2007 by Andreas Pakulat * + * apaku@gmx.de * + * * + * 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 _CUSTOMPROJECTPART_H_ +#define _CUSTOMPROJECTPART_H_ + +#include <qdict.h> +#include <qguardedptr.h> +#include <qmap.h> +#include <qdatetime.h> +#include <qvaluestack.h> + +#include <kdevbuildtool.h> + +class QListViewItem; +class QPopupMenu; +class QStringList; +class KDialogBase; +class CustomProjectWidget; +class Context; +class KSelectAction; + +class CustomProjectPart : public KDevBuildTool +{ + Q_OBJECT + +public: + CustomProjectPart( QObject *parent, const char *name, const QStringList & ); + ~CustomProjectPart(); + + QStringList allMakeEnvironments() const; + QString currentMakeEnvironment() const; + + bool isDirty(); + QStringList distFiles() const; + + virtual void openProject( const QString &dirName, const QString &projectName ); + virtual void closeProject(); + + virtual QString projectDirectory() const; + virtual QString projectName() const; + virtual QString mainProgram() const; + virtual QString activeDirectory() const; + virtual QStringList allFiles() const; + virtual void addFile( const QString &fileName ); + virtual void addFiles( const QStringList& fileList ); + virtual void removeFile( const QString &fileName ); + virtual void removeFiles( const QStringList &fileList ); + virtual QString buildDirectory() const; + virtual QString runDirectory() const; + virtual QString debugArguments() const; + virtual QString runArguments() const; + virtual DomUtil::PairList runEnvironmentVars() const; + QString relativeToProject( const QString& ) const; + + +private slots: + void populateProject(); + void projectConfigWidget( KDialogBase *dlg ); + void contextMenu( QPopupMenu *popup, const Context *context ); + void slotAddToProject(); + void slotRemoveFromProject(); + void slotAddToProjectRecursive(); + void slotRemoveFromProjectRecursive(); + void addNewFilesToProject( const QStringList& ); + void slotChangeBlacklist(); + void slotChooseActiveDirectory(); + void slotBuild(); + void slotBuildActiveDir(); + void slotCompileFile(); + void slotInstall(); + void slotInstallActiveDir(); + void slotInstallWithKdesu(); + void slotClean(); + void slotExecute(); + void updateTargetMenu(); + void targetMenuActivated( int id ); + void targetObjectFilesMenuActivated( int id ); + void targetOtherFilesMenuActivated( int id ); + void updateMakeEnvironmentsMenu(); + void makeEnvironmentsMenuActivated( int id ); + void slotCommandFinished( const QString& command ); + void slotCommandFailed( const QString& command ); + +private: + bool containsNonProjectFiles( const QString& url ); + QStringList projectFilesInDir( const QString& dir ); + bool containsProjectFiles( const QString& url ); + bool isProjectFileType( const QString& absFile ) const; + bool isInBlacklist( const QString& ) const; + void cleanFileList(); + void setFiletypes( const QStringList& ); + void findNewFiles( const QString& dir, QStringList& list) const; + + QStringList filetypes() const; + QStringList blacklist() const; + void updateBlacklist( const QStringList& ); + void saveProject(); + void startMakeCommand( const QString &dir, const QString &target, bool withKdesu = false ); + void parseMakefile( const QString& file ); + QString makeEnvironment() const; + void putEnvVarsInVarMap(); + void switchBlacklistEntry(const QString& ); + + bool isInProject( const QString& fileName ) const; + void addToProject( const QString& fileName ); + void removeFromProject( const QString& fileName ); + + /** + * @brief Set of all the project's files. + * + * @bug + * Due to deficiency in QT3, + * we have to use a map with next-to-useless element value, + * keyed by the file name, + * as a set-container replacement. + */ + typedef QMap<QString, bool> ProjectFilesSet; + + QString m_projectDirectory; + QString m_projectName; + QString m_filelistDir; + /** All the sources (files and directories) of this project. */ + ProjectFilesSet m_sourceFilesSet; + QPopupMenu *m_targetMenu; + QPopupMenu *m_targetObjectFilesMenu; + QPopupMenu *m_targetOtherFilesMenu; + KSelectAction *m_makeEnvironmentsSelector; + QStringList m_targets; + QStringList m_targetsObjectFiles; + QStringList m_targetsOtherFiles; + QStringList m_contextAddFiles; + QStringList m_contextRemoveFiles; + QString m_contextDirName; + + QMap<QString, QDateTime> m_timestamp; + bool m_executeAfterBuild; + QString m_buildCommand; + bool m_lastCompilationFailed; + QMap<QString, int> m_parsedMakefiles; + QValueStack<QString> m_makefilesToParse; + QMap<QString, QString> m_makefileVars; + bool m_recursive; + bool m_first_recursive; +}; + +#endif +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/custommakefiles/kdevcustomproject.desktop b/buildtools/custommakefiles/kdevcustomproject.desktop new file mode 100644 index 00000000..276f4c1a --- /dev/null +++ b/buildtools/custommakefiles/kdevcustomproject.desktop @@ -0,0 +1,91 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=Custom Project +Comment[br]=Raktres diouzhoc'h +Comment[ca]=Projecte a mida +Comment[cs]=Vlastní projekt +Comment[da]=Brugerdefineret projekt +Comment[de]=Benutzerdefiniertes Projekt für KDevelop +Comment[el]=Προσαρμοσμένo έργο +Comment[es]=Proyecto personalizado +Comment[et]=Kohandatav projekt +Comment[eu]=Proiektu pertsonalizatua +Comment[fa]=پروژۀ سفارشی +Comment[fr]=Projet personnalisé +Comment[ga]=Tionscadal Saincheaptha +Comment[gl]=Proxecto persoalizado +Comment[hi]=कस्टम परियोजना +Comment[hu]=Egyedi projekt +Comment[is]=Sérsniðið verkefni +Comment[it]=Progetto personalizzato +Comment[ja]=カスタムプロジェクト +Comment[ms]=Projek Tersendiri +Comment[nds]=Egen Projekt +Comment[ne]=अनुकूल परियोजना +Comment[nl]=Aangepast project +Comment[pl]=Własny projekt +Comment[pt]=Projecto Personalizado +Comment[pt_BR]=Projeto Personalizado +Comment[ru]=Особый проект +Comment[sk]=Vlastný projekt +Comment[sl]=Poljuben projekt +Comment[sr]=Произвољан пројекат +Comment[sr@Latn]=Proizvoljan projekat +Comment[sv]=Eget projekt +Comment[ta]=தனிப்பயன் பிராஜக்ட் +Comment[tg]=Лоиҳаи оддӣ +Comment[tr]=Özel Proje +Comment[zh_CN]=自定义工程 +Comment[zh_TW]=自訂專案 +Name=KDevCustomProject +Name[da]=KDevelop brugerdefineret projekt +Name[de]=Benutzerdefiniertes Projekt (KDevelop) +Name[hi]=के-डेव-कस्टम-परियोजना +Name[nds]=Egen Projekt (KDevelop) +Name[ne]=केडीई विकास अनुकूल परियोजना +Name[pl]=KDevWłasnyProjekt +Name[sk]=KDevVlastnýProjekt +Name[sv]=KDevelop eget projekt +Name[ta]=கெடெவ் தனிப்பயன் பிராஜக்ட் +Name[tg]=Лоиҳаи оддӣKDev +Name[zh_TW]=KDevelop 自訂專案 +GenericName=Custom Project +GenericName[br]=Raktres diouzhoc'h +GenericName[ca]=Projecte a mida +GenericName[da]=Brugerdefineret projekt +GenericName[de]=Benutzerdefiniertes Projekt +GenericName[el]=Προσαρμοσμένο έργο +GenericName[es]=Proyecto personalizado +GenericName[et]=Kohandatav projekt +GenericName[eu]=Proiektu pertsonalizatua +GenericName[fa]=پروژۀ سفارشی +GenericName[fr]=Projet personnalisé +GenericName[ga]=Tionscadal Saincheaptha +GenericName[gl]=Proxecto persoalizado +GenericName[hi]=कस्टम परियोजना +GenericName[hu]=Egyedi projekt +GenericName[it]=Progetto personalizzato +GenericName[ja]=カスタムプロジェクト +GenericName[ms]=Projek Tersendiri +GenericName[nds]=Egen Projekt +GenericName[ne]=अनुकूल परियोजना +GenericName[nl]=Aangepast project +GenericName[pl]=Projekt: własny +GenericName[pt]=Projecto Personalizado +GenericName[pt_BR]=Projeto Personalizado +GenericName[ru]=Особый проект +GenericName[sk]=Vlastný projekt +GenericName[sl]=Poljuben projekt +GenericName[sr]=Произвољан пројекат +GenericName[sr@Latn]=Proizvoljan projekat +GenericName[sv]=Eget projekt +GenericName[ta]=தனிப்பயன் பிராஜக்ட் +GenericName[tg]=Лоиҳаи оддӣ +GenericName[tr]=Özel Proje +GenericName[zh_CN]=自定义工程 +GenericName[zh_TW]=自訂專案 +ServiceTypes=KDevelop/Project +X-KDE-Library=libkdevcustomproject +X-KDevelop-Version=5 +X-KDevelop-Args= diff --git a/buildtools/custommakefiles/kdevcustomproject.rc b/buildtools/custommakefiles/kdevcustomproject.rc new file mode 100644 index 00000000..c744b4be --- /dev/null +++ b/buildtools/custommakefiles/kdevcustomproject.rc @@ -0,0 +1,30 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KDevCustomProject" version="7"> +<MenuBar> + <Menu name="project" > + <Action name="repopulate_project" /> + <Action name="addnewfiles_project" /> + </Menu> + <Menu name="build" > + <Action name="build_build" /> + <Action name="build_buildactivetarget" /> + <Action name="build_compilefile" /> + <Action name="build_target" /> + <Action name="build_install" /> + <Action name="build_installactivetarget" /> + <Action name="build_make_environment" /> + <Action name="build_clean" /> + <Separator/> + <Action name="build_execute" /> + </Menu> +</MenuBar> +<ToolBar name="buildToolBar" noMerge="1"> + <Action name="build_build" group="build_operations" /> + <Action name="build_buildactivetarget" group="build_operations" /> + <Action name="build_compilefile" group="build_operations" /> + <Separator group="build_operations"/> + <Action name="build_install" group="build_operations" /> + <Action name="build_execute" group="build_operations" /> +</ToolBar> +</kpartgui> + diff --git a/buildtools/custommakefiles/selectnewfilesdialog.cpp b/buildtools/custommakefiles/selectnewfilesdialog.cpp new file mode 100644 index 00000000..cfcb84e6 --- /dev/null +++ b/buildtools/custommakefiles/selectnewfilesdialog.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + * Copyright (C) 2007 by Andreas Pakulat * + * apaku@gmx.de * + * * + * 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 "selectnewfilesdialog.h" + +#include <qlistview.h> +#include <klistview.h> +#include <qheader.h> +#include <qstringlist.h> +#include <klocale.h> +#include <kdebug.h> +#include "selectnewfilesdialogbase.h" + +SelectNewFilesDialog::SelectNewFilesDialog( QStringList paths, QWidget* parent, const char* name ) + : KDialogBase( parent, name, true, i18n("Add newly created files to project"), KDialogBase::Ok|KDialogBase::Cancel ) +{ + m_widget = new SelectNewFilesDialogBase(this); + m_widget->fileView->header()->hide(); + m_widget->fileView->addColumn(i18n("Path") ); + for( QStringList::const_iterator it = paths.begin(); it != paths.end(); ++it) + { + addPath(0, *it); + } + setMainWidget( m_widget ); + resize( 300,400 ); +} + +SelectNewFilesDialog::~SelectNewFilesDialog() +{} + +void SelectNewFilesDialog::slotCancel() +{ + excludePaths.clear(); + includePaths.clear(); + KDialogBase::slotCancel(); +} + +void SelectNewFilesDialog::checkItem( QCheckListItem* item, const QString& curpath ) +{ + if( !item ) + return; + + QString path = curpath + item->text(); + if( item->state() != QCheckListItem::Off ) + includePaths << path; + else + excludePaths << path; + if( item->firstChild() ) + { + checkItem( static_cast<QCheckListItem*>(item->firstChild()), path+"/" ); + } + if( item->nextSibling() ) + { + checkItem( static_cast<QCheckListItem*>(item->nextSibling()), curpath ); + } +} + +void SelectNewFilesDialog::slotOk() +{ + QCheckListItem* item = static_cast<QCheckListItem*> (m_widget->fileView->firstChild()); + checkItem( item, "" ); + kdDebug(9025) << "Inc List:" << includePaths << endl; + kdDebug(9025) << "Exc List:" << excludePaths << endl; + KDialogBase::slotOk(); +} + +void SelectNewFilesDialog::addPath( QCheckListItem* item, const QString& path ) +{ + if( path.isEmpty() ) + return; + + QStringList parts = QStringList::split("/", path ); + QString name = parts.first(); + parts.pop_front(); + QCheckListItem* i = createItem( item, name, parts.size() ); + i->setState( QCheckListItem::On ); + i->setTristate( true ); + addPath(i, parts.join("/") ); +} + +QCheckListItem* SelectNewFilesDialog::createItem( QCheckListItem* parent, const QString& name, int count ) +{ + QCheckListItem::Type t = QCheckListItem::CheckBox; + if( count > 0 ) + t = QCheckListItem::CheckBoxController; + + if( parent == 0 ) + { + QListViewItem* item = m_widget->fileView->firstChild(); + while( item ) + { + if( item->text( 0 ) == name ) + return static_cast<QCheckListItem*>(item); + item = item->nextSibling(); + } + return new QCheckListItem( m_widget->fileView, name, t ); + }else + { + QListViewItem* item = parent->firstChild(); + while( item ) + { + if( item->text( 0 ) == name ) + return static_cast<QCheckListItem*>(item); + item = item->nextSibling(); + } + return new QCheckListItem( parent, name, t ); + } +} + +QStringList SelectNewFilesDialog::excludedPaths() const +{ + return excludePaths; +} + +QStringList SelectNewFilesDialog::includedPaths() const +{ + return includePaths; +} + +#include "selectnewfilesdialog.moc" + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/custommakefiles/selectnewfilesdialog.h b/buildtools/custommakefiles/selectnewfilesdialog.h new file mode 100644 index 00000000..b970dc7d --- /dev/null +++ b/buildtools/custommakefiles/selectnewfilesdialog.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2007 by Andreas Pakulat * + * apaku@gmx.de * + * * + * 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 SELECTNEWFILESDIALOG_H +#define SELECTNEWFILESDIALOG_H + +#include "kdialogbase.h" + +class QCheckListItem; +class QStringList; +class SelectNewFilesDialogBase; + +class SelectNewFilesDialog : public KDialogBase +{ +Q_OBJECT + +public: + SelectNewFilesDialog( QStringList paths, QWidget* parent = 0, const char* name = 0 ); + ~SelectNewFilesDialog(); + + QStringList excludedPaths() const; + QStringList includedPaths() const; + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + virtual void slotCancel(); + virtual void slotOk(); +private: + void addPath( QCheckListItem* , const QString& ); + void checkItem( QCheckListItem* item, const QString& curpath ); + QCheckListItem* createItem( QCheckListItem*, const QString&, int ); + SelectNewFilesDialogBase* m_widget; + QStringList excludePaths; + QStringList includePaths; +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/custommakefiles/selectnewfilesdialogbase.ui b/buildtools/custommakefiles/selectnewfilesdialogbase.ui new file mode 100644 index 00000000..fbd5b5ec --- /dev/null +++ b/buildtools/custommakefiles/selectnewfilesdialogbase.ui @@ -0,0 +1,50 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>SelectNewFilesDialogBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>SelectNewFilesDialogBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>532</width> + <height>324</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Files to add to the Project:</string> + </property> + </widget> + <widget class="KListView"> + <property name="name"> + <cstring>fileView</cstring> + </property> + <property name="rootIsDecorated"> + <bool>true</bool> + </property> + <property name="itemsMovable"> + <bool>false</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Select the files to add to the project</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Select the files and directories that should be added to the list of project files. All other files and directories will be put into the blacklist.</string> + </property> + </widget> + </vbox> +</widget> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/buildtools/lib/Makefile.am b/buildtools/lib/Makefile.am new file mode 100644 index 00000000..c772e395 --- /dev/null +++ b/buildtools/lib/Makefile.am @@ -0,0 +1,8 @@ +# This directory collects some classes related to +# project management for the sole purpose that they +# can be shared between parts. + +SUBDIRS = parsers widgets base + +DOXYGEN_EMPTY = YES +include ../../Doxyfile.am diff --git a/buildtools/lib/base/Mainpage.dox b/buildtools/lib/base/Mainpage.dox new file mode 100644 index 00000000..dbf199a5 --- /dev/null +++ b/buildtools/lib/base/Mainpage.dox @@ -0,0 +1,19 @@ +/** +@mainpage The KDevelop Buildtool Base Library + +This library contains base classes for KDevelop builtool support plugins. + +<b>Link with</b>: -lkdevbuildbase + +<b>Include path</b>: -I\$(kde_includes)/kdevelop/buildtools/base + +\section btbaseoverview Overview +This library is created to provide KDevBuildTool compat class which can be used +as drop-in replacement of KDevProject class for buildtool support plugins +written for old KDevelop architecture (before version 3.2). + +Nevertheless, it can be useful for new buildtool plugins as well because it provides +useful methods to get application and make frontend extensions. + +*/ + diff --git a/buildtools/lib/base/Makefile.am b/buildtools/lib/base/Makefile.am new file mode 100644 index 00000000..6c9f6df6 --- /dev/null +++ b/buildtools/lib/base/Makefile.am @@ -0,0 +1,15 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/util -I$(top_srcdir)/lib/widgets/propeditor \ + $(all_includes) +METASOURCES = AUTO +lib_LTLIBRARIES = libkdevbuildbase.la +libkdevbuildbase_la_LDFLAGS = $(all_libraries) +libkdevbuildbase_la_LIBADD = $(top_builddir)/lib/interfaces/libkdevinterfaces.la $(LIB_QT) $(LIB_KDEUI) +libkdevbuildbase_la_SOURCES = kdevbuildtool.cpp +kdevelopbuildtoolsincludedir = $(includedir)/kdevelop/buildtools/base +kdevelopbuildtoolsinclude_HEADERS = kdevbuildtool.h + +DOXYGEN_REFERENCES = dcop interfaces kdecore kdefx kdeui khtml kmdi kio kjs kparts kutils kdevutil kdevinterfaces kdevextensions +DOXYGEN_PROJECTNAME = KDevelop Buildtool Base Library +DOXYGEN_DOCDIRPREFIX = kdevbt +include ../../../Doxyfile.am diff --git a/buildtools/lib/base/kdevbuildtool.cpp b/buildtools/lib/base/kdevbuildtool.cpp new file mode 100644 index 00000000..a8b7de3a --- /dev/null +++ b/buildtools/lib/base/kdevbuildtool.cpp @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Alexander Dymo <adymo@kdevelop.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include "kdevbuildtool.h" + +#include <kdevmakefrontend.h> +#include <kdevappfrontend.h> + +KDevBuildTool::KDevBuildTool(const KDevPluginInfo* info, QObject* parent, const char* name) + :KDevProject(info, parent, name) +{ +} + +KDevMakeFrontend * KDevBuildTool::makeFrontend() +{ + return extension<KDevMakeFrontend>("KDevelop/MakeFrontend"); +} + +KDevAppFrontend * KDevBuildTool::appFrontend() +{ + return extension<KDevAppFrontend>("KDevelop/AppFrontend"); +} + diff --git a/buildtools/lib/base/kdevbuildtool.h b/buildtools/lib/base/kdevbuildtool.h new file mode 100644 index 00000000..95ed8d37 --- /dev/null +++ b/buildtools/lib/base/kdevbuildtool.h @@ -0,0 +1,41 @@ +/* This file is part of the KDE project + Copyright (C) 1999-2001 Bernd Gehrmann <bernd@kdevelop.org> + Copyright (C) 2004 Alexander Dymo <adymo@kdevelop.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef KDEVBUILDTOOL_H +#define KDEVBUILDTOOL_H + +#include <kdevproject.h> + +class KDevMakeFrontend; +class KDevAppFrontend; + +/**Base class for KDevelop build tool support plugins.*/ +class KDevBuildTool: public KDevProject +{ +public: + KDevBuildTool(const KDevPluginInfo* info, QObject* parent, const char* name); + + /**@return The make frontend.*/ + KDevMakeFrontend *makeFrontend(); + /**@return The application frontend.*/ + KDevAppFrontend *appFrontend(); + +}; + +#endif diff --git a/buildtools/lib/parsers/Makefile.am b/buildtools/lib/parsers/Makefile.am new file mode 100644 index 00000000..a1c9f256 --- /dev/null +++ b/buildtools/lib/parsers/Makefile.am @@ -0,0 +1,8 @@ +# This directory collects some classes related to +# project management for the sole purpose that they +# can be shared between parts. + +SUBDIRS = qmake autotools + +DOXYGEN_EMPTY = YES +include ../../../Doxyfile.am diff --git a/buildtools/lib/parsers/autotools/Mainpage.dox b/buildtools/lib/parsers/autotools/Mainpage.dox new file mode 100644 index 00000000..99d200d9 --- /dev/null +++ b/buildtools/lib/parsers/autotools/Mainpage.dox @@ -0,0 +1,11 @@ +/** +@mainpage The KDevelop Makefile.am Parser + +This library contains a parser that handles Makefile.am. + +<b>Link with</b>: -lkdevautotoolsparser + +<b>Include path</b>: -I\$(kde_includes)/kdevelop/buildtools/parsers/autotools + +*/ + diff --git a/buildtools/lib/parsers/autotools/Makefile.am b/buildtools/lib/parsers/autotools/Makefile.am new file mode 100644 index 00000000..c0776c2f --- /dev/null +++ b/buildtools/lib/parsers/autotools/Makefile.am @@ -0,0 +1,24 @@ +# This directory collects some classes related to +# project management for the sole purpose that they +# can be shared between parts. +SUBDIRS = . tests +INCLUDES = -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/util -I$(top_srcdir)/lib/widgets/propeditor \ + $(all_includes) +METASOURCES = AUTO +noinst_LTLIBRARIES = libkdevautotoolsparser.la +libkdevautotoolsparser_la_LDFLAGS = $(all_libraries) $(LIB_KIO) +libkdevautotoolsparser_la_SOURCES = autotoolsast.cpp autotoolsdriver.cpp autotools_yacc.cpp + +parser: + cd $(srcdir) ; \ + bison -d autotools.yy -o autotools_yacc.cpp ; \ + mv -f autotools_yacc.hpp autotools_yacc.h ; \ + flex -oautotools_lex.cpp autotools.ll + +EXTRA_DIST = autotools.yy autotools.ll + +DOXYGEN_REFERENCES = dcop interfaces kdecore kdefx kdeui khtml kmdi kio kjs kparts kutils +DOXYGEN_PROJECTNAME = KDevelop AutoTools Parser +DOXYGEN_DOCDIRPREFIX = kdevparser +include ../../../../Doxyfile.am diff --git a/buildtools/lib/parsers/autotools/autotools.ll b/buildtools/lib/parsers/autotools/autotools.ll new file mode 100644 index 00000000..ae646edb --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotools.ll @@ -0,0 +1,136 @@ +%{ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include <autotools_yacc.h> +#include <stdlib.h> + +/** +@file autotools.ll +Autotools Lexer + +There are 3 types of identifiers recognized by this lexer: +-id_simple: examples of such identifiers are qmake variables and scoped variables +at the left of the operator in assignments (like "SOURCES" in "SOURCES+=foo.cpp goo.cpp"); +-id_list: those are "value list identifiers" at the right side in assignments +(like "foo.cpp goo.cpp" in "SOURCES+=foo.cpp goo.cpp"); +-id_args: function arguments recognized as one identifier +(example: ""${QMAKE_FILE} is intended only for Windows!"" +in "!win32-*:!wince-*:error("${QMAKE_FILE} is intended only for Windows!")" statements). +. + +To recognize those identifiers two additional start conditions are used: list and funcargs. + +@note "Not" operator (!) is recognized as a part of an identifier. Linefeeds passed to +the parser as NEWLINE tokens to preserve file structure but whitespaces are stripped +so no indentation is preserved by this lexer (and parser). + +To debug this lexer, put the line below into the next flex file section. +%option debug +*/ +%} +%option noyywrap + +%x list +%x funcargs +%x conditional + +delim [ \t] +ws {delim}+ +letter [A-Za-z] +digit [0-9] +id_simple ({digit}|{letter}|\!|-|_|\*|\$|@)({letter}|{digit}|\||\!|-|_|\*|\$|\(|\.|\+|\-|\)|\/)* +id_list [^\n]*\\{ws}* +id_args [^\n]*\) +number {digit}+ +comment #.* +comment_cont {ws}*#.*\n +id_list_single [^\n]* +cont \\{ws}*\n +keywords (if|else|endif|include) +rule [\t]+[^\n]* + +%% + +<list,INITIAL>{ws} {} +<list,INITIAL>{cont} { BEGIN(list); return CONT; } +{keywords} { + yylval.value = yytext; + if ( yylval.value == "if" ) + return IF_KEYWORD; + + if ( yylval.value == "else" ) + return ELSE_KEYWORD; + + if ( yylval.value == "endif" ) + return ENDIF_KEYWORD; + + return KEYWORD; +} + + +{id_simple} { yylval.value = yytext; return (ID_SIMPLE); } + +<INITIAL>{rule} { + yylval.value = yytext; + return RULE; +} + +<list>{id_list} { + yylval.value = yytext; + yylval.value = yylval.value.mid(0, yylval.value.findRev("\\")); + unput('\\'); + BEGIN(INITIAL); + return (ID_LIST); + } + +<list>{comment_cont} { + yylval.value = yytext; + BEGIN(list); + return (LIST_COMMENT); + } + +<list>{id_list_single} { + yylval.value = yytext; + BEGIN(INITIAL); + return (ID_LIST_SINGLE); + } + +<funcargs>{id_args} { + yylval.value = yytext; + yylval.value = yylval.value.mid(0, yylval.value.length()-1); + unput(')'); + BEGIN(INITIAL); + return (ID_ARGS); + } + +"=" { BEGIN(list); yylval.value = yytext; return EQ; } +"+=" { BEGIN(list); yylval.value = yytext; return PLUSEQ; } +"{" { return LCURLY; } +"}" { return RCURLY; } +":" { BEGIN(list); yylval.value = yytext; return COLON; } +<list,INITIAL>"\n" { BEGIN(INITIAL); return NEWLINE; } +{comment} { yylval.value = yytext; return (COMMENT); } + +%% + diff --git a/buildtools/lib/parsers/autotools/autotools.yy b/buildtools/lib/parsers/autotools/autotools.yy new file mode 100644 index 00000000..e124ee85 --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotools.yy @@ -0,0 +1,323 @@ +%{ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/** +@file qmake.yy +Autotools Parser + +Simple LALR parser which builds the syntax tree (see @ref Autotools::AST). + +@todo Recognize comments after statements like: +noinst_HEADERS = foo.h #regognize me + +@fixme Parser fails on files that do not end with a newline +@fixme 1 shift/reduce conflict in "line_body" rule +*/ + +#include <qvaluestack.h> +#include "autotoolsast.h" + +#define YYSTYPE_IS_DECLARED + +using namespace AutoTools; + +/** +The yylval type. +*/ +struct Result { + Result(): node(0) {} + + /**Type of semantic value for simple grammar rules.*/ + QString value; + /**Type of semantic value for grammar rules which are parts of AST.*/ + AST *node; + /**Type of semantic value for "multiline_values" grammar rule. + Each line of multiline value is stored as a string in the list. + + For example we have in Makefile.am file: + @code + foo_SOURCES = foo1.cpp \ + foo2.cpp \ + foo3.cpp foo4.cpp + @endcode + The string list will be populated with three strings: + <pre> + foo1.cpp + foo2.cpp + foo3.cpp foo4.cpp + </pre> + */ + QStringList values; +}; + +typedef Result YYSTYPE; + +void yyerror(const char *str) { + printf("bison error: %s\n", str); +} + +int yylex(); + +/** +The stack to store ProjectAST pointers when a new child +ProjectAST is created and filled with statements. + +Parser creates root ProjectAST for a .pro file, pushes it onto the stack and starts +adding statements. Each statement is added as a child StatementAST to the ProjectAST +currently on the top in the stack. + +When a scope or function scope statement is parsed, the child ProjectAST is created +and pushed onto the stack. Therefore all statements which belong to the scope +or function scope are added as childs to their direct parent (scope or function scope). +*/ +QValueStack<ProjectAST*> projects; + +/** +The current depth of AST node is stored here. +AST depth is important to know because automatic indentation can +be easily implemented (the parser itself looses all information +about indentation). +*/ +int depth = 0; + +/* +To debug this parser, put the line below into the next bison file section. +Don't forget to uncomment "yydebug = 1" line in qmakedriver.cpp. +%debug +*/ +%} + +%token ID_SIMPLE +%token ID_LIST +%token LBRACE +%token EQ +%token PLUSEQ +%token MINUSQE +%token STAREQ +%token TILDEEQ +%token LBRACE +%token RBRACE +%token COLON +%token NUMSIGN +%token NEWLINE +%token NUMBER +%token COMMENT +%token CONT +%token DOT +%token RCURLY +%token LCURLY +%token ID_ARGS +%token LIST_COMMENT +%token ID_LIST_SINGLE +%token IF_KEYWORD +%token ELSE_KEYWORD +%token ENDIF_KEYWORD +%token KEYWORD +%token RULE + +%% + +project : +{ + ProjectAST *projectAST = new ProjectAST(); + projects.push(projectAST); +} +statements +; + +statements : statements statement +{ + projects.top()->addChildAST($<node>2); + + if ( $<node>2->nodeType() == AST::ProjectAST && + static_cast<ProjectAST*>( $<node>2 )->scopedID == "if" ) + { + $<node>2->setDepth(depth); + depth++; + } + else if ( $<node>2->nodeType() == AST::ProjectAST && + static_cast<ProjectAST*>( $<node>2 )->scopedID == "else" ) + { + --depth; + $<node>2->setDepth(depth); + ++depth; + } + else if ( $<node>2->nodeType() == AST::ProjectAST && + static_cast<ProjectAST*>( $<node>2 )->scopedID == "endif" ) + { + --depth; + $<node>2->setDepth(depth); + } + else + $<node>2->setDepth(depth); +} +| +; + +statement : variable_assignment +{ + $<node>$ = $<node>1; +} +| automake_if +{ + $<node>$ = $<node>1; +} +| else_statement +{ + $<node>$ = $<node>1; +} +| endif_statement +{ + $<node>$ = $<node>1; +} +| target +{ + $<node>$ = $<node>1; +} +| am_rule +{ + $<node>$ = $<node>1; +} +| include_directive +{ + $<node>$ = $<node>1; +} +| comment +{ + $<node>$ = $<node>1; +} +| emptyline +{ + $<node>$ = new NewLineAST(); +} +; + +automake_if: IF_KEYWORD scoped_identifier +{ + ConditionAST* projectAST = new ConditionAST(); + projectAST->type = "if"; + projectAST->conditionName = $<value>2; + $<node>$ = projectAST; +}; + +endif_statement: ENDIF_KEYWORD +{ + ConditionAST* past = new ConditionAST(); + past->type= "endif"; + $<node>$ = past; +} +| ENDIF_KEYWORD scoped_identifier +{ + ConditionAST* past = new ConditionAST(); + past->type= "endif"; + past->conditionName = $<value>2; + $<node>$ = past; +} +; + +else_statement: ELSE_KEYWORD +{ + ConditionAST* past = new ConditionAST(); + past->type = "else"; + $<node>$ = past; +} +| ELSE_KEYWORD scoped_identifier +{ + ConditionAST* past = new ConditionAST(); + past->type = "else"; + past->conditionName = $<value>2; + $<node>$ = past; +} +; + +variable_assignment : scoped_identifier operator multiline_values +{ + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $<value>1; + node->op = $<value>2; + node->values = $<values>3; + $<node>$ = node; +} +; + +scoped_identifier : ID_SIMPLE scoped_identifier +{ $<value>$ = $<value>1 + $<value>2; } +| ID_SIMPLE +; + +multiline_values : multiline_values line_body +{ + $<values>$.append($<value>2); +} +| { $<values>$.clear(); } + ; + +line_body : ID_LIST CONT { $<value>$ = $<value>1 + " \\\n"; } + | ID_LIST_SINGLE NEWLINE { $<value>$ = $<value>1 + "\n"; } + | CONT { $<value>$ = "\\\n"; } + | LIST_COMMENT + ; + +target: scoped_identifier COLON multiline_values +{ + AutomakeTargetAST *node = new AutomakeTargetAST(); + node->target = $<value>1; + node->deps = $<values>3; + $<node>$ = node; +} +; + +am_rule: RULE +{ + ProjectAST* node = new ProjectAST(ProjectAST::Rule); + node->scopedID = $<value>1; + $<node>$ = node; +} +; + +include_directive: KEYWORD scoped_identifier +{ + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $<value>1; + node->values = QStringList($<value>2); + $<node>$ = node; +} +; + +operator : EQ | PLUSEQ +; + +comment : COMMENT NEWLINE +{ + CommentAST *node = new CommentAST(); + node->comment = $<value>1 + "\n"; + $<node>$ = node; +} +; + +emptyline : NEWLINE +; +%% + +#include "autotools_lex.cpp" diff --git a/buildtools/lib/parsers/autotools/autotools_lex.cpp b/buildtools/lib/parsers/autotools/autotools_lex.cpp new file mode 100644 index 00000000..ac307240 --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotools_lex.cpp @@ -0,0 +1,1894 @@ +#line 2 "autotools_lex.cpp" + +#line 4 "autotools_lex.cpp" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 31 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef unsigned int yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart (FILE *input_file ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +void yy_delete_buffer (YY_BUFFER_STATE b ); +void yy_flush_buffer (YY_BUFFER_STATE b ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state (void ); + +static void yyensure_buffer_stack (void ); +static void yy_load_buffer_state (void ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define yywrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + +typedef int yy_state_type; + +extern int yylineno; + +int yylineno = 1; + +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 17 +#define YY_END_OF_BUFFER 18 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[64] = + { 0, + 0, 0, 8, 8, 0, 0, 0, 0, 18, 17, + 1, 15, 1, 4, 16, 17, 14, 10, 17, 4, + 4, 12, 13, 8, 1, 8, 6, 17, 9, 5, + 1, 1, 1, 4, 4, 16, 11, 0, 2, 4, + 4, 3, 4, 8, 6, 1, 8, 8, 7, 6, + 6, 0, 9, 4, 4, 4, 6, 6, 4, 4, + 4, 4, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 4, 5, 1, 6, 7, 1, 1, 1, 8, + 9, 10, 11, 1, 12, 13, 14, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 16, 1, 1, + 17, 1, 1, 18, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 1, 20, 1, 1, 21, 1, 19, 19, 22, 23, + + 24, 25, 19, 19, 26, 19, 19, 27, 19, 28, + 19, 19, 19, 19, 29, 19, 30, 19, 19, 19, + 19, 19, 31, 32, 33, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[34] = + { 0, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[72] = + { 0, + 0, 0, 32, 51, 34, 36, 0, 0, 155, 156, + 38, 156, 42, 67, 0, 137, 156, 156, 45, 23, + 31, 156, 156, 133, 63, 38, 98, 134, 133, 0, + 58, 59, 62, 0, 0, 0, 156, 101, 156, 112, + 117, 0, 117, 118, 104, 105, 65, 67, 156, 110, + 113, 127, 126, 110, 106, 104, 117, 124, 104, 93, + 99, 96, 156, 144, 146, 148, 109, 97, 83, 150, + 72 + } ; + +static yyconst flex_int16_t yy_def[72] = + { 0, + 63, 1, 64, 64, 65, 65, 66, 66, 63, 63, + 67, 63, 63, 63, 68, 63, 63, 63, 63, 14, + 14, 63, 63, 69, 69, 70, 69, 71, 71, 67, + 67, 67, 63, 14, 14, 68, 63, 63, 63, 14, + 14, 14, 14, 69, 69, 69, 70, 70, 63, 70, + 69, 71, 71, 14, 14, 14, 69, 70, 14, 14, + 14, 14, 0, 63, 63, 63, 63, 63, 63, 63, + 63 + } ; + +static yyconst flex_int16_t yy_nxt[190] = + { 0, + 10, 11, 12, 13, 14, 15, 14, 10, 10, 14, + 16, 14, 10, 10, 14, 17, 18, 14, 14, 19, + 14, 14, 14, 20, 14, 21, 14, 14, 14, 14, + 22, 10, 23, 25, 12, 25, 10, 26, 10, 31, + 49, 32, 29, 33, 29, 33, 38, 39, 38, 40, + 41, 27, 25, 12, 25, 42, 26, 50, 43, 31, + 32, 32, 32, 33, 46, 33, 46, 49, 47, 49, + 27, 34, 52, 34, 34, 34, 34, 34, 35, 34, + 34, 34, 45, 44, 50, 34, 50, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 36, 34, 51, + + 39, 51, 38, 39, 38, 57, 46, 57, 46, 30, + 47, 58, 49, 58, 51, 39, 51, 45, 57, 42, + 57, 62, 61, 45, 45, 58, 49, 58, 42, 50, + 60, 59, 45, 42, 53, 53, 45, 45, 56, 55, + 54, 53, 53, 50, 24, 24, 28, 28, 10, 10, + 48, 48, 45, 37, 63, 9, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63 + } ; + +static yyconst flex_int16_t yy_chk[190] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 3, 3, 5, 3, 6, 11, + 26, 11, 5, 13, 6, 13, 19, 19, 19, 20, + 20, 3, 4, 4, 4, 21, 4, 26, 21, 31, + 32, 31, 32, 33, 25, 33, 25, 47, 25, 48, + 4, 14, 71, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 25, 69, 47, 14, 48, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 68, 14, 27, + + 27, 27, 38, 38, 38, 45, 46, 45, 46, 67, + 46, 50, 50, 50, 51, 51, 51, 27, 57, 62, + 57, 61, 60, 45, 46, 58, 58, 58, 59, 50, + 56, 55, 51, 54, 53, 52, 57, 44, 43, 41, + 40, 29, 28, 58, 64, 64, 65, 65, 66, 66, + 70, 70, 24, 16, 9, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "autotools.ll" +#line 2 "autotools.ll" +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include <autotools_yacc.h> +#include <stdlib.h> + +/** +@file autotools.ll +Autotools Lexer + +There are 3 types of identifiers recognized by this lexer: +-id_simple: examples of such identifiers are qmake variables and scoped variables +at the left of the operator in assignments (like "SOURCES" in "SOURCES+=foo.cpp goo.cpp"); +-id_list: those are "value list identifiers" at the right side in assignments +(like "foo.cpp goo.cpp" in "SOURCES+=foo.cpp goo.cpp"); +-id_args: function arguments recognized as one identifier +(example: ""${QMAKE_FILE} is intended only for Windows!"" +in "!win32-*:!wince-*:error("${QMAKE_FILE} is intended only for Windows!")" statements). +. + +To recognize those identifiers two additional start conditions are used: list and funcargs. + +@note "Not" operator (!) is recognized as a part of an identifier. Linefeeds passed to +the parser as NEWLINE tokens to preserve file structure but whitespaces are stripped +so no indentation is preserved by this lexer (and parser). + +To debug this lexer, put the line below into the next flex file section. +%option debug +*/ + + + +#line 559 "autotools_lex.cpp" + +#define INITIAL 0 +#define list 1 +#define funcargs 2 +#define conditional 3 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include <unistd.h> +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (void ); +#else +extern int yywrap (void ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 73 "autotools.ll" + + +#line 716 "autotools_lex.cpp" + + if ( (yy_init) ) + { + (yy_init) = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 64 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 156 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 75 "autotools.ll" +{} + YY_BREAK +case 2: +/* rule 2 can match eol */ +YY_RULE_SETUP +#line 76 "autotools.ll" +{ BEGIN(list); return CONT; } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 77 "autotools.ll" +{ + yylval.value = yytext; + if ( yylval.value == "if" ) + return IF_KEYWORD; + + if ( yylval.value == "else" ) + return ELSE_KEYWORD; + + if ( yylval.value == "endif" ) + return ENDIF_KEYWORD; + + return KEYWORD; +} + YY_BREAK +case 4: +YY_RULE_SETUP +#line 92 "autotools.ll" +{ yylval.value = yytext; return (ID_SIMPLE); } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 94 "autotools.ll" +{ + yylval.value = yytext; + return RULE; +} + YY_BREAK +case 6: +YY_RULE_SETUP +#line 99 "autotools.ll" +{ + yylval.value = yytext; + yylval.value = yylval.value.mid(0, yylval.value.findRev("\\")); + unput('\\'); + BEGIN(INITIAL); + return (ID_LIST); + } + YY_BREAK +case 7: +/* rule 7 can match eol */ +YY_RULE_SETUP +#line 107 "autotools.ll" +{ + yylval.value = yytext; + BEGIN(list); + return (LIST_COMMENT); + } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 113 "autotools.ll" +{ + yylval.value = yytext; + BEGIN(INITIAL); + return (ID_LIST_SINGLE); + } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 119 "autotools.ll" +{ + yylval.value = yytext; + yylval.value = yylval.value.mid(0, yylval.value.length()-1); + unput(')'); + BEGIN(INITIAL); + return (ID_ARGS); + } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 127 "autotools.ll" +{ BEGIN(list); yylval.value = yytext; return EQ; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 128 "autotools.ll" +{ BEGIN(list); yylval.value = yytext; return PLUSEQ; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 129 "autotools.ll" +{ return LCURLY; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 130 "autotools.ll" +{ return RCURLY; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 131 "autotools.ll" +{ BEGIN(list); yylval.value = yytext; return COLON; } + YY_BREAK +case 15: +/* rule 15 can match eol */ +YY_RULE_SETUP +#line 132 "autotools.ll" +{ BEGIN(INITIAL); return NEWLINE; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 133 "autotools.ll" +{ yylval.value = yytext; return (COMMENT); } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 135 "autotools.ll" +ECHO; + YY_BREAK +#line 922 "autotools_lex.cpp" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(list): +case YY_STATE_EOF(funcargs): +case YY_STATE_EOF(conditional): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 64 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 64 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 63); + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp ) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ); + + yyfree((void *) b ); +} + +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + int num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param str a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yy_str ) +{ + + return yy_scan_bytes(yy_str,strlen(yy_str) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * bytes, int len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param line_number + * + */ +void yyset_lineno (int line_number ) +{ + + yylineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str ) +{ + yyin = in_str ; +} + +void yyset_out (FILE * out_str ) +{ + yyout = out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int bdebug ) +{ + yy_flex_debug = bdebug ; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef yytext_ptr +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif +#line 135 "autotools.ll" + + + + diff --git a/buildtools/lib/parsers/autotools/autotools_yacc.cpp b/buildtools/lib/parsers/autotools/autotools_yacc.cpp new file mode 100644 index 00000000..f4a3892c --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotools_yacc.cpp @@ -0,0 +1,1631 @@ +/* A Bison parser, made by GNU Bison 1.875d. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + ID_SIMPLE = 258, + ID_LIST = 259, + LBRACE = 260, + EQ = 261, + PLUSEQ = 262, + MINUSQE = 263, + STAREQ = 264, + TILDEEQ = 265, + RBRACE = 266, + COLON = 267, + NUMSIGN = 268, + NEWLINE = 269, + NUMBER = 270, + COMMENT = 271, + CONT = 272, + DOT = 273, + RCURLY = 274, + LCURLY = 275, + ID_ARGS = 276, + LIST_COMMENT = 277, + ID_LIST_SINGLE = 278, + IF_KEYWORD = 279, + ELSE_KEYWORD = 280, + ENDIF_KEYWORD = 281, + KEYWORD = 282, + RULE = 283 + }; +#endif +#define ID_SIMPLE 258 +#define ID_LIST 259 +#define LBRACE 260 +#define EQ 261 +#define PLUSEQ 262 +#define MINUSQE 263 +#define STAREQ 264 +#define TILDEEQ 265 +#define RBRACE 266 +#define COLON 267 +#define NUMSIGN 268 +#define NEWLINE 269 +#define NUMBER 270 +#define COMMENT 271 +#define CONT 272 +#define DOT 273 +#define RCURLY 274 +#define LCURLY 275 +#define ID_ARGS 276 +#define LIST_COMMENT 277 +#define ID_LIST_SINGLE 278 +#define IF_KEYWORD 279 +#define ELSE_KEYWORD 280 +#define ENDIF_KEYWORD 281 +#define KEYWORD 282 +#define RULE 283 + + + + +/* Copy the first part of user declarations. */ +#line 1 "autotools.yy" + +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/** +@file qmake.yy +Autotools Parser + +Simple LALR parser which builds the syntax tree (see @ref Autotools::AST). + +@todo Recognize comments after statements like: +noinst_HEADERS = foo.h #regognize me + +@fixme Parser fails on files that do not end with a newline +@fixme 1 shift/reduce conflict in "line_body" rule +*/ + +#include <qvaluestack.h> +#include "autotoolsast.h" + +#define YYSTYPE_IS_DECLARED + +using namespace AutoTools; + +/** +The yylval type. +*/ +struct Result { + Result(): node(0) {} + + /**Type of semantic value for simple grammar rules.*/ + QString value; + /**Type of semantic value for grammar rules which are parts of AST.*/ + AST *node; + /**Type of semantic value for "multiline_values" grammar rule. + Each line of multiline value is stored as a string in the list. + + For example we have in Makefile.am file: + @code + foo_SOURCES = foo1.cpp \ + foo2.cpp \ + foo3.cpp foo4.cpp + @endcode + The string list will be populated with three strings: + <pre> + foo1.cpp + foo2.cpp + foo3.cpp foo4.cpp + </pre> + */ + QStringList values; +}; + +typedef Result YYSTYPE; + +void yyerror(const char *str) { + printf("bison error: %s\n", str); +} + +int yylex(); + +/** +The stack to store ProjectAST pointers when a new child +ProjectAST is created and filled with statements. + +Parser creates root ProjectAST for a .pro file, pushes it onto the stack and starts +adding statements. Each statement is added as a child StatementAST to the ProjectAST +currently on the top in the stack. + +When a scope or function scope statement is parsed, the child ProjectAST is created +and pushed onto the stack. Therefore all statements which belong to the scope +or function scope are added as childs to their direct parent (scope or function scope). +*/ +QValueStack<ProjectAST*> projects; + +/** +The current depth of AST node is stored here. +AST depth is important to know because automatic indentation can +be easily implemented (the parser itself looses all information +about indentation). +*/ +int depth = 0; + +/* +To debug this parser, put the line below into the next bison file section. +Don't forget to uncomment "yydebug = 1" line in qmakedriver.cpp. +%debug +*/ + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +typedef int YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +/* Line 214 of yacc.c. */ +#line 253 "autotools_yacc.cpp" + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +# ifndef YYFREE +# define YYFREE free +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# endif + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# endif +# else +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short int yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined (__GNUC__) && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short int yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 3 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 33 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 29 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 18 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 35 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 43 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 283 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned char yyprhs[] = +{ + 0, 0, 3, 4, 7, 10, 11, 13, 15, 17, + 19, 21, 23, 25, 27, 29, 32, 34, 37, 39, + 42, 46, 49, 51, 54, 55, 58, 61, 63, 65, + 69, 71, 74, 76, 78, 81 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 30, 0, -1, -1, 31, 32, -1, 32, 33, -1, + -1, 37, -1, 34, -1, 36, -1, 35, -1, 41, + -1, 42, -1, 43, -1, 45, -1, 46, -1, 24, + 38, -1, 26, -1, 26, 38, -1, 25, -1, 25, + 38, -1, 38, 44, 39, -1, 3, 38, -1, 3, + -1, 39, 40, -1, -1, 4, 17, -1, 23, 14, + -1, 17, -1, 22, -1, 38, 12, 39, -1, 28, + -1, 27, 38, -1, 6, -1, 7, -1, 16, 14, + -1, 14, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short int yyrline[] = +{ + 0, 142, 142, 142, 149, 175, 178, 182, 186, 190, + 194, 198, 202, 206, 210, 216, 224, 230, 239, 245, + 254, 264, 266, 269, 273, 276, 277, 278, 279, 282, + 291, 299, 308, 308, 311, 319 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "ID_SIMPLE", "ID_LIST", "LBRACE", "EQ", + "PLUSEQ", "MINUSQE", "STAREQ", "TILDEEQ", "RBRACE", "COLON", "NUMSIGN", + "NEWLINE", "NUMBER", "COMMENT", "CONT", "DOT", "RCURLY", "LCURLY", + "ID_ARGS", "LIST_COMMENT", "ID_LIST_SINGLE", "IF_KEYWORD", + "ELSE_KEYWORD", "ENDIF_KEYWORD", "KEYWORD", "RULE", "$accept", "project", + "@1", "statements", "statement", "automake_if", "endif_statement", + "else_statement", "variable_assignment", "scoped_identifier", + "multiline_values", "line_body", "target", "am_rule", + "include_directive", "operator", "comment", "emptyline", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short int yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 29, 31, 30, 32, 32, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 34, 35, 35, 36, 36, + 37, 38, 38, 39, 39, 40, 40, 40, 40, 41, + 42, 43, 44, 44, 45, 46 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 0, 2, 2, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, + 3, 2, 1, 2, 0, 2, 2, 1, 1, 3, + 1, 2, 1, 1, 2, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 2, 0, 5, 1, 3, 22, 35, 0, 0, 18, + 16, 0, 30, 4, 7, 9, 8, 6, 0, 10, + 11, 12, 13, 14, 21, 34, 15, 19, 17, 31, + 32, 33, 24, 24, 29, 20, 0, 27, 28, 0, + 23, 25, 26 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yysigned_char yydefgoto[] = +{ + -1, 1, 2, 4, 13, 14, 15, 16, 17, 18, + 34, 40, 19, 20, 21, 33, 22, 23 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -18 +static const yysigned_char yypact[] = +{ + -18, 2, -18, -18, -3, 0, -18, -6, 0, 0, + 0, 0, -18, -18, -18, -18, -18, -18, 3, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, 10, 10, -5, -18, -18, 4, + -18, -18, -18 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yysigned_char yypgoto[] = +{ + -18, -18, -18, -18, -18, -18, -18, -18, -18, -4, + -17, -18, -18, -18, -18, -18, -18, -18 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const unsigned char yytable[] = +{ + 5, 24, 3, 5, 26, 27, 28, 29, 25, 30, + 31, 6, 41, 7, 36, 32, 35, 0, 42, 0, + 0, 8, 9, 10, 11, 12, 0, 37, 0, 0, + 0, 0, 38, 39 +}; + +static const yysigned_char yycheck[] = +{ + 3, 5, 0, 3, 8, 9, 10, 11, 14, 6, + 7, 14, 17, 16, 4, 12, 33, -1, 14, -1, + -1, 24, 25, 26, 27, 28, -1, 17, -1, -1, + -1, -1, 22, 23 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 30, 31, 0, 32, 3, 14, 16, 24, 25, + 26, 27, 28, 33, 34, 35, 36, 37, 38, 41, + 42, 43, 45, 46, 38, 14, 38, 38, 38, 38, + 6, 7, 12, 44, 39, 39, 4, 17, 22, 23, + 40, 17, 14 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + ((Current).first_line = (Rhs)[1].first_line, \ + (Current).first_column = (Rhs)[1].first_column, \ + (Current).last_line = (Rhs)[N].last_line, \ + (Current).last_column = (Rhs)[N].last_column) +#endif + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short int *bottom, short int *top) +#else +static void +yy_stack_print (bottom, top) + short int *bottom; + short int *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + short int yyssa[YYINITDEPTH]; + short int *yyss = yyssa; + register short int *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short int *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short int *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 142 "autotools.yy" + { + ProjectAST *projectAST = new ProjectAST(); + projects.push(projectAST); +;} + break; + + case 4: +#line 150 "autotools.yy" + { + projects.top()->addChildAST(yyvsp[0].node); + + if ( yyvsp[0].node->nodeType() == AST::ProjectAST && + static_cast<ProjectAST*>( yyvsp[0].node )->scopedID == "if" ) + { + yyvsp[0].node->setDepth(depth); + depth++; + } + else if ( yyvsp[0].node->nodeType() == AST::ProjectAST && + static_cast<ProjectAST*>( yyvsp[0].node )->scopedID == "else" ) + { + --depth; + yyvsp[0].node->setDepth(depth); + ++depth; + } + else if ( yyvsp[0].node->nodeType() == AST::ProjectAST && + static_cast<ProjectAST*>( yyvsp[0].node )->scopedID == "endif" ) + { + --depth; + yyvsp[0].node->setDepth(depth); + } + else + yyvsp[0].node->setDepth(depth); +;} + break; + + case 6: +#line 179 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 7: +#line 183 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 8: +#line 187 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 9: +#line 191 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 10: +#line 195 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 11: +#line 199 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 12: +#line 203 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 13: +#line 207 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 14: +#line 211 "autotools.yy" + { + yyval.node = new NewLineAST(); +;} + break; + + case 15: +#line 217 "autotools.yy" + { + ConditionAST* projectAST = new ConditionAST(); + projectAST->type = "if"; + projectAST->conditionName = yyvsp[0].value; + yyval.node = projectAST; +;} + break; + + case 16: +#line 225 "autotools.yy" + { + ConditionAST* past = new ConditionAST(); + past->type= "endif"; + yyval.node = past; +;} + break; + + case 17: +#line 231 "autotools.yy" + { + ConditionAST* past = new ConditionAST(); + past->type= "endif"; + past->conditionName = yyvsp[0].value; + yyval.node = past; +;} + break; + + case 18: +#line 240 "autotools.yy" + { + ConditionAST* past = new ConditionAST(); + past->type = "else"; + yyval.node = past; +;} + break; + + case 19: +#line 246 "autotools.yy" + { + ConditionAST* past = new ConditionAST(); + past->type = "else"; + past->conditionName = yyvsp[0].value; + yyval.node = past; +;} + break; + + case 20: +#line 255 "autotools.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = yyvsp[-2].value; + node->op = yyvsp[-1].value; + node->values = yyvsp[0].values; + yyval.node = node; +;} + break; + + case 21: +#line 265 "autotools.yy" + { yyval.value = yyvsp[-1].value + yyvsp[0].value; ;} + break; + + case 23: +#line 270 "autotools.yy" + { + yyval.values.append(yyvsp[0].value); +;} + break; + + case 24: +#line 273 "autotools.yy" + { yyval.values.clear(); ;} + break; + + case 25: +#line 276 "autotools.yy" + { yyval.value = yyvsp[-1].value + " \\\n"; ;} + break; + + case 26: +#line 277 "autotools.yy" + { yyval.value = yyvsp[-1].value + "\n"; ;} + break; + + case 27: +#line 278 "autotools.yy" + { yyval.value = "\\\n"; ;} + break; + + case 29: +#line 283 "autotools.yy" + { + AutomakeTargetAST *node = new AutomakeTargetAST(); + node->target = yyvsp[-2].value; + node->deps = yyvsp[0].values; + yyval.node = node; +;} + break; + + case 30: +#line 292 "autotools.yy" + { + ProjectAST* node = new ProjectAST(ProjectAST::Rule); + node->scopedID = yyvsp[0].value; + yyval.node = node; +;} + break; + + case 31: +#line 300 "autotools.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = yyvsp[-1].value; + node->values = QStringList(yyvsp[0].value); + yyval.node = node; +;} + break; + + case 34: +#line 312 "autotools.yy" + { + CommentAST *node = new CommentAST(); + node->comment = yyvsp[-1].value + "\n"; + yyval.node = node; +;} + break; + + + } + +/* Line 1010 of yacc.c. */ +#line 1403 "autotools_yacc.cpp" + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + const char* yyprefix; + char *yymsg; + int yyx; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 0; + + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); + yycount += 1; + if (yycount == 5) + { + yysize = 0; + break; + } + } + yysize += (sizeof ("syntax error, unexpected ") + + yystrlen (yytname[yytype])); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yyp = yystpcpy (yyp, yyprefix); + yyp = yystpcpy (yyp, yytname[yyx]); + yyprefix = " or "; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* If at end of input, pop the error token, + then the rest of the stack, then return failure. */ + if (yychar == YYEOF) + for (;;) + { + YYPOPSTACK; + if (yyssp == yyss) + YYABORT; + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + } + } + else + { + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + +#ifdef __GNUC__ + /* Pacify GCC when the user code never invokes YYERROR and the label + yyerrorlab therefore never appears in user code. */ + if (0) + goto yyerrorlab; +#endif + + yyvsp -= yylen; + yyssp -= yylen; + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + YYPOPSTACK; + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + +#line 321 "autotools.yy" + + +#include "autotools_lex.cpp" + diff --git a/buildtools/lib/parsers/autotools/autotools_yacc.h b/buildtools/lib/parsers/autotools/autotools_yacc.h new file mode 100644 index 00000000..b8becb4a --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotools_yacc.h @@ -0,0 +1,100 @@ +/* A Bison parser, made by GNU Bison 1.875d. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + ID_SIMPLE = 258, + ID_LIST = 259, + LBRACE = 260, + EQ = 261, + PLUSEQ = 262, + MINUSQE = 263, + STAREQ = 264, + TILDEEQ = 265, + RBRACE = 266, + COLON = 267, + NUMSIGN = 268, + NEWLINE = 269, + NUMBER = 270, + COMMENT = 271, + CONT = 272, + DOT = 273, + RCURLY = 274, + LCURLY = 275, + ID_ARGS = 276, + LIST_COMMENT = 277, + ID_LIST_SINGLE = 278, + IF_KEYWORD = 279, + ELSE_KEYWORD = 280, + ENDIF_KEYWORD = 281, + KEYWORD = 282, + RULE = 283 + }; +#endif +#define ID_SIMPLE 258 +#define ID_LIST 259 +#define LBRACE 260 +#define EQ 261 +#define PLUSEQ 262 +#define MINUSQE 263 +#define STAREQ 264 +#define TILDEEQ 265 +#define RBRACE 266 +#define COLON 267 +#define NUMSIGN 268 +#define NEWLINE 269 +#define NUMBER 270 +#define COMMENT 271 +#define CONT 272 +#define DOT 273 +#define RCURLY 274 +#define LCURLY 275 +#define ID_ARGS 276 +#define LIST_COMMENT 277 +#define ID_LIST_SINGLE 278 +#define IF_KEYWORD 279 +#define ELSE_KEYWORD 280 +#define ENDIF_KEYWORD 281 +#define KEYWORD 282 +#define RULE 283 + + + + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +typedef int YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +extern YYSTYPE yylval; + + + diff --git a/buildtools/lib/parsers/autotools/autotoolsast.cpp b/buildtools/lib/parsers/autotools/autotoolsast.cpp new file mode 100644 index 00000000..71596e3d --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotoolsast.cpp @@ -0,0 +1,117 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "autotoolsast.h" + +namespace AutoTools { + +//AST + +AST::~AST() +{ + for (QValueList<AST*>::iterator it = m_children.begin(); it != m_children.end(); ++it) + { + AST *node = *it; + delete node; + } +} + +void AST::addChildAST(AST *node) +{ + m_children.append(node); +} + +void AST::writeBack(QString &buffer) +{ + for (QValueList<AST*>::const_iterator it = m_children.constBegin(); + it != m_children.constEnd(); ++it) + { + if (*it) + (*it)->writeBack(buffer); + } +} + +QString AST::indentation() +{ + QString result; + for (int i = 0; i < depth(); i++) + result += '\t'; + return result; +} + +bool AST::hasChildren() const +{ + return !m_children.isEmpty(); +} + +QValueList<AST*> AST::children() const +{ + return m_children; +} + +//ProjectAST + +void ProjectAST::writeBack(QString &buffer) +{ + if ( isRule() ) + buffer += scopedID; + else + buffer += indentation(); + + AST::writeBack(buffer); + +} + +void ProjectAST::addChildAST(AST *node) +{ + statements.append(node); + AST::addChildAST(node); +} + +void AssignmentAST::writeBack(QString &buffer) +{ + buffer += indentation() + scopedID + " " + op + values.join(""); +} + +void AutomakeTargetAST::writeBack( QString& buffer ) +{ + buffer += target + ":" + deps.join(""); +} + +void ConditionAST::writeBack( QString& buffer ) +{ + buffer += indentation() + type + " " + conditionName; +} + +void NewLineAST::writeBack(QString &buffer) +{ + buffer += "\n"; +} + +void CommentAST::writeBack(QString &buffer) +{ + buffer += indentation() + comment; +} + +} + +// kate: indent-mode csands; tab-width 4; space-indent off; diff --git a/buildtools/lib/parsers/autotools/autotoolsast.h b/buildtools/lib/parsers/autotools/autotoolsast.h new file mode 100644 index 00000000..c92c17c7 --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotoolsast.h @@ -0,0 +1,269 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef AUTOTOOLSAST_H +#define AUTOTOOLSAST_H + +#include <qstringlist.h> + +/** +@file autotools.h +Abstract Syntax Tree (AST) class declarations. +*/ + +namespace AutoTools +{ + +/** + * AST node. + * This is the base class. Objects of this type are not created by the parser. + * + * Each AST node holds the list of its children which are always deleted in the + * destructor. This way, it's possible call delete for only root AST node and + * others will be deleted automatically. + * + * Each AST node also knows how to write the information back into .pro file. + */ +class AST +{ +public: + /**Type of AST node.*/ + enum NodeType { + ProjectAST, ///< Project, scope or function scope. + AssignmentAST, ///< Variable assignment. + TargetAST, ///< Automake target + MakefileConditionalAST, ///< Makefile.am conditional + NewLineAST, ///< Line feed. + CommentAST ///< Comment. + }; + + /** Constructs AST with given node type.*/ + AST(NodeType nodeType): m_nodeType(nodeType), m_depth(0) {} + virtual ~AST(); + + /** + * Adds child AST node to this node. Despite this function is virtual, + * reimplementations should call it to make automatic destruction of + * AST tree possible.*/ + virtual void addChildAST(AST *node); + + /** + * Writes information stored in the AST into the @p buffer. + * This is a default implementation which iterates over child nodes + * and calls writeBack for each child node. + */ + virtual void writeBack(QString &buffer); + + /** @return The type of the node.*/ + virtual NodeType nodeType() const { return m_nodeType; } + + /** Sets the depth of the node in AST.*/ + void setDepth(int depth) { m_depth = depth; } + + /** @return The depth of the node in AST.*/ + int depth() const { return m_depth; } + + /** @return The indentation string based on node depth.*/ + virtual QString indentation(); + + //! \return true if this AST has children + bool hasChildren() const; + + /** + * Get the children of this ast + * \return the list of this ast's childre + */ + QValueList<AST*> children() const; + + + +protected: + NodeType m_nodeType; + QValueList<AST*> m_children; + +private: + int m_depth; + +}; + + +/** + * Project AST node. + * Represents complete projects, scopes and function scopes. + * Examples: + * @code + * scopename{ + * var=value + * } + * function(args){ + * var=value + * } + * @endcode + */ +class ProjectAST: public AST +{ +public: + /**The kind of a project node.*/ + enum Kind + { + Project, ///< Project + Target, ///< Custom Automake Target + ConditionalScope, ///< Automake Conditional + Rule, ///< Automake Rule + Empty ///< Project does not exist. the AST is empty + }; + + /** Constructs a project node of given @p kind. */ + ProjectAST(Kind kind = Project): AST(AST::ProjectAST), m_kind(kind) {} + + virtual void writeBack(QString &buffer); + virtual void addChildAST(AST *node); + + /** @return true if this node is a project.*/ + bool isProject() const { return m_kind == Project; } + + bool isRule() const { return m_kind == Rule; } + + /** @return true if this node is an automake conditional */ + bool isConditionalScope() const { return m_kind == ConditionalScope; } + + /** @return true if this node is empty.*/ + bool isEmpty() const { return m_kind == Empty; } + + /**Scoped identifier (scope name or rule).*/ + QString scopedID; + + /**Function arguments. Empty for other kinds of projects.*/ + QString args; + + /** The automake conditional has an else attached */ + bool hasElse; + + /**List of statements.*/ + QValueList<AutoTools::AST*> statements; + +private: + Kind m_kind; + +}; + + +/** + * Assignment AST node. + * Represents assignments, for example: + * \code + * var=value + * \endcode + * + * Values can be specified on several lines and + * each line is stored as a string in the list of values.@n + * For example, if we have in .pro: + * \code + * SOURCES=a.cpp \ + * b.cpp c.cpp + * \endcode + * then values will be stored as a two elements list: + * \code + * a.cpp + * b.cpp c.cpp + * \endcode + */ +class AssignmentAST: public AST +{ +public: + AssignmentAST(): AST(AST::AssignmentAST) {} + + virtual void writeBack(QString &buffer); + + /**Scoped name of the variable.*/ + QString scopedID; + + /**Operator.*/ + QString op; + + /**List of values.*/ + QStringList values; +}; + +class AutomakeTargetAST : public AST +{ +public: + AutomakeTargetAST() : AST(AST::TargetAST) {} + + virtual void writeBack( QString& buffer ); + + /// The name of the target + QString target; + + /// The dependencies for the target, if any + QStringList deps; +}; + +class ConditionAST : public AST +{ +public: + ConditionAST() : AST( AST::MakefileConditionalAST ) {} + + virtual void writeBack( QString& buffer ); + + /// The keyword for the condition (if, else, endif) + QString type; + + /// The name of the condition + QString conditionName; +}; + +/** + * New line AST node. + * Represents line feeds in files. + */ +class NewLineAST: public AST +{ +public: + NewLineAST(): AST(AST::NewLineAST) {} + + virtual void writeBack(QString &buffer); + +}; + + +/** + * Comment AST node. + * Represents comments. + */ +class CommentAST: public AST +{ +public: + CommentAST(): AST(AST::CommentAST) {} + + virtual void writeBack(QString &buffer); + + /**Comment text.*/ + QString comment; + +}; + +} + +#endif + +// kate: indent-mode csands; space-indent off; tab-width 4; auto-insert-doxygen on; diff --git a/buildtools/lib/parsers/autotools/autotoolsdriver.cpp b/buildtools/lib/parsers/autotools/autotoolsdriver.cpp new file mode 100644 index 00000000..8ec643ab --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotoolsdriver.cpp @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "autotoolsdriver.h" +#include "autotoolsast.h" + +#include <stdio.h> +#include <qvaluestack.h> +#include <kio/netaccess.h> + +extern FILE *yyin, *yyout; +extern int yyparse(); +//extern int yydebug; +extern QValueStack<AutoTools::ProjectAST *> projects; + +namespace AutoTools { + +int Driver::parseFile(const char *fileName, ProjectAST **ast) +{ + //yydebug = 1; + yyin = fopen(fileName, "r"); + if (yyin == 0) + { + ast = 0; + return 1; + } + int ret = yyparse(); + *ast = projects.top(); + fclose(yyin); + return ret; +} + +int Driver::parseFile(QString fileName, ProjectAST **ast) +{ + return parseFile(fileName.ascii(), ast); +} + +int Driver::parseFile(KURL fileName, ProjectAST **ast) +{ + QString tmpFile; + int ret = 0; + if (KIO::NetAccess::download(fileName, tmpFile, 0)) + ret = parseFile(tmpFile, ast); + KIO::NetAccess::removeTempFile(tmpFile); + return ret; +} + +} + +//kate: indent-mode csands; space-indent off; tab-width 4; + diff --git a/buildtools/lib/parsers/autotools/autotoolsdriver.h b/buildtools/lib/parsers/autotools/autotoolsdriver.h new file mode 100644 index 00000000..eba0a823 --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotoolsdriver.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QMAKEQMAKEDRIVER_H +#define QMAKEQMAKEDRIVER_H + +#include <qvaluelist.h> +#include <kurl.h> + +namespace AutoTools { + +/** +@file autotoolsdriver.h +Driver for a qmake parser. +*/ + +class ProjectAST; + +/** + * Driver. + * Use methods of this class to lauch parsing and build the AST. + */ +class Driver +{ +public: + /** + * Parses the file @p fileName and stores the resulting ProjectAST root + * into @p ast. @p ast should not be initialized before. Driver will + * initialize it on its own. + * @return The result of parsing. Result is 0 on success and <> 0 on failure. + */ + static int parseFile(const char *fileName, ProjectAST **ast); + static int parseFile(QString fileName, ProjectAST **ast); + static int parseFile(KURL fileName, ProjectAST **ast); + +/* template<class Op> + static void walkAST(Op &op, const ProjectAST *ast) + { +// op(ast); + for (QValueList<QMake::AST*>::const_iterator it = ast->statements.constBegin(); + it != ast->statements.constEnd(); ++it) + { + const AST *child = *it; + if (child->nodeType() == AST::ProjectAST) + walkAST<Op>(op, static_cast<const QMake::ProjectAST*>(child)); + else + op(child); + } + } +*/ +}; + +} + +#endif + +// kate: indent-mode csands; tab-width 4; space-indent off; auto-insert-doxygen on; diff --git a/buildtools/lib/parsers/autotools/tests/Makefile.am b/buildtools/lib/parsers/autotools/tests/Makefile.am new file mode 100644 index 00000000..222a0482 --- /dev/null +++ b/buildtools/lib/parsers/autotools/tests/Makefile.am @@ -0,0 +1,21 @@ +# This directory collects some classes related to +# project management for the sole purpose that they +# can be shared between parts. + +INCLUDES = -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/util -I$(top_srcdir)/lib/widgets/propeditor \ + -I$(top_srcdir)/buildtools/lib/parsers/autotools \ + -I$(top_builddir)/buildtools/lib/parsers/autotools/tests \ + $(all_includes) + +METASOURCES = AUTO + +check_PROGRAMS = runner viewer + +runner_LDFLAGS = $(all_libraries) $(LIB_KDECORE) $(KDE_RPATH) +runner_LDADD = $(top_builddir)/buildtools/lib/parsers/autotools/libkdevautotoolsparser.la +runner_SOURCES = runner.cpp + +viewer_LDFLAGS = $(all_libraries) $(LIB_KDECORE) $(KDE_RPATH) +viewer_LDADD = $(top_builddir)/buildtools/lib/parsers/autotools/libkdevautotoolsparser.la +viewer_SOURCES = viewer.cpp viewer_main.cpp viewerbase.ui diff --git a/buildtools/lib/parsers/autotools/tests/runner.cpp b/buildtools/lib/parsers/autotools/tests/runner.cpp new file mode 100644 index 00000000..cf9f68d1 --- /dev/null +++ b/buildtools/lib/parsers/autotools/tests/runner.cpp @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include <autotoolsast.h> +#include <autotoolsdriver.h> + +using namespace AutoTools; + +int main(int argc, char *argv[]) +{ + ProjectAST *projectAST; + if (argc > 1) + return Driver::parseFile(argv[1], &projectAST); + else + return 0; +} + diff --git a/buildtools/lib/parsers/autotools/tests/viewer.cpp b/buildtools/lib/parsers/autotools/tests/viewer.cpp new file mode 100644 index 00000000..047e6b28 --- /dev/null +++ b/buildtools/lib/parsers/autotools/tests/viewer.cpp @@ -0,0 +1,162 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "viewer.h" + +#include <qdir.h> +#include <qlineedit.h> +#include <qlistbox.h> +#include <qfiledialog.h> +#include <qtextedit.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qlistview.h> +#include <qtabwidget.h> + +#include <autotoolsast.h> +#include <autotoolsdriver.h> + +using namespace AutoTools; + +Viewer::Viewer(QWidget *parent, const char *name) + :ViewerBase(parent, name) +{ + if (QFile::exists(QDir::currentDirPath() + "/" + "qtlist")) + { + QFile f(QDir::currentDirPath() + "/" + "qtlist"); + f.open(IO_ReadOnly); + QTextStream str(&f); + while (!str.eof()) + files->insertItem(str.readLine()); + } + ast->setSorting(-1); + parentProject.push((QListViewItem*)0); +} + +void Viewer::addAll_clicked() +{ + if (allLocation->text().isEmpty()) + return; + QDir d(allLocation->text()); + QStringList l = d.entryList("*.am"); + for (QStringList::iterator it = l.begin(); it != l.end(); ++it) + (*it) = QDir::cleanDirPath(allLocation->text() + "/" + (*it)); + files->insertStringList(l); +} + +void Viewer::choose_clicked() +{ + QString fileName = QFileDialog::getOpenFileName(QDir::currentDirPath(), "*.am", this); + if (!fileName.isEmpty()) + files->insertItem(fileName); +} + +void Viewer::files_currentChanged(QListBoxItem* item) +{ + ast->clear(); + + QFile f(item->text()); + f.open(IO_ReadOnly); + QTextStream str(&f); + source->setText(str.read()); + f.close(); + + int result = Driver::parseFile(item->text().ascii(), &projectAST); + if (projectAST && (result == 0)) + { + processAST(projectAST); + } + if (tabWidget2->currentPageIndex() == 1) + tabWidget2_selected("Source to be written back"); +} + +void Viewer::tabWidget2_selected(const QString& text) +{ + if ((text == "Source to be written back") && projectAST) + { + QString buffer; + projectAST->writeBack(buffer); + writeBack->setText(buffer); + } +} + +void Viewer::processAST(ProjectAST *projectAST, QListViewItem *globAfter) +{ + QListViewItem *projectIt; + if (!parentProject.top()) + projectIt = new QListViewItem(ast, "Project"); + else + { + if ( projectAST->isConditionalScope() || projectAST->isRule() ) + projectIt = new QListViewItem(parentProject.top(), globAfter, projectAST->scopedID); + } + projectIt->setOpen(true); + + QListViewItem *after = 0; + for (QValueList<AST*>::const_iterator it = projectAST->statements.constBegin(); + it != projectAST->statements.constEnd(); ++it) + { + AST *ast = *it; + if (ast == 0) + continue; + switch (ast->nodeType()) { + case AST::AssignmentAST: { + AssignmentAST *assignmentAST = static_cast<AssignmentAST*>(ast); + QListViewItem *item = new QListViewItem(projectIt, after, + assignmentAST->scopedID, assignmentAST->op, assignmentAST->values.join("")); + item->setMultiLinesEnabled(true); + after = item; } + break; + + case AST::TargetAST: + { + AutomakeTargetAST* ata = static_cast<AutomakeTargetAST*>(ast); + QListViewItem* item = new QListViewItem(projectIt, after, + ata->target, QString::null, ata->deps.join("")); + after = item; + } + break; + + case AST::NewLineAST: +// after = new QListViewItem(projectIt, after, "<newline>"); + break; + + case AST::CommentAST: +// after = new QListViewItem(projectIt, after, "<comment>"); + break; + + case AST::MakefileConditionalAST: + { + ConditionAST* ata = static_cast<ConditionAST*>(ast); + QListViewItem* item = new QListViewItem(projectIt, after, + ata->type, ata->conditionName, QString::null ); + after = item; + } + case AST::ProjectAST: { + ProjectAST *projectAST = static_cast<ProjectAST*>(ast); + parentProject.push(projectIt); + processAST(projectAST, after); + parentProject.pop(); } + break; + } + } +} + +#include "viewer.moc" + diff --git a/buildtools/lib/parsers/autotools/tests/viewer.h b/buildtools/lib/parsers/autotools/tests/viewer.h new file mode 100644 index 00000000..46698483 --- /dev/null +++ b/buildtools/lib/parsers/autotools/tests/viewer.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef VIEWER_H +#define VIEWER_H + +#include <qvaluestack.h> + +#include "viewerbase.h" + +namespace AutoTools { class ProjectAST; } + +class QListViewItem; + +class Viewer: public ViewerBase { +Q_OBJECT +public: + Viewer(QWidget *parent = 0, const char *name = 0); + void processAST(AutoTools::ProjectAST *projectAST, QListViewItem *globAfter = 0); +public slots: + virtual void tabWidget2_selected(const QString&); + virtual void files_currentChanged(QListBoxItem*); + virtual void choose_clicked(); + virtual void addAll_clicked(); +private: + AutoTools::ProjectAST *projectAST; + QValueStack<QListViewItem *> parentProject; +}; + +#endif diff --git a/buildtools/lib/parsers/autotools/tests/viewer_main.cpp b/buildtools/lib/parsers/autotools/tests/viewer_main.cpp new file mode 100644 index 00000000..32641eff --- /dev/null +++ b/buildtools/lib/parsers/autotools/tests/viewer_main.cpp @@ -0,0 +1,34 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include <qapplication.h> +#include "viewer.h" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + Viewer viewer; + app.setMainWidget(&viewer); + viewer.show(); + viewer.resize(800, 600); + //viewer.setWindowState(viewer.windowState() | Qt::WindowMaximized); + + return app.exec(); +} diff --git a/buildtools/lib/parsers/autotools/tests/viewerbase.ui b/buildtools/lib/parsers/autotools/tests/viewerbase.ui new file mode 100644 index 00000000..7c228299 --- /dev/null +++ b/buildtools/lib/parsers/autotools/tests/viewerbase.ui @@ -0,0 +1,220 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>ViewerBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ViewerBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>480</height> + </rect> + </property> + <property name="caption"> + <string>Viewer</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="0" column="1" rowspan="4" colspan="1"> + <property name="name"> + <cstring>layout2</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QTextEdit"> + <property name="name"> + <cstring>source</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="QTabWidget"> + <property name="name"> + <cstring>tabWidget2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>2</verstretch> + </sizepolicy> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>Parse Tree</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QListView" row="0" column="0"> + <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>Value 1</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value 2</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>ast</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>Source to Be Written Back</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QTextEdit" row="0" column="0"> + <property name="name"> + <cstring>writeBack</cstring> + </property> + </widget> + </grid> + </widget> + </widget> + </vbox> + </widget> + <widget class="QLineEdit" row="0" column="0"> + <property name="name"> + <cstring>allLocation</cstring> + </property> + <property name="maximumSize"> + <size> + <width>150</width> + <height>32767</height> + </size> + </property> + </widget> + <widget class="QPushButton" row="1" column="0"> + <property name="name"> + <cstring>addAll</cstring> + </property> + <property name="maximumSize"> + <size> + <width>150</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string>Add All From Directory</string> + </property> + </widget> + <widget class="QPushButton" row="2" column="0"> + <property name="name"> + <cstring>choose</cstring> + </property> + <property name="maximumSize"> + <size> + <width>150</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string>Choose File to Add...</string> + </property> + </widget> + <widget class="QListBox" row="3" column="0"> + <property name="name"> + <cstring>files</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>150</width> + <height>32767</height> + </size> + </property> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>addAll</sender> + <signal>clicked()</signal> + <receiver>ViewerBase</receiver> + <slot>addAll_clicked()</slot> + </connection> + <connection> + <sender>choose</sender> + <signal>clicked()</signal> + <receiver>ViewerBase</receiver> + <slot>choose_clicked()</slot> + </connection> + <connection> + <sender>files</sender> + <signal>currentChanged(QListBoxItem*)</signal> + <receiver>ViewerBase</receiver> + <slot>files_currentChanged(QListBoxItem*)</slot> + </connection> + <connection> + <sender>tabWidget2</sender> + <signal>selected(const QString&)</signal> + <receiver>ViewerBase</receiver> + <slot>tabWidget2_selected(const QString&)</slot> + </connection> +</connections> +<slots> + <slot>addAll_clicked()</slot> + <slot>choose_clicked()</slot> + <slot>files_currentChanged(QListBoxItem*)</slot> + <slot>tabWidget2_selected(const QString&)</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/buildtools/lib/parsers/qmake/FlexLexer.h b/buildtools/lib/parsers/qmake/FlexLexer.h new file mode 100644 index 00000000..1db844da --- /dev/null +++ b/buildtools/lib/parsers/qmake/FlexLexer.h @@ -0,0 +1,205 @@ + +// -*-C++-*- +// FlexLexer.h -- define interfaces for lexical analyzer classes generated +// by flex + +// Copyright (c) 1993 The Regents of the University of California. +// All rights reserved. +// +// This code is derived from software contributed to Berkeley by +// Kent Williams and Tom Epperly. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: + +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. + +// Neither the name of the University nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE. + +// This file defines FlexLexer, an abstract class which specifies the +// external interface provided to flex C++ lexer objects, and yyFlexLexer, +// which defines a particular lexer class. +// +// If you want to create multiple lexer classes, you use the -P flag +// to rename each yyFlexLexer to some other xxFlexLexer. You then +// include <FlexLexer.h> in your other sources once per lexer class: +// +// #undef yyFlexLexer +// #define yyFlexLexer xxFlexLexer +// #include <FlexLexer.h> +// +// #undef yyFlexLexer +// #define yyFlexLexer zzFlexLexer +// #include <FlexLexer.h> +// ... + +#ifndef __FLEX_LEXER_H +// Never included before - need to define base class. +#define __FLEX_LEXER_H + +#include <iostream> +# ifndef FLEX_STD +# define FLEX_STD std:: +# endif + +extern "C++" { + +struct yy_buffer_state; +typedef int yy_state_type; + +class FlexLexer { +public: + virtual ~FlexLexer() { } + + const char* YYText() const { return yytext; } + int YYLeng() const { return yyleng; } + + virtual void + yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0; + virtual struct yy_buffer_state* + yy_create_buffer( FLEX_STD istream* s, int size ) = 0; + virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0; + virtual void yyrestart( FLEX_STD istream* s ) = 0; + + virtual int yylex() = 0; + + // Call yylex with new input/output sources. + int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 ) + { + switch_streams( new_in, new_out ); + return yylex(); + } + + // Switch to new input/output streams. A nil stream pointer + // indicates "keep the current one". + virtual void switch_streams( FLEX_STD istream* new_in = 0, + FLEX_STD ostream* new_out = 0 ) = 0; + + int lineno() const { return yylineno; } + + int debug() const { return yy_flex_debug; } + void set_debug( int flag ) { yy_flex_debug = flag; } + +protected: + char* yytext; + int yyleng; + int yylineno; // only maintained if you use %option yylineno + int yy_flex_debug; // only has effect with -d or "%option debug" +}; + +} +#endif + +#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce) +// Either this is the first time through (yyFlexLexerOnce not defined), +// or this is a repeated include to define a different flavor of +// yyFlexLexer, as discussed in the flex man page. +#define yyFlexLexerOnce + +extern "C++" { + +class yyFlexLexer : public FlexLexer { +public: + // arg_yyin and arg_yyout default to the cin and cout, but we + // only make that assignment when initializing in yylex(). + yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 ); + + virtual ~yyFlexLexer(); + + void yy_switch_to_buffer( struct yy_buffer_state* new_buffer ); + struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size ); + void yy_delete_buffer( struct yy_buffer_state* b ); + void yyrestart( FLEX_STD istream* s ); + + void yypush_buffer_state( struct yy_buffer_state* new_buffer ); + void yypop_buffer_state(void); + + virtual int yylex(); + virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out ); + +protected: + virtual int LexerInput( char* buf, int max_size ); + virtual void LexerOutput( const char* buf, int size ); + virtual void LexerError( const char* msg ); + + void yyunput( int c, char* buf_ptr ); + int yyinput(); + + void yy_load_buffer_state(); + void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s ); + void yy_flush_buffer( struct yy_buffer_state* b ); + + int yy_start_stack_ptr; + int yy_start_stack_depth; + int* yy_start_stack; + + void yy_push_state( int new_state ); + void yy_pop_state(); + int yy_top_state(); + + yy_state_type yy_get_previous_state(); + yy_state_type yy_try_NUL_trans( yy_state_type current_state ); + int yy_get_next_buffer(); + + FLEX_STD istream* yyin; // input source for default LexerInput + FLEX_STD ostream* yyout; // output sink for default LexerOutput + + // yy_hold_char holds the character lost when yytext is formed. + char yy_hold_char; + + // Number of characters read into yy_ch_buf. + int yy_n_chars; + + // Points to current character in buffer. + char* yy_c_buf_p; + + int yy_init; // whether we need to initialize + int yy_start; // start state number + + // Flag which is used to allow yywrap()'s to do buffer switches + // instead of setting up a fresh yyin. A bit of a hack ... + int yy_did_buffer_switch_on_eof; + + + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */ + void yyensure_buffer_stack(void); + + // The following are not always needed, but may be depending + // on use of certain flex features (like REJECT or yymore()). + + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + yy_state_type* yy_state_buf; + yy_state_type* yy_state_ptr; + + char* yy_full_match; + int* yy_full_state; + int yy_full_lp; + + int yy_lp; + int yy_looking_for_trail_begin; + + int yy_more_flag; + int yy_more_len; + int yy_more_offset; + int yy_prev_more_offset; +}; + +} + +#endif diff --git a/buildtools/lib/parsers/qmake/Mainpage.dox b/buildtools/lib/parsers/qmake/Mainpage.dox new file mode 100644 index 00000000..7b2e2682 --- /dev/null +++ b/buildtools/lib/parsers/qmake/Mainpage.dox @@ -0,0 +1,16 @@ +/** +@mainpage The KDevelop QMake Parser + +This library contains qmake parser. + +<b>Link with</b>: -lkdevqmakeparser + +<b>Include path</b>: -I\$(kde_includes)/kdevelop/buildtools/parsers/qmake + +\section qmakeparseroverview Overview +Here resides a parser for qmake .pro (.pri) files. This parser +reads project files, builds an AST which then can be written +back to the project file. + +*/ + diff --git a/buildtools/lib/parsers/qmake/Makefile.am b/buildtools/lib/parsers/qmake/Makefile.am new file mode 100644 index 00000000..fd80170c --- /dev/null +++ b/buildtools/lib/parsers/qmake/Makefile.am @@ -0,0 +1,31 @@ +# This directory collects some classes related to +# project management for the sole purpose that they +# can be shared between parts. + +#SUBDIRS = tests + +INCLUDES = -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/util -I$(top_srcdir)/lib/widgets/propeditor \ + $(all_includes) +METASOURCES = AUTO +lib_LTLIBRARIES = libkdevqmakeparser.la +libkdevqmakeparser_la_LDFLAGS = -no-undefined $(all_libraries) $(LIB_KIO) +libkdevqmakeparser_la_SOURCES = qmake_lex.cpp qmake_yacc.cpp qmakeast.cpp \ + qmakeastvisitor.cpp qmakedriver.cpp + +kdevelopbuildtoolsincludedir = $(includedir)/kdevelop/buildtools/parsers/qmake +kdevelopbuildtoolsinclude_HEADERS = qmakeast.h qmakedriver.h qmakeastvisitor.h + +parser: + cd $(srcdir) ; \ + bison -d qmake.yy -r all -k -t -oqmake_yacc.cpp ; \ + flex -d -oqmake_lex.cpp qmake.ll + +EXTRA_DIST = qmake.yy qmake.ll + +DOXYGEN_REFERENCES = dcop interfaces kdecore kdefx kdeui khtml kmdi kio kjs kparts kutils +DOXYGEN_PROJECTNAME = KDevelop QMake parser +DOXYGEN_DOCDIRPREFIX = kdevparser +include ../../../../Doxyfile.am + +noinst_HEADERS = qmake.ll qmake.yy qmake_lex.h diff --git a/buildtools/lib/parsers/qmake/location.hh b/buildtools/lib/parsers/qmake/location.hh new file mode 100644 index 00000000..4da36b8a --- /dev/null +++ b/buildtools/lib/parsers/qmake/location.hh @@ -0,0 +1,145 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Locations for Bison parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/** + ** \file location.hh + ** Define the QMake::location class. + */ + +#ifndef BISON_LOCATION_HH +# define BISON_LOCATION_HH + +# include <iostream> +# include <string> +# include "position.hh" + +namespace QMake +{ + + /// Abstract a location. + class location + { + public: + + /// Construct a location. + location () + : begin (), end () + { + } + + + /// Initialization. + inline void initialize (std::string* fn) + { + begin.initialize (fn); + end = begin; + } + + /** \name Line and Column related manipulators + ** \{ */ + public: + /// Reset initial location to final location. + inline void step () + { + begin = end; + } + + /// Extend the current location to the COUNT next columns. + inline void columns (unsigned int count = 1) + { + end += count; + } + + /// Extend the current location to the COUNT next lines. + inline void lines (unsigned int count = 1) + { + end.lines (count); + } + /** \} */ + + + public: + /// Beginning of the located region. + position begin; + /// End of the located region. + position end; + }; + + /// Join two location objects to create a location. + inline const location operator+ (const location& begin, const location& end) + { + location res = begin; + res.end = end.end; + return res; + } + + /// Add two location objects. + inline const location operator+ (const location& begin, unsigned int width) + { + location res = begin; + res.columns (width); + return res; + } + + /// Add and assign a location. + inline location& operator+= (location& res, unsigned int width) + { + res.columns (width); + return res; + } + + /** \brief Intercept output stream redirection. + ** \param ostr the destination output stream + ** \param loc a reference to the location to redirect + ** + ** Avoid duplicate information. + */ + inline std::ostream& operator<< (std::ostream& ostr, const location& loc) + { + position last = loc.end - 1; + ostr << loc.begin; + if (last.filename + && (!loc.begin.filename + || *loc.begin.filename != *last.filename)) + ostr << '-' << last; + else if (loc.begin.line != last.line) + ostr << '-' << last.line << '.' << last.column; + else if (loc.begin.column != last.column) + ostr << '-' << last.column; + return ostr; + } + +} + +#endif // not BISON_LOCATION_HH diff --git a/buildtools/lib/parsers/qmake/position.hh b/buildtools/lib/parsers/qmake/position.hh new file mode 100644 index 00000000..704f0df4 --- /dev/null +++ b/buildtools/lib/parsers/qmake/position.hh @@ -0,0 +1,142 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Positions for Bison parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/** + ** \file position.hh + ** Define the QMake::position class. + */ + +#ifndef BISON_POSITION_HH +# define BISON_POSITION_HH + +# include <iostream> +# include <string> + +namespace QMake +{ + /// Abstract a position. + class position + { + public: + + /// Construct a position. + position () + : filename (0), line (1), column (0) + { + } + + + /// Initialization. + inline void initialize (std::string* fn) + { + filename = fn; + line = 1; + column = 0; + } + + /** \name Line and Column related manipulators + ** \{ */ + public: + /// (line related) Advance to the COUNT next lines. + inline void lines (int count = 1) + { + column = 0; + line += count; + } + + /// (column related) Advance to the COUNT next columns. + inline void columns (int count = 1) + { + int leftmost = 0; + int current = column; + if (leftmost <= current + count) + column += count; + else + column = 0; + } + /** \} */ + + public: + /// File name to which this position refers. + std::string* filename; + /// Current line number. + unsigned int line; + /// Current column number. + unsigned int column; + }; + + /// Add and assign a position. + inline const position& + operator+= (position& res, const int width) + { + res.columns (width); + return res; + } + + /// Add two position objects. + inline const position + operator+ (const position& begin, const int width) + { + position res = begin; + return res += width; + } + + /// Add and assign a position. + inline const position& + operator-= (position& res, const int width) + { + return res += -width; + } + + /// Add two position objects. + inline const position + operator- (const position& begin, const int width) + { + return begin + -width; + } + + /** \brief Intercept output stream redirection. + ** \param ostr the destination output stream + ** \param pos a reference to the position to redirect + */ + inline std::ostream& + operator<< (std::ostream& ostr, const position& pos) + { + if (pos.filename) + ostr << *pos.filename << ':'; + return ostr << pos.line << '.' << pos.column; + } + +} +#endif // not BISON_POSITION_HH diff --git a/buildtools/lib/parsers/qmake/qmake.ll b/buildtools/lib/parsers/qmake/qmake.ll new file mode 100644 index 00000000..715d60b3 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmake.ll @@ -0,0 +1,237 @@ +%{ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include <stdlib.h> + +#define DONT_INCLUDE_FLEXLEXER + +#include "qmake_lex.h" + +/** +@file qmake.ll +QMake Lexer + +There are 3 types of identifiers recognized by this lexer: +-id_simple: examples of such identifiers are qmake variables and scoped variables +at the left of the operator in assignments (like "SOURCES" in "SOURCES+=foo.cpp goo.cpp"); +-id_list: those are "value list identifiers" at the right side in assignments +(like "foo.cpp goo.cpp" in "SOURCES+=foo.cpp goo.cpp"); +-id_args: function arguments recognized as one identifier +(example: ""${QMAKE_FILE} is intended only for Windows!"" +in "!win32-*:!wince-*:error("${QMAKE_FILE} is intended only for Windows!")" statements). +. + +To recognize those identifiers two additional start conditions are used: list and funcargs. + +@note "Not" operator (!) is recognized as a part of an identifier. Linefeeds passed to +the parser as NEWLINE tokens to preserve file structure but whitespaces are stripped +so no indentation is preserved by this lexer (and parser). + +To debug this lexer, put the line below into the next flex file section. +%option debug +*/ +%} + +%option noyywrap +%option yylineno +%option c++ +%option yyclass="QMake::Lexer" + +%x vallist +%x funcargs + +delim [ \t] +ws {delim}+ +newline (\n|\r|\r\n) +quote "\"" +var_value [^#\r\n\t ]*[^\r\n\t \\] +quoted_var_value {quote}({var_value}|[\t ])({var_value}|[\t ])*{quote} +letter [A-Za-z] +digit [0-9] +id_simple ({digit}|{letter}|\!|-|_|\*|\$)({letter}|{digit}|\||\!|-|_|\*|\$|\.|\+)* +id_args [^\r\n]*\) +number {digit}+ +comment #[^\r\n]*{newline} +comment_cont (\\{ws}*#[^\r\n]*{newline}|#[^\r\n]*\\{newline}) +cont \\{ws}*{newline} + +%% +<vallist><<EOF>> { + BEGIN(INITIAL); + return Parser::token::token::ENDOFFILE; +} +<INITIAL>{ws} {} + +<vallist>{ws} { + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::LIST_WS; +} + +<vallist,INITIAL>{cont} { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::CONT; +} + +<vallist,INITIAL>{comment_cont} { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::COMMENT_CONT; +} + +{id_simple} { + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return (Parser::token::token::ID_SIMPLE); +} + +<funcargs>{id_args} { + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + mylval->value = mylval->value.mid(0, mylval->value.length()-1); + unput(')'); + BEGIN(INITIAL); + return (Parser::token::token::ID_ARGS); + } + +<vallist>{var_value} { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::VARIABLE_VALUE; +} + +<vallist>{quoted_var_value} { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::QUOTED_VARIABLE_VALUE; +} + +"=" { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::EQ; +} + +"+=" { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::PLUSEQ; +} + +"-=" { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::MINUSEQ; +} + +"*=" { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::STAREQ; +} + +"~=" { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::TILDEEQ; +} + +"{" { + return Parser::token::token::LCURLY; +} + +":"{delim}*"{" { + return Parser::token::token::LCURLY; +} + +"}" { + return Parser::token::token::RCURLY; +} + +"(" { + BEGIN(funcargs); + return Parser::token::token::LBRACE; +} + +<funcargs,INITIAL>")" { + BEGIN(INITIAL); + return Parser::token::token::RBRACE; +} + +":" { + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::COLON; +} + + +<vallist>{ws}{newline} { + BEGIN(INITIAL); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + setLineEndingFromString( mylval->value ); + return Parser::token::token::NEWLINE; +} + +<vallist,INITIAL>{newline} { + BEGIN(INITIAL); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + setLineEndingFromString( mylval->value ); + return Parser::token::token::NEWLINE; +} + +<vallist,INITIAL>{comment} { + BEGIN(INITIAL); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return (Parser::token::token::COMMENT); +} + +%% +namespace QMake +{ + Lexer::Lexer( std::istream* argin, std::ostream* argout ) + : yyFlexLexer(argin, argout), mylval(0), m_lineEnding(None) + { + } + + int Lexer::yylex( QMake::Parser::semantic_type* yylval ) + { + mylval = yylval; + return yylex(); + } + + void Lexer::setLineEndingFromString( const QString& str ) + { + if( str.endsWith("\r\n") && m_lineEnding == None ) + m_lineEnding = Windows; + else if ( str.endsWith("\r") && m_lineEnding == None ) + m_lineEnding = MacOS; + else if ( m_lineEnding == None ) + m_lineEnding = Unix; + } + + Lexer::LineEnding Lexer::lineending() + { + return m_lineEnding; + } +} + +int QMakelex( QMake::Parser::semantic_type* yylval, QMake::Lexer* lexer) +{ + return lexer->yylex( yylval ); +} + diff --git a/buildtools/lib/parsers/qmake/qmake.yy b/buildtools/lib/parsers/qmake/qmake.yy new file mode 100644 index 00000000..9e6d378a --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmake.yy @@ -0,0 +1,430 @@ +%{ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * Copyright (C) 2006 by Andreas Pakulat * + * apaku@gmx.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/** +@file qmake.yy +QMake Parser + +Simple LALR parser which builds the syntax tree (see @ref QMake::AST). + +@todo Recognize comments after statements like: +SOURCES = foo #regognize me + +@fixme Parser fails on files that do not end with a newline +@fixme 1 shift/reduce conflict in "line_body" rule +*/ + +#include <qvaluestack.h> +#include "qmakeast.h" +#include <qregexp.h> + +#define YYSTYPE_IS_DECLARED + +namespace QMake +{ + class Lexer; + +/** +The yylval type. +*/ +struct Result { + Result(): node(0) {} + + /**Type of semantic value for simple grammar rules.*/ + QString value; + /**Type of semantic value for grammar rules which are parts of AST.*/ + AST *node; + /**Type of semantic value for "multiline_values" grammar rule. + Each line of multiline value is stored as a string in the list. + + For example we have in .pro file: + @code + SOURCE = foo1.cpp \ + foo2.cpp \ + foo3.cpp foo4.cpp + @endcode + The string list will be populated with three strings: + <pre> + foo1.cpp + foo2.cpp + foo3.cpp foo4.cpp + </pre> + */ + QStringList values; + QString indent; +}; + +#define YYSTYPE Result +typedef Result YYSTYPE; +} + +extern int QMakelex( QMake::Result* yylval, QMake::Lexer* lexer ); + +/** +The stack to store ProjectAST pointers when a new child +ProjectAST is created and filled with statements. + +Parser creates root ProjectAST for a .pro file, pushes it onto the stack and starts +adding statements. Each statement is added as a child StatementAST to the ProjectAST +currently on the top in the stack. + +When a scope or function scope statement is parsed, the child ProjectAST is created +and pushed onto the stack. Therefore all statements which belong to the scope +or function scope are added as childs to their direct parent (scope or function scope). +*/ +//QValueStack<ProjectAST*> projects; + +/** +The current depth of AST node is stored here. +AST depth is important to know because automatic indentation can +be easily implemented (the parser itself looses all information +about indentation). +*/ +// int depth = 0; + +/* +To debug this parser, put the line below into the next bison file section. +Don't forget to uncomment "yydebug = 1" line in qmakedriver.cpp. +%debug +*/ +%} + +%skeleton "lalr1.cc" +%define "parser_class_name" "Parser" +%name-prefix="QMake" +%parse-param { QMake::Lexer* lexer } +%parse-param { QValueStack<ProjectAST*>& projects } +%parse-param { int depth } +%lex-param { QMake::Lexer* lexer } +%start project + +%token ID_SIMPLE +%token EQ +%token PLUSEQ +%token MINUSEQ +%token STAREQ +%token TILDEEQ +%token LBRACE +%token RBRACE +%token COLON +%token NEWLINE +%token COMMENT +%token CONT +%token COMMENT_CONT +%token RCURLY +%token LCURLY +%token ID_ARGS +%token QUOTED_VARIABLE_VALUE +%token VARIABLE_VALUE +%token LIST_WS +%token ENDOFFILE +%% + +project : + { + ProjectAST *projectAST = new ProjectAST(); + projects.push(projectAST); + } + statements + ; + +statements : statements statement + { + projects.top()->addChildAST($<node>2); + $<node>2->setDepth(depth); + } + | + ; + +statement : variable_assignment + { + $<node>$ = $<node>1; + } + | scope + { + $<node>$ = $<node>1; + } + | function_call + { + $<node>$ = $<node>1; + } + | comment + { + $<node>$ = $<node>1; + } + | emptyline + { + $<node>$ = new NewLineAST(); + } + ; + +variable_assignment : ID_SIMPLE operator multiline_values listws NEWLINE + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $<value>1; + node->op = $<value>2; + node->values = $<values>3 ; + node->values.append( $<value>4 ); + node->values.append( $<value>5 ); + node->indent = $<indent>3; + $<node>$ = node; + } + | ID_SIMPLE operator multiline_values listws ENDOFFILE + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $<value>1; + node->op = $<value>2; + node->values = $<values>3 ; + node->values.append( $<value>4 ); + node->indent = $<indent>3; + $<node>$ = node; + } + | ID_SIMPLE operator multiline_values listws CONT + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $<value>1; + node->op = $<value>2; + node->values = $<values>3 ; + node->values.append( $<value>4 ); + node->values.append( $<value>5 ); + node->indent = $<indent>3; + $<node>$ = node; + } + | ID_SIMPLE operator multiline_values listws COMMENT_CONT + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $<value>1; + node->op = $<value>2; + node->values = $<values>3 ; + node->values.append( $<value>4 ); + node->values.append( $<value>5 ); + node->indent = $<indent>3; + $<node>$ = node; + } + | ID_SIMPLE operator listws NEWLINE + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $<value>1; + node->op = $<value>2; + node->values.append( $<value>3 ); + node->values.append( $<value>4 ); + $<node>$ = node; + } + | ID_SIMPLE operator listws ENDOFFILE + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $<value>1; + node->op = $<value>2; + node->values.append( $<value>3 ); + $<node>$ = node; + } + | ID_SIMPLE operator listws COMMENT + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $<value>1; + node->op = $<value>2; + node->values.append( $<value>3 ); + node->values.append( $<value>4 ); + $<node>$ = node; + } + | ID_SIMPLE operator multiline_values listws COMMENT + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $<value>1; + node->op = $<value>2; + node->values = $<values>3; + node->values.append( $<value>4 ); + node->values.append( $<value>5 ); + node->indent = $<indent>3; + $<node>$ = node; + } + ; + +possible_value : variable_value | COMMENT_CONT | CONT + +multiline_values : multiline_values LIST_WS possible_value + { + $<values>$.append( $<value>2 ); + $<values>$.append( $<value>3 ); + } + | multiline_values variable_value + { + $<values>$.append( $<value>2 ); + } + | multiline_values listws CONT listws possible_value + { + $<values>$.append( $<value>2 ); + $<values>$.append( $<value>3 ); + $<values>$.append( $<value>4 ); + $<values>$.append( $<value>5 ); + if( $<indent>4 != "" && $<indent>$ == "" ) + $<indent>$ = $<indent>4; + } + | multiline_values listws COMMENT_CONT listws possible_value + { + $<values>$.append( $<value>2 ); + $<values>$.append( $<value>3 ); + $<values>$.append( $<value>4 ); + $<values>$.append( $<value>5 ); + if( $<indent>4 != "" && $<indent>$ == "" ) + $<indent>$ = $<indent>4; + } + | listws possible_value + { + $<values>$ = QStringList(); + $<values>$.append( $<value>1 ); + $<values>$.append( $<value>2 ); + } + ; + + +variable_value : VARIABLE_VALUE { $<value>$ = $<value>1; } + | QUOTED_VARIABLE_VALUE { $<value>$ = $<value>1; } + ; + + +listws: LIST_WS + { + $<value>$ = $<value>1; + $<indent>$ = $<value>1; + } + | + { + $<value>$ = QString(); + $<indent>$ = QString(); + } + ; +operator : EQ + { + $<value>$ = $<value>1; + } + | PLUSEQ + { + $<value>$ = $<value>1; + } + | MINUSEQ + { + $<value>$ = $<value>1; + } + | STAREQ + { + $<value>$ = $<value>1; + } + | TILDEEQ + { + $<value>$ = $<value>1; + } + ; + +scope : ID_SIMPLE + { + ProjectAST *projectAST = new ProjectAST(ProjectAST::Scope); + projects.push(projectAST); + projects.top()->scopedID = $<value>1; + depth++; + } + scope_body + { + $<node>$ = projects.pop(); + depth--; + } + ; + +function_call : ID_SIMPLE LBRACE function_args RBRACE + { + ProjectAST *projectAST = new ProjectAST(ProjectAST::FunctionScope); + projects.push(projectAST); + projects.top()->scopedID = $<value>1; + projects.top()->args = $<value>3; + depth++; + + //qWarning("%s", $<value>1.ascii()); + if ($<value>1.contains("include")) + { + IncludeAST *includeAST = new IncludeAST(); + includeAST->projectName = $<value>3; + projects.top()->addChildAST(includeAST); + includeAST->setDepth(depth); + } + } + scope_body + else_statement + { + $<node>$ = projects.pop(); + depth--; + } + ; + +function_args : ID_ARGS { $<value>$ = $<value>1; } + | { $<value>$ = ""; } + ; + +scope_body : LCURLY statements RCURLY + | COLON statement + { + projects.top()->addChildAST($<node>2); + $<node>2->setDepth(depth); + } + | + ; + +else_statement : "else" LCURLY + { + ProjectAST *projectAST = new ProjectAST(ProjectAST::FunctionScope); + projects.push(projectAST); + projects.top()->scopedID = "else"; + projects.top()->args = ""; + depth++; + } + scope_body RCURLY + { + $<node>$ = projects.pop(); + depth--; + } + | + { + $<node>$ = new ProjectAST(); + } + ; + +comment : COMMENT + { + CommentAST *node = new CommentAST(); + node->comment = $<value>1; + $<node>$ = node; + } + ; + +emptyline : NEWLINE + ; + +%% + + +namespace QMake +{ + void Parser::error(const location_type& /*l*/, const std::string& m) + { + std::cerr << m << std::endl; + } +} diff --git a/buildtools/lib/parsers/qmake/qmake_lex.cpp b/buildtools/lib/parsers/qmake/qmake_lex.cpp new file mode 100644 index 00000000..b49677fe --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmake_lex.cpp @@ -0,0 +1,2239 @@ +#line 2 "qmake_lex.cpp" + +#line 4 "qmake_lex.cpp" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 33 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* %if-c++-only */ + /* The c++ scanner is a mess. The FlexLexer.h header file relies on the + * following macro. This is required in order to pass the c++-multiple-scanners + * test in the regression suite. We get reports that it breaks inheritance. + * We will address this in a future release of flex, or omit the C++ scanner + * altogether. + */ + #define yyFlexLexer yyFlexLexer +/* %endif */ + +/* %if-c-only */ +/* %endif */ + +/* %if-c-only */ +/* %endif */ + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +/* %if-c-only */ +/* %endif */ + +/* %if-tables-serialization */ +/* %endif */ +/* end standard C headers. */ + +/* %if-c-or-c++ */ +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +/* %endif */ + +/* %if-c++-only */ +/* begin standard C++ headers. */ +#include <iostream> +#include <errno.h> +#include <cstdlib> +#include <cstring> +/* end standard C++ headers. */ +/* %endif */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* %not-for-header */ + +/* Returned upon end-of-file. */ +#define YY_NULL 0 +/* %ok-for-header */ + +/* %not-for-header */ + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) +/* %ok-for-header */ + +/* %if-reentrant */ +/* %endif */ + +/* %if-not-reentrant */ + +/* %endif */ + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +/* %if-not-reentrant */ +extern int yyleng; +/* %endif */ + +/* %if-c-only */ +/* %if-not-reentrant */ +/* %endif */ +/* %endif */ + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE yylex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ + #define YY_LESS_LINENO(n) \ + do { \ + int yyl;\ + for ( yyl = n; yyl < yyleng; ++yyl )\ + if ( yytext[yyl] == '\n' )\ + --yylineno;\ + }while(0) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef unsigned int yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { +/* %if-c-only */ +/* %endif */ + +/* %if-c++-only */ + std::istream* yy_input_file; +/* %endif */ + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* %if-c-only Standard (non-C++) definition */ +/* %not-for-header */ + +/* %if-not-reentrant */ +/* %endif */ +/* %ok-for-header */ + +/* %endif */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* %if-c-only Standard (non-C++) definition */ +/* %if-not-reentrant */ +/* %not-for-header */ + +/* %ok-for-header */ + +/* %endif */ +/* %endif */ + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */ +/* Begin user sect3 */ + +#define yywrap() 1 +#define YY_SKIP_YYWRAP + +#define FLEX_DEBUG + +typedef unsigned char YY_CHAR; + +#define yytext_ptr yytext +#define YY_INTERACTIVE + +#include <FlexLexer.h> +int yyFlexLexer::yylex() + { + LexerError( "yyFlexLexer::yylex invoked but %option yyclass used" ); + return 0; + } + +#define YY_DECL int QMake::Lexer::yylex() + +/* %if-c-only Standard (non-C++) definition */ +/* %endif */ + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ +/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\ + yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ +/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\ + (yy_c_buf_p) = yy_cp; + +/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */ +#define YY_NUM_RULES 23 +#define YY_END_OF_BUFFER 24 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[76] = + { 0, + 0, 0, 0, 0, 0, 0, 24, 23, 1, 21, + 21, 5, 23, 17, 18, 5, 23, 5, 19, 9, + 23, 14, 16, 23, 7, 2, 7, 7, 23, 23, + 6, 1, 21, 5, 0, 22, 22, 0, 12, 10, + 11, 0, 15, 0, 3, 3, 0, 13, 7, 7, + 0, 2, 20, 20, 7, 0, 7, 0, 7, 0, + 6, 4, 4, 0, 4, 4, 7, 0, 7, 7, + 0, 0, 8, 0, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 5, 6, 7, 8, 1, 1, 1, 9, + 10, 11, 12, 1, 13, 14, 1, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 16, 1, 1, + 17, 1, 1, 1, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 1, 19, 1, 1, 20, 1, 18, 18, 18, 18, + + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 21, 22, 23, 24, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[25] = + { 0, + 1, 2, 3, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[85] = + { 0, + 0, 0, 23, 41, 28, 30, 132, 289, 126, 289, + 123, 56, 32, 289, 289, 106, 105, 104, 35, 289, + 77, 289, 289, 103, 34, 55, 47, 69, 87, 108, + 106, 111, 289, 0, 79, 289, 96, 82, 289, 289, + 289, 44, 289, 0, 289, 90, 59, 289, 68, 289, + 85, 93, 289, 74, 105, 123, 141, 98, 99, 45, + 42, 289, 47, 105, 289, 36, 159, 177, 195, 213, + 108, 231, 249, 112, 289, 268, 271, 274, 27, 277, + 279, 281, 284, 286 + } ; + +static yyconst flex_int16_t yy_def[85] = + { 0, + 75, 1, 76, 76, 77, 77, 75, 75, 75, 75, + 75, 75, 78, 75, 75, 12, 75, 12, 75, 75, + 75, 75, 75, 75, 79, 75, 80, 78, 79, 81, + 81, 75, 75, 12, 78, 75, 75, 78, 75, 75, + 75, 75, 75, 21, 75, 75, 82, 75, 79, 75, + 79, 75, 75, 75, 83, 84, 84, 80, 82, 81, + 81, 75, 75, 82, 75, 75, 83, 84, 83, 84, + 83, 84, 84, 84, 0, 75, 75, 75, 75, 75, + 75, 75, 75, 75 + } ; + +static yyconst flex_int16_t yy_nxt[314] = + { 0, + 8, 9, 10, 11, 12, 8, 13, 12, 14, 15, + 16, 17, 18, 8, 12, 19, 20, 12, 21, 12, + 22, 8, 23, 24, 26, 10, 11, 49, 27, 28, + 8, 8, 8, 8, 36, 37, 42, 31, 65, 31, + 50, 29, 26, 10, 11, 42, 27, 28, 56, 62, + 38, 61, 51, 57, 61, 43, 52, 53, 54, 29, + 34, 65, 66, 34, 43, 58, 34, 34, 34, 34, + 34, 36, 37, 34, 50, 34, 53, 34, 44, 45, + 46, 36, 37, 47, 62, 63, 51, 38, 44, 45, + 46, 50, 45, 59, 52, 53, 54, 38, 36, 75, + + 38, 65, 66, 51, 57, 51, 68, 65, 66, 75, + 69, 70, 32, 75, 70, 61, 58, 61, 68, 48, + 41, 40, 39, 71, 68, 33, 71, 32, 73, 68, + 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 74, 68, 75, 75, 75, 73, 68, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 74, + 68, 75, 75, 75, 69, 70, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 71, 68, 75, + 75, 75, 73, 68, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 74, 68, 75, 75, 75, + + 69, 70, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 71, 68, 75, 75, 75, 73, 68, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 74, 68, 75, 75, 75, 73, 68, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 74, + 68, 75, 75, 75, 73, 68, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 74, 25, 25, + 25, 30, 30, 30, 35, 35, 35, 55, 55, 60, + 60, 64, 64, 64, 67, 67, 72, 72, 7, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75 + } ; + +static yyconst flex_int16_t yy_chk[314] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 3, 79, 3, 3, + 5, 5, 6, 6, 13, 13, 19, 5, 66, 6, + 25, 3, 4, 4, 4, 42, 4, 4, 27, 63, + 13, 61, 25, 27, 60, 19, 26, 26, 26, 4, + 12, 47, 47, 12, 42, 27, 12, 12, 12, 12, + 12, 28, 28, 12, 49, 12, 54, 12, 21, 21, + 21, 35, 35, 21, 38, 38, 49, 28, 29, 29, + 29, 51, 46, 29, 52, 52, 52, 35, 37, 58, + + 38, 59, 59, 51, 58, 29, 55, 64, 64, 71, + 55, 55, 32, 74, 71, 31, 58, 30, 74, 24, + 18, 17, 16, 55, 56, 11, 71, 9, 56, 56, + 74, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 56, 57, 0, 0, 0, 57, 57, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, + 67, 0, 0, 0, 67, 67, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, + 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 68, 69, 0, 0, 0, + + 69, 69, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 69, 70, 0, 0, 0, 70, 70, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 70, 72, 0, 0, 0, 72, 72, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, + 73, 0, 0, 0, 73, 73, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 73, 76, 76, + 76, 77, 77, 77, 78, 78, 78, 80, 80, 81, + 81, 82, 82, 82, 83, 83, 84, 84, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75 + } ; + +/* Table of booleans, true if rule could match eol. */ +static yyconst flex_int32_t yy_rule_can_match_eol[24] = + { 0, +0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, }; + +static yyconst flex_int16_t yy_rule_linenum[23] = + { 0, + 81, 83, 88, 94, 100, 105, 113, 119, 125, 131, + 137, 143, 149, 155, 159, 163, 167, 172, 177, 183, + 190, 197 + } ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +#line 1 "qmake.ll" +#line 2 "qmake.ll" +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include <stdlib.h> + +#define DONT_INCLUDE_FLEXLEXER + +#include "qmake_lex.h" + +/** +@file qmake.ll +QMake Lexer + +There are 3 types of identifiers recognized by this lexer: +-id_simple: examples of such identifiers are qmake variables and scoped variables +at the left of the operator in assignments (like "SOURCES" in "SOURCES+=foo.cpp goo.cpp"); +-id_list: those are "value list identifiers" at the right side in assignments +(like "foo.cpp goo.cpp" in "SOURCES+=foo.cpp goo.cpp"); +-id_args: function arguments recognized as one identifier +(example: ""${QMAKE_FILE} is intended only for Windows!"" +in "!win32-*:!wince-*:error("${QMAKE_FILE} is intended only for Windows!")" statements). +. + +To recognize those identifiers two additional start conditions are used: list and funcargs. + +@note "Not" operator (!) is recognized as a part of an identifier. Linefeeds passed to +the parser as NEWLINE tokens to preserve file structure but whitespaces are stripped +so no indentation is preserved by this lexer (and parser). + +To debug this lexer, put the line below into the next flex file section. +%option debug +*/ + + +#line 657 "qmake_lex.cpp" + +#define INITIAL 0 +#define vallist 1 +#define funcargs 2 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +#include <unistd.h> +/* %endif */ +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* %if-c-only Reentrant structure and macros (non-C++). */ +/* %if-reentrant */ +/* %if-c-only */ +/* %endif */ +/* %if-reentrant */ +/* %endif */ +/* %if-bison-bridge */ +/* %endif */ +/* %endif End reentrant structures and macros. */ +/* %not-for-header */ + +/* %ok-for-header */ + +/* %endif */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT +/* %if-c-only Standard (non-C++) definition */ +/* %not-for-header */ + +/* %ok-for-header */ + +/* %endif */ +#endif + +/* %if-c-only */ +/* %endif */ + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* %if-c-only Standard (non-C++) definition */ +/* %endif */ +/* %if-c++-only C++ definition */ +#define ECHO LexerOutput( yytext, yyleng ) +/* %endif */ +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ +/* %% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ */\ +\ +/* %if-c++-only C++ definition \ */\ + if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +/* %endif */ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +#define YY_FATAL_ERROR(msg) LexerError( msg ) +/* %endif */ +#endif + +/* %if-tables-serialization structures and prototypes */ +/* %not-for-header */ + +/* %ok-for-header */ + +/* %not-for-header */ + +/* %tables-yydmap generated elements */ +/* %endif */ +/* end tables serialization structures and prototypes */ + +/* %ok-for-header */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 +/* %if-c-only Standard (non-C++) definition */ +/* %endif */ +/* %if-c++-only C++ definition */ +#define YY_DECL int yyFlexLexer::yylex() +/* %endif */ +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +/* %% [6.0] YY_RULE_SETUP definition goes here */ +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/* %not-for-header */ + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +/* %% [7.0] user's declarations go here */ +#line 76 "qmake.ll" + +#line 818 "qmake_lex.cpp" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + yyin = & std::cin; +/* %endif */ + + if ( ! yyout ) +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + yyout = & std::cout; +/* %endif */ + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { +/* %% [8.0] yymore()-related code goes here */ + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + +/* %% [9.0] code to set up and find next match goes here */ + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 76 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 289 ); + +yy_find_action: +/* %% [10.0] code to find the action number goes here */ + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +/* %% [11.0] code for yylineno update goes here */ + + if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) + { + int yyl; + for ( yyl = 0; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + + yylineno++; +; + } + +do_action: /* This label is used only to access EOF actions. */ + +/* %% [12.0] debug code goes here */ + if ( yy_flex_debug ) + { + if ( yy_act == 0 ) + std::cerr << "--scanner backing up\n"; + else if ( yy_act < 23 ) + std::cerr << "--accepting rule at line " << yy_rule_linenum[yy_act] << + "(\"" << yytext << "\")\n"; + else if ( yy_act == 23 ) + std::cerr << "--accepting default rule (\"" << yytext << "\")\n"; + else if ( yy_act == 24 ) + std::cerr << "--(end of buffer or a NUL)\n"; + else + std::cerr << "--EOF (start condition " << YY_START << ")\n"; + } + + switch ( yy_act ) + { /* beginning of action switch */ +/* %% [13.0] actions go here */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case YY_STATE_EOF(vallist): +#line 77 "qmake.ll" +{ + BEGIN(INITIAL); + return Parser::token::token::ENDOFFILE; +} + YY_BREAK +case 1: +YY_RULE_SETUP +#line 81 "qmake.ll" +{} + YY_BREAK +case 2: +YY_RULE_SETUP +#line 83 "qmake.ll" +{ + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::LIST_WS; +} + YY_BREAK +case 3: +/* rule 3 can match eol */ +YY_RULE_SETUP +#line 88 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::CONT; +} + YY_BREAK +case 4: +/* rule 4 can match eol */ +YY_RULE_SETUP +#line 94 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::COMMENT_CONT; +} + YY_BREAK +case 5: +YY_RULE_SETUP +#line 100 "qmake.ll" +{ + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return (Parser::token::token::ID_SIMPLE); +} + YY_BREAK +case 6: +YY_RULE_SETUP +#line 105 "qmake.ll" +{ + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + mylval->value = mylval->value.mid(0, mylval->value.length()-1); + unput(')'); + BEGIN(INITIAL); + return (Parser::token::token::ID_ARGS); + } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 113 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::VARIABLE_VALUE; +} + YY_BREAK +case 8: +YY_RULE_SETUP +#line 119 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::QUOTED_VARIABLE_VALUE; +} + YY_BREAK +case 9: +YY_RULE_SETUP +#line 125 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::EQ; +} + YY_BREAK +case 10: +YY_RULE_SETUP +#line 131 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::PLUSEQ; +} + YY_BREAK +case 11: +YY_RULE_SETUP +#line 137 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::MINUSEQ; +} + YY_BREAK +case 12: +YY_RULE_SETUP +#line 143 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::STAREQ; +} + YY_BREAK +case 13: +YY_RULE_SETUP +#line 149 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::TILDEEQ; +} + YY_BREAK +case 14: +YY_RULE_SETUP +#line 155 "qmake.ll" +{ + return Parser::token::token::LCURLY; +} + YY_BREAK +case 15: +YY_RULE_SETUP +#line 159 "qmake.ll" +{ + return Parser::token::token::LCURLY; +} + YY_BREAK +case 16: +YY_RULE_SETUP +#line 163 "qmake.ll" +{ + return Parser::token::token::RCURLY; +} + YY_BREAK +case 17: +YY_RULE_SETUP +#line 167 "qmake.ll" +{ + BEGIN(funcargs); + return Parser::token::token::LBRACE; +} + YY_BREAK +case 18: +YY_RULE_SETUP +#line 172 "qmake.ll" +{ + BEGIN(INITIAL); + return Parser::token::token::RBRACE; +} + YY_BREAK +case 19: +YY_RULE_SETUP +#line 177 "qmake.ll" +{ + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::COLON; +} + YY_BREAK +case 20: +/* rule 20 can match eol */ +YY_RULE_SETUP +#line 183 "qmake.ll" +{ + BEGIN(INITIAL); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + setLineEndingFromString( mylval->value ); + return Parser::token::token::NEWLINE; +} + YY_BREAK +case 21: +/* rule 21 can match eol */ +YY_RULE_SETUP +#line 190 "qmake.ll" +{ + BEGIN(INITIAL); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + setLineEndingFromString( mylval->value ); + return Parser::token::token::NEWLINE; +} + YY_BREAK +case 22: +/* rule 22 can match eol */ +YY_RULE_SETUP +#line 197 "qmake.ll" +{ + BEGIN(INITIAL); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return (Parser::token::token::COMMENT); +} + YY_BREAK +case 23: +YY_RULE_SETUP +#line 203 "qmake.ll" +ECHO; + YY_BREAK +#line 1145 "qmake_lex.cpp" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(funcargs): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { +/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */ + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ +/* %ok-for-header */ + +/* %if-c++-only */ +/* %not-for-header */ + +yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) +{ + yyin = arg_yyin; + yyout = arg_yyout; + yy_c_buf_p = 0; + yy_init = 0; + yy_start = 0; + yy_flex_debug = 0; + yylineno = 1; // this will only get updated if %option yylineno + + yy_did_buffer_switch_on_eof = 0; + + yy_looking_for_trail_begin = 0; + yy_more_flag = 0; + yy_more_len = 0; + yy_more_offset = yy_prev_more_offset = 0; + + yy_start_stack_ptr = yy_start_stack_depth = 0; + yy_start_stack = NULL; + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + + yy_state_buf = 0; + +} + +void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) +{ + if ( new_in ) + { + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); + } + + if ( new_out ) + yyout = new_out; +} + +#ifdef YY_INTERACTIVE +int yyFlexLexer::LexerInput( char* buf, int /* max_size */ ) +#else +int yyFlexLexer::LexerInput( char* buf, int max_size ) +#endif +{ + if ( yyin->eof() || yyin->fail() ) + return 0; + +#ifdef YY_INTERACTIVE + yyin->get( buf[0] ); + + if ( yyin->eof() ) + return 0; + + if ( yyin->bad() ) + return -1; + + return 1; + +#else + (void) yyin->read( buf, max_size ); + + if ( yyin->bad() ) + return -1; + else + return yyin->gcount(); +#endif +} + +void yyFlexLexer::LexerOutput( const char* buf, int size ) +{ + (void) yyout->write( buf, size ); +} +/* %ok-for-header */ + +/* %endif */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +int yyFlexLexer::yy_get_next_buffer() +/* %endif */ +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +/* %if-c-only */ +/* %not-for-header */ + +/* %endif */ +/* %if-c++-only */ + yy_state_type yyFlexLexer::yy_get_previous_state() +/* %endif */ +{ + register yy_state_type yy_current_state; + register char *yy_cp; + +/* %% [15.0] code to get the start state into yy_current_state goes here */ + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { +/* %% [16.0] code to find the next state goes here */ + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 76 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) +/* %endif */ +{ + register int yy_is_jam; + /* %% [17.0] code to find the next state, and perhaps do backing up, goes here */ + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 76 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 75); + + return yy_is_jam ? 0 : yy_current_state; +} + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yyunput( int c, register char* yy_bp) +/* %endif */ +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + +/* %% [18.0] update yylineno here */ + + if ( c == '\n' ){ + --yylineno; + } + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} +/* %if-c-only */ +/* %endif */ + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + int yyFlexLexer::yyinput() +/* %endif */ +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + +/* %% [19.0] update BOL and yylineno */ + if ( c == '\n' ) + + yylineno++; +; + + return c; +} +/* %if-c-only */ +/* %endif */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yyrestart( std::istream* input_file ) +/* %endif */ +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +/* %endif */ +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yy_load_buffer_state() +/* %endif */ +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) +/* %endif */ +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) +/* %endif */ +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ); + + yyfree((void *) b ); +} + +/* %if-c-only */ +/* %endif */ + +/* %if-c++-only */ + +extern "C" int isatty (int ); + +/* %endif */ + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) +/* %endif */ + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + b->yy_is_interactive = 0; +/* %endif */ + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) +/* %endif */ +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/* %if-c-or-c++ */ +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) +/* %endif */ +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} +/* %endif */ + +/* %if-c-or-c++ */ +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +void yyFlexLexer::yypop_buffer_state (void) +/* %endif */ +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} +/* %endif */ + +/* %if-c-or-c++ */ +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +void yyFlexLexer::yyensure_buffer_stack(void) +/* %endif */ +{ + int num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} +/* %endif */ + +/* %if-c-only */ +/* %endif */ + +/* %if-c-only */ +/* %endif */ + +/* %if-c-only */ +/* %endif */ + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yy_push_state( int new_state ) +/* %endif */ +{ + if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) + { + yy_size_t new_size; + + (yy_start_stack_depth) += YY_START_STACK_INCR; + new_size = (yy_start_stack_depth) * sizeof( int ); + + if ( ! (yy_start_stack) ) + (yy_start_stack) = (int *) yyalloc(new_size ); + + else + (yy_start_stack) = (int *) yyrealloc((void *) (yy_start_stack),new_size ); + + if ( ! (yy_start_stack) ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; + + BEGIN(new_state); +} + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yy_pop_state() +/* %endif */ +{ + if ( --(yy_start_stack_ptr) < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); +} + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + int yyFlexLexer::yy_top_state() +/* %endif */ +{ + return (yy_start_stack)[(yy_start_stack_ptr) - 1]; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +void yyFlexLexer::LexerError( yyconst char msg[] ) +{ + std::cerr << msg << std::endl; + exit( YY_EXIT_FAILURE ); +} +/* %endif */ + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/* %if-c-only */ +/* %if-reentrant */ +/* %endif */ +/* %if-reentrant */ +/* %endif */ +/* %endif */ + +/* %if-reentrant */ +/* %if-bison-bridge */ +/* %endif */ +/* %endif */ + +/* %if-c-only */ +/* %endif */ + +/* %if-c-or-c++ */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +yyFlexLexer::~yyFlexLexer() +/* %endif */ +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + +/* %if-c++-only */ + delete [] (yy_state_buf); + yyfree((yy_start_stack) ); +/* %endif */ + +/* %if-c-only */ +/* %if-reentrant */ +/* %endif */ +/* %endif */ +} +/* %endif */ + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +/* %if-tables-serialization definitions */ +/* %define-yytables The name for this specific scanner's tables. */ +#define YYTABLES_NAME "yytables" +/* %endif */ + +/* %ok-for-header */ + +#line 203 "qmake.ll" + + +namespace QMake +{ + Lexer::Lexer( std::istream* argin, std::ostream* argout ) + : yyFlexLexer(argin, argout), mylval(0), m_lineEnding(None) + { + } + + int Lexer::yylex( QMake::Parser::semantic_type* yylval ) + { + mylval = yylval; + return yylex(); + } + + void Lexer::setLineEndingFromString( const QString& str ) + { + if( str.endsWith("\r\n") && m_lineEnding == None ) + m_lineEnding = Windows; + else if ( str.endsWith("\r") && m_lineEnding == None ) + m_lineEnding = MacOS; + else if ( m_lineEnding == None ) + m_lineEnding = Unix; + } + + Lexer::LineEnding Lexer::lineending() + { + return m_lineEnding; + } +} + +int QMakelex( QMake::Parser::semantic_type* yylval, QMake::Lexer* lexer) +{ + return lexer->yylex( yylval ); +} + + diff --git a/buildtools/lib/parsers/qmake/qmake_lex.h b/buildtools/lib/parsers/qmake/qmake_lex.h new file mode 100644 index 00000000..1b91e747 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmake_lex.h @@ -0,0 +1,49 @@ +/* KDevelop QMake Support + * + * Copyright 2007 Andreas Pakulat <apaku@gmx.de> + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#ifndef QMAKE_LEX_H +#define QMAKE_LEX_H + +#include "qmake_yacc.hpp" +#include <iostream> + +#ifndef DONT_INCLUDE_FLEXLEXER +#include "FlexLexer.h" +#endif + +namespace QMake +{ + class Lexer : public yyFlexLexer + { + public: + enum LineEnding{ None, Unix, MacOS, Windows }; + Lexer( std::istream* argin = 0, std::ostream* argout = 0 ); + int yylex( QMake::Parser::semantic_type* yylval ); + int yylex(); + void setLineEndingFromString( const QString& ); + LineEnding lineending(); + private: + QMake::Parser::semantic_type* mylval; + LineEnding m_lineEnding; + }; +} + +#endif + +// kate: space-indent on; indent-width 4; tab-width: 4; replace-tabs on; auto-insert-doxygen on diff --git a/buildtools/lib/parsers/qmake/qmake_yacc.cpp b/buildtools/lib/parsers/qmake/qmake_yacc.cpp new file mode 100644 index 00000000..9cd09ebe --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmake_yacc.cpp @@ -0,0 +1,1243 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton implementation for Bison LALR(1) parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +// Take the name prefix into account. +#define yylex QMakelex + +#include "qmake_yacc.hpp" + +/* User implementation prologue. */ + + +/* Line 317 of lalr1.cc. */ +#line 45 "qmake_yacc.cpp" + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include <libintl.h> /* FIXME: INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#define YYUSE(e) ((void) (e)) + +/* A pseudo ostream that takes yydebug_ into account. */ +# define YYCDEBUG \ + for (bool yydebugcond_ = yydebug_; yydebugcond_; yydebugcond_ = false) \ + (*yycdebug_) + +/* Enable debugging if requested. */ +#if YYDEBUG + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug_) \ + { \ + *yycdebug_ << Title << ' '; \ + yy_symbol_print_ ((Type), (Value), (Location)); \ + *yycdebug_ << std::endl; \ + } \ +} while (false) + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug_) \ + yy_reduce_print_ (Rule); \ +} while (false) + +# define YY_STACK_PRINT() \ +do { \ + if (yydebug_) \ + yystack_print_ (); \ +} while (false) + +#else /* !YYDEBUG */ + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_REDUCE_PRINT(Rule) +# define YY_STACK_PRINT() + +#endif /* !YYDEBUG */ + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + +namespace QMake +{ +#if YYERROR_VERBOSE + + /* Return YYSTR after stripping away unnecessary quotes and + backslashes, so that it's suitable for yyerror. The heuristic is + that double-quoting is unnecessary unless the string contains an + apostrophe, a comma, or backslash (other than backslash-backslash). + YYSTR is taken from yytname. */ + std::string + Parser::yytnamerr_ (const char *yystr) + { + if (*yystr == '"') + { + std::string yyr = ""; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + yyr += *yyp; + break; + + case '"': + return yyr; + } + do_not_strip_quotes: ; + } + + return yystr; + } + +#endif + + /// Build a parser object. + Parser::Parser (QMake::Lexer* lexer_yyarg, QValueStack<ProjectAST*>& projects_yyarg, int depth_yyarg) + : yydebug_ (false), + yycdebug_ (&std::cerr), + lexer (lexer_yyarg), + projects (projects_yyarg), + depth (depth_yyarg) + { + } + + Parser::~Parser () + { + } + +#if YYDEBUG + /*--------------------------------. + | Print this symbol on YYOUTPUT. | + `--------------------------------*/ + + inline void + Parser::yy_symbol_value_print_ (int yytype, + const semantic_type* yyvaluep, const location_type* yylocationp) + { + YYUSE (yylocationp); + YYUSE (yyvaluep); + switch (yytype) + { + default: + break; + } + } + + + void + Parser::yy_symbol_print_ (int yytype, + const semantic_type* yyvaluep, const location_type* yylocationp) + { + *yycdebug_ << (yytype < yyntokens_ ? "token" : "nterm") + << ' ' << yytname_[yytype] << " (" + << *yylocationp << ": "; + yy_symbol_value_print_ (yytype, yyvaluep, yylocationp); + *yycdebug_ << ')'; + } +#endif /* ! YYDEBUG */ + + void + Parser::yydestruct_ (const char* yymsg, + int yytype, semantic_type* yyvaluep, location_type* yylocationp) + { + YYUSE (yylocationp); + YYUSE (yymsg); + YYUSE (yyvaluep); + + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } + } + + void + Parser::yypop_ (unsigned int n) + { + yystate_stack_.pop (n); + yysemantic_stack_.pop (n); + yylocation_stack_.pop (n); + } + + std::ostream& + Parser::debug_stream () const + { + return *yycdebug_; + } + + void + Parser::set_debug_stream (std::ostream& o) + { + yycdebug_ = &o; + } + + + Parser::debug_level_type + Parser::debug_level () const + { + return yydebug_; + } + + void + Parser::set_debug_level (debug_level_type l) + { + yydebug_ = l; + } + + + int + Parser::parse () + { + /// Look-ahead and look-ahead in internal form. + int yychar = yyempty_; + int yytoken = 0; + + /* State. */ + int yyn; + int yylen = 0; + int yystate = 0; + + /* Error handling. */ + int yynerrs_ = 0; + int yyerrstatus_ = 0; + + /// Semantic value of the look-ahead. + semantic_type yylval; + /// Location of the look-ahead. + location_type yylloc; + /// The locations where the error started and ended. + location yyerror_range[2]; + + /// $$. + semantic_type yyval; + /// @$. + location_type yyloc; + + int yyresult; + + YYCDEBUG << "Starting parse" << std::endl; + + + /* Initialize the stacks. The initial state will be pushed in + yynewstate, since the latter expects the semantical and the + location values to have been already stored, initialize these + stacks with a primary value. */ + yystate_stack_ = state_stack_type (0); + yysemantic_stack_ = semantic_stack_type (0); + yylocation_stack_ = location_stack_type (0); + yysemantic_stack_.push (yylval); + yylocation_stack_.push (yylloc); + + /* New state. */ + yynewstate: + yystate_stack_.push (yystate); + YYCDEBUG << "Entering state " << yystate << std::endl; + goto yybackup; + + /* Backup. */ + yybackup: + + /* Try to take a decision without look-ahead. */ + yyn = yypact_[yystate]; + if (yyn == yypact_ninf_) + goto yydefault; + + /* Read a look-ahead token. */ + if (yychar == yyempty_) + { + YYCDEBUG << "Reading a token: "; + yychar = yylex (&yylval, lexer); + } + + + /* Convert token to internal form. */ + if (yychar <= yyeof_) + { + yychar = yytoken = yyeof_; + YYCDEBUG << "Now at end of input." << std::endl; + } + else + { + yytoken = yytranslate_ (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken) + goto yydefault; + + /* Reduce or error. */ + yyn = yytable_[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == yytable_ninf_) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Accept? */ + if (yyn == yyfinal_) + goto yyacceptlab; + + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != yyeof_) + yychar = yyempty_; + + yysemantic_stack_.push (yylval); + yylocation_stack_.push (yylloc); + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus_) + --yyerrstatus_; + + yystate = yyn; + goto yynewstate; + + /*-----------------------------------------------------------. + | yydefault -- do the default action for the current state. | + `-----------------------------------------------------------*/ + yydefault: + yyn = yydefact_[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + /*-----------------------------. + | yyreduce -- Do a reduction. | + `-----------------------------*/ + yyreduce: + yylen = yyr2_[yyn]; + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. Otherwise, use the top of the stack. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. */ + if (yylen) + yyval = yysemantic_stack_[yylen - 1]; + else + yyval = yysemantic_stack_[0]; + + { + slice<location_type, location_stack_type> slice (yylocation_stack_, yylen); + YYLLOC_DEFAULT (yyloc, slice, yylen); + } + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 144 "qmake.yy" + { + ProjectAST *projectAST = new ProjectAST(); + projects.push(projectAST); + ;} + break; + + case 4: +#line 152 "qmake.yy" + { + projects.top()->addChildAST((yysemantic_stack_[(2) - (2)].node)); + (yysemantic_stack_[(2) - (2)].node)->setDepth(depth); + ;} + break; + + case 6: +#line 160 "qmake.yy" + { + (yyval.node) = (yysemantic_stack_[(1) - (1)].node); + ;} + break; + + case 7: +#line 164 "qmake.yy" + { + (yyval.node) = (yysemantic_stack_[(1) - (1)].node); + ;} + break; + + case 8: +#line 168 "qmake.yy" + { + (yyval.node) = (yysemantic_stack_[(1) - (1)].node); + ;} + break; + + case 9: +#line 172 "qmake.yy" + { + (yyval.node) = (yysemantic_stack_[(1) - (1)].node); + ;} + break; + + case 10: +#line 176 "qmake.yy" + { + (yyval.node) = new NewLineAST(); + ;} + break; + + case 11: +#line 182 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(5) - (1)].value); + node->op = (yysemantic_stack_[(5) - (2)].value); + node->values = (yysemantic_stack_[(5) - (3)].values) ; + node->values.append( (yysemantic_stack_[(5) - (4)].value) ); + node->values.append( (yysemantic_stack_[(5) - (5)].value) ); + node->indent = (yysemantic_stack_[(5) - (3)].indent); + (yyval.node) = node; + ;} + break; + + case 12: +#line 193 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(5) - (1)].value); + node->op = (yysemantic_stack_[(5) - (2)].value); + node->values = (yysemantic_stack_[(5) - (3)].values) ; + node->values.append( (yysemantic_stack_[(5) - (4)].value) ); + node->indent = (yysemantic_stack_[(5) - (3)].indent); + (yyval.node) = node; + ;} + break; + + case 13: +#line 203 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(5) - (1)].value); + node->op = (yysemantic_stack_[(5) - (2)].value); + node->values = (yysemantic_stack_[(5) - (3)].values) ; + node->values.append( (yysemantic_stack_[(5) - (4)].value) ); + node->values.append( (yysemantic_stack_[(5) - (5)].value) ); + node->indent = (yysemantic_stack_[(5) - (3)].indent); + (yyval.node) = node; + ;} + break; + + case 14: +#line 214 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(5) - (1)].value); + node->op = (yysemantic_stack_[(5) - (2)].value); + node->values = (yysemantic_stack_[(5) - (3)].values) ; + node->values.append( (yysemantic_stack_[(5) - (4)].value) ); + node->values.append( (yysemantic_stack_[(5) - (5)].value) ); + node->indent = (yysemantic_stack_[(5) - (3)].indent); + (yyval.node) = node; + ;} + break; + + case 15: +#line 225 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(4) - (1)].value); + node->op = (yysemantic_stack_[(4) - (2)].value); + node->values.append( (yysemantic_stack_[(4) - (3)].value) ); + node->values.append( (yysemantic_stack_[(4) - (4)].value) ); + (yyval.node) = node; + ;} + break; + + case 16: +#line 234 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(4) - (1)].value); + node->op = (yysemantic_stack_[(4) - (2)].value); + node->values.append( (yysemantic_stack_[(4) - (3)].value) ); + (yyval.node) = node; + ;} + break; + + case 17: +#line 242 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(4) - (1)].value); + node->op = (yysemantic_stack_[(4) - (2)].value); + node->values.append( (yysemantic_stack_[(4) - (3)].value) ); + node->values.append( (yysemantic_stack_[(4) - (4)].value) ); + (yyval.node) = node; + ;} + break; + + case 18: +#line 251 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(5) - (1)].value); + node->op = (yysemantic_stack_[(5) - (2)].value); + node->values = (yysemantic_stack_[(5) - (3)].values); + node->values.append( (yysemantic_stack_[(5) - (4)].value) ); + node->values.append( (yysemantic_stack_[(5) - (5)].value) ); + node->indent = (yysemantic_stack_[(5) - (3)].indent); + (yyval.node) = node; + ;} + break; + + case 22: +#line 266 "qmake.yy" + { + (yyval.values).append( (yysemantic_stack_[(3) - (2)].value) ); + (yyval.values).append( (yysemantic_stack_[(3) - (3)].value) ); + ;} + break; + + case 23: +#line 271 "qmake.yy" + { + (yyval.values).append( (yysemantic_stack_[(2) - (2)].value) ); + ;} + break; + + case 24: +#line 275 "qmake.yy" + { + (yyval.values).append( (yysemantic_stack_[(5) - (2)].value) ); + (yyval.values).append( (yysemantic_stack_[(5) - (3)].value) ); + (yyval.values).append( (yysemantic_stack_[(5) - (4)].value) ); + (yyval.values).append( (yysemantic_stack_[(5) - (5)].value) ); + if( (yysemantic_stack_[(5) - (4)].indent) != "" && (yyval.indent) == "" ) + (yyval.indent) = (yysemantic_stack_[(5) - (4)].indent); + ;} + break; + + case 25: +#line 284 "qmake.yy" + { + (yyval.values).append( (yysemantic_stack_[(5) - (2)].value) ); + (yyval.values).append( (yysemantic_stack_[(5) - (3)].value) ); + (yyval.values).append( (yysemantic_stack_[(5) - (4)].value) ); + (yyval.values).append( (yysemantic_stack_[(5) - (5)].value) ); + if( (yysemantic_stack_[(5) - (4)].indent) != "" && (yyval.indent) == "" ) + (yyval.indent) = (yysemantic_stack_[(5) - (4)].indent); + ;} + break; + + case 26: +#line 293 "qmake.yy" + { + (yyval.values) = QStringList(); + (yyval.values).append( (yysemantic_stack_[(2) - (1)].value) ); + (yyval.values).append( (yysemantic_stack_[(2) - (2)].value) ); + ;} + break; + + case 27: +#line 301 "qmake.yy" + { (yyval.value) = (yysemantic_stack_[(1) - (1)].value); ;} + break; + + case 28: +#line 302 "qmake.yy" + { (yyval.value) = (yysemantic_stack_[(1) - (1)].value); ;} + break; + + case 29: +#line 307 "qmake.yy" + { + (yyval.value) = (yysemantic_stack_[(1) - (1)].value); + (yyval.indent) = (yysemantic_stack_[(1) - (1)].value); + ;} + break; + + case 30: +#line 312 "qmake.yy" + { + (yyval.value) = QString(); + (yyval.indent) = QString(); + ;} + break; + + case 31: +#line 318 "qmake.yy" + { + (yyval.value) = (yysemantic_stack_[(1) - (1)].value); + ;} + break; + + case 32: +#line 322 "qmake.yy" + { + (yyval.value) = (yysemantic_stack_[(1) - (1)].value); + ;} + break; + + case 33: +#line 326 "qmake.yy" + { + (yyval.value) = (yysemantic_stack_[(1) - (1)].value); + ;} + break; + + case 34: +#line 330 "qmake.yy" + { + (yyval.value) = (yysemantic_stack_[(1) - (1)].value); + ;} + break; + + case 35: +#line 334 "qmake.yy" + { + (yyval.value) = (yysemantic_stack_[(1) - (1)].value); + ;} + break; + + case 36: +#line 340 "qmake.yy" + { + ProjectAST *projectAST = new ProjectAST(ProjectAST::Scope); + projects.push(projectAST); + projects.top()->scopedID = (yysemantic_stack_[(1) - (1)].value); + depth++; + ;} + break; + + case 37: +#line 347 "qmake.yy" + { + (yyval.node) = projects.pop(); + depth--; + ;} + break; + + case 38: +#line 354 "qmake.yy" + { + ProjectAST *projectAST = new ProjectAST(ProjectAST::FunctionScope); + projects.push(projectAST); + projects.top()->scopedID = (yysemantic_stack_[(4) - (1)].value); + projects.top()->args = (yysemantic_stack_[(4) - (3)].value); + depth++; + + //qWarning("%s", $<value>1.ascii()); + if ((yysemantic_stack_[(4) - (1)].value).contains("include")) + { + IncludeAST *includeAST = new IncludeAST(); + includeAST->projectName = (yysemantic_stack_[(4) - (3)].value); + projects.top()->addChildAST(includeAST); + includeAST->setDepth(depth); + } + ;} + break; + + case 39: +#line 372 "qmake.yy" + { + (yyval.node) = projects.pop(); + depth--; + ;} + break; + + case 40: +#line 378 "qmake.yy" + { (yyval.value) = (yysemantic_stack_[(1) - (1)].value); ;} + break; + + case 41: +#line 379 "qmake.yy" + { (yyval.value) = ""; ;} + break; + + case 43: +#line 384 "qmake.yy" + { + projects.top()->addChildAST((yysemantic_stack_[(2) - (2)].node)); + (yysemantic_stack_[(2) - (2)].node)->setDepth(depth); + ;} + break; + + case 45: +#line 392 "qmake.yy" + { + ProjectAST *projectAST = new ProjectAST(ProjectAST::FunctionScope); + projects.push(projectAST); + projects.top()->scopedID = "else"; + projects.top()->args = ""; + depth++; + ;} + break; + + case 46: +#line 400 "qmake.yy" + { + (yyval.node) = projects.pop(); + depth--; + ;} + break; + + case 47: +#line 405 "qmake.yy" + { + (yyval.node) = new ProjectAST(); + ;} + break; + + case 48: +#line 411 "qmake.yy" + { + CommentAST *node = new CommentAST(); + node->comment = (yysemantic_stack_[(1) - (1)].value); + (yyval.node) = node; + ;} + break; + + + /* Line 675 of lalr1.cc. */ +#line 756 "qmake_yacc.cpp" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], &yyval, &yyloc); + + yypop_ (yylen); + yylen = 0; + YY_STACK_PRINT (); + + yysemantic_stack_.push (yyval); + yylocation_stack_.push (yyloc); + + /* Shift the result of the reduction. */ + yyn = yyr1_[yyn]; + yystate = yypgoto_[yyn - yyntokens_] + yystate_stack_[0]; + if (0 <= yystate && yystate <= yylast_ + && yycheck_[yystate] == yystate_stack_[0]) + yystate = yytable_[yystate]; + else + yystate = yydefgoto_[yyn - yyntokens_]; + goto yynewstate; + + /*------------------------------------. + | yyerrlab -- here on detecting error | + `------------------------------------*/ + yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus_) + { + ++yynerrs_; + error (yylloc, yysyntax_error_ (yystate)); + } + + yyerror_range[0] = yylloc; + if (yyerrstatus_ == 3) + { + /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ + + if (yychar <= yyeof_) + { + /* Return failure if at end of input. */ + if (yychar == yyeof_) + YYABORT; + } + else + { + yydestruct_ ("Error: discarding", yytoken, &yylval, &yylloc); + yychar = yyempty_; + } + } + + /* Else will try to reuse look-ahead token after shifting the error + token. */ + goto yyerrlab1; + + + /*---------------------------------------------------. + | yyerrorlab -- error raised explicitly by YYERROR. | + `---------------------------------------------------*/ + yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (false) + goto yyerrorlab; + + yyerror_range[0] = yylocation_stack_[yylen - 1]; + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + yypop_ (yylen); + yylen = 0; + yystate = yystate_stack_[0]; + goto yyerrlab1; + + /*-------------------------------------------------------------. + | yyerrlab1 -- common code for both syntax error and YYERROR. | + `-------------------------------------------------------------*/ + yyerrlab1: + yyerrstatus_ = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact_[yystate]; + if (yyn != yypact_ninf_) + { + yyn += yyterror_; + if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_) + { + yyn = yytable_[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yystate_stack_.height () == 1) + YYABORT; + + yyerror_range[0] = yylocation_stack_[0]; + yydestruct_ ("Error: popping", + yystos_[yystate], + &yysemantic_stack_[0], &yylocation_stack_[0]); + yypop_ (); + yystate = yystate_stack_[0]; + YY_STACK_PRINT (); + } + + if (yyn == yyfinal_) + goto yyacceptlab; + + yyerror_range[1] = yylloc; + // Using YYLLOC is tempting, but would change the location of + // the look-ahead. YYLOC is available though. + YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); + yysemantic_stack_.push (yylval); + yylocation_stack_.push (yyloc); + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos_[yyn], + &yysemantic_stack_[0], &yylocation_stack_[0]); + + yystate = yyn; + goto yynewstate; + + /* Accept. */ + yyacceptlab: + yyresult = 0; + goto yyreturn; + + /* Abort. */ + yyabortlab: + yyresult = 1; + goto yyreturn; + + yyreturn: + if (yychar != yyeof_ && yychar != yyempty_) + yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc); + + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + yypop_ (yylen); + while (yystate_stack_.height () != 1) + { + yydestruct_ ("Cleanup: popping", + yystos_[yystate_stack_[0]], + &yysemantic_stack_[0], + &yylocation_stack_[0]); + yypop_ (); + } + + return yyresult; + } + + // Generate an error message. + std::string + Parser::yysyntax_error_ (int yystate) + { + std::string res; + YYUSE (yystate); +#if YYERROR_VERBOSE + int yyn = yypact_[yystate]; + if (yypact_ninf_ < yyn && yyn <= yylast_) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = yylast_ - yyn + 1; + int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_; + int count = 0; + for (int x = yyxbegin; x < yyxend; ++x) + if (yycheck_[x + yyn] == x && x != yyterror_) + ++count; + + // FIXME: This method of building the message is not compatible + // with internationalization. It should work like yacc.c does it. + // That is, first build a string that looks like this: + // "syntax error, unexpected %s or %s or %s" + // Then, invoke YY_ on this string. + // Finally, use the string as a format to output + // yytname_[tok], etc. + // Until this gets fixed, this message appears in English only. + res = "syntax error, unexpected "; + res += yytnamerr_ (yytname_[tok]); + if (count < 5) + { + count = 0; + for (int x = yyxbegin; x < yyxend; ++x) + if (yycheck_[x + yyn] == x && x != yyterror_) + { + res += (!count++) ? ", expecting " : " or "; + res += yytnamerr_ (yytname_[x]); + } + } + } + else +#endif + res = YY_("syntax error"); + return res; + } + + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ + const signed char Parser::yypact_ninf_ = -44; + const signed char + Parser::yypact_[] = + { + -44, 19, -44, -44, 8, 45, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, 12, + 10, 31, -44, 24, -44, -15, -5, 8, -44, -44, + -44, -44, -44, 26, -44, 14, -44, -44, -44, -44, + -44, -44, -44, -44, 0, 31, -44, -44, -44, 18, + 18, -44, -44, 20, 26, 26, 27, -44, -44, -44, + -44, 31, 39, -44 + }; + + /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE + doesn't specify something else to do. Zero means the default is an + error. */ + const unsigned char + Parser::yydefact_[] = + { + 2, 0, 5, 1, 3, 36, 49, 48, 4, 6, + 7, 8, 9, 10, 31, 32, 33, 34, 35, 41, + 30, 44, 40, 0, 29, 30, 0, 0, 5, 37, + 38, 28, 27, 29, 23, 0, 15, 17, 21, 20, + 16, 26, 19, 43, 0, 44, 22, 11, 18, 13, + 14, 12, 42, 47, 0, 0, 0, 39, 24, 25, + 45, 44, 0, 46 + }; + + /* YYPGOTO[NTERM-NUM]. */ + const signed char + Parser::yypgoto_[] = + { + -44, -44, -44, 7, 29, -44, -32, -44, 22, -25, + -44, -44, -44, -44, -44, -44, -43, -44, -44, -44, + -44 + }; + + /* YYDEFGOTO[NTERM-NUM]. */ + const signed char + Parser::yydefgoto_[] = + { + -1, 1, 2, 4, 8, 9, 41, 25, 42, 26, + 20, 10, 21, 11, 45, 23, 29, 57, 61, 12, + 13 + }; + + /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. */ + const signed char Parser::yytable_ninf_ = -31; + const signed char + Parser::yytable_[] = + { + 35, 46, 53, 5, 31, 32, 33, 36, 37, 38, + 39, 5, 6, 7, 31, 32, 52, 40, 62, 3, + 6, 7, 58, 59, 54, 55, 47, 48, 49, 50, + 22, 24, -30, -30, 30, 44, 51, -30, -30, 24, + 38, 39, 27, 56, 60, 31, 32, 34, 28, 14, + 15, 16, 17, 18, 19, 63, 43 + }; + + /* YYCHECK. */ + const unsigned char + Parser::yycheck_[] = + { + 25, 33, 45, 3, 19, 20, 21, 12, 13, 14, + 15, 3, 12, 13, 19, 20, 16, 22, 61, 0, + 12, 13, 54, 55, 49, 50, 12, 13, 14, 15, + 18, 21, 14, 15, 10, 28, 22, 19, 20, 21, + 14, 15, 11, 23, 17, 19, 20, 25, 17, 4, + 5, 6, 7, 8, 9, 16, 27 + }; + + /* STOS_[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ + const unsigned char + Parser::yystos_[] = + { + 0, 25, 26, 0, 27, 3, 12, 13, 28, 29, + 35, 37, 43, 44, 4, 5, 6, 7, 8, 9, + 34, 36, 18, 39, 21, 31, 33, 11, 17, 40, + 10, 19, 20, 21, 32, 33, 12, 13, 14, 15, + 22, 30, 32, 28, 27, 38, 30, 12, 13, 14, + 15, 22, 16, 40, 33, 33, 23, 41, 30, 30, + 17, 42, 40, 16 + }; + +#if YYDEBUG + /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding + to YYLEX-NUM. */ + const unsigned short int + Parser::yytoken_number_[] = + { + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278 + }; +#endif + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ + const unsigned char + Parser::yyr1_[] = + { + 0, 24, 26, 25, 27, 27, 28, 28, 28, 28, + 28, 29, 29, 29, 29, 29, 29, 29, 29, 30, + 30, 30, 31, 31, 31, 31, 31, 32, 32, 33, + 33, 34, 34, 34, 34, 34, 36, 35, 38, 37, + 39, 39, 40, 40, 40, 42, 41, 41, 43, 44 + }; + + /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ + const unsigned char + Parser::yyr2_[] = + { + 0, 2, 0, 2, 2, 0, 1, 1, 1, 1, + 1, 5, 5, 5, 5, 4, 4, 4, 5, 1, + 1, 1, 3, 2, 5, 5, 2, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 0, 3, 0, 7, + 1, 0, 3, 2, 0, 0, 5, 0, 1, 1 + }; + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at \a yyntokens_, nonterminals. */ + const char* + const Parser::yytname_[] = + { + "$end", "error", "$undefined", "ID_SIMPLE", "EQ", "PLUSEQ", "MINUSEQ", + "STAREQ", "TILDEEQ", "LBRACE", "RBRACE", "COLON", "NEWLINE", "COMMENT", + "CONT", "COMMENT_CONT", "RCURLY", "LCURLY", "ID_ARGS", + "QUOTED_VARIABLE_VALUE", "VARIABLE_VALUE", "LIST_WS", "ENDOFFILE", + "\"else\"", "$accept", "project", "@1", "statements", "statement", + "variable_assignment", "possible_value", "multiline_values", + "variable_value", "listws", "operator", "scope", "@2", "function_call", + "@3", "function_args", "scope_body", "else_statement", "@4", "comment", + "emptyline", 0 + }; +#endif + +#if YYDEBUG + /* YYRHS -- A `-1'-separated list of the rules' RHS. */ + const Parser::rhs_number_type + Parser::yyrhs_[] = + { + 25, 0, -1, -1, 26, 27, -1, 27, 28, -1, + -1, 29, -1, 35, -1, 37, -1, 43, -1, 44, + -1, 3, 34, 31, 33, 12, -1, 3, 34, 31, + 33, 22, -1, 3, 34, 31, 33, 14, -1, 3, + 34, 31, 33, 15, -1, 3, 34, 33, 12, -1, + 3, 34, 33, 22, -1, 3, 34, 33, 13, -1, + 3, 34, 31, 33, 13, -1, 32, -1, 15, -1, + 14, -1, 31, 21, 30, -1, 31, 32, -1, 31, + 33, 14, 33, 30, -1, 31, 33, 15, 33, 30, + -1, 33, 30, -1, 20, -1, 19, -1, 21, -1, + -1, 4, -1, 5, -1, 6, -1, 7, -1, 8, + -1, -1, 3, 36, 40, -1, -1, 3, 9, 39, + 10, 38, 40, 41, -1, 18, -1, -1, 17, 27, + 16, -1, 11, 28, -1, -1, -1, 23, 17, 42, + 40, 16, -1, -1, 13, -1, 12, -1 + }; + + /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ + const unsigned char + Parser::yyprhs_[] = + { + 0, 0, 3, 4, 7, 10, 11, 13, 15, 17, + 19, 21, 27, 33, 39, 45, 50, 55, 60, 66, + 68, 70, 72, 76, 79, 85, 91, 94, 96, 98, + 100, 101, 103, 105, 107, 109, 111, 112, 116, 117, + 125, 127, 128, 132, 135, 136, 137, 143, 144, 146 + }; + + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ + const unsigned short int + Parser::yyrline_[] = + { + 0, 144, 144, 144, 151, 156, 159, 163, 167, 171, + 175, 181, 192, 202, 213, 224, 233, 241, 250, 263, + 263, 263, 265, 270, 274, 283, 292, 301, 302, 306, + 312, 317, 321, 325, 329, 333, 340, 339, 354, 353, + 378, 379, 382, 383, 388, 392, 391, 405, 410, 418 + }; + + // Print the state stack on the debug stream. + void + Parser::yystack_print_ () + { + *yycdebug_ << "Stack now"; + for (state_stack_type::const_iterator i = yystate_stack_.begin (); + i != yystate_stack_.end (); ++i) + *yycdebug_ << ' ' << *i; + *yycdebug_ << std::endl; + } + + // Report on the debug stream that the rule \a yyrule is going to be reduced. + void + Parser::yy_reduce_print_ (int yyrule) + { + unsigned int yylno = yyrline_[yyrule]; + int yynrhs = yyr2_[yyrule]; + /* Print the symbols being reduced, and their result. */ + *yycdebug_ << "Reducing stack by rule " << yyrule - 1 + << " (line " << yylno << "), "; + /* The symbols being reduced. */ + for (int yyi = 0; yyi < yynrhs; yyi++) + YY_SYMBOL_PRINT (" $" << yyi + 1 << " =", + yyrhs_[yyprhs_[yyrule] + yyi], + &(yysemantic_stack_[(yynrhs) - (yyi + 1)]), + &(yylocation_stack_[(yynrhs) - (yyi + 1)])); + } +#endif // YYDEBUG + + /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ + Parser::token_number_type + Parser::yytranslate_ (int t) + { + static + const token_number_type + translate_table[] = + { + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23 + }; + if ((unsigned int) t <= yyuser_token_number_max_) + return translate_table[t]; + else + return yyundef_token_; + } + + const int Parser::yyeof_ = 0; + const int Parser::yylast_ = 56; + const int Parser::yynnts_ = 21; + const int Parser::yyempty_ = -2; + const int Parser::yyfinal_ = 3; + const int Parser::yyterror_ = 1; + const int Parser::yyerrcode_ = 256; + const int Parser::yyntokens_ = 24; + + const unsigned int Parser::yyuser_token_number_max_ = 278; + const Parser::token_number_type Parser::yyundef_token_ = 2; + +} // namespace QMake + +#line 421 "qmake.yy" + + + +namespace QMake +{ + void Parser::error(const location_type& /*l*/, const std::string& m) + { + std::cerr << m << std::endl; + } +} + diff --git a/buildtools/lib/parsers/qmake/qmake_yacc.hpp b/buildtools/lib/parsers/qmake/qmake_yacc.hpp new file mode 100644 index 00000000..69b8a035 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmake_yacc.hpp @@ -0,0 +1,418 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton interface for Bison LALR(1) parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C++ LALR(1) parser skeleton written by Akim Demaille. */ + +#ifndef PARSER_HEADER_H +# define PARSER_HEADER_H + +#include <string> +#include <iostream> +#include "stack.hh" + +namespace QMake +{ + class position; + class location; +} + +/* First part of user declarations. */ +#line 1 "qmake.yy" + +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * Copyright (C) 2006 by Andreas Pakulat * + * apaku@gmx.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/** +@file qmake.yy +QMake Parser + +Simple LALR parser which builds the syntax tree (see @ref QMake::AST). + +@todo Recognize comments after statements like: +SOURCES = foo #regognize me + +@fixme Parser fails on files that do not end with a newline +@fixme 1 shift/reduce conflict in "line_body" rule +*/ + +#include <qvaluestack.h> +#include "qmakeast.h" +#include <qregexp.h> + +#define YYSTYPE_IS_DECLARED + +namespace QMake +{ + class Lexer; + +/** +The yylval type. +*/ +struct Result { + Result(): node(0) {} + + /**Type of semantic value for simple grammar rules.*/ + QString value; + /**Type of semantic value for grammar rules which are parts of AST.*/ + AST *node; + /**Type of semantic value for "multiline_values" grammar rule. + Each line of multiline value is stored as a string in the list. + + For example we have in .pro file: + @code + SOURCE = foo1.cpp \ + foo2.cpp \ + foo3.cpp foo4.cpp + @endcode + The string list will be populated with three strings: + <pre> + foo1.cpp + foo2.cpp + foo3.cpp foo4.cpp + </pre> + */ + QStringList values; + QString indent; +}; + +#define YYSTYPE Result +typedef Result YYSTYPE; +} + +extern int QMakelex( QMake::Result* yylval, QMake::Lexer* lexer ); + +/** +The stack to store ProjectAST pointers when a new child +ProjectAST is created and filled with statements. + +Parser creates root ProjectAST for a .pro file, pushes it onto the stack and starts +adding statements. Each statement is added as a child StatementAST to the ProjectAST +currently on the top in the stack. + +When a scope or function scope statement is parsed, the child ProjectAST is created +and pushed onto the stack. Therefore all statements which belong to the scope +or function scope are added as childs to their direct parent (scope or function scope). +*/ +//QValueStack<ProjectAST*> projects; + +/** +The current depth of AST node is stored here. +AST depth is important to know because automatic indentation can +be easily implemented (the parser itself looses all information +about indentation). +*/ +// int depth = 0; + +/* +To debug this parser, put the line below into the next bison file section. +Don't forget to uncomment "yydebug = 1" line in qmakedriver.cpp. +%debug +*/ + + +/* Line 35 of lalr1.cc. */ +#line 165 "qmake_yacc.hpp" + +#include "location.hh" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 1 +#endif + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ +do { \ + if (N) \ + { \ + (Current).begin = (Rhs)[1].begin; \ + (Current).end = (Rhs)[N].end; \ + } \ + else \ + { \ + (Current).begin = (Current).end = (Rhs)[0].end; \ + } \ +} while (false) +#endif + +namespace QMake +{ + + /// A Bison parser. + class Parser + { + public: + /// Symbol semantic values. +#ifndef YYSTYPE + typedef int semantic_type; +#else + typedef YYSTYPE semantic_type; +#endif + /// Symbol locations. + typedef location location_type; + /// Tokens. + struct token + { + /* Tokens. */ + enum yytokentype { + ID_SIMPLE = 258, + EQ = 259, + PLUSEQ = 260, + MINUSEQ = 261, + STAREQ = 262, + TILDEEQ = 263, + LBRACE = 264, + RBRACE = 265, + COLON = 266, + NEWLINE = 267, + COMMENT = 268, + CONT = 269, + COMMENT_CONT = 270, + RCURLY = 271, + LCURLY = 272, + ID_ARGS = 273, + QUOTED_VARIABLE_VALUE = 274, + VARIABLE_VALUE = 275, + LIST_WS = 276, + ENDOFFILE = 277 + }; + + }; + /// Token type. + typedef token::yytokentype token_type; + + /// Build a parser object. + Parser (QMake::Lexer* lexer_yyarg, QValueStack<ProjectAST*>& projects_yyarg, int depth_yyarg); + virtual ~Parser (); + + /// Parse. + /// \returns 0 iff parsing succeeded. + virtual int parse (); + + /// The current debugging stream. + std::ostream& debug_stream () const; + /// Set the current debugging stream. + void set_debug_stream (std::ostream &); + + /// Type for debugging levels. + typedef int debug_level_type; + /// The current debugging level. + debug_level_type debug_level () const; + /// Set the current debugging level. + void set_debug_level (debug_level_type l); + + private: + /// Report a syntax error. + /// \param loc where the syntax error is found. + /// \param msg a description of the syntax error. + virtual void error (const location_type& loc, const std::string& msg); + + /// Generate an error message. + /// \param state the state where the error occurred. + /// \param tok the look-ahead token. + virtual std::string yysyntax_error_ (int yystate); + +#if YYDEBUG + /// \brief Report a symbol value on the debug stream. + /// \param yytype The token type. + /// \param yyvaluep Its semantic value. + /// \param yylocationp Its location. + virtual void yy_symbol_value_print_ (int yytype, + const semantic_type* yyvaluep, + const location_type* yylocationp); + /// \brief Report a symbol on the debug stream. + /// \param yytype The token type. + /// \param yyvaluep Its semantic value. + /// \param yylocationp Its location. + virtual void yy_symbol_print_ (int yytype, + const semantic_type* yyvaluep, + const location_type* yylocationp); +#endif /* ! YYDEBUG */ + + + /// State numbers. + typedef int state_type; + /// State stack type. + typedef stack<state_type> state_stack_type; + /// Semantic value stack type. + typedef stack<semantic_type> semantic_stack_type; + /// location stack type. + typedef stack<location_type> location_stack_type; + + /// The state stack. + state_stack_type yystate_stack_; + /// The semantic value stack. + semantic_stack_type yysemantic_stack_; + /// The location stack. + location_stack_type yylocation_stack_; + + /// Internal symbol numbers. + typedef unsigned char token_number_type; + /* Tables. */ + /// For a state, the index in \a yytable_ of its portion. + static const signed char yypact_[]; + static const signed char yypact_ninf_; + + /// For a state, default rule to reduce. + /// Unless\a yytable_ specifies something else to do. + /// Zero means the default is an error. + static const unsigned char yydefact_[]; + + static const signed char yypgoto_[]; + static const signed char yydefgoto_[]; + + /// What to do in a state. + /// \a yytable_[yypact_[s]]: what to do in state \a s. + /// - if positive, shift that token. + /// - if negative, reduce the rule which number is the opposite. + /// - if zero, do what YYDEFACT says. + static const signed char yytable_[]; + static const signed char yytable_ninf_; + + static const unsigned char yycheck_[]; + + /// For a state, its accessing symbol. + static const unsigned char yystos_[]; + + /// For a rule, its LHS. + static const unsigned char yyr1_[]; + /// For a rule, its RHS length. + static const unsigned char yyr2_[]; + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE + /// For a symbol, its name in clear. + static const char* const yytname_[]; +#endif + +#if YYERROR_VERBOSE + /// Convert the symbol name \a n to a form suitable for a diagnostic. + virtual std::string yytnamerr_ (const char *n); +#endif + +#if YYDEBUG + /// A type to store symbol numbers and -1. + typedef signed char rhs_number_type; + /// A `-1'-separated list of the rules' RHS. + static const rhs_number_type yyrhs_[]; + /// For each rule, the index of the first RHS symbol in \a yyrhs_. + static const unsigned char yyprhs_[]; + /// For each rule, its source line number. + static const unsigned short int yyrline_[]; + /// For each scanner token number, its symbol number. + static const unsigned short int yytoken_number_[]; + /// Report on the debug stream that the rule \a r is going to be reduced. + virtual void yy_reduce_print_ (int r); + /// Print the state stack on the debug stream. + virtual void yystack_print_ (); +#endif + + /// Convert a scanner token number \a t to a symbol number. + token_number_type yytranslate_ (int t); + + /// \brief Reclaim the memory associated to a symbol. + /// \param yymsg Why this token is reclaimed. + /// \param yytype The symbol type. + /// \param yyvaluep Its semantic value. + /// \param yylocationp Its location. + inline void yydestruct_ (const char* yymsg, + int yytype, + semantic_type* yyvaluep, + location_type* yylocationp); + + /// Pop \a n symbols the three stacks. + inline void yypop_ (unsigned int n = 1); + + /* Constants. */ + static const int yyeof_; + /* LAST_ -- Last index in TABLE_. */ + static const int yylast_; + static const int yynnts_; + static const int yyempty_; + static const int yyfinal_; + static const int yyterror_; + static const int yyerrcode_; + static const int yyntokens_; + static const unsigned int yyuser_token_number_max_; + static const token_number_type yyundef_token_; + + /* Debugging. */ + int yydebug_; + std::ostream* yycdebug_; + + + /* User arguments. */ + QMake::Lexer* lexer; + QValueStack<ProjectAST*>& projects; + int depth; + }; +} + + +#endif /* ! defined PARSER_HEADER_H */ diff --git a/buildtools/lib/parsers/qmake/qmakeast.cpp b/buildtools/lib/parsers/qmake/qmakeast.cpp new file mode 100644 index 00000000..e6283e28 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmakeast.cpp @@ -0,0 +1,170 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qmakeast.h" + +#include <kdebug.h> + +namespace QMake { + +//AST + +AST::~AST() +{ + for (QValueList<AST*>::iterator it = m_children.begin(); it != m_children.end(); ++it) + { + AST *node = *it; + delete node; + } + m_children.clear(); +} + +void AST::addChildAST(AST *node) +{ + m_children.append(node); +} + +void AST::removeChildAST(AST *node) +{ + m_children.remove(node); +} + +void AST::writeBack(QString &buffer) +{ + for (QValueList<AST*>::const_iterator it = m_children.constBegin(); + it != m_children.constEnd(); ++it) + { + if (*it) + { + (*it)->writeBack(buffer); + } + } +} + +QString AST::indentation() +{ + QString result; + for (int i = 0; i < depth(); i++) + result += " "; + return result; +} + +//ProjectAST + +void ProjectAST::writeBack(QString &buffer) +{ + bool hasActualStatements = false; + for (QValueList<QMake::AST*>::const_iterator it = m_children.begin(); it != m_children.end(); ++it) + { + if ((*it)->nodeType() != AST::IncludeAST) + { + hasActualStatements = true; + break; + } + } + + if (isScope()) + { + if( !buffer.endsWith(": ") ) + buffer += indentation(); + buffer += scopedID; + if( m_children.count() == 1 ) + buffer += " : "; + else + buffer += " {"; + } + else if (isFunctionScope()) + { + if( !buffer.endsWith(": ") ) + buffer += indentation(); + buffer += scopedID + "(" + args + ")"; + if( m_children.count() == 1 && hasActualStatements ) + buffer += ": "; + else if( (m_children.count() > 0 && hasActualStatements) ) + buffer += "{"; + else + buffer += ""; + } + else if( !buffer.endsWith(": ") ) + buffer += indentation(); + AST::writeBack(buffer); + if (isScope() && m_children.count() > 1 ) + buffer += indentation() + "}"; + + if (isFunctionScope() && (hasActualStatements) && m_children.count() > 1) + buffer += indentation() + "}"; +} + + +void ProjectAST::setLineEnding( ProjectAST::LineEnding l ) +{ + m_lineEnding = l; +} + +ProjectAST::LineEnding ProjectAST::lineEnding() +{ + return m_lineEnding; +} + +//AssignmentAST + +AssignmentAST::~AssignmentAST() +{ +} + +void AssignmentAST::writeBack(QString &buffer) +{ + if( !buffer.endsWith(": ") ) + buffer += indentation(); + buffer += scopedID + " " + op; + if( values.first().stripWhiteSpace() != "" ) + buffer += " "; + buffer += values.join(""); +} + + +//NewLineAST + +void NewLineAST::writeBack(QString &buffer) +{ + buffer += "\n"; +} + + +//CommentAST + +void CommentAST::writeBack(QString &buffer) +{ + if( !buffer.endsWith(": ") ) + buffer += indentation(); + buffer += comment; +} + + +//IncludeAST + +void IncludeAST::writeBack(QString &/*buffer*/) +{ +} + +} + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + + diff --git a/buildtools/lib/parsers/qmake/qmakeast.h b/buildtools/lib/parsers/qmake/qmakeast.h new file mode 100644 index 00000000..b8486433 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmakeast.h @@ -0,0 +1,236 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QMAKEQMAKEAST_H +#define QMAKEQMAKEAST_H + +#include <qstringlist.h> + +/** +@file qmakeast.h +Abstract Syntax Tree (AST) class declarations. +*/ + +namespace QMake { + +/** +AST node. +This is the base class. Objects of this type are not created by the parser. + +Each AST node holds the list of its children which are always deleted in the +destructor. This way, it's possible call delete for only root AST node and +others will be deleted automatically. + +Each AST node also knows how to write the information back into .pro file. +*/ +class AST { +public: + /**Type of AST node.*/ + enum NodeType { + ProjectAST /**<Project, scope or function scope.*/, + AssignmentAST /**<Variable assignment.*/, + NewLineAST /**<Line feed.*/, + CommentAST /**<Comment.*/, + IncludeAST /**<.pri include.*/, + OrOperatorAST /* | */ + }; + + /**Constructs AST with given node type.*/ + AST(NodeType nodeType): m_nodeType(nodeType), m_depth(0) {} + virtual ~AST(); + + /**Adds child AST node to this node. Despite this function is virtual, + reimplementations should call it to make automatic destruction of + AST tree possible.*/ + virtual void addChildAST(AST *node); + /**Removes child AST node from this node. Despite this function is virtual, + reimplementations should call it to make automatic destruction of + AST tree possible.*/ + virtual void removeChildAST(AST *node); + /**Writes information stored in the AST into the @p buffer. + This is a default implementation which iterates over child nodes + and calls writeBack for each child node.*/ + virtual void writeBack(QString &buffer); + + /**@return The type of the node.*/ + virtual NodeType nodeType() const { return m_nodeType; } + + /**Sets the depth of the node in AST.*/ + void setDepth(int depth) { m_depth = depth; } + /**@return The depth of the node in AST.*/ + int depth() const { return m_depth; } + /**@return The indentation string based on node depth.*/ + virtual QString indentation(); + + /**The list of child AST nodes.*/ + QValueList<AST*> m_children; + +protected: + NodeType m_nodeType; + +private: + int m_depth; + +}; + + +/** +Project AST node. +Represents complete projects, scopes and function scopes. +Examples: +@code +scopename{ +var=value +} +function(args){ +var=value +} +@endcode +*/ +class ProjectAST: public AST { +public: + /**The kind of a project node.*/ + enum Kind { + Project /**<Project*/, + Scope /**<Scope*/, + FunctionScope /**<FunctionScope*/, + Empty /**<Project does not exist, the AST is empty*/ + }; + + enum LineEnding { + Unix, + MacOS, + Windows + }; + + /**Constructs a project node of given @p kind.*/ + ProjectAST(Kind kind = Project): AST(AST::ProjectAST), m_kind(kind) {} + + virtual void writeBack(QString &buffer); + + /**@return true if this node is a project.*/ + bool isProject() const { return m_kind == Project; } + /**@return true if this node is a scope.*/ + bool isScope() const { return m_kind == Scope; } + /**@return true if this node is a function scope.*/ + bool isFunctionScope() const { return m_kind == FunctionScope; } + /**@return true if this node is empty.*/ + bool isEmpty() const { return m_kind == Empty; } + + void setFileName(const QString& fileName) { m_fileName = fileName; } + QString fileName() const { return m_fileName; } + + void setLineEnding( LineEnding ); + LineEnding lineEnding(); + + /**Scoped identifier (scope name or function name).*/ + QString scopedID; + /**Function arguments. Empty for other kinds of projects.*/ + QString args; + +private: + Kind m_kind; + QString m_fileName; + LineEnding m_lineEnding; +}; + + +/** +Assignment AST node. +Represents assignments, for example: +<pre> +var=value +</pre> + +Values can be specified on several lines and +each line is stored as a string in the list of values.@n +For example, if we have in .pro: +<pre> +SOURCES=a.cpp \ + b.cpp c.cpp +</pre> +then values will be stored as a two elements list: +<pre> +a.cpp + b.cpp c.cpp +</pre> +*/ +class AssignmentAST: public AST { +public: + AssignmentAST(): AST(AST::AssignmentAST){} + ~AssignmentAST(); + + virtual void writeBack(QString &buffer); + + /**Scoped name of the variable.*/ + QString scopedID; + /**Operator.*/ + QString op; + /**List of values.*/ + QStringList values; + /**Indentation of multiline values*/ + QString indent; +}; + + +/** +New line AST node. +Represents line feeds in files. +*/ +class NewLineAST: public AST { +public: + NewLineAST(): AST(AST::NewLineAST) {} + + virtual void writeBack(QString &buffer); + +}; + + +/** +Comment AST node. +Represents comments. +*/ +class CommentAST: public AST { +public: + CommentAST(): AST(AST::CommentAST) {} + + virtual void writeBack(QString &buffer); + + /**Comment text.*/ + QString comment; + +}; + + +/** +Include AST node. +Represents pri include. + */ +class IncludeAST: public AST { +public: + IncludeAST(): AST(AST::IncludeAST) {} + + virtual void writeBack(QString &buffer); + + QString projectName; +}; + +} + +#endif diff --git a/buildtools/lib/parsers/qmake/qmakeastvisitor.cpp b/buildtools/lib/parsers/qmake/qmakeastvisitor.cpp new file mode 100644 index 00000000..d8dd7751 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmakeastvisitor.cpp @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qmakeastvisitor.h" + +namespace QMake { + +void ASTVisitor::processProject(ProjectAST *project) +{ + if (project->isProject()) + enterRealProject(project); + else if (project->isScope()) + enterScope(project); + else if (project->isFunctionScope()) + enterFunctionScope(project); + for (QValueList<QMake::AST*>::const_iterator it = project->m_children.constBegin(); + it != project->m_children.constEnd(); ++it) + { + AST *ast = *it; + if (ast == 0) + continue; + switch (ast->nodeType()) { + case AST::AssignmentAST: + processAssignment(static_cast<QMake::AssignmentAST*>(ast)); + break; + + case AST::NewLineAST: + processNewLine(static_cast<QMake::NewLineAST*>(ast)); + break; + + case AST::CommentAST: + processComment(static_cast<QMake::CommentAST*>(ast)); + break; + + case AST::ProjectAST: + processProject(static_cast<QMake::ProjectAST*>(ast)); + break; + + case AST::IncludeAST: + processInclude(static_cast<QMake::IncludeAST*>(ast)); + break; + } + } + if (project->isProject()) + leaveRealProject(project); + else if (project->isScope()) + leaveScope(project); + else if (project->isFunctionScope()) + leaveFunctionScope(project); +} + +} diff --git a/buildtools/lib/parsers/qmake/qmakeastvisitor.h b/buildtools/lib/parsers/qmake/qmakeastvisitor.h new file mode 100644 index 00000000..006d1de3 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmakeastvisitor.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QMAKEQMAKEASTVISITOR_H +#define QMAKEQMAKEASTVISITOR_H + +#include "qmakeast.h" + +namespace QMake { + +class ASTVisitor{ +public: + ASTVisitor() {} + + virtual void processProject(ProjectAST *); + virtual void enterRealProject(ProjectAST *) {} + virtual void leaveRealProject(ProjectAST *) {} + virtual void enterScope(ProjectAST *) {} + virtual void leaveScope(ProjectAST *) {} + virtual void enterFunctionScope(ProjectAST *) {} + virtual void leaveFunctionScope(ProjectAST *) {} + virtual void processAssignment(AssignmentAST *) {} + virtual void processNewLine(NewLineAST *) {} + virtual void processComment(CommentAST *) {} + virtual void processInclude(IncludeAST *) {} +}; + +} + +#endif diff --git a/buildtools/lib/parsers/qmake/qmakedriver.cpp b/buildtools/lib/parsers/qmake/qmakedriver.cpp new file mode 100644 index 00000000..3e385c7a --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmakedriver.cpp @@ -0,0 +1,113 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qmakedriver.h" +#include "qmakeast.h" + +#include <qvaluestack.h> +#include <kio/netaccess.h> + +#include <iostream> +#include <fstream> +#include <sstream> + +#include "qmake_lex.h" +#include "qmake_yacc.hpp" + +namespace QMake { + +int Driver::parseFile(const char *fileName, ProjectAST **ast, int debug) +{ + std::ifstream inf( fileName, std::ios::in ); + if ( !inf.is_open() ) + { + *ast = 0; + return 1; + } +// yydebug = 1; + Lexer l(&inf); + l.set_debug(debug); + int depth = 0; + QValueStack<ProjectAST*> stack; + Parser p(&l, stack, depth); + p.set_debug_level(debug); + int ret = p.parse(); + *ast = stack.top(); + (*ast)->setFileName(fileName); + switch( l.lineending() ) + { + case QMake::Lexer::Windows: + (*ast)->setLineEnding(QMake::ProjectAST::Windows); + break; + case QMake::Lexer::MacOS: + (*ast)->setLineEnding(QMake::ProjectAST::MacOS); + break; + case QMake::Lexer::Unix: + default: + (*ast)->setLineEnding(QMake::ProjectAST::Unix); + break; + } + return ret; +} + +int Driver::parseFile(QString fileName, ProjectAST **ast, int debug) +{ + return parseFile(fileName.ascii(), ast, debug); +} + +int Driver::parseFile(KURL fileName, ProjectAST **ast, int debug) +{ + QString tmpFile; + int ret = 0; + if (KIO::NetAccess::download(fileName, tmpFile, 0)) + ret = parseFile(tmpFile, ast, debug); + KIO::NetAccess::removeTempFile(tmpFile); + return ret; +} + +int Driver::parseString( const char* string, ProjectAST **ast, int debug ) +{ + std::istringstream ins; + ins.str(string); + Lexer l(&ins); + l.set_debug(debug); + int depth = 0; + QValueStack<ProjectAST*> stack; + Parser p(&l, stack, depth); + p.set_debug_level(debug); + int ret = p.parse(); + *ast = stack.top(); + (*ast)->setFileName(""); + switch( l.lineending() ) + { + case QMake::Lexer::Windows: + (*ast)->setLineEnding(QMake::ProjectAST::Windows); + break; + case QMake::Lexer::MacOS: + (*ast)->setLineEnding(QMake::ProjectAST::MacOS); + break; + case QMake::Lexer::Unix: + default: + (*ast)->setLineEnding(QMake::ProjectAST::Unix); + break; + } + return ret; +} + +} diff --git a/buildtools/lib/parsers/qmake/qmakedriver.h b/buildtools/lib/parsers/qmake/qmakedriver.h new file mode 100644 index 00000000..a1cdc9d9 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmakedriver.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QMAKEQMAKEDRIVER_H +#define QMAKEQMAKEDRIVER_H + +class QString; +class KURL; + +namespace QMake { + +/** +@file qmakedriver.h +Driver for a qmake parser. +*/ + +class ProjectAST; + +/** +Driver. +Use methods of this class to lauch parsing and build the AST. +*/ +class Driver{ +public: + /**Parses the file @p fileName and stores the resulting ProjectAST root + into @p ast. @p ast should not be initialized before. Driver will + initialize it on its own. + @return The result of parsing. Result is 0 on success and <> 0 on failure. + */ + static int parseFile(const char *fileName, ProjectAST **ast, int debug); + static int parseFile(QString fileName, ProjectAST **ast, int debug); + static int parseFile(KURL fileName, ProjectAST **ast, int debug); + static int parseString(const char* string, ProjectAST **ast, int debug); + +}; + +} + +#endif diff --git a/buildtools/lib/parsers/qmake/stack.hh b/buildtools/lib/parsers/qmake/stack.hh new file mode 100644 index 00000000..b81e4a28 --- /dev/null +++ b/buildtools/lib/parsers/qmake/stack.hh @@ -0,0 +1,129 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Stack handling for Bison parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef BISON_STACK_HH +# define BISON_STACK_HH + +#include <deque> + +namespace QMake +{ + template <class T, class S = std::deque<T> > + class stack + { + public: + + // Hide our reversed order. + typedef typename S::reverse_iterator iterator; + typedef typename S::const_reverse_iterator const_iterator; + + stack () : seq_ () + { + } + + stack (unsigned int n) : seq_ (n) + { + } + + inline + T& + operator [] (unsigned int i) + { + return seq_[i]; + } + + inline + const T& + operator [] (unsigned int i) const + { + return seq_[i]; + } + + inline + void + push (const T& t) + { + seq_.push_front (t); + } + + inline + void + pop (unsigned int n = 1) + { + for (; n; --n) + seq_.pop_front (); + } + + inline + unsigned int + height () const + { + return seq_.size (); + } + + inline const_iterator begin () const { return seq_.rbegin (); } + inline const_iterator end () const { return seq_.rend (); } + + private: + + S seq_; + }; + + /// Present a slice of the top of a stack. + template <class T, class S = stack<T> > + class slice + { + public: + + slice (const S& stack, + unsigned int range) : stack_ (stack), + range_ (range) + { + } + + inline + const T& + operator [] (unsigned int i) const + { + return stack_[range_ - i]; + } + + private: + + const S& stack_; + unsigned int range_; + }; +} + +#endif // not BISON_STACK_HH diff --git a/buildtools/lib/parsers/qmake/tests/Makefile.am b/buildtools/lib/parsers/qmake/tests/Makefile.am new file mode 100644 index 00000000..a73f8f4e --- /dev/null +++ b/buildtools/lib/parsers/qmake/tests/Makefile.am @@ -0,0 +1,21 @@ +# This directory collects some classes related to +# project management for the sole purpose that they +# can be shared between parts. + +INCLUDES = -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/util -I$(top_srcdir)/lib/widgets/propeditor \ + -I$(top_srcdir)/buildtools/lib/parsers/qmake \ + -I$(top_builddir)/buildtools/lib/parsers/qmake/tests \ + $(all_includes) + +METASOURCES = AUTO + +noinst_PROGRAMS = runner viewer + +runner_LDFLAGS = $(all_libraries) $(LIB_KDECORE) $(KDE_RPATH) +runner_LDADD = $(top_builddir)/buildtools/lib/parsers/qmake/libkdevqmakeparser.la +runner_SOURCES = runner.cpp + +viewer_LDFLAGS = --no-undefined $(all_libraries) $(LIB_KDECORE) $(KDE_RPATH) +viewer_LDADD = $(top_builddir)/buildtools/lib/parsers/qmake/libkdevqmakeparser.la +viewer_SOURCES = viewer.cpp viewer_main.cpp viewerbase.ui diff --git a/buildtools/lib/parsers/qmake/tests/runner.cpp b/buildtools/lib/parsers/qmake/tests/runner.cpp new file mode 100644 index 00000000..b01284f1 --- /dev/null +++ b/buildtools/lib/parsers/qmake/tests/runner.cpp @@ -0,0 +1,169 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include <cstdlib> +#include <iostream> +#include <stdio.h> +#include "qmakedriver.h" +#include "qmakeastvisitor.h" + +#include <qstring.h> + +#include <kdebug.h> +#include <kcmdlineargs.h> +#include <kurl.h> + +static const KCmdLineOptions options[] = +{ + {"silent", "Enable Parser debug output", 0}, + {"!debug", "Disable output of the generated AST", 0}, + {"!+files", "QMake project files", 0} +}; + + +class PrintAST : QMake::ASTVisitor +{ +public: + PrintAST() : QMake::ASTVisitor() + { + indent = 0; + } + + virtual void processProject( QMake::ProjectAST* p ) + { + QMake::ASTVisitor::processProject(p); + } +private: + virtual void enterRealProject( QMake::ProjectAST* p ) + { + kdDebug(9024) << getIndent() << "--------- Entering Project: " << replaceWs(p->fileName()) << "| LineEnding:" << p->lineEnding() << " --------------" << endl; + indent += 4; + QMake::ASTVisitor::enterRealProject(p); + } + + virtual void leaveRealProject( QMake::ProjectAST* p ) + { + indent -= 4; + kdDebug(9024) << getIndent() << "--------- Leaving Project: " << replaceWs(p->fileName()) << " --------------" << endl; + QMake::ASTVisitor::leaveRealProject(p); + } + + virtual void enterScope( QMake::ProjectAST* p ) + { + kdDebug(9024) << getIndent() << "--------- Entering Scope: " << replaceWs(p->scopedID) << " --------------" << endl; + indent += 4; + QMake::ASTVisitor::enterScope(p); + } + + virtual void leaveScope( QMake::ProjectAST* p ) + { + indent -= 4; + kdDebug(9024) << getIndent() << "--------- Leaving Scope: " << replaceWs(p->scopedID) << " --------------" << endl; + QMake::ASTVisitor::leaveScope(p); + } + + virtual void enterFunctionScope( QMake::ProjectAST* p ) + { + kdDebug(9024) << getIndent() << "--------- Entering FunctionScope: " << replaceWs(p->scopedID) << "(" << replaceWs(p->args) << ")"<< " --------------" << endl; + indent += 4; + QMake::ASTVisitor::enterFunctionScope(p); + } + + virtual void leaveFunctionScope( QMake::ProjectAST* p ) + { + indent -= 4; + kdDebug(9024) << getIndent() << "--------- Leaving FunctionScope: " << replaceWs(p->scopedID) << "(" << replaceWs(p->args) << ")"<< " --------------" << endl; + QMake::ASTVisitor::leaveFunctionScope(p); + } + + QString replaceWs(QString s) + { + return s.replace("\n", "%nl").replace("\t", "%tab").replace(" ", "%spc"); + } + + virtual void processAssignment( QMake::AssignmentAST* a) + { + kdDebug(9024) << getIndent() << "Assignment(" << replaceWs(a->indent) << "):" << replaceWs(a->scopedID) << " " << replaceWs(a->op) << " " << replaceWs(a->values.join("|")) << endl; + QMake::ASTVisitor::processAssignment(a); + } + + virtual void processNewLine( QMake::NewLineAST* n) + { + kdDebug(9024) << getIndent() << "Newline " << endl; + QMake::ASTVisitor::processNewLine(n); + } + + virtual void processComment( QMake::CommentAST* a) + { + kdDebug(9024) << getIndent() << "Comment: " << replaceWs(a->comment) << endl; + QMake::ASTVisitor::processComment(a); + } + + virtual void processInclude( QMake::IncludeAST* a) + { + kdDebug(9024) << getIndent() << "Include: " << replaceWs(a->projectName) << endl; + QMake::ASTVisitor::processInclude(a); + } + + QString getIndent() + { + QString ind; + for( int i = 0 ; i < indent ; i++) + ind += " "; + return ind; + } + int indent; +}; +int main(int argc, char *argv[]) +{ + KCmdLineArgs::init( argc, argv, "QMake Parser", "qmake-parser", "Parse QMake project files", "1.0.0"); + KCmdLineArgs::addCmdLineOptions(options); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + if( args->count() < 1 ) + { + KCmdLineArgs::usage(0); + } + + int debug = 0; + bool silent = false; + + if( args->isSet("silent") ) + silent = true; + if( args->isSet("debug") ) + debug = 1; + for( int i = 0 ; i < args->count() ; i++ ) + { + QMake::ProjectAST *projectAST; + int ret = QMake::Driver::parseFile(args->url(i).path(), &projectAST, debug); + PrintAST pa; + if ( ret == 0 ) + if ( !silent ) + { + pa.processProject(projectAST); + QString profile; + projectAST->writeBack(profile); + kdDebug(9024) << "QMake file written back:\n" << profile << endl; + } + return ret; + } + return 0; +} diff --git a/buildtools/lib/parsers/qmake/tests/viewer.cpp b/buildtools/lib/parsers/qmake/tests/viewer.cpp new file mode 100644 index 00000000..dba2b7fb --- /dev/null +++ b/buildtools/lib/parsers/qmake/tests/viewer.cpp @@ -0,0 +1,182 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "viewer.h" + +#include <qdir.h> +#include <qlineedit.h> +#include <qlistbox.h> +#include <qfiledialog.h> +#include <qtextedit.h> +#include <qfile.h> +#include <qtextstream.h> +#include <qlistview.h> +#include <qtabwidget.h> + +#include <qmakeast.h> +#include <qmakedriver.h> +#include <qmakeastvisitor.h> + +using namespace QMake; + +Viewer::Viewer(QWidget *parent, const char *name) + :ViewerBase(parent, name), projectAST(0) +{ + if (QFile::exists(QDir::currentDirPath() + "/" + "qtlist")) + { + QFile f(QDir::currentDirPath() + "/" + "qtlist"); + f.open(IO_ReadOnly); + QTextStream str(&f); + while (!str.eof()) + files->insertItem(str.readLine()); + } + ast->setSorting(-1); +// parentProject.push((QListViewItem*)0); +} + +void Viewer::addAll_clicked() +{ + if (allLocation->text().isEmpty()) + return; + QDir d(allLocation->text()); + QStringList l = d.entryList("*.pro *.pri"); + for (QStringList::iterator it = l.begin(); it != l.end(); ++it) + (*it) = QDir::cleanDirPath(allLocation->text() + "/" + (*it)); + files->insertStringList(l); +} + +void Viewer::choose_clicked() +{ + QString fileName = QFileDialog::getOpenFileName(QDir::currentDirPath(), "*.pro *.pri", this); + if (!fileName.isEmpty()) + files->insertItem(fileName); +} + +void Viewer::files_currentChanged(QListBoxItem* item) +{ + ast->clear(); + + QFile f(item->text()); + f.open(IO_ReadOnly); + QTextStream str(&f); + source->setText(str.read()); + f.close(); + + int result = QMake::Driver::parseFile(item->text().ascii(), &projectAST, 0); + if (projectAST && (result == 0)) + { + processAST(projectAST); + } + if (tabWidget2->currentPageIndex() == 1) + tabWidget2_selected("Source to be written back"); +} + +void Viewer::tabWidget2_selected(const QString& text) +{ + if ((text == "Source to Be Written Back") && projectAST) + { + QString buffer; + projectAST->writeBack(buffer); + writeBack->setText(buffer); + } +} + +class ViewerVisitor: public ASTVisitor { +public: + ViewerVisitor(Viewer *v): ASTVisitor() + { + this->v = v; + parentProject.push((QListViewItem*)0); + } + + virtual void processProject(ProjectAST *project) + { + ASTVisitor::processProject(project); + } + + virtual void enterRealProject(ProjectAST *project) + { + QListViewItem *projectIt; + if (!parentProject.top()) + { + projectIt = new QListViewItem(v->ast, "Project"); + projectIt->setOpen(true); + parentProject.push(projectIt); + } + + ASTVisitor::enterRealProject(project); + } + virtual void enterScope(ProjectAST *scope) + { + QListViewItem *projectIt = new QListViewItem(parentProject.top(), scope->scopedID, "scope"); + parentProject.push(projectIt); + ASTVisitor::enterScope(scope); + } + virtual void leaveScope(ProjectAST *scope) + { + parentProject.pop(); + } + virtual void enterFunctionScope(ProjectAST *fscope) + { + QListViewItem *projectIt = new QListViewItem(parentProject.top(), + fscope->scopedID + "(" + fscope->args + ")", "function scope"); + parentProject.push(projectIt); + ASTVisitor::enterFunctionScope(fscope); + } + virtual void leaveFunctionScope(ProjectAST *fscope) + { + parentProject.pop(); + } + virtual void processAssignment(AssignmentAST *assignment) + { + QListViewItem *item = new QListViewItem(parentProject.top(), + assignment->scopedID, assignment->op, assignment->values.join("|"), + "assignment"); + item->setMultiLinesEnabled(true); + + ASTVisitor::processAssignment(assignment); + } + virtual void processNewLine(NewLineAST *newline) + { + new QListViewItem(parentProject.top(), "<newline>"); + ASTVisitor::processNewLine(newline); + } + virtual void processComment(CommentAST *comment) + { + new QListViewItem(parentProject.top(), "<comment>"); + ASTVisitor::processComment(comment); + } + virtual void processInclude(IncludeAST *include) + { + new QListViewItem(parentProject.top(), "<include>", include->projectName); + QMake::ASTVisitor::processInclude(include); + } + + Viewer *v; + QValueStack<QListViewItem *> parentProject; +}; + + +void Viewer::processAST(QMake::ProjectAST *projectAST, QListViewItem *globAfter) +{ + ViewerVisitor visitor(this); + visitor.processProject(projectAST); +} + +#include "viewer.moc" diff --git a/buildtools/lib/parsers/qmake/tests/viewer.h b/buildtools/lib/parsers/qmake/tests/viewer.h new file mode 100644 index 00000000..8d0da49f --- /dev/null +++ b/buildtools/lib/parsers/qmake/tests/viewer.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef VIEWER_H +#define VIEWER_H + +#include <qvaluestack.h> + +#include "viewerbase.h" + +namespace QMake { +class ProjectAST; +} + +class QListViewItem; + +class Viewer: public ViewerBase { +Q_OBJECT +public: + Viewer(QWidget *parent = 0, const char *name = 0); + void processAST(QMake::ProjectAST *projectAST, QListViewItem *globAfter = 0); +public slots: + virtual void tabWidget2_selected(const QString&); + virtual void files_currentChanged(QListBoxItem*); + virtual void choose_clicked(); + virtual void addAll_clicked(); +private: + QMake::ProjectAST *projectAST; + friend class ViewerVisitor; +}; + +#endif diff --git a/buildtools/lib/parsers/qmake/tests/viewer_main.cpp b/buildtools/lib/parsers/qmake/tests/viewer_main.cpp new file mode 100644 index 00000000..8fdbc910 --- /dev/null +++ b/buildtools/lib/parsers/qmake/tests/viewer_main.cpp @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include <qapplication.h> +#include "viewer.h" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + Viewer viewer; + app.setMainWidget(&viewer); + viewer.show(); + viewer.setWindowState(viewer.windowState() | Qt::WindowMaximized); + + return app.exec(); +} diff --git a/buildtools/lib/parsers/qmake/tests/viewerbase.ui b/buildtools/lib/parsers/qmake/tests/viewerbase.ui new file mode 100644 index 00000000..976d4d0f --- /dev/null +++ b/buildtools/lib/parsers/qmake/tests/viewerbase.ui @@ -0,0 +1,250 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ViewerBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>ViewerBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>480</height> + </rect> + </property> + <property name="caption"> + <string>Viewer</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QSplitter" row="0" column="0"> + <property name="name"> + <cstring>splitter5</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLineEdit"> + <property name="name"> + <cstring>allLocation</cstring> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>32767</height> + </size> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>addAll</cstring> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string>Add All From Directory</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>choose</cstring> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string>Choose File to Add...</string> + </property> + </widget> + <widget class="QListBox"> + <property name="name"> + <cstring>files</cstring> + </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="hScrollBarMode"> + <enum>Auto</enum> + </property> + </widget> + </vbox> + </widget> + <widget class="QSplitter"> + <property name="name"> + <cstring>splitter2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <widget class="QTextEdit"> + <property name="name"> + <cstring>source</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>1</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="QTabWidget"> + <property name="name"> + <cstring>tabWidget2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>2</verstretch> + </sizepolicy> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>Parse Tree</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QListView" row="0" column="0"> + <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>Value 1</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value 2</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value 3</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>ast</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>Source to Be Written Back</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QTextEdit" row="0" column="0"> + <property name="name"> + <cstring>writeBack</cstring> + </property> + </widget> + </grid> + </widget> + </widget> + </widget> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>addAll</sender> + <signal>clicked()</signal> + <receiver>ViewerBase</receiver> + <slot>addAll_clicked()</slot> + </connection> + <connection> + <sender>choose</sender> + <signal>clicked()</signal> + <receiver>ViewerBase</receiver> + <slot>choose_clicked()</slot> + </connection> + <connection> + <sender>files</sender> + <signal>currentChanged(QListBoxItem*)</signal> + <receiver>ViewerBase</receiver> + <slot>files_currentChanged(QListBoxItem*)</slot> + </connection> + <connection> + <sender>tabWidget2</sender> + <signal>selected(const QString&)</signal> + <receiver>ViewerBase</receiver> + <slot>tabWidget2_selected(const QString&)</slot> + </connection> +</connections> +<slots> + <slot>addAll_clicked()</slot> + <slot>choose_clicked()</slot> + <slot>files_currentChanged( QListBoxItem * )</slot> + <slot>tabWidget2_selected( const QString & )</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/buildtools/lib/widgets/Mainpage.dox b/buildtools/lib/widgets/Mainpage.dox new file mode 100644 index 00000000..56884c97 --- /dev/null +++ b/buildtools/lib/widgets/Mainpage.dox @@ -0,0 +1,10 @@ +/** +@mainpage The KDevelop Buildtool Widgets Library + +This library contains widgets commonly used in buildtool support plugins. + +<b>Link with</b>: -lkdevbuildtoolswidgets + +<b>Include path</b>: -I\$(kde_includes)/kdevelop/buildtools/widgets +*/ + diff --git a/buildtools/lib/widgets/Makefile.am b/buildtools/lib/widgets/Makefile.am new file mode 100644 index 00000000..2277d9d0 --- /dev/null +++ b/buildtools/lib/widgets/Makefile.am @@ -0,0 +1,30 @@ +# This directory collects some classes related to +# project management for the sole purpose that they +# can be shared between parts. + +INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util \ + -I$(top_srcdir)/lib/widgets/propeditor $(all_includes) + +lib_LTLIBRARIES = libkdevbuildtoolswidgets.la +libkdevbuildtoolswidgets_la_LDFLAGS = $(all_libraries) +libkdevbuildtoolswidgets_la_LIBADD = $(top_builddir)/lib/interfaces/libkdevinterfaces.la \ + $(LIB_QT) $(LIB_KDECORE) $(LIB_KDEUI) $(LIB_KIO) -lktexteditor +libkdevbuildtoolswidgets_la_SOURCES = addenvvardlg.cpp addfilesdialog.cpp \ + environmentdisplaydialog.cpp environmentdisplaydialogbase.ui environmentvariableswidget.cpp \ + environmentvariableswidgetbase.ui envvartools.cpp makeoptionswidget.cpp makeoptionswidgetbase.ui \ + removesubprojectdialog.cpp removesubprojectdlgbase.ui runoptionswidget.cpp runoptionswidgetbase.ui \ + subclassesdlg.cpp subclassesdlgbase.ui + +METASOURCES = AUTO + +kdevelopbuildtoolsincludedir = $(includedir)/kdevelop/buildtools/widgets +kdevelopbuildtoolsinclude_HEADERS = addenvvardlg.h addfilesdialog.h \ + environmentvariableswidget.h environmentvariableswidgetbase.h envvartools.h makeoptionswidget.h \ + makeoptionswidgetbase.h removesubprojectdialog.h removesubprojectdlgbase.h runoptionswidget.h \ + runoptionswidgetbase.h subclassesdlg.h subclassesdlgbase.h + +DOXYGEN_REFERENCES = dcop interfaces kdecore kdefx kdeui khtml kmdi kio kjs kparts kutils kdevutil kdevinterfaces kdevutil +DOXYGEN_PROJECTNAME = KDevelop Buildtool Widgets Library +DOXYGEN_DOCDIRPREFIX = kdevbt +include ../../../Doxyfile.am +noinst_HEADERS = environmentdisplaydialog.h diff --git a/buildtools/lib/widgets/addenvvardlg.cpp b/buildtools/lib/widgets/addenvvardlg.cpp new file mode 100644 index 00000000..aaf82774 --- /dev/null +++ b/buildtools/lib/widgets/addenvvardlg.cpp @@ -0,0 +1,84 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Bernd Gehrmann <bernd@kdevelop.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <qlabel.h> +#include <qlayout.h> +#include <qpushbutton.h> +#include <kbuttonbox.h> +#include <klocale.h> +#include <kstdguiitem.h> +#include <kdeversion.h> + +#include "addenvvardlg.h" + + +AddEnvvarDialog::AddEnvvarDialog(QWidget *parent, const char *name) + : QDialog(parent, name, true) +{ + setCaption(i18n("Add Environment Variable")); + + QLabel *varname_label = new QLabel(i18n("&Name:"), this); + varname_edit = new KLineEdit(this); + varname_edit->setFocus(); + varname_label->setBuddy(varname_edit); + + connect( varname_edit, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotTextChanged() ) ); + QLabel *value_label = new QLabel(i18n("&Value:"), this); + value_edit = new KLineEdit(this); + value_label->setBuddy(value_edit); + QFontMetrics fm(value_edit->fontMetrics()); + value_edit->setMinimumWidth(fm.width('X')*35); + connect( value_edit, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotTextChanged() ) ); + + + QVBoxLayout *layout = new QVBoxLayout(this, 10); + + QGridLayout *grid = new QGridLayout(2, 2); + layout->addLayout(grid); + grid->addWidget(varname_label, 0, 0); + grid->addWidget(varname_edit, 0, 1); + grid->addWidget(value_label, 1, 0); + grid->addWidget(value_edit, 1, 1); + + QFrame *frame = new QFrame(this); + frame->setFrameStyle(QFrame::HLine | QFrame::Sunken); + layout->addWidget(frame, 0); + + KButtonBox *buttonbox = new KButtonBox(this); + buttonbox->addStretch(); + m_pOk = buttonbox->addButton( KStdGuiItem::ok()); + QPushButton *cancel = buttonbox->addButton(KStdGuiItem::cancel()); + m_pOk->setDefault(true); + connect( m_pOk, SIGNAL(clicked()), this, SLOT(accept()) ); + connect( cancel, SIGNAL(clicked()), this, SLOT(reject()) ); + buttonbox->layout(); + layout->addWidget(buttonbox, 0); + slotTextChanged(); +} + + +AddEnvvarDialog::~AddEnvvarDialog() +{} + +void AddEnvvarDialog::slotTextChanged() +{ + m_pOk->setEnabled( !varname_edit->text().isEmpty() && !value_edit->text().isEmpty() ); +} + +#include "addenvvardlg.moc" diff --git a/buildtools/lib/widgets/addenvvardlg.h b/buildtools/lib/widgets/addenvvardlg.h new file mode 100644 index 00000000..0ffdbde1 --- /dev/null +++ b/buildtools/lib/widgets/addenvvardlg.h @@ -0,0 +1,54 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Bernd Gehrmann <bernd@kdevelop.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _ADDENVVARDLG_H_ +#define _ADDENVVARDLG_H_ + +#include <qdialog.h> +#include <klineedit.h> +class QPushButton; + +/** +Dialog to add environment variables. +*/ +class AddEnvvarDialog : public QDialog +{ + Q_OBJECT + +public: + AddEnvvarDialog( QWidget *parent=0, const char *name=0 ); + ~AddEnvvarDialog(); + + QString varname() const + { return varname_edit->text(); } + QString value() const + { return value_edit->text(); } + void setvarname(const QString name) const + { varname_edit->setText(name); } + void setvalue(const QString value) const + { value_edit->setText(value); } + private slots: + void slotTextChanged(); +private: + KLineEdit *varname_edit; + KLineEdit *value_edit; + QPushButton *m_pOk; +}; + +#endif diff --git a/buildtools/lib/widgets/addfilesdialog.cpp b/buildtools/lib/widgets/addfilesdialog.cpp new file mode 100644 index 00000000..8ba14539 --- /dev/null +++ b/buildtools/lib/widgets/addfilesdialog.cpp @@ -0,0 +1,78 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include <klocale.h> +#include <kapplication.h> + +#include <qcombobox.h> + +#include "addfilesdialog.h" +#include "addfilesdialog.moc" + +AddFilesDialog::AddFilesDialog(const QString& startDir, const QString& filter, + QWidget *parent, const char *name, bool modal): + KFileDialog(startDir, filter, parent, name, modal) +{ + KConfig *config = kapp->config(); + config->setGroup("Add Files Dialog"); + + m_extraWidget = new QComboBox(false, this); + m_extraWidget->insertItem(i18n("Copy File(s)"), 0); + m_extraWidget->insertItem(i18n("Create Symbolic Link(s)"), 1); + m_extraWidget->insertItem(i18n("Add Relative Path(s)"), 2); + m_extraWidget->setCurrentItem(config->readNumEntry("Mode")); + connect(m_extraWidget, SIGNAL(activated(int)), this, SLOT(storePreferred(int))); + + setPreviewWidget(m_extraWidget); + + setOperationMode(Opening); +} + + +AddFilesDialog::AddFilesDialog(const QString& startDir, const QString& filter, + QWidget *parent, const char *name, bool modal, QComboBox *extraWidget): + KFileDialog(startDir, filter, parent, name, modal, extraWidget), m_extraWidget(extraWidget) +{ + KConfig *config = kapp->config(); + config->setGroup("Add Files Dialog"); + + m_extraWidget->insertItem(i18n("Copy File(s)"), 0); + m_extraWidget->insertItem(i18n("Create Symbolic Link(s)"), 1); + m_extraWidget->insertItem(i18n("Add Relative Path(s)"), 2); + m_extraWidget->setCurrentItem(config->readNumEntry("Mode")); + connect(m_extraWidget, SIGNAL(activated(int)), this, SLOT(storePreferred(int))); + + setOperationMode(Opening); +} + + +AddFilesDialog::~AddFilesDialog() +{ +} + +AddFilesDialog::Mode AddFilesDialog::mode( ) +{ + return (AddFilesDialog::Mode)m_extraWidget->currentItem(); +} + +void AddFilesDialog::storePreferred( int index ) +{ + KConfig *config = kapp->config(); + config->setGroup("Add Files Dialog"); + config->writeEntry("Mode", index); +} diff --git a/buildtools/lib/widgets/addfilesdialog.h b/buildtools/lib/widgets/addfilesdialog.h new file mode 100644 index 00000000..00b238a7 --- /dev/null +++ b/buildtools/lib/widgets/addfilesdialog.h @@ -0,0 +1,57 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef ADDFILESDIALOG_H +#define ADDFILESDIALOG_H + +#include <kdeversion.h> +#include <kfiledialog.h> + +class QComboBox; + +/** +This class allows you to choose additional modes when adding +files to the project. +Currently available modes are Copy, Link and Relative. +Relative means that file should be not copied but added +with the relative path (e.g. ../../dir/filename) +*/ +class AddFilesDialog : public KFileDialog +{ + Q_OBJECT +public: + enum Mode { Copy, Link, Relative }; + + AddFilesDialog(const QString& startDir, const QString& filter, + QWidget *parent, const char *name, bool modal); + + AddFilesDialog(const QString& startDir, const QString& filter, + QWidget *parent, const char *name, bool modal, QComboBox *extraWidget); + + virtual ~AddFilesDialog(); + + virtual AddFilesDialog::Mode mode(); + +private: + QComboBox * m_extraWidget; + +private slots: + void storePreferred(int index); +}; + +#endif diff --git a/buildtools/lib/widgets/environmentdisplaydialog.cpp b/buildtools/lib/widgets/environmentdisplaydialog.cpp new file mode 100644 index 00000000..7d01b031 --- /dev/null +++ b/buildtools/lib/widgets/environmentdisplaydialog.cpp @@ -0,0 +1,54 @@ +/* This file is part of the KDE project + Copyright (C) 2007 Jens Dagerbo <jens.dagerbo@swipnet.se> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <unistd.h> +#include <klistview.h> +#include <qstringlist.h> + +#include "environmentdisplaydialog.h" + +extern char **environ; + +EnvironmentDisplayDialog::EnvironmentDisplayDialog(QWidget* parent, const char* name, bool modal, WFlags fl) +: EnvironmentDisplayDialogBase(parent,name, modal,fl) +{ + QStringList environment; + char ** e = ::environ; + + while ( *e ) + { + environment << *e; + e++; + } + + QStringList::ConstIterator it = environment.begin(); + while( it !=environment.end() ) + { + QStringList pair = QStringList::split( QChar('='), *it ); + if ( pair.count() == 2 ) + { + new QListViewItem( environmentListView, pair.first(), pair.last() ); + } + ++it; + } +} + + +#include "environmentdisplaydialog.moc" + diff --git a/buildtools/lib/widgets/environmentdisplaydialog.h b/buildtools/lib/widgets/environmentdisplaydialog.h new file mode 100644 index 00000000..af284a3b --- /dev/null +++ b/buildtools/lib/widgets/environmentdisplaydialog.h @@ -0,0 +1,35 @@ +/* This file is part of the KDE project + Copyright (C) 2007 Jens Dagerbo <jens.dagerbo@swipnet.se> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef ENVIRONMENTDISPLAYDIALOG_H +#define ENVIRONMENTDISPLAYDIALOG_H + + +#include "environmentdisplaydialogbase.h" + +class EnvironmentDisplayDialog : public EnvironmentDisplayDialogBase +{ +Q_OBJECT + +public: + EnvironmentDisplayDialog(QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); +}; + +#endif + diff --git a/buildtools/lib/widgets/environmentdisplaydialogbase.ui b/buildtools/lib/widgets/environmentdisplaydialogbase.ui new file mode 100644 index 00000000..8b41862f --- /dev/null +++ b/buildtools/lib/widgets/environmentdisplaydialogbase.ui @@ -0,0 +1,111 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>EnvironmentDisplayDialogBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>EnvironmentDisplayDialogBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>583</width> + <height>523</height> + </rect> + </property> + <property name="caption"> + <string>Environment</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="title"> + <string>Current Environment</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KListView"> + <column> + <property name="text"> + <string>Variable</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>environmentListView</cstring> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <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>321</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>closeButton</cstring> + </property> + <property name="text"> + <string>&Close</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>closeButton</sender> + <signal>clicked()</signal> + <receiver>EnvironmentDisplayDialogBase</receiver> + <slot>accept()</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/buildtools/lib/widgets/environmentvariableswidget.cpp b/buildtools/lib/widgets/environmentvariableswidget.cpp new file mode 100644 index 00000000..7ba08427 --- /dev/null +++ b/buildtools/lib/widgets/environmentvariableswidget.cpp @@ -0,0 +1,126 @@ +/* This file is part of the KDE project + Copyright (C) 2001-2002 Bernd Gehrmann <bernd@kdevelop.org> + Copyright (C) 2003 John Firebaugh <jfirebaugh@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "environmentvariableswidget.h" +#include "environmentdisplaydialog.h" + +#include <qcheckbox.h> +#include <qlineedit.h> +#include <qspinbox.h> +#include <qlistview.h> +#include "domutil.h" +#include "addenvvardlg.h" + + +void EnvironmentVariablesWidget::addVarClicked() +{ + AddEnvvarDialog dlg( this, "add env dialog" ) ; + if (QListViewItem *Item = listview->selectedItem()) + { + dlg.setvarname(Item->text(0)); + dlg.setvalue(Item->text(1)); + } + if (!dlg.exec()) + return; + + (void) new QListViewItem(listview, dlg.varname(), dlg.value()); +} + + +void EnvironmentVariablesWidget::editVarClicked() +{ + AddEnvvarDialog dlg( this, "edit env dialog" ); + QListViewItem *item = listview->selectedItem(); + if ( !item ) + return; + dlg.setvarname(item->text(0)); + dlg.setvalue(item->text(1)); + if (!dlg.exec()) + return; + + item->setText(0,dlg.varname()); + item->setText(1,dlg.value()); +} + + +void EnvironmentVariablesWidget::removeVarClicked() +{ + delete listview->selectedItem(); +} + + +EnvironmentVariablesWidget::EnvironmentVariablesWidget(QDomDocument &dom, const QString &configGroup, + QWidget *parent, const char *name) + : EnvironmentVariablesWidgetBase(parent, name), + m_dom(dom), m_configGroup(configGroup) +{ + readEnvironment(dom, configGroup); + connect( listview, SIGNAL( doubleClicked ( QListViewItem *, const QPoint &, int ) ), this, SLOT( editVarClicked() ) ); +} + + +EnvironmentVariablesWidget::~EnvironmentVariablesWidget() +{} + +void EnvironmentVariablesWidget::readEnvironment(QDomDocument &dom, const QString &configGroup) +{ + m_dom = dom; + m_configGroup = configGroup; + + listview->clear(); + + DomUtil::PairList list = + DomUtil::readPairListEntry(dom, m_configGroup, "envvar", "name", "value"); + + QListViewItem *lastItem = 0; + + DomUtil::PairList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + QListViewItem *newItem = new QListViewItem(listview, (*it).first, (*it).second); + if (lastItem) + newItem->moveItem(lastItem); + lastItem = newItem; + } +} + +void EnvironmentVariablesWidget::changeConfigGroup( const QString &configGroup) +{ + m_configGroup = configGroup; +} + +void EnvironmentVariablesWidget::accept() +{ + DomUtil::PairList list; + QListViewItem *item = listview->firstChild(); + while (item) { + list << DomUtil::Pair(item->text(0), item->text(1)); + item = item->nextSibling(); + } + + DomUtil::writePairListEntry(m_dom, m_configGroup, "envvar", "name", "value", list); +} + +void EnvironmentVariablesWidget::environmentClicked() +{ + EnvironmentDisplayDialog dlg; + dlg.exec(); +} + +#include "environmentvariableswidget.moc" diff --git a/buildtools/lib/widgets/environmentvariableswidget.h b/buildtools/lib/widgets/environmentvariableswidget.h new file mode 100644 index 00000000..9f2d472e --- /dev/null +++ b/buildtools/lib/widgets/environmentvariableswidget.h @@ -0,0 +1,59 @@ +/* This file is part of the KDE project + Copyright (C) 2001-2002 Bernd Gehrmann <bernd@kdevelop.org> + Copyright (C) 2003 John Firebaugh <jfirebaugh@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _ENVIRONMENTVARIABLESWIDGET_H_ +#define _ENVIRONMENTVARIABLESWIDGET_H_ + +#include "environmentvariableswidgetbase.h" + +#include <qdom.h> + +/** +Environment variables widget. +*/ +class EnvironmentVariablesWidget : public EnvironmentVariablesWidgetBase +{ + Q_OBJECT + +public: + EnvironmentVariablesWidget( QDomDocument &dom, const QString &configGroup, + QWidget *parent=0, const char *name=0 ); + ~EnvironmentVariablesWidget(); + + /// read in a set of environment variables from the DOM document + void readEnvironment(QDomDocument &dom, const QString &configGroup); + + /// changes the path in the DOM structure where the environment variables are stored + void changeConfigGroup( const QString &configGroup); + +public slots: + void accept(); + +private: + virtual void addVarClicked(); + virtual void removeVarClicked(); + virtual void editVarClicked(); + virtual void environmentClicked(); + + QDomDocument &m_dom; + QString m_configGroup; +}; + +#endif diff --git a/buildtools/lib/widgets/environmentvariableswidgetbase.ui b/buildtools/lib/widgets/environmentvariableswidgetbase.ui new file mode 100644 index 00000000..d16cc613 --- /dev/null +++ b/buildtools/lib/widgets/environmentvariableswidgetbase.ui @@ -0,0 +1,200 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>EnvironmentVariablesWidgetBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>EnvironmentVariablesWidgetBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>566</width> + <height>451</height> + </rect> + </property> + <property name="caption"> + <string>Environment Variables</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QListView" row="0" column="0" rowspan="6" colspan="1"> + <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>Value</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <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> + <property name="showSortIndicator"> + <bool>true</bool> + </property> + <property name="resizeMode"> + <enum>AllColumns</enum> + </property> + </widget> + <widget class="QPushButton" row="2" column="1"> + <property name="name"> + <cstring>removevar_button</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + <widget class="QPushButton" row="1" column="1"> + <property name="name"> + <cstring>editvar_button</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</string> + </property> + </widget> + <widget class="QPushButton" row="0" column="1"> + <property name="name"> + <cstring>addvar_button</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>A&dd / Copy</string> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>Spacer12</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>60</height> + </size> + </property> + </spacer> + <widget class="QPushButton" row="4" column="1"> + <property name="name"> + <cstring>environmentButton</cstring> + </property> + <property name="text"> + <string>E&nvironment</string> + </property> + </widget> + <spacer row="5" column="1"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>171</height> + </size> + </property> + </spacer> + </grid> +</widget> +<connections> + <connection> + <sender>addvar_button</sender> + <signal>clicked()</signal> + <receiver>EnvironmentVariablesWidgetBase</receiver> + <slot>addVarClicked()</slot> + </connection> + <connection> + <sender>removevar_button</sender> + <signal>clicked()</signal> + <receiver>EnvironmentVariablesWidgetBase</receiver> + <slot>removeVarClicked()</slot> + </connection> + <connection> + <sender>editvar_button</sender> + <signal>clicked()</signal> + <receiver>EnvironmentVariablesWidgetBase</receiver> + <slot>editVarClicked()</slot> + </connection> + <connection> + <sender>environmentButton</sender> + <signal>clicked()</signal> + <receiver>EnvironmentVariablesWidgetBase</receiver> + <slot>environmentClicked()</slot> + </connection> +</connections> +<tabstops> + <tabstop>listview</tabstop> + <tabstop>addvar_button</tabstop> + <tabstop>removevar_button</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<slots> + <slot>addVarClicked()</slot> + <slot>removeVarClicked()</slot> + <slot>editVarClicked()</slot> + <slot>environmentClicked()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +</UI> diff --git a/buildtools/lib/widgets/envvartools.cpp b/buildtools/lib/widgets/envvartools.cpp new file mode 100644 index 00000000..bc8eaf51 --- /dev/null +++ b/buildtools/lib/widgets/envvartools.cpp @@ -0,0 +1,31 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include "envvartools.h" + +#include <qregexp.h> + +QString EnvVarTools::quote( const QString & arg ) +{ + QString res = arg; + res.replace(QRegExp(QString::fromLatin1("'")), QString::fromLatin1("'\\''")); + res.prepend("\""); + res.append("\""); + return res; +} + diff --git a/buildtools/lib/widgets/envvartools.h b/buildtools/lib/widgets/envvartools.h new file mode 100644 index 00000000..65db1b8d --- /dev/null +++ b/buildtools/lib/widgets/envvartools.h @@ -0,0 +1,28 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include <qstring.h> + +/**Environment support functions.*/ +namespace EnvVarTools{ + + /**Quotes the argument using double quotes ("). Created as a replacement + for KShellProcess::quote.*/ + QString quote(const QString &arg); + +} diff --git a/buildtools/lib/widgets/makeoptionswidget.cpp b/buildtools/lib/widgets/makeoptionswidget.cpp new file mode 100644 index 00000000..c720de8b --- /dev/null +++ b/buildtools/lib/widgets/makeoptionswidget.cpp @@ -0,0 +1,64 @@ +/* This file is part of the KDE project + Copyright (C) 2001-2002 Bernd Gehrmann <bernd@kdevelop.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "makeoptionswidget.h" + +#include <qcheckbox.h> +#include <klineedit.h> +#include <qspinbox.h> +#include <qlistview.h> +#include <qgroupbox.h> + +#include "domutil.h" +#include "environmentvariableswidget.h" + +MakeOptionsWidget::MakeOptionsWidget(QDomDocument &dom, const QString &configGroup, + QWidget *parent, const char *name) + : MakeOptionsWidgetBase(parent, name), + m_dom(dom), m_configGroup(configGroup) +{ + env_var_group->setColumnLayout( 1, Qt::Vertical ); + m_environmentVariablesWidget = new EnvironmentVariablesWidget( dom, configGroup + "/make/envvars", env_var_group ); + + abort_box->setChecked(DomUtil::readBoolEntry(dom, configGroup + "/make/abortonerror", true )); + jobs_box->setValue(DomUtil::readIntEntry(dom, configGroup + "/make/numberofjobs")); + runMultiJobs->setChecked(DomUtil::readBoolEntry(dom, configGroup + "/make/runmultiplejobs")); + dontact_box->setChecked(DomUtil::readBoolEntry(dom, configGroup + "/make/dontact")); + makebin_edit->setText(DomUtil::readEntry(dom, configGroup + "/make/makebin")); + prio_box->setValue(DomUtil::readIntEntry(dom, configGroup + "/make/prio")); +} + + +MakeOptionsWidget::~MakeOptionsWidget() +{} + + +void MakeOptionsWidget::accept() +{ + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/make/abortonerror", abort_box->isChecked()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/make/runmultiplejobs", runMultiJobs->isChecked()); + DomUtil::writeIntEntry(m_dom, m_configGroup + "/make/numberofjobs", jobs_box->value()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/make/dontact", dontact_box->isChecked()); + DomUtil::writeEntry(m_dom, m_configGroup + "/make/makebin", makebin_edit->text()); + DomUtil::writeIntEntry(m_dom, m_configGroup + "/make/prio", prio_box->value()); + + m_environmentVariablesWidget->accept(); +} + +#include "makeoptionswidget.moc" diff --git a/buildtools/lib/widgets/makeoptionswidget.h b/buildtools/lib/widgets/makeoptionswidget.h new file mode 100644 index 00000000..b6deeb05 --- /dev/null +++ b/buildtools/lib/widgets/makeoptionswidget.h @@ -0,0 +1,50 @@ +/* This file is part of the KDE project + Copyright (C) 2001-2002 Bernd Gehrmann <bernd@kdevelop.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _MAKEOPTIONSWIDGET_H_ +#define _MAKEOPTIONSWIDGET_H_ + +#include "makeoptionswidgetbase.h" + +#include <qdom.h> + +class EnvironmentVariablesWidget; + +/** +Make options widget. +*/ +class MakeOptionsWidget : public MakeOptionsWidgetBase +{ + Q_OBJECT + +public: + MakeOptionsWidget( QDomDocument &dom, const QString &configGroup, + QWidget *parent=0, const char *name=0 ); + ~MakeOptionsWidget(); + +public slots: + void accept(); + +private: + QDomDocument &m_dom; + QString m_configGroup; + EnvironmentVariablesWidget* m_environmentVariablesWidget; +}; + +#endif diff --git a/buildtools/lib/widgets/makeoptionswidgetbase.ui b/buildtools/lib/widgets/makeoptionswidgetbase.ui new file mode 100644 index 00000000..4bddebd1 --- /dev/null +++ b/buildtools/lib/widgets/makeoptionswidgetbase.ui @@ -0,0 +1,194 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>MakeOptionsWidgetBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>make_options_widget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>507</width> + <height>366</height> + </rect> + </property> + <property name="caption"> + <string>Make Options</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="0" column="0" rowspan="1" colspan="6"> + <property name="name"> + <cstring>abort_box</cstring> + </property> + <property name="text"> + <string>&Abort on first error</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="6"> + <property name="name"> + <cstring>dontact_box</cstring> + </property> + <property name="text"> + <string>Onl&y display commands without actually executing them</string> + </property> + </widget> + <widget class="QGroupBox" row="6" column="0" rowspan="1" colspan="6"> + <property name="name"> + <cstring>env_var_group</cstring> + </property> + <property name="title"> + <string>Environment &Variables</string> + </property> + </widget> + <widget class="QLabel" row="5" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>makebin_label</cstring> + </property> + <property name="text"> + <string>&Name of make executable:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>makebin_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="5" column="3" rowspan="1" colspan="3"> + <property name="name"> + <cstring>makebin_edit</cstring> + </property> + </widget> + <widget class="QSpinBox" row="4" column="4"> + <property name="name"> + <cstring>jobs_box</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxValue"> + <number>30</number> + </property> + <property name="minValue"> + <number>1</number> + </property> + </widget> + <widget class="QLabel" row="4" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Num&ber of jobs to run simultaneously:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>jobs_box</cstring> + </property> + </widget> + <spacer row="4" column="5"> + <property name="name"> + <cstring>spacer33</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>121</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="4" column="0"> + <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>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QCheckBox" row="3" column="0" rowspan="1" colspan="6"> + <property name="name"> + <cstring>runMultiJobs</cstring> + </property> + <property name="text"> + <string>Run more than one &job at a time</string> + </property> + </widget> + <widget class="QLabel" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>prio_label</cstring> + </property> + <property name="text"> + <string>Make priority:</string> + </property> + </widget> + <widget class="QSpinBox" row="2" column="2"> + <property name="name"> + <cstring>prio_box</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maxValue"> + <number>19</number> + </property> + <property name="minValue"> + <number>-20</number> + </property> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>runMultiJobs</sender> + <signal>toggled(bool)</signal> + <receiver>textLabel1</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>runMultiJobs</sender> + <signal>toggled(bool)</signal> + <receiver>jobs_box</receiver> + <slot>setEnabled(bool)</slot> + </connection> +</connections> +<tabstops> + <tabstop>abort_box</tabstop> + <tabstop>dontact_box</tabstop> + <tabstop>makebin_edit</tabstop> + <tabstop>jobs_box</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +</UI> diff --git a/buildtools/lib/widgets/removesubprojectdialog.cpp b/buildtools/lib/widgets/removesubprojectdialog.cpp new file mode 100644 index 00000000..37f9aaf8 --- /dev/null +++ b/buildtools/lib/widgets/removesubprojectdialog.cpp @@ -0,0 +1,52 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include <qcheckbox.h> +#include <qlabel.h> +#include "removesubprojectdialog.h" + +RemoveSubprojectDialog::RemoveSubprojectDialog(QString caption, QString question, QWidget* parent, const char* name, bool modal, WFlags fl) + : RemoveSubprojectDlgBase(parent,name, modal,fl) +{ + setCaption(caption); + removeLabel->setText(question); +} + +RemoveSubprojectDialog::~RemoveSubprojectDialog() +{ +} + +/*$SPECIALIZATION$*/ +void RemoveSubprojectDialog::reject() +{ + QDialog::reject(); +} + +void RemoveSubprojectDialog::accept() +{ + QDialog::accept(); +} + +bool RemoveSubprojectDialog::removeFromDisk( ) +{ + return removeCheckBox->isChecked(); +} + + +#include "removesubprojectdialog.moc" + diff --git a/buildtools/lib/widgets/removesubprojectdialog.h b/buildtools/lib/widgets/removesubprojectdialog.h new file mode 100644 index 00000000..89487511 --- /dev/null +++ b/buildtools/lib/widgets/removesubprojectdialog.h @@ -0,0 +1,52 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef REMOVESUBPROJECTDIALOG_H +#define REMOVESUBPROJECTDIALOG_H + +#include "removesubprojectdlgbase.h" + +/** +Subproject removal dialog. +*/ +class RemoveSubprojectDialog : public RemoveSubprojectDlgBase +{ + Q_OBJECT + +public: + RemoveSubprojectDialog(QString caption, QString question, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~RemoveSubprojectDialog(); + /*$PUBLIC_FUNCTIONS$*/ + bool removeFromDisk(); + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + virtual void reject(); + virtual void accept(); + +}; + +#endif + diff --git a/buildtools/lib/widgets/removesubprojectdlgbase.ui b/buildtools/lib/widgets/removesubprojectdlgbase.ui new file mode 100644 index 00000000..cd36b6ff --- /dev/null +++ b/buildtools/lib/widgets/removesubprojectdlgbase.ui @@ -0,0 +1,154 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>RemoveSubprojectDlgBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>RemoveSubprojectDlgBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>378</width> + <height>147</height> + </rect> + </property> + <property name="caption"> + <string>[REMOVE SUBPROJECT]</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>fileGroupBox</cstring> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32767</width> + <height>140</height> + </size> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="title"> + <string>&Information</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>removeLabel</cstring> + </property> + <property name="text"> + <string>[REMOVE QUESTION]</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>removeCheckBox</cstring> + </property> + <property name="text"> + <string>Also &remove it from disk</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>noticeLabel</cstring> + </property> + <property name="minimumSize"> + <size> + <width>200</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string><b>Note:</b> You will not be able to undo this operation.</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>buttonLayout</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>buttonSpacer</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>30</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>removeButton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelButton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>removeButton</sender> + <signal>clicked()</signal> + <receiver>RemoveSubprojectDlgBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>cancelButton</sender> + <signal>clicked()</signal> + <receiver>RemoveSubprojectDlgBase</receiver> + <slot>reject()</slot> + </connection> +</connections> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<slots> + <slot>accept()</slot> + <slot>reject()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +</UI> diff --git a/buildtools/lib/widgets/runoptionswidget.cpp b/buildtools/lib/widgets/runoptionswidget.cpp new file mode 100644 index 00000000..95fe4529 --- /dev/null +++ b/buildtools/lib/widgets/runoptionswidget.cpp @@ -0,0 +1,138 @@ +/* This file is part of the KDE project + Copyright (C) 2001-2002 Bernd Gehrmann <bernd@kdevelop.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "runoptionswidget.h" + +#include <klocale.h> +#include <kfiledialog.h> +#include <kurlrequester.h> +#include <kurlcompletion.h> +#include <klineedit.h> +#include <urlutil.h> + +#include <qlistview.h> +#include <qgroupbox.h> +#include <qcheckbox.h> +#include <qradiobutton.h> +#include <qpushbutton.h> +#include <qbuttongroup.h> +#include <qlabel.h> + +#include "domutil.h" +#include "environmentvariableswidget.h" + + +RunOptionsWidget::RunOptionsWidget(QDomDocument &dom, const QString &configGroup, + const QString &buildDirectory, QWidget *parent, const char *name) + : RunOptionsWidgetBase(parent, name), + m_dom(dom), m_configGroup(configGroup) +{ + // Create the "Environment Variables" GUI + env_var_group->setColumnLayout( 1, Qt::Vertical ); + m_environmentVariablesWidget = new EnvironmentVariablesWidget( dom, configGroup + "/run/envvars", env_var_group ); + + mainprogram_edit->completionObject()->setMode(KURLCompletion::FileCompletion); + mainprogram_edit->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly ); + if( DomUtil::readEntry(dom, configGroup + "/run/mainprogram").isEmpty() && QFileInfo( buildDirectory ).exists() ) + { + mainprogram_edit->setURL( buildDirectory ); + mainprogram_edit->fileDialog()->setURL( KURL::fromPathOrURL(buildDirectory) ); + }else if ( QFileInfo( DomUtil::readEntry(dom, configGroup + "/run/mainprogram") ).exists() ) + { + QString program = DomUtil::readEntry(dom, configGroup + "/run/mainprogram"); + if( QDir::isRelativePath(program) ) + program = buildDirectory + "/" + program; + mainprogram_edit->setURL(program); + mainprogram_edit->fileDialog()->setURL( program ); + }else + { + mainprogram_edit->setURL(QString()); + mainprogram_edit->fileDialog()->setURL(QString()); + } + + cwd_edit->completionObject()->setMode(KURLCompletion::DirCompletion); + cwd_edit->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + if( DomUtil::readEntry(dom, configGroup + "/run/globalcwd").isEmpty() && QFileInfo( buildDirectory ).exists() ) + { + cwd_edit->setURL( buildDirectory ); + cwd_edit->fileDialog()->setURL( KURL::fromPathOrURL(buildDirectory) ); + }else if( QFileInfo( DomUtil::readEntry(dom, configGroup + "/run/globalcwd") ).exists() ) + { + cwd_edit->setURL(DomUtil::readEntry(dom, configGroup + "/run/globalcwd")); + cwd_edit->fileDialog()->setURL( KURL::fromPathOrURL( DomUtil::readEntry(dom, configGroup + "/run/globalcwd") ) ); + }else + { + cwd_edit->setURL(QString()); + cwd_edit->fileDialog()->setURL(QString()); + } + + if( configGroup == "/kdevautoproject" || configGroup == "/kdevtrollproject" ) + { + mainProgramGroupBox->setCheckable(true); + mainProgramGroupBox->setChecked( DomUtil::readBoolEntry(dom, configGroup+"/run/useglobalprogram", false ) ); + }else + { + delete notelabel; + } + + // Read the main program command line arguments and store them in the edit box + + runargs_edit->setText(DomUtil::readEntry(dom, configGroup + "/run/programargs")); + debugargs_edit->setText(DomUtil::readEntry(dom, configGroup + "/run/globaldebugarguments")); + + startinterminal_box->setChecked(DomUtil::readBoolEntry(dom, configGroup + "/run/terminal")); + autocompile_box->setChecked(DomUtil::readBoolEntry(dom, configGroup + "/run/autocompile", false)); + autoinstall_box->setChecked(DomUtil::readBoolEntry(dom, configGroup + "/run/autoinstall", false)); + autokdesu_box->setChecked(DomUtil::readBoolEntry(dom, configGroup + "/run/autokdesu", false)); +} + + +RunOptionsWidget::~RunOptionsWidget() +{} + + +void RunOptionsWidget::accept() +{ + DomUtil::writeEntry(m_dom, m_configGroup + "/run/mainprogram", mainprogram_edit->url()); + DomUtil::writeEntry(m_dom, m_configGroup + "/run/programargs", runargs_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/run/globaldebugarguments", debugargs_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/run/globalcwd", cwd_edit->url()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/run/useglobalprogram", mainProgramGroupBox->isChecked()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/run/terminal", startinterminal_box->isChecked()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/run/autocompile", autocompile_box->isChecked()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/run/autoinstall", autoinstall_box->isChecked()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/run/autokdesu", autokdesu_box->isChecked()); + + m_environmentVariablesWidget->accept(); +} + +void RunOptionsWidget::mainProgramChanged( ) +{ + + if( mainProgramGroupBox->isChecked() && mainprogram_edit->url().isEmpty() ) + { + mainprogram_label->setPaletteForegroundColor(QColor("#ff0000")); + } + else + { + mainprogram_label->unsetPalette(); + } +} + +#include "runoptionswidget.moc" diff --git a/buildtools/lib/widgets/runoptionswidget.h b/buildtools/lib/widgets/runoptionswidget.h new file mode 100644 index 00000000..758ef4b1 --- /dev/null +++ b/buildtools/lib/widgets/runoptionswidget.h @@ -0,0 +1,57 @@ +/* This file is part of the KDE project + Copyright (C) 2001-2002 Bernd Gehrmann <bernd@kdevelop.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _RUNOPTIONSWIDGET_H_ +#define _RUNOPTIONSWIDGET_H_ + +#include "runoptionswidgetbase.h" + +#include <qdom.h> +#include <kurl.h> + +class EnvironmentVariablesWidget; + +/** +Run options widget. +*/ +class RunOptionsWidget : public RunOptionsWidgetBase +{ + Q_OBJECT + +public: + RunOptionsWidget( QDomDocument &dom, //!< document DOM + const QString &configGroup, //!< configuration group + const QString &buildDirectory, //!< project build directory + QWidget *parent=0, //!< parent widget + const char *name=0 //!< widget's name + ); + ~RunOptionsWidget(); + +public slots: + void accept(); + +private: + virtual void mainProgramChanged( ); + + QDomDocument &m_dom; + QString m_configGroup; + EnvironmentVariablesWidget* m_environmentVariablesWidget; +}; + +#endif diff --git a/buildtools/lib/widgets/runoptionswidgetbase.ui b/buildtools/lib/widgets/runoptionswidgetbase.ui new file mode 100644 index 00000000..1163484c --- /dev/null +++ b/buildtools/lib/widgets/runoptionswidgetbase.ui @@ -0,0 +1,257 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>RunOptionsWidgetBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>run_options_widget</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>500</width> + <height>506</height> + </rect> + </property> + <property name="caption"> + <string>Run Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>mainProgramGroupBox</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Main Program</string> + </property> + <property name="checkable"> + <bool>false</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>notelabel</cstring> + </property> + <property name="text"> + <string>Note: These options override target specific settings.</string> + </property> + <property name="alignment"> + <set>AlignVCenter</set> + </property> + <property name="whatsThis" stdset="0"> + <string>For Automake and QMake type projects, the proper way to set these options are per target in the <b>Automake Manager</b> and <b>QMake Manager</b>, respectively.</string> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>runargs_edit</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>The command line arguments passed to the main program when run</string> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>mainprogram_label_2</cstring> + </property> + <property name="text"> + <string>Run Arg&uments:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mainprogram_edit</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>mainprogram_label</cstring> + </property> + <property name="text"> + <string>Executa&ble:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mainprogram_edit</cstring> + </property> + </widget> + <widget class="KURLRequester" row="1" column="1"> + <property name="name"> + <cstring>mainprogram_edit</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Full path to the executable</string> + </property> + </widget> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>mainprogram_label_3</cstring> + </property> + <property name="text"> + <string>Debug Ar&guments:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mainprogram_edit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="3" column="1"> + <property name="name"> + <cstring>debugargs_edit</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>The command line arguments passed to the main program when debugged</string> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>mainprogram_label_3_2</cstring> + </property> + <property name="text"> + <string>Working &Directory:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mainprogram_edit</cstring> + </property> + </widget> + <widget class="KURLRequester" row="4" column="1"> + <property name="name"> + <cstring>cwd_edit</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Sets the current working directory for the launched process</string> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>autocompile_box</cstring> + </property> + <property name="text"> + <string>Automaticall&y compile before execution</string> + </property> + <property name="toolTip" stdset="0"> + <string>If the program is not up-to-date with the source code, compile it before starting its execution</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>autoinstall_box</cstring> + </property> + <property name="text"> + <string>&Automatically install before execution</string> + </property> + <property name="toolTip" stdset="0"> + <string></string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>autokdesu_box</cstring> + </property> + <property name="text"> + <string>Use &kdesu when installing</string> + </property> + <property name="toolTip" stdset="0"> + <string></string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>startinterminal_box</cstring> + </property> + <property name="text"> + <string>Start in e&xternal terminal</string> + </property> + <property name="toolTip" stdset="0"> + <string>Start the main program in an external terminal</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>env_var_group</cstring> + </property> + <property name="title"> + <string>Environment &Variables</string> + </property> + </widget> + </vbox> +</widget> +<connections> + <connection> + <sender>mainprogram_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>run_options_widget</receiver> + <slot>mainProgramChanged()</slot> + </connection> + <connection> + <sender>mainprogram_edit</sender> + <signal>urlSelected(const QString&)</signal> + <receiver>run_options_widget</receiver> + <slot>mainProgramChanged()</slot> + </connection> + <connection> + <sender>mainProgramGroupBox</sender> + <signal>toggled(bool)</signal> + <receiver>run_options_widget</receiver> + <slot>mainProgramChanged()</slot> + </connection> +</connections> +<tabstops> + <tabstop>startinterminal_box</tabstop> + <tabstop>autocompile_box</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> + <include location="global" impldecl="in declaration">ksqueezedtextlabel.h</include> +</includes> +<slots> + <slot>mainProgramChanged()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>klineedit.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/buildtools/lib/widgets/subclassesdlg.cpp b/buildtools/lib/widgets/subclassesdlg.cpp new file mode 100644 index 00000000..5c3a0fef --- /dev/null +++ b/buildtools/lib/widgets/subclassesdlg.cpp @@ -0,0 +1,122 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include <qlistbox.h> +#include <kurlrequester.h> + +#include "subclassesdlg.h" +#include "subclassesdlg.moc" +SubclassesDlg::SubclassesDlg(QString form, DomUtil::PairList &config, QString projectDir, QWidget* parent, const char* name, bool modal, WFlags fl) +: SubclassesDlgBase(parent,name, modal,fl), m_form(form), m_config(config), m_projectDir(projectDir) +{ + subclass_url->setEnabled(false); + + DomUtil::PairList::iterator it; + for ( it = config.begin(); it != config.end(); ++it ) + { + if ((*it).second == form) + subclasses_box->insertItem(projectDir + (*it).first); + } +} + +SubclassesDlg::~SubclassesDlg() +{ +} + +/*$SPECIALIZATION$*/ +void SubclassesDlg::accept() +{ + QPtrList<DomUtil::Pair> pairsToRemove; + + DomUtil::PairList::iterator it; + for ( it = m_config.begin(); it != m_config.end(); ++it ) + { + if ((*it).second == m_form) + { + pairsToRemove.append(&(*it)); + } + } + + DomUtil::Pair *pair; + for ( pair = pairsToRemove.first(); pair; pair = pairsToRemove.next() ) + { + m_config.remove(*pair); + } + + for (int i = 0; i < (int)subclasses_box->count(); ++i) + { + m_config << DomUtil::Pair(subclasses_box->text(i).remove(0,m_projectDir.length()), m_form); + } + + SubclassesDlgBase::accept(); +} + + +void SubclassesDlg::newRelation() +{ + subclasses_box->setFocus(); + subclasses_box->insertItem(""); + subclasses_box->setCurrentItem(subclasses_box->count()-1); + subclass_url->setEnabled(true); + subclass_url->setURL(""); + subclass_url->setFocus(); +} + +void SubclassesDlg::removeRelation() +{ + if (subclasses_box->currentItem() > -1) + { + QListBoxItem *item = subclasses_box->item(subclasses_box->currentItem()); + int itemIdx = subclasses_box->currentItem(); + + if (item->prev()) + { + subclasses_box->setCurrentItem(item->prev()); + subclass_url->setURL(item->prev()->text()); + } + else if (item->next()) + { + subclasses_box->setCurrentItem(item->next()); + subclass_url->setURL(item->next()->text()); + } + else + { + subclass_url->setEnabled(false); + subclass_url->setURL(""); + } + subclasses_box->removeItem(itemIdx); + } +} + +void SubclassesDlg::changeCurrentURL(const QString &str) +{ + if ( subclasses_box->currentItem() > -1 ) + { + subclasses_box->changeItem(str, subclasses_box->currentItem()); + } +} + +void SubclassesDlg::currentRelationChanged( QListBoxItem * item ) +{ + if (item) + { + subclass_url->setEnabled(true); + subclass_url->setURL(item->text()); + } +} + diff --git a/buildtools/lib/widgets/subclassesdlg.h b/buildtools/lib/widgets/subclassesdlg.h new file mode 100644 index 00000000..46b07b31 --- /dev/null +++ b/buildtools/lib/widgets/subclassesdlg.h @@ -0,0 +1,58 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo <cloudtemple@mksat.net> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef SUBCLASSESDLG_H +#define SUBCLASSESDLG_H +#include "domutil.h" +#include "subclassesdlgbase.h" + +/** +Subclass creation dialog. +*/ +class SubclassesDlg : public SubclassesDlgBase +{ + Q_OBJECT + +public: + SubclassesDlg(QString form, DomUtil::PairList &config, QString projectDir, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~SubclassesDlg(); + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + virtual void accept(); + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + virtual void newRelation(); + virtual void removeRelation(); + virtual void changeCurrentURL(const QString &str); + virtual void currentRelationChanged(QListBoxItem *item); + +private: + QString m_form; + DomUtil::PairList &m_config; + QString m_projectDir; +}; + +#endif + diff --git a/buildtools/lib/widgets/subclassesdlgbase.ui b/buildtools/lib/widgets/subclassesdlgbase.ui new file mode 100644 index 00000000..026ab2ca --- /dev/null +++ b/buildtools/lib/widgets/subclassesdlgbase.ui @@ -0,0 +1,224 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>SubclassesDlgBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>SubclassesDlgBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>514</width> + <height>278</height> + </rect> + </property> + <property name="caption"> + <string>Related Subclasses</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton" row="1" column="0"> + <property name="name"> + <cstring>add_button</cstring> + </property> + <property name="text"> + <string>&Add Relation</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + <widget class="QPushButton" row="2" column="0"> + <property name="name"> + <cstring>remove_button</cstring> + </property> + <property name="text"> + <string>&Remove Relation</string> + </property> + <property name="autoDefault"> + <bool>false</bool> + </property> + </widget> + <widget class="QListBox" row="1" column="1" rowspan="3" colspan="1"> + <property name="name"> + <cstring>subclasses_box</cstring> + </property> + </widget> + <widget class="KURLRequester" row="0" column="1"> + <property name="name"> + <cstring>subclass_url</cstring> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>24</height> + </size> + </property> + <property name="focusPolicy"> + <enum>WheelFocus</enum> + </property> + </widget> + <spacer row="3" column="0"> + <property name="name"> + <cstring>spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>90</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Related subclass &location:</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter</set> + </property> + <property name="buddy" stdset="0"> + <cstring>subclass_url</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="4" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>310</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>false</bool> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>SubclassesDlgBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>subclass_url</sender> + <signal>textChanged(const QString&)</signal> + <receiver>SubclassesDlgBase</receiver> + <slot>changeCurrentURL(const QString&)</slot> + </connection> + <connection> + <sender>remove_button</sender> + <signal>clicked()</signal> + <receiver>SubclassesDlgBase</receiver> + <slot>removeRelation()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>SubclassesDlgBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>add_button</sender> + <signal>clicked()</signal> + <receiver>SubclassesDlgBase</receiver> + <slot>newRelation()</slot> + </connection> + <connection> + <sender>subclasses_box</sender> + <signal>clicked(QListBoxItem*)</signal> + <receiver>SubclassesDlgBase</receiver> + <slot>currentRelationChanged(QListBoxItem*)</slot> + </connection> +</connections> +<tabstops> + <tabstop>subclasses_box</tabstop> + <tabstop>add_button</tabstop> + <tabstop>subclass_url</tabstop> + <tabstop>remove_button</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<slots> + <slot access="protected">changeCurrentURL(const QString &str)</slot> + <slot access="protected">removeRelation()</slot> + <slot access="protected">newRelation()</slot> + <slot access="protected">currentRelationChanged(QListBoxItem *item)</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/buildtools/pascal/Makefile.am b/buildtools/pascal/Makefile.am new file mode 100644 index 00000000..d975575a --- /dev/null +++ b/buildtools/pascal/Makefile.am @@ -0,0 +1,24 @@ +INCLUDES = -I$(top_srcdir)/buildtools/lib/base \ + -I$(top_srcdir)/buildtools/lib/widgets -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/interfaces/external \ + -I$(top_srcdir)/lib/interfaces/extras -I$(top_srcdir)/lib/util -I$(top_builddir)/buildtools/lib/widgets \ + $(all_includes) + +kde_module_LTLIBRARIES = libkdevpascalproject.la +libkdevpascalproject_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevpascalproject_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/buildtools/lib/widgets/libkdevbuildtoolswidgets.la $(top_builddir)/buildtools/lib/base/libkdevbuildbase.la + +libkdevpascalproject_la_SOURCES = pascalproject_part.cpp pascalproject_widget.cpp pascalproject_optionsdlgbase.ui pascalprojectoptionsdlg.cpp pascalglobaloptionsdlg.cpp service.cpp + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevpascalproject.desktop + +rcdir = $(kde_datadir)/kdevpascalproject +rc_DATA = kdevpascalproject.rc + + + + diff --git a/buildtools/pascal/README.dox b/buildtools/pascal/README.dox new file mode 100644 index 00000000..4f3b9897 --- /dev/null +++ b/buildtools/pascal/README.dox @@ -0,0 +1,13 @@ +/** \class PascalProjectPart +This is the Pascal build tool part. + +Common build tool part part for all available pascal compilers (gpc, fpc, dcc). +It holds no project file list and tries to abstract from their specifics. + +\authors <a href="mailto:cloudtemple AT mksat.net">Alexander Dymo</a> + +\maintainer <a href="mailto:cloudtemple AT mksat.net">Alexander Dymo</a> + +\deprecated This class is deprecated, use GenericProjectPart (buildtools/generic) instead. + +*/ diff --git a/buildtools/pascal/kdevpascalproject.desktop b/buildtools/pascal/kdevpascalproject.desktop new file mode 100644 index 00000000..05b7e507 --- /dev/null +++ b/buildtools/pascal/kdevpascalproject.desktop @@ -0,0 +1,93 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=Pascal Project +Comment[br]=Raktres Pascal +Comment[ca]=Projecte Pascal +Comment[da]=Pascal projekt +Comment[de]=Pascal-Projekt für KDevelop +Comment[el]=Έργο Pascal +Comment[es]=Proyecto de Pascal +Comment[et]=Pascali projekt +Comment[eu]=Pascal proiektua +Comment[fa]=پروژۀ پاسکال +Comment[fr]=Projet en langage PASCAL +Comment[ga]=Tionscadal Pascal +Comment[gl]=Proxecto Pascal +Comment[hi]=पास्कल परियोजना +Comment[hu]=Pascal-projekt +Comment[is]=Pascal verkefni +Comment[it]=Progetto per Pascal +Comment[ja]=Pascal プロジェクト +Comment[ms]=Projek Pascal +Comment[nds]=Pascal-Projekt +Comment[ne]=पास्कल परियोजना +Comment[nl]=Pascal-project +Comment[pa]=ਪਾਸਕਲ ਪ੍ਰੋਜੈਕਟ +Comment[pl]=Projekt: Pascal +Comment[pt]=Projecto de Pascal +Comment[pt_BR]=Projeto Pascal +Comment[ru]=Проект Pascal +Comment[sk]=Pascal projekt +Comment[sl]=Projekt Pascal +Comment[sr]=Pascal пројекат +Comment[sr@Latn]=Pascal projekat +Comment[sv]=Pascal-projekt +Comment[ta]=பாஸ்கல் பிராஜக்ட் +Comment[tg]=Лоиҳаи Pascal +Comment[tr]=Pascal Projesi +Comment[uz]=Pascal loyihasi +Comment[uz@cyrillic]=Pascal лойиҳаси +Comment[zh_CN]=Pascal 工程 +Comment[zh_TW]=Pascal 專案 +Name=KDevPascalProject +Name[da]=KDevelop Pascal-projekt +Name[de]=Pascal-Projekt (KDevelop) +Name[hi]=के-डेव-पास्कल-परियोजना +Name[nds]=Pascal-Projekt (KDevelop) +Name[ne]=केडीई विकास पास्कल परियोजना +Name[pl]=KDevProjektPascal +Name[sk]=KDevPascalProjekt +Name[sv]=KDevelop Pascal-projekt +Name[ta]=கெடெவ் பாஸ்கல் பிராஜக்ட் +Name[tg]=Лоиҳаи ПаскалKDev +Name[zh_TW]=KDevelop Pascal 專案 +GenericName=Pascal Project +GenericName[br]=Raktres Pascal +GenericName[ca]=Projecte Pascal +GenericName[da]=Pascal projekt +GenericName[de]=Pascal-Projekt +GenericName[el]=Έργο Pascal +GenericName[es]=Proyecto de Pascal +GenericName[et]=Pascali projekt +GenericName[eu]=Pascal proiektua +GenericName[fa]=پروژۀ پاسکال +GenericName[fr]=Projet en langage PASCAL +GenericName[ga]=Tionscadal Pascal +GenericName[gl]=Proxecto Pascal +GenericName[hi]=पास्कल परियोजना +GenericName[hu]=Pascal-projekt +GenericName[it]=Progetto in Pascal +GenericName[ja]=Pascal プロジェクト +GenericName[ms]=Projek Pascal +GenericName[nds]=Pascal-Projekt +GenericName[ne]=पास्कल परियोजना +GenericName[nl]=Pascal-project +GenericName[pl]=Projekt: Pascal +GenericName[pt]=Projecto de Pascal +GenericName[pt_BR]=Projeto Pascal +GenericName[ru]=Проект Pascal +GenericName[sk]=Pascal projekt +GenericName[sl]=Projekt Pascal +GenericName[sr]=Pascal пројекат +GenericName[sr@Latn]=Pascal projekat +GenericName[sv]=Pascal-projekt +GenericName[ta]=பாஸ்கல் பிராஜக்ட் +GenericName[tr]=Pascal Projesi +GenericName[uz]=Pascal loyihasi +GenericName[uz@cyrillic]=Pascal лойиҳаси +GenericName[zh_CN]=Pascal 工程 +GenericName[zh_TW]=Pascal 專案 +ServiceTypes=KDevelop/Project +X-KDE-Library=libkdevpascalproject +X-KDevelop-Version=5 diff --git a/buildtools/pascal/kdevpascalproject.rc b/buildtools/pascal/kdevpascalproject.rc new file mode 100644 index 00000000..9e7f46fd --- /dev/null +++ b/buildtools/pascal/kdevpascalproject.rc @@ -0,0 +1,14 @@ +<!DOCTYPE kpartgui> +<kpartplugin name="KDevPascalProject" version="2"> +<MenuBar> + <Menu name="build" > + <Action name="build_build" /> + <Separator/> + <Action name="build_execute" /> + </Menu> +</MenuBar> +<ToolBar name="buildToolBar" noMerge="1"> + <Action name="build_build" group="build_operations" /> + <Action name="build_execute" group="build_operations" /> +</ToolBar> +</kpartplugin> diff --git a/buildtools/pascal/pascalglobaloptionsdlg.cpp b/buildtools/pascal/pascalglobaloptionsdlg.cpp new file mode 100644 index 00000000..a710db19 --- /dev/null +++ b/buildtools/pascal/pascalglobaloptionsdlg.cpp @@ -0,0 +1,132 @@ +/*************************************************************************** + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 <qlayout.h> +#include <qlabel.h> +#include <qlineedit.h> +#include <qcombobox.h> + +#include <kurlrequester.h> +#include <kdebug.h> +#include <kconfig.h> + +#include "kdevcompileroptions.h" + +#include "service.h" +#include "pascalproject_part.h" +#include "pascalglobaloptionsdlg.h" + +PascalGlobalOptionsDlg::PascalGlobalOptionsDlg(PascalProjectPart *part, QWidget* parent, const char* name, WFlags fl) + :PascalProjectOptionsDlgBase(parent,name,fl), m_part(part) +{ + delete config_label; + delete config_combo; + delete addconfig_button; + delete removeconfig_button; + delete compiler_label; + delete configuration_layout; + delete configuration_line; + delete exec_label; + delete exec_edit; + delete mainSourceLabel; + delete mainSourceUrl; + delete defaultopts_button; + + + offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Pascal'"); + + ServiceComboBox::insertStringList(compiler_box, offers, &service_names, &service_execs); + + if (offers.isEmpty()) + options_button->setEnabled(false); + + currentCompiler = QString::null; + + /*kdDebug() << ServiceComboBox::defaultCompiler() << endl; + kdDebug() << ServiceComboBox::itemForText(ServiceComboBox::defaultCompiler(), service_names) << endl; + kdDebug() << compiler_box->text(ServiceComboBox::itemForText(ServiceComboBox::defaultCompiler(), service_names)) << endl; +*/ + ServiceComboBox::setCurrentText(compiler_box, ServiceComboBox::defaultCompiler(), service_names); + compiler_box_activated(compiler_box->currentText()); +} + +PascalGlobalOptionsDlg::~PascalGlobalOptionsDlg() +{ +} + +void PascalGlobalOptionsDlg::optionsButtonClicked() +{ + QString name = ServiceComboBox::currentText(compiler_box, service_names); + KDevCompilerOptions *plugin = m_part->createCompilerOptions(name); + + if (plugin) { + QString flags = plugin->exec(this, options_edit->text()); + options_edit->setText(flags); + delete plugin; + } +} + +void PascalGlobalOptionsDlg::compiler_box_activated(const QString& text) +{ + kdDebug() << "text changed from " << currentCompiler << " to " << text << endl; + if (currentCompiler == text) + return; + if (!currentCompiler.isEmpty()) + saveCompilerOpts(currentCompiler); + currentCompiler = text; + readCompilerOpts(currentCompiler); +} + +void PascalGlobalOptionsDlg::accept() +{ + saveCompilerOpts(currentCompiler); + + saveConfigCache(); +} + +void PascalGlobalOptionsDlg::saveCompilerOpts( QString compiler ) +{ + configCache[compiler] = options_edit->text(); +} + +void PascalGlobalOptionsDlg::readCompilerOpts( QString compiler ) +{ + QString settings = configCache[compiler]; + if (settings.isEmpty()) + { + KConfig *config = KGlobal::config(); + config->setGroup("Pascal Compiler"); + settings = config->readPathEntry(compiler); + } + + options_edit->setText(settings); +} + +void PascalGlobalOptionsDlg::readConfigCache( ) +{ +/* KConfig *config = KGlobal::config(); + config->setGroup("Pascal Compiler"); + + QMap<QString, QString> settings = config->entryMap("Pascal Compiler"); +*/ +} + +void PascalGlobalOptionsDlg::saveConfigCache( ) +{ + KConfig *config = KGlobal::config(); + config->setGroup("Pascal Compiler"); + + for (QMap<QString, QString>::iterator it = configCache.begin(); it != configCache.end(); ++it) + { + config->writeEntry(it.key(), it.data()); + } +} + +#include "pascalglobaloptionsdlg.moc" diff --git a/buildtools/pascal/pascalglobaloptionsdlg.h b/buildtools/pascal/pascalglobaloptionsdlg.h new file mode 100644 index 00000000..14da2221 --- /dev/null +++ b/buildtools/pascal/pascalglobaloptionsdlg.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 PASCALGLOBALOPTIONSDLG_H +#define PASCALGLOBALOPTIONSDLG_H + +#include <qmap.h> + +#include <ktrader.h> + +#include "pascalproject_optionsdlgbase.h" + +class PascalProjectPart; + +class PascalGlobalOptionsDlg : public PascalProjectOptionsDlgBase +{ + Q_OBJECT + +public: + PascalGlobalOptionsDlg(PascalProjectPart *part, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~PascalGlobalOptionsDlg(); + +public slots: + virtual void accept(); + +protected slots: + virtual void optionsButtonClicked(); + virtual void compiler_box_activated(const QString& text); + +private: + PascalProjectPart *m_part; + KTrader::OfferList offers; + QString currentCompiler; + QStringList service_names; + QStringList service_execs; + QMap<QString, QString> configCache; + + void saveCompilerOpts(QString compiler); + void readCompilerOpts(QString compiler); + + void readConfigCache(); + void saveConfigCache(); +}; + +#endif diff --git a/buildtools/pascal/pascalproject_optionsdlgbase.ui b/buildtools/pascal/pascalproject_optionsdlgbase.ui new file mode 100644 index 00000000..0f0b2324 --- /dev/null +++ b/buildtools/pascal/pascalproject_optionsdlgbase.ui @@ -0,0 +1,474 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>PascalProjectOptionsDlgBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>PascalProjectOptionsDlgBase</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>480</height> + </rect> + </property> + <property name="caption"> + <string>Pascal Compiler</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="0" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>configuration_layout</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>config_label</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Con&figuration:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>config_combo</cstring> + </property> + </widget> + <widget class="QComboBox"> + <property name="name"> + <cstring>config_combo</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="editable"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer17_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>8</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>addconfig_button</cstring> + </property> + <property name="text"> + <string>&Add</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>removeconfig_button</cstring> + </property> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer18_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QPushButton" row="6" column="4"> + <property name="name"> + <cstring>options_button</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>30</width> + <height>32767</height> + </size> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + <widget class="QLabel" row="6" column="0"> + <property name="name"> + <cstring>options_label</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Compiler op&tions:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>compiler_box</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>compiler_label</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Pascal compiler:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>compiler_box</cstring> + </property> + </widget> + <widget class="QLineEdit" row="4" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>exec_edit</cstring> + </property> + </widget> + <widget class="QLineEdit" row="6" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>options_edit</cstring> + </property> + </widget> + <widget class="QComboBox" row="2" column="1" rowspan="1" colspan="3"> + <property name="name"> + <cstring>compiler_box</cstring> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>exec_label</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Compiler co&mmand:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>compiler_box</cstring> + </property> + </widget> + <widget class="Line" row="1" column="0" rowspan="1" colspan="5"> + <property name="name"> + <cstring>configuration_line</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <spacer row="3" column="1"> + <property name="name"> + <cstring>spacer11</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <spacer row="5" column="3"> + <property name="name"> + <cstring>spacer12</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + <spacer row="8" column="2"> + <property name="name"> + <cstring>spacer13</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Fixed</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>30</height> + </size> + </property> + </spacer> + <spacer row="7" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>spacer7</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="QPushButton" row="7" column="3" rowspan="1" colspan="2"> + <property name="name"> + <cstring>defaultopts_button</cstring> + </property> + <property name="text"> + <string>Load &Default Compiler Options</string> + </property> + </widget> + <widget class="KURLRequester" row="9" column="1" rowspan="1" colspan="4"> + <property name="name"> + <cstring>mainSourceUrl</cstring> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>26</height> + </size> + </property> + <property name="focusPolicy"> + <enum>WheelFocus</enum> + </property> + </widget> + <widget class="QLabel" row="9" column="0"> + <property name="name"> + <cstring>mainSourceLabel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Main &source file:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>compiler_box</cstring> + </property> + </widget> + <spacer row="12" 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>20</height> + </size> + </property> + </spacer> + </grid> +</widget> +<connections> + <connection> + <sender>compiler_box</sender> + <signal>activated(const QString&)</signal> + <receiver>PascalProjectOptionsDlgBase</receiver> + <slot>compiler_box_activated(const QString&)</slot> + </connection> + <connection> + <sender>removeconfig_button</sender> + <signal>clicked()</signal> + <receiver>PascalProjectOptionsDlgBase</receiver> + <slot>configRemoved()</slot> + </connection> + <connection> + <sender>config_combo</sender> + <signal>textChanged(const QString&)</signal> + <receiver>PascalProjectOptionsDlgBase</receiver> + <slot>configComboTextChanged(const QString&)</slot> + </connection> + <connection> + <sender>config_combo</sender> + <signal>activated(const QString&)</signal> + <receiver>PascalProjectOptionsDlgBase</receiver> + <slot>configChanged(const QString&)</slot> + </connection> + <connection> + <sender>addconfig_button</sender> + <signal>clicked()</signal> + <receiver>PascalProjectOptionsDlgBase</receiver> + <slot>configAdded()</slot> + </connection> + <connection> + <sender>options_button</sender> + <signal>clicked()</signal> + <receiver>PascalProjectOptionsDlgBase</receiver> + <slot>optionsButtonClicked()</slot> + </connection> + <connection> + <sender>exec_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>PascalProjectOptionsDlgBase</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>options_edit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>PascalProjectOptionsDlgBase</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>mainSourceUrl</sender> + <signal>textChanged(const QString&)</signal> + <receiver>PascalProjectOptionsDlgBase</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>mainSourceUrl</sender> + <signal>urlSelected(const QString&)</signal> + <receiver>PascalProjectOptionsDlgBase</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>compiler_box</sender> + <signal>activated(const QString&)</signal> + <receiver>PascalProjectOptionsDlgBase</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>compiler_box</sender> + <signal>textChanged(const QString&)</signal> + <receiver>PascalProjectOptionsDlgBase</receiver> + <slot>setDirty()</slot> + </connection> + <connection> + <sender>defaultopts_button</sender> + <signal>clicked()</signal> + <receiver>PascalProjectOptionsDlgBase</receiver> + <slot>setDefaultOptions()</slot> + </connection> + <connection> + <sender>defaultopts_button</sender> + <signal>clicked()</signal> + <receiver>PascalProjectOptionsDlgBase</receiver> + <slot>setDirty()</slot> + </connection> +</connections> +<tabstops> + <tabstop>compiler_box</tabstop> + <tabstop>exec_edit</tabstop> + <tabstop>options_edit</tabstop> + <tabstop>options_button</tabstop> + <tabstop>defaultopts_button</tabstop> + <tabstop>mainSourceUrl</tabstop> + <tabstop>config_combo</tabstop> + <tabstop>addconfig_button</tabstop> + <tabstop>removeconfig_button</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<slots> + <slot access="protected">compiler_box_activated(const QString&)</slot> + <slot access="protected">addconfig_button_clicked()</slot> + <slot access="protected">configRemoved()</slot> + <slot access="protected">configComboTextChanged(const QString&)</slot> + <slot access="protected">configChanged(const QString&)</slot> + <slot access="protected">optionsButtonClicked()</slot> + <slot access="protected">configAdded()</slot> + <slot access="protected">setDirty()</slot> + <slot access="protected">setDefaultOptions()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/buildtools/pascal/pascalproject_part.cpp b/buildtools/pascal/pascalproject_part.cpp new file mode 100644 index 00000000..3fe09420 --- /dev/null +++ b/buildtools/pascal/pascalproject_part.cpp @@ -0,0 +1,493 @@ +/*************************************************************************** + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 "pascalproject_part.h" + +#include <qdom.h> +#include <qfileinfo.h> +#include <qdir.h> +#include <qvaluestack.h> +#include <qregexp.h> +#include <qvbox.h> +#include <qlabel.h> + +#include <kiconloader.h> +#include <klocale.h> +#include <kaction.h> +#include <kdevgenericfactory.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <kmessagebox.h> +#include <klibloader.h> +#include <kservice.h> +#include <kconfig.h> +#include <kdeversion.h> +#include <kprocess.h> + +#include "domutil.h" +#include "kdevcore.h" +#include "kdevmainwindow.h" +#include "kdevmakefrontend.h" +#include "kdevappfrontend.h" +#include "kdevpartcontroller.h" +#include "kdevlanguagesupport.h" +#include "kdevcompileroptions.h" +#include "runoptionswidget.h" +#include "envvartools.h" + +#include "pascalproject_widget.h" +#include "pascalprojectoptionsdlg.h" +#include "pascalglobaloptionsdlg.h" + +#include <kdevplugininfo.h> + +typedef KDevGenericFactory<PascalProjectPart> PascalProjectFactory; +static const KDevPluginInfo data("kdevpascalproject"); +K_EXPORT_COMPONENT_FACTORY( libkdevpascalproject, PascalProjectFactory( data ) ) + +PascalProjectPart::PascalProjectPart(QObject *parent, const char *name, const QStringList& ) + :KDevBuildTool(&data, parent, name ? name : "PascalProjectPart" ) +{ + setInstance(PascalProjectFactory::instance()); + setXMLFile("kdevpascalproject.rc"); + + KAction *action; + action = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8, + this, SLOT(slotBuild()), + actionCollection(), "build_build" ); + action->setToolTip(i18n("Build project")); + action->setWhatsThis(i18n("<b>Build project</b><p>Runs the compiler on a main source file of the project. " + "The compiler and the main source file can be set in project settings, <b>Pascal Compiler</b> tab.")); + action = new KAction( i18n("Execute Program"), "exec", 0, + this, SLOT(slotExecute()), + actionCollection(), "build_execute" ); + action->setToolTip(i18n("Execute program")); + action->setWhatsThis(i18n("<b>Execute program</b><p>Executes the main program specified in project settings, <b>Run options</b> tab. " + "If nothing is set, the binary file with the same name as the main source file name is executed.")); + + connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), + this, SLOT(projectConfigWidget(KDialogBase*)) ); + + connect( core(), SIGNAL(configWidget(KDialogBase*)), + this, SLOT(configWidget(KDialogBase*)) ); + +// m_widget = new PascalProjectWidget(this); + +// QWhatsThis::add(m_widget, i18n("WHAT DOES THIS PART DO?")); + + // now you decide what should happen to the widget. Take a look at kdevcore.h + // or at other plugins how to embed it. + + // if you want to embed your widget as an outputview, simply uncomment + // the following line. + + // mainWindow()->embedOutputView( m_widget, "name that should appear", "enter a tooltip" ); + +} + +PascalProjectPart::~PascalProjectPart() +{ +// delete m_widget; +} + +/** + * @todo This should really be merged with FileTreeWidget::matchesHidePattern() + * and put in its own class. Currently this is repeated in scriptprojectpart.cpp, pascalproject_part.cpp, adaproject_part.cpp + */ +static bool matchesPattern(const QString &fileName, const QStringList &patternList) +{ + QStringList::ConstIterator it; + for (it = patternList.begin(); it != patternList.end(); ++it) { + QRegExp re(*it, true, true); + if (re.search(fileName) == 0 && re.matchedLength() == (int)fileName.length()) + return true; + } + + return false; +} + +void PascalProjectPart::openProject(const QString &dirName, const QString &projectName) +{ + m_buildDir = dirName; + m_projectDir = dirName; + m_projectName = projectName; + + QDomDocument &dom = *projectDom(); + // Set the default directory radio to "executable" + if (DomUtil::readEntry(dom, "/kdevpascalproject/run/directoryradio") == "" ) { + DomUtil::writeEntry(dom, "/kdevpascalproject/run/directoryradio", "executable"); + } + + loadProjectConfig(); + + // Put all files from all subdirectories into file list + QValueStack<QString> s; + int prefixlen = m_projectDir.length()+1; + s.push(m_projectDir); + + QStringList includepatternList; + if ( languageSupport() ) + { + KMimeType::List list = languageSupport()->mimeTypes(); + KMimeType::List::Iterator it = list.begin(); + while( it != list.end() ){ + includepatternList += (*it)->patterns(); + ++it; + } + } + QString excludepatterns = "*~"; + QStringList excludepatternList = QStringList::split(",", excludepatterns); + + QDir dir; + do { + dir.setPath(s.pop()); + kdDebug(9033) << "Examining: " << dir.path() << endl; + const QFileInfoList *dirEntries = dir.entryInfoList(); + QPtrListIterator<QFileInfo> it(*dirEntries); + for (; it.current(); ++it) { + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == "..") + continue; + QString path = it.current()->absFilePath(); + if (it.current()->isDir()) { + kdDebug(9033) << "Pushing: " << path << endl; + s.push(path); + } + else { + if (matchesPattern(path, includepatternList) + && !matchesPattern(path, excludepatternList)) { + kdDebug(9033) << "Adding: " << path << endl; + m_sourceFiles.append(path.mid(prefixlen)); + } else { + kdDebug(9033) << "Ignoring: " << path << endl; + } + } + } + } while (!s.isEmpty()); + + KDevProject::openProject( dirName, projectName ); +} + +void PascalProjectPart::closeProject() +{ +} + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList PascalProjectPart::runEnvironmentVars() const +{ + return DomUtil::readPairListEntry(*projectDom(), "/kdevpascalproject/run/envvars", "envvar", "name", "value"); +} + + +/** Retuns the currently selected run directory + * The returned string can be: + * if run/directoryradio == executable + * The directory where the executable is + * if run/directoryradio == build + * The directory where the executable is relative to build directory + * if run/directoryradio == custom + * The custom directory absolute path + */ +QString PascalProjectPart::runDirectory() const +{ + QString cwd = defaultRunDirectory("kdevpascalproject"); + if (cwd.isEmpty()) + cwd = buildDirectory(); + return cwd; +} + + +/** Retuns the currently selected main program + * The returned string can be: + * if run/directoryradio == executable + * The executable name + * if run/directoryradio == build + * The path to executable relative to build directory + * if run/directoryradio == custom or relative == false + * The absolute path to executable + */ +QString PascalProjectPart::mainProgram() const +{ + QDomDocument * dom = projectDom(); + + if ( !dom ) return QString(); + + QString DomMainProgram = DomUtil::readEntry( *dom, "/kdevpascalproject/run/mainprogram"); + + if ( DomMainProgram.isEmpty() ) return QString(); + + if ( DomMainProgram.startsWith("/") ) // assume absolute path + { + return DomMainProgram; + } + else // assume project relative path + { + return projectDirectory() + "/" + DomMainProgram; + } + + return QString(); +} + +/** Retuns a QString with the debug command line arguments */ +QString PascalProjectPart::debugArguments() const +{ + return DomUtil::readEntry(*projectDom(), "/kdevpascalproject/run/globaldebugarguments"); +} + + +/** Retuns a QString with the run command line arguments */ +QString PascalProjectPart::runArguments() const +{ + return DomUtil::readEntry(*projectDom(), "/kdevpascalproject/run/programargs"); +} + +QString PascalProjectPart::mainSource() const +{ + return projectDirectory() + "/" + m_mainSource; +} + +void PascalProjectPart::setMainSource(QString fullPath) +{ + QString olddir = activeDirectory(); + m_mainSource = fullPath.replace(QRegExp(QString(projectDirectory() + QString("/"))),""); + emit activeDirectoryChanged( olddir, activeDirectory() ); +} + +QString PascalProjectPart::projectDirectory() const +{ + return m_projectDir; +} + +QString PascalProjectPart::projectName() const +{ + return m_projectName; +} + +QString PascalProjectPart::activeDirectory() const +{ + QFileInfo fi(mainSource()); + return fi.dirPath(true).replace(QRegExp(projectDirectory()),""); +} + +QString PascalProjectPart::buildDirectory() const +{ + QFileInfo fi(mainSource()); + return fi.dirPath(true); +} + +void PascalProjectPart::listOfFiles(QStringList &result, QString path) const +{ + QDir d(path); + if (!d.exists()) + return; + QFileInfoList *entries = const_cast<QFileInfoList*>(d.entryInfoList(QDir::Dirs | QDir::Files | QDir::Hidden)); + for (QFileInfo *it = entries->first(); it; it = entries->next()) + { + if ((it->isDir()) && (it->filePath() != path)) + { +// qWarning("entering dir %s", it->dirPath().latin1()); + listOfFiles(result, it->dirPath()); + } + else + { +// qWarning("adding to result: %s", it->filePath().latin1()); + result << it->filePath(); + } + } +} + +QStringList PascalProjectPart::allFiles() const +{ +// QStringList files; + +// listOfFiles(files, projectDirectory()); + +// return files; + return m_sourceFiles; +} + +void PascalProjectPart::addFile(const QString& /*fileName*/) +{ +} + +void PascalProjectPart::addFiles(const QStringList& /*fileList*/) +{ +} + +void PascalProjectPart::removeFile(const QString& /*fileName*/) +{ +} + +void PascalProjectPart::removeFiles(const QStringList& /*fileList*/) +{ +} + +void PascalProjectPart::slotBuild() +{ + if (partController()->saveAllFiles()==false) + return; //user cancelled + + QString cmdline = m_compilerExec + " " + m_compilerOpts + " "; + + if (cmdline.isEmpty()) + { + KMessageBox::sorry(0, i18n("Could not find pascal compiler.\nCheck if your compiler settings are correct.")); + return; + } + + QFileInfo fi(mainSource()); + cmdline += fi.fileName(); + + QString dircmd = "cd "; + dircmd += KProcess::quote(buildDirectory()); + dircmd += " && "; + + makeFrontend()->queueCommand(buildDirectory(), dircmd + cmdline); +} + +void PascalProjectPart::slotExecute() +{ + partController()->saveAllFiles(); + + QDomDocument &dom = *(projectDom()); + bool runInTerminal = DomUtil::readBoolEntry(dom, "/kdevpascalproject/run/terminal", true); + + // Get the run environment variables pairs into the environstr string + // in the form of: "ENV_VARIABLE=ENV_VALUE" + // Note that we quote the variable value due to the possibility of + // embedded spaces + DomUtil::PairList envvars = + DomUtil::readPairListEntry(*projectDom(), "/kdevpascalproject/run/envvars", "envvar", "name", "value"); + + QString environstr; + DomUtil::PairList::ConstIterator it; + for (it = envvars.begin(); it != envvars.end(); ++it) { + environstr += (*it).first; + environstr += "="; + environstr += EnvVarTools::quote((*it).second); + environstr += " "; + } + + QString program = mainProgram(); + program.prepend(environstr); + program += " " + DomUtil::readEntry(*projectDom(), "/kdevpascalproject/run/programargs"); + + appFrontend()->startAppCommand(buildDirectory(), program, runInTerminal); +} + +void PascalProjectPart::changedFiles( const QStringList & fileList ) +{ + KDevProject::changedFiles(fileList); +} + +void PascalProjectPart::changedFile( const QString & fileName ) +{ + KDevProject::changedFile(fileName); +} + +void PascalProjectPart::projectConfigWidget( KDialogBase * dlg ) +{ + QVBox *vbox; + vbox = dlg->addVBoxPage(i18n("Pascal Compiler")); + PascalProjectOptionsDlg *w = new PascalProjectOptionsDlg(this, vbox); + connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); + connect( dlg, SIGNAL(okClicked()), this, SLOT(loadProjectConfig()) ); + + vbox = dlg->addVBoxPage(i18n("Run Options"), i18n("Run Options"), BarIcon( "make", KIcon::SizeMedium )); + RunOptionsWidget *w3 = new RunOptionsWidget(*projectDom(), "/kdevpascalproject", buildDirectory(), vbox); + connect( dlg, SIGNAL(okClicked()), w3, SLOT(accept()) ); + +} + +void PascalProjectPart::loadProjectConfig( ) +{ + QDomDocument &dom = *(projectDom()); + + QString config = DomUtil::readEntry(dom, "/kdevpascalproject/general/useconfiguration", "default"); + m_mainSource = DomUtil::readEntry(dom, QString("/kdevpascalproject/configurations/") + config + QString("/mainsource") ); + m_compilerOpts = DomUtil::readEntry(dom, QString("/kdevpascalproject/configurations/") + config + QString("/compileroptions")); + m_compilerExec = DomUtil::readEntry(dom, QString("/kdevpascalproject/configurations/") + config + QString("/compilerexec")); + + if (m_compilerExec.isEmpty()) + { + KTrader::OfferList offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Pascal'"); + QValueList<KService::Ptr>::ConstIterator it; + for (it = offers.begin(); it != offers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + m_compilerExec = (*it)->exec(); + break; + } + } + } +} + +void PascalProjectPart::configWidget( KDialogBase * dlg ) +{ + QVBox *vbox; + vbox = dlg->addVBoxPage(i18n("Pascal Compiler")); + PascalGlobalOptionsDlg *w = new PascalGlobalOptionsDlg(this, vbox); + connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); +} + +KDevCompilerOptions *PascalProjectPart::createCompilerOptions(const QString &name) +{ + KService::Ptr service = KService::serviceByDesktopName(name); + if (!service) { + kdDebug() << "Can't find service " << name; + return 0; + } + + KLibFactory *factory = KLibLoader::self()->factory(QFile::encodeName(service->library())); + if (!factory) { + QString errorMessage = KLibLoader::self()->lastErrorMessage(); + KMessageBox::error(0, i18n("There was an error loading the module %1.\n" + "The diagnostics is:\n%2").arg(service->name()).arg(errorMessage)); + exit(1); + } + + QStringList args; + QVariant prop = service->property("X-KDevelop-Args"); + if (prop.isValid()) + args = QStringList::split(" ", prop.toString()); + + QObject *obj = factory->create(this, service->name().latin1(), + "KDevCompilerOptions", args); + + if (!obj->inherits("KDevCompilerOptions")) { + kdDebug() << "Component does not inherit KDevCompilerOptions" << endl; + return 0; + } + KDevCompilerOptions *dlg = (KDevCompilerOptions*) obj; + + return dlg; +} + +QString PascalProjectPart::defaultOptions( const QString compiler ) const +{ + KConfig *config = KGlobal::config(); + config->setGroup("Pascal Compiler"); + return config->readPathEntry(compiler); +} + +#include "pascalproject_part.moc" + + +/*! + \fn PascalProjectPart::distFiles() const + */ +QStringList PascalProjectPart::distFiles() const +{ + QStringList sourceList = allFiles(); + // Scan current source directory for any .pro files. + QString projectDir = projectDirectory(); + QDir dir(projectDir); + QStringList files = dir.entryList( "Makefile"); + return sourceList + files; +} diff --git a/buildtools/pascal/pascalproject_part.h b/buildtools/pascal/pascalproject_part.h new file mode 100644 index 00000000..3273011d --- /dev/null +++ b/buildtools/pascal/pascalproject_part.h @@ -0,0 +1,95 @@ +/*************************************************************************** + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 __KDEVPART_PASCALPROJECT_H__ +#define __KDEVPART_PASCALPROJECT_H__ + +#include <qguardedptr.h> + +#include "kdevbuildtool.h" + +class PascalProjectWidget; +class KDialogBase; +class KDevCompilerOptions; + +class PascalProjectPart : public KDevBuildTool +{ + Q_OBJECT +public: + PascalProjectPart(QObject *parent, const char *name, const QStringList &); + ~PascalProjectPart(); + + virtual void openProject(const QString &dirName, const QString &projectName); + virtual void closeProject(); + + /**Returns the name of the main source file without extension. + All pascal compilers call the binary by that way*/ + virtual QString mainProgram() const; + /**Main source file (like src/main.pp)*/ + virtual QString mainSource() const; + virtual void setMainSource(QString fullPath); + + virtual QString projectDirectory() const; + virtual QString projectName() const; + virtual QString activeDirectory() const; + /**The location of the main source file*/ + virtual QString buildDirectory() const; + virtual QString runDirectory() const; + virtual QString debugArguments() const; + virtual QString runArguments() const; + virtual DomUtil::PairList runEnvironmentVars() const; + + /**Returns everything in the project directory*/ + virtual QStringList allFiles() const; + /**This does absolutelly nothing*/ + virtual void addFile(const QString &fileName); + /**This does absolutelly nothing*/ + virtual void addFiles(const QStringList &fileList); + /**This does absolutelly nothing*/ + virtual void removeFile(const QString &fileName); + /**This does absolutelly nothing*/ + virtual void removeFiles(const QStringList &fileList); + + virtual void changedFiles( const QStringList & fileList ); + virtual void changedFile( const QString & fileName ); + + KDevCompilerOptions *createCompilerOptions(const QString &name); + + virtual QString defaultOptions(const QString compiler) const; + QStringList distFiles() const; + +public slots: + /**loads config from project file*/ + void loadProjectConfig(); + +private slots: + void slotBuild(); + void slotExecute(); + void projectConfigWidget(KDialogBase *dlg); + void configWidget(KDialogBase *dlg); + +private: + QGuardedPtr<PascalProjectWidget> m_widget; + + void listOfFiles(QStringList &result, QString path) const; + + QString m_buildDir; + QString m_projectDir; + QString m_projectName; + + QString m_mainProg; + QString m_mainSource; + QString m_compilerExec; + QString m_compilerOpts; + + QStringList m_sourceFiles; +}; + +#endif diff --git a/buildtools/pascal/pascalproject_widget.cpp b/buildtools/pascal/pascalproject_widget.cpp new file mode 100644 index 00000000..039c97e6 --- /dev/null +++ b/buildtools/pascal/pascalproject_widget.cpp @@ -0,0 +1,26 @@ +#include <kparts/part.h> +#include <klibloader.h> +#include <kurl.h> +#include <kdebug.h> + + +#include <kdevcore.h> + + +#include "pascalproject_part.h" +#include "pascalproject_widget.h" + + +PascalProjectWidget::PascalProjectWidget(PascalProjectPart *part) + : QWidget(0, "PascalProject widget") +{ + Q_UNUSED( part ); +} + + +PascalProjectWidget::~PascalProjectWidget() +{ +} + + +#include "pascalproject_widget.moc" diff --git a/buildtools/pascal/pascalproject_widget.h b/buildtools/pascal/pascalproject_widget.h new file mode 100644 index 00000000..198cf794 --- /dev/null +++ b/buildtools/pascal/pascalproject_widget.h @@ -0,0 +1,25 @@ +#ifndef __PASCALPROJECT_WIDGET_H__ +#define __PASCALPROJECT_WIDGET_H__ + + +#include <qwidget.h> +#include <qstring.h> + + +class KDevProject; +class PascalProjectPart; + + +class PascalProjectWidget : public QWidget +{ + Q_OBJECT + +public: + + PascalProjectWidget(PascalProjectPart *part); + ~PascalProjectWidget(); + +}; + + +#endif diff --git a/buildtools/pascal/pascalprojectoptionsdlg.cpp b/buildtools/pascal/pascalprojectoptionsdlg.cpp new file mode 100644 index 00000000..7a97cea3 --- /dev/null +++ b/buildtools/pascal/pascalprojectoptionsdlg.cpp @@ -0,0 +1,210 @@ +/*************************************************************************** + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 <kurlrequester.h> +#include <kservice.h> +#include <kdebug.h> +#include <kmessagebox.h> +#include <klocale.h> + +#include <qlineedit.h> +#include <qcombobox.h> +#include <qregexp.h> +#include <qvalidator.h> + +#include "domutil.h" +#include "kdevcompileroptions.h" + +#include "service.h" +#include "pascalproject_part.h" +#include "pascalprojectoptionsdlg.h" + +PascalProjectOptionsDlg::PascalProjectOptionsDlg(PascalProjectPart *part, QWidget* parent, const char* name, WFlags fl) + : PascalProjectOptionsDlgBase(parent,name, fl), m_part(part) +{ + config_combo->setValidator(new QRegExpValidator(QRegExp("^\\D.*"), this)); + + offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Pascal'"); + + ServiceComboBox::insertStringList(compiler_box, offers, &service_names, &service_execs); + + if (offers.isEmpty()) + options_button->setEnabled(false); + + allConfigs = allBuildConfigs(); + config_combo->insertStringList(allConfigs); + + dirty = false; + + QDomDocument &dom = *(m_part->projectDom()); + currentConfig = QString::null; + configChanged(DomUtil::readEntry(dom, "/kdevpascalproject/general/useconfiguration", "default")); +} + +PascalProjectOptionsDlg::~PascalProjectOptionsDlg() +{ +} + +QStringList PascalProjectOptionsDlg::allBuildConfigs() +{ + QDomDocument &dom = *(m_part->projectDom()); + + QStringList allConfigs; + allConfigs.append("default"); + + QDomNode node = dom.documentElement().namedItem("kdevpascalproject").namedItem("configurations"); + QDomElement childEl = node.firstChild().toElement(); + while (!childEl.isNull()) { + QString config = childEl.tagName(); + kdDebug() << "Found config " << config << endl; + if (config != "default") + allConfigs.append(config); + childEl = childEl.nextSibling().toElement(); + } + + return allConfigs; +} + +void PascalProjectOptionsDlg::accept() +{ + DomUtil::writeEntry(*m_part->projectDom(), "/kdevpascalproject/general/useconfiguration", currentConfig); + if (dirty) + { + saveConfig(currentConfig); + } +} + +void PascalProjectOptionsDlg::compiler_box_activated( const QString& /*s*/ ) +{ + QString exec = ServiceComboBox::currentText(compiler_box, service_execs); + exec_edit->setText(exec); +} + +void PascalProjectOptionsDlg::saveConfig( QString config ) +{ + QDomDocument dom = *m_part->projectDom(); + QString prefix = "/kdevpascalproject/configurations/" + config + "/"; + + DomUtil::writeEntry(dom, prefix + "compiler", + ServiceComboBox::currentText(compiler_box, service_names)); + DomUtil::writeEntry(dom, prefix + "compileroptions", options_edit->text()); + DomUtil::writeEntry(dom, prefix + "compilerexec", exec_edit->text()); + DomUtil::writeEntry(dom, prefix + "mainsource", mainSourceUrl->url().replace(QRegExp(m_part->projectDirectory() + QString("/")),"")); +} + +void PascalProjectOptionsDlg::readConfig( QString config ) +{ + QDomDocument dom = *m_part->projectDom(); + QString prefix = "/kdevpascalproject/configurations/" + config + "/"; + + QString compiler = DomUtil::readEntry(dom, prefix + "compiler", ""); + + if (compiler.isEmpty()) + { + offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Pascal'"); + QValueList<KService::Ptr>::ConstIterator it; + for (it = offers.begin(); it != offers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + compiler = (*it)->name(); + kdDebug() << "compiler is " << compiler << endl; + break; + } + } + } + ServiceComboBox::setCurrentText(compiler_box, compiler, service_names); + + QString exec = DomUtil::readEntry(dom, prefix + "compilerexec", ""); + if (exec.isEmpty()) + exec = ServiceComboBox::currentText(compiler_box, service_execs); + exec_edit->setText(exec); + options_edit->setText(DomUtil::readEntry(dom, prefix + "compileroptions")); + mainSourceUrl->setURL(m_part->projectDirectory() + "/" + DomUtil::readEntry(dom, prefix + "mainsource")); +} + +void PascalProjectOptionsDlg::configComboTextChanged(const QString &config) +{ + bool canAdd = !allConfigs.contains(config) && !config.contains("/") && !config.isEmpty(); + bool canRemove = allConfigs.contains(config) && config != "default"; + addconfig_button->setEnabled(canAdd); + removeconfig_button->setEnabled(canRemove); +} + + +void PascalProjectOptionsDlg::configChanged(const QString &config) +{ + if (config == currentConfig || !allConfigs.contains(config)) + return; + + if (!currentConfig.isNull() && dirty) + saveConfig(currentConfig); + + currentConfig = config; + readConfig(config); + dirty = false; + + config_combo->blockSignals(true); + config_combo->setEditText(config); + config_combo->blockSignals(false); +} + + +void PascalProjectOptionsDlg::configAdded() +{ + QString config = config_combo->currentText(); + + allConfigs.append(config); + + config_combo->clear(); + config_combo->insertStringList(allConfigs); + configChanged(config); + setDirty(); // force saving +} + + +void PascalProjectOptionsDlg::configRemoved() +{ + QString config = config_combo->currentText(); + + QDomDocument dom = *m_part->projectDom(); + QDomNode node = dom.documentElement().namedItem("kdevpascalproject").namedItem("configurations"); + node.removeChild(node.namedItem(config)); + allConfigs.remove(config); + + config_combo->clear(); + config_combo->insertStringList(allConfigs); + + currentConfig = QString::null; + configChanged("default"); +} + +void PascalProjectOptionsDlg::optionsButtonClicked( ) +{ + QString name = ServiceComboBox::currentText(compiler_box, service_names); + KDevCompilerOptions *plugin = m_part->createCompilerOptions(name); + + if (plugin) { + QString flags = plugin->exec(this, options_edit->text()); + options_edit->setText(flags); + delete plugin; + } +} + +void PascalProjectOptionsDlg::setDirty( ) +{ + dirty = true; +} + +void PascalProjectOptionsDlg::setDefaultOptions( ) +{ + if (!compiler_box->currentText().isEmpty()) + options_edit->setText(m_part->defaultOptions(compiler_box->currentText())); +} + +#include "pascalprojectoptionsdlg.moc" diff --git a/buildtools/pascal/pascalprojectoptionsdlg.h b/buildtools/pascal/pascalprojectoptionsdlg.h new file mode 100644 index 00000000..70e911de --- /dev/null +++ b/buildtools/pascal/pascalprojectoptionsdlg.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 PASCALPROJECTOPTIONSDLG_H +#define PASCALPROJECTOPTIONSDLG_H + +#include <ktrader.h> + +#include "pascalproject_optionsdlgbase.h" + +class PascalProjectPart; +class KDevCompilerOptions; + +class PascalProjectOptionsDlg : public PascalProjectOptionsDlgBase +{ + Q_OBJECT + +public: + PascalProjectOptionsDlg(PascalProjectPart *part, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~PascalProjectOptionsDlg(); + +public slots: + virtual void accept(); + +protected slots: + virtual void compiler_box_activated(const QString &s); + void configComboTextChanged(const QString &config); + void configChanged(const QString &config); + void configAdded(); + void configRemoved(); + void optionsButtonClicked(); + void setDirty(); + void setDefaultOptions(); + +private: + QStringList allConfigs; + QString currentConfig; + bool dirty; + + KTrader::OfferList offers; + QStringList service_names; + QStringList service_execs; + + PascalProjectPart *m_part; + + void saveConfig(QString config); + void readConfig(QString config); + QStringList allBuildConfigs(); +}; + +#endif + diff --git a/buildtools/pascal/service.cpp b/buildtools/pascal/service.cpp new file mode 100644 index 00000000..c678f916 --- /dev/null +++ b/buildtools/pascal/service.cpp @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 <qcombobox.h> +#include <qvaluelist.h> + +#include <kservice.h> +#include <kdebug.h> + +#include "service.h" + + +void ServiceComboBox::insertStringList(QComboBox *combo, const QValueList<KService::Ptr> &list, + QStringList *names, QStringList *execs) +{ + QValueList<KService::Ptr>::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + combo->insertItem((*it)->comment()); + (*names) << (*it)->desktopEntryName(); + (*execs) << (*it)->exec(); + kdDebug() << "insertStringList item " << (*it)->name() << "," << (*it)->exec() << endl; + } +} + +QString ServiceComboBox::currentText(QComboBox *combo, const QStringList &names) +{ + if (combo->currentItem() == -1) + return QString::null; + return names[combo->currentItem()]; +} + +void ServiceComboBox::setCurrentText(QComboBox *combo, const QString &str, const QStringList &names) +{ + QStringList::ConstIterator it; + int i = 0; + for (it = names.begin(); it != names.end(); ++it) { + if (*it == str) { + combo->setCurrentItem(i); + break; + } + ++i; + } +} + +int ServiceComboBox::itemForText(const QString &str, const QStringList &names) +{ + QStringList::ConstIterator it; + int i = 0; + for (it = names.begin(); it != names.end(); ++it) { + if (*it == str) { + return i; + } + ++i; + } + return 0; +} + +QString ServiceComboBox::defaultCompiler() +{ + KTrader::OfferList offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Pascal'"); + QValueList<KService::Ptr>::ConstIterator it; + for (it = offers.begin(); it != offers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + return (*it)->name();; + } + } + return ""; +} diff --git a/buildtools/pascal/service.h b/buildtools/pascal/service.h new file mode 100644 index 00000000..30bb142b --- /dev/null +++ b/buildtools/pascal/service.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 SERVICE_H +#define SERVICE_H + +#include <ktrader.h> + +class ServiceComboBox +{ +public: + static void insertStringList(QComboBox *combo, const QValueList<KService::Ptr> &list, + QStringList *names, QStringList *execs); + static QString currentText(QComboBox *combo, const QStringList &names); + static void setCurrentText(QComboBox *combo, const QString &str, const QStringList &names); + static int itemForText(const QString &str, const QStringList &names); + static QString defaultCompiler(); +}; + +#endif diff --git a/buildtools/qmake/Makefile.am b/buildtools/qmake/Makefile.am new file mode 100644 index 00000000..6b65901a --- /dev/null +++ b/buildtools/qmake/Makefile.am @@ -0,0 +1,34 @@ +# Here resides the troll project part for tmake or qmake + + +INCLUDES = -I$(top_srcdir)/buildtools/lib/base \ + -I$(top_srcdir)/buildtools/lib/widgets -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/buildtools/lib/parsers/qmake \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/interfaces/external -I$(top_srcdir)/lib/util \ + -I$(top_builddir)/buildtools/lib/widgets $(all_includes) + + +kde_module_LTLIBRARIES = libkdevtrollproject.la +libkdevtrollproject_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevtrollproject_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/lib/util/libkdevutil.la $(top_builddir)/buildtools/lib/widgets/libkdevbuildtoolswidgets.la \ + $(top_builddir)/buildtools/lib/base/libkdevbuildbase.la \ + $(top_builddir)/buildtools/lib/parsers/qmake/libkdevqmakeparser.la + +libkdevtrollproject_la_SOURCES = choosesubprojectdlg.cpp \ + choosesubprojectdlgbase.ui createscopedlg.cpp createscopedlgbase.ui disablesubprojectdlg.cpp \ + disablesubprojectdlgbase.ui newwidgetdlg.cpp newwidgetdlgbase.ui \ + projectconfigurationdlg.cpp projectconfigurationdlgbase.ui qmakedefaultopts.cpp \ + qmakeoptionswidget.cpp qmakeoptionswidgetbase.ui qmakescopeitem.cpp scope.cpp \ + trolllistview.cpp trollprojectpart.cpp trollprojectwidget.cpp + + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevtrollproject.desktop kdevtmakeproject.desktop + +rcdir = $(kde_datadir)/kdevtrollproject +rc_DATA = kdevtrollproject.rc +noinst_HEADERS = createscopedlg.h disablesubprojectdlg.h qmakedefaultopts.h \ + qmakeoptionswidget.h qmakescopeitem.h trolllistview.h diff --git a/buildtools/qmake/README b/buildtools/qmake/README new file mode 100644 index 00000000..0146b60f --- /dev/null +++ b/buildtools/qmake/README @@ -0,0 +1 @@ +Please read the README.dox file.
\ No newline at end of file diff --git a/buildtools/qmake/README.dox b/buildtools/qmake/README.dox new file mode 100644 index 00000000..6f0a4027 --- /dev/null +++ b/buildtools/qmake/README.dox @@ -0,0 +1,39 @@ +/** \class TrollProjectPart +A projectmanager for qmake based projects. + +Loads and maintains .pro files (qmake project files). The trollprojectpart +supports subprojects and qmake scopes. Qmake projects can be configured on +project, subproject and file level. +It will regenerate a projects .pro files dynamically as you add,remove or +reconfigure (sub)projects. Unsupported qmake features will be left unchanged +(hopefully) no major testing has been run yet. + +\authors <a href="mailto:bernd AT kdevelop.org">Bernd Gehrmann</a> +\authors <a href="mailto:thasart AT gmx.de">Thomas Hasart</a> + +\maintainer <a href="mailto:jsgaarde AT tdcspace.dk">Jakob Simon-Gaarde </a> + +\feature Loads and maintains .pro files (qmake project files). +\feature Supports subprojects and qmake scopes. +\feature Qmake projects can be configured on project, subproject and file level. +\feature Regenerates a projects .pro files dynamically as you add, +remove or reconfigure (sub)projects. +\feature Unsupported qmake features will be left unchanged (hopefully) + no major testing has been run yet. + +\bug bugs in <a href="http://bugs.kde.org/buglist.cgi?product=kdevelop&component=trollproject&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&order=Bug+Number">trollproject component at Bugzilla database</a> + +\requirement <a href="http://www.trolltech.com">QMake</a> >= 3.0.3 + +\todo <b>Relative directories (priority 1)</b> + By default a qmake projects created with kdevelop must be distributable, + therefore all directory-selections must be relative the subproject where + it is used (user can override this ofcourse). So when a select-directory + dialog is opened getRelativeDirectory() (#include pathutil.h) should be + called. +\todo <b>Ignore shell-expressions and qmake-functions (priority 2-3)</b> + FileBuffer should recognize and ignore shell-expressions and qmake-functions. + (Jakob Simon-Gaarde says: I'm on this one) + + +*/ diff --git a/buildtools/qmake/choosesubprojectdlg.cpp b/buildtools/qmake/choosesubprojectdlg.cpp new file mode 100644 index 00000000..20264144 --- /dev/null +++ b/buildtools/qmake/choosesubprojectdlg.cpp @@ -0,0 +1,114 @@ +/*************************************************************************** + * Copyright (C) 2003 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 <kpushbutton.h> + +#include "trollprojectwidget.h" + +#include "choosesubprojectdlg.h" +#include "scope.h" + +ChooseSubprojectDlg::ChooseSubprojectDlg(TrollProjectWidget *widget, QWidget* parent, const char* name, bool modal, WFlags fl) + : ChooseSubprojectDlgBase(parent,name, modal,fl), m_widget(widget) +{ + connect(subprojects_view, SIGNAL(selectionChanged(QListViewItem*)), this, SLOT(itemSelected(QListViewItem *))); + if( m_widget->m_rootSubproject) + { + ChooseItem *it = new ChooseItem(m_widget->m_rootSubproject, subprojects_view, m_widget->m_rootSubproject->text(0)); + it->setPixmap(0, *(m_widget->m_rootSubproject->pixmap(0))); + it->setOpen(true); + fillSubprojectsView(it); + subprojects_view->setSelected(it, true); + } +} + +ChooseSubprojectDlg::~ChooseSubprojectDlg() +{ +} + +/*$SPECIALIZATION$*/ +void ChooseSubprojectDlg::accept() +{ + if (!subprojects_view->currentItem()) + return; + ChooseItem *item = dynamic_cast<ChooseItem*>(subprojects_view->currentItem()); + if (!item) + return; + if ( item->subproject()->scope->variableValues("TEMPLATE").findIndex("subdirs") != -1 ) + return; + + QDialog::accept(); +} + +ChooseItem::ChooseItem( QMakeScopeItem * spitem, QListViewItem * parent, QString text ) + :KListViewItem(parent, text), m_spitem(spitem) +{ +} + +ChooseItem::ChooseItem( QMakeScopeItem * spitem, QListView * parent, QString text ) + :KListViewItem(parent, text), m_spitem(spitem) +{ +} + +QMakeScopeItem * ChooseItem::subproject( ) +{ + return m_spitem; +} + +void ChooseSubprojectDlg::fillSubprojectsView( ChooseItem *item ) +{ + if (!item->subproject()) + return; + + QListViewItem * sub_spitem = item->subproject()->firstChild(); + while( sub_spitem ) { + QMakeScopeItem *spitem = dynamic_cast<QMakeScopeItem *>(sub_spitem); + if ( spitem && spitem->scope->scopeType() == Scope::ProjectScope ) + { + ChooseItem *child_item = new ChooseItem(spitem, item, spitem->text(0)); + child_item->setPixmap(0, *(spitem->pixmap(0))); + child_item->setOpen(true); + fillSubprojectsView(child_item); + } + + sub_spitem = sub_spitem->nextSibling(); + } +} + +void ChooseSubprojectDlg::itemSelected( QListViewItem * it ) +{ + if (!it) + return; + ChooseItem *item = dynamic_cast<ChooseItem*>(it); + if (!item) + return; + if ( item->subproject()->scope->variableValues("TEMPLATE").findIndex("subdirs") != -1 ) + buttonOk->setEnabled(false); + else + buttonOk->setEnabled(true); +} + +QMakeScopeItem * ChooseSubprojectDlg::selectedSubproject( ) +{ + if (subprojects_view->currentItem()) + { + ChooseItem *item = dynamic_cast<ChooseItem*>(subprojects_view->currentItem()); + if (item) + return item->subproject(); + } + + return 0; +} + + +#include "choosesubprojectdlg.moc" + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + diff --git a/buildtools/qmake/choosesubprojectdlg.h b/buildtools/qmake/choosesubprojectdlg.h new file mode 100644 index 00000000..689fe8b3 --- /dev/null +++ b/buildtools/qmake/choosesubprojectdlg.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2003 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 CHOOSESUBPROJECTDLG_H +#define CHOOSESUBPROJECTDLG_H + +#include <klistview.h> + +#include "choosesubprojectdlgbase.h" + +class QMakeScopeItem; +class TrollProjectWidget; + +class ChooseItem: public KListViewItem +{ +public: + ChooseItem(QMakeScopeItem *spitem, QListViewItem *parent, QString text); + ChooseItem(QMakeScopeItem *spitem, QListView *parent, QString text); + + QMakeScopeItem *subproject(); + +private: + QMakeScopeItem *m_spitem; +}; + +class ChooseSubprojectDlg : public ChooseSubprojectDlgBase +{ + Q_OBJECT + +public: + ChooseSubprojectDlg(TrollProjectWidget *widget, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~ChooseSubprojectDlg(); + /*$PUBLIC_FUNCTIONS$*/ + + QMakeScopeItem *selectedSubproject(); + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + TrollProjectWidget *m_widget; + +protected slots: + /*$PROTECTED_SLOTS$*/ + virtual void accept(); + virtual void itemSelected(QListViewItem *it); + +private: + void fillSubprojectsView(ChooseItem *item); + +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/choosesubprojectdlgbase.ui b/buildtools/qmake/choosesubprojectdlgbase.ui new file mode 100644 index 00000000..12db29e2 --- /dev/null +++ b/buildtools/qmake/choosesubprojectdlgbase.ui @@ -0,0 +1,134 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>ChooseSubprojectDlgBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>ChooseSubprojectDlgBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>511</width> + <height>282</height> + </rect> + </property> + <property name="caption"> + <string>Select Subproject</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + <widget class="KListView" row="0" column="0"> + <column> + <property name="text"> + <string>Subprojects</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>subprojects_view</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>ChooseSubprojectDlgBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>ChooseSubprojectDlgBase</receiver> + <slot>reject()</slot> + </connection> +</connections> +<tabstops> + <tabstop>subprojects_view</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistview.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/buildtools/qmake/createscopedlg.cpp b/buildtools/qmake/createscopedlg.cpp new file mode 100644 index 00000000..439ddd70 --- /dev/null +++ b/buildtools/qmake/createscopedlg.cpp @@ -0,0 +1,100 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 "createscopedlg.h" + +#include <klineedit.h> +#include <kurlrequester.h> +#include <qcheckbox.h> +#include <kfile.h> +#include <kcombobox.h> +#include <kmessagebox.h> +#include <klocale.h> +#include <kfiledialog.h> +#include <kurlcompletion.h> + +#include "urlutil.h" +#include "qmakescopeitem.h" +#include "scope.h" +#include "trollprojectwidget.h" + +CreateScopeDlg::CreateScopeDlg( QMakeScopeItem* item, QWidget* parent, const char* name, bool modal, WFlags fl ) + : CreateScopeDlgBase( parent, name, modal, fl ), m_item( item ) +{ + incUrl->setMode( KFile::File | KFile::LocalOnly ); + incUrl->setCaption( i18n( "Choose existing .pri file or give a new filename for creation" ) ); + incUrl->setURL( QString("") ); + incUrl->completionObject() ->setDir( item->scope->projectDir() ); + incUrl->fileDialog()->setURL( KURL::fromPathOrURL( item->scope->projectDir() ) ); +} + +CreateScopeDlg::~CreateScopeDlg() +{} + +void CreateScopeDlg::accept() +{ + Scope * s = 0; + switch ( comboScopeType->currentItem() ) + { + case 0: + if ( !editScopeName->text().isEmpty() ) + s = m_item->scope->createSimpleScope( editScopeName->text() ); + break; + case 1: + if ( !editFunction->text().isEmpty() && !editArguments->text().isEmpty() ) + s = m_item->scope->createFunctionScope( editFunction->text(), editArguments->text() ); + break; + case 2: + if ( !incUrl->url().isEmpty() ) + { + QString file = incUrl->url(); + if ( !incUrl->url().endsWith( ".pri" ) ) + file += ".pri"; + if( file.find("/") == -1 ) + file = m_item->scope->projectDir()+"/"+file; + // We need to create the file, because getRelativePath checks for existent paths + if( !QFile::exists(file) ) + { + QFile temp(file); + if( temp.open(IO_WriteOnly) ) + temp.close(); + } + file = URLUtil::getRelativePath( m_item->scope->projectDir(), file ); + s = m_item->scope->createIncludeScope( file ); + } + break; + } + if ( s ) + { + if ( !m_item->firstChild() ) + new QMakeScopeItem( m_item, s->scopeName(), s ); + else + { + QListViewItem* item = m_item->firstChild(); + while( item->nextSibling() ) + item = item->nextSibling(); + QMakeScopeItem* newitem = new QMakeScopeItem( m_item, s->scopeName(), s ); + newitem->moveItem( item ); + } + QDialog::accept(); + } + else + { + if ( KMessageBox::warningYesNo( this, i18n( "You did not specify all needed information. " + "The scope will not be created.<br>Do you want to abort the scope creation?" ), + i18n( "Missing information" ) ) == KMessageBox:: Yes ) + QDialog::reject(); + } +} + +#include "createscopedlg.moc" + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/createscopedlg.h b/buildtools/qmake/createscopedlg.h new file mode 100644 index 00000000..c8ed86ef --- /dev/null +++ b/buildtools/qmake/createscopedlg.h @@ -0,0 +1,45 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 CREATESCOPEDLG_H +#define CREATESCOPEDLG_H + +#include "createscopedlgbase.h" + +class QMakeScopeItem; +class TrollProjectWigdet; + +class CreateScopeDlg : public CreateScopeDlgBase +{ + Q_OBJECT + +public: + CreateScopeDlg( QMakeScopeItem* item, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~CreateScopeDlg(); + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + virtual void accept(); +private: + QMakeScopeItem* m_item; +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + diff --git a/buildtools/qmake/createscopedlgbase.ui b/buildtools/qmake/createscopedlgbase.ui new file mode 100644 index 00000000..244589cd --- /dev/null +++ b/buildtools/qmake/createscopedlgbase.ui @@ -0,0 +1,329 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>CreateScopeDlgBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>CreateScopeDlgBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>348</width> + <height>208</height> + </rect> + </property> + <property name="caption"> + <string>Create Scope</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Scopetype:</string> + </property> + </widget> + <widget class="KComboBox"> + <item> + <property name="text"> + <string>Simple Scope</string> + </property> + </item> + <item> + <property name="text"> + <string>Function Scope</string> + </property> + </item> + <item> + <property name="text"> + <string>Include File</string> + </property> + </item> + <property name="name"> + <cstring>comboScopeType</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Choose between the different types of new scopes</string> + </property> + </widget> + <spacer> + <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>95</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="title"> + <string>Scope Settings</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QWidgetStack" row="0" column="0"> + <property name="name"> + <cstring>widgetStack1</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>simplePage</cstring> + </property> + <attribute name="id"> + <number>0</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>editScopeName</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Specify the new scope name</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Scopename:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editScopeName</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>funcPage</cstring> + </property> + <attribute name="id"> + <number>1</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>editFunction</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>Function:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editFunction</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Specify the function name</string> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel4</cstring> + </property> + <property name="text"> + <string>Arguments:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>editArguments</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>Specify the list of function arguments, delimited by a comma</string> + </property> + </widget> + <widget class="KLineEdit" row="1" column="1"> + <property name="name"> + <cstring>editArguments</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>incPage</cstring> + </property> + <attribute name="id"> + <number>2</number> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KURLRequester" row="0" column="1"> + <property name="name"> + <cstring>incUrl</cstring> + </property> + <property name="focusPolicy"> + <enum>StrongFocus</enum> + </property> + <property name="filter"> + <string>*.pri</string> + </property> + <property name="mode"> + <number>25</number> + </property> + <property name="toolTip" stdset="0"> + <string>Choose the .pri file to include</string> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel5</cstring> + </property> + <property name="text"> + <string>Include File:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>incUrl</cstring> + </property> + </widget> + <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>checkNotInc</cstring> + </property> + <property name="text"> + <string>&use !include instead of include</string> + </property> + <property name="toolTip" stdset="0"> + <string>Use !include instead of include for the function scope</string> + </property> + </widget> + </grid> + </widget> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout3</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer> + <property name="name"> + <cstring>spacer2</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="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>O&K</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>Ca&ncel</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>comboScopeType</sender> + <signal>activated(int)</signal> + <receiver>widgetStack1</receiver> + <slot>raiseWidget(int)</slot> + </connection> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>CreateScopeDlgBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>CreateScopeDlgBase</receiver> + <slot>reject()</slot> + </connection> +</connections> +<tabstops> + <tabstop>editFunction</tabstop> + <tabstop>editArguments</tabstop> + <tabstop>comboScopeType</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> + <tabstop>editScopeName</tabstop> + <tabstop>incUrl</tabstop> + <tabstop>checkNotInc</tabstop> +</tabstops> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kcombobox.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/buildtools/qmake/disablesubprojectdlg.cpp b/buildtools/qmake/disablesubprojectdlg.cpp new file mode 100644 index 00000000..335bf33f --- /dev/null +++ b/buildtools/qmake/disablesubprojectdlg.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 "disablesubprojectdlg.h" +#include <klistview.h> +#include <qstringlist.h> +#include "scope.h" +#include "qmakescopeitem.h" + +DisableSubprojectDlg::DisableSubprojectDlg( const QStringList& projects, QWidget* parent, const char* name, WFlags fl ) + : DisableSubprojectDlgBase( parent, name, fl ) +{ + for( QStringList::const_iterator it = projects.begin(); it != projects.end(); ++it ) + { + new QCheckListItem(subprojects_view, *it, QCheckListItem::CheckBox); + } +} + +DisableSubprojectDlg::~DisableSubprojectDlg() +{ +} + +QStringList DisableSubprojectDlg::selectedProjects() +{ + QStringList result; + QListViewItem* item = subprojects_view->firstChild(); + while( item ) + { + QCheckListItem* ci = dynamic_cast<QCheckListItem*>(item); + if( ci && ci->isOn() ) + { + result << ci->text(0); + } + item = item->nextSibling(); + } + return result; +} + +#include "disablesubprojectdlg.moc" + + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/disablesubprojectdlg.h b/buildtools/qmake/disablesubprojectdlg.h new file mode 100644 index 00000000..13a27468 --- /dev/null +++ b/buildtools/qmake/disablesubprojectdlg.h @@ -0,0 +1,42 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 DISABLESUBPROJECTDLG_H +#define DISABLESUBPROJECTDLG_H + +#include "disablesubprojectdlgbase.h" + +class DisableSubprojectDlg : public DisableSubprojectDlgBase +{ + Q_OBJECT + +public: + DisableSubprojectDlg( const QStringList& projects, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~DisableSubprojectDlg(); + /*$PUBLIC_FUNCTIONS$*/ + + QStringList selectedProjects(); + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + +}; + +#endif + + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/disablesubprojectdlgbase.ui b/buildtools/qmake/disablesubprojectdlgbase.ui new file mode 100644 index 00000000..ffcc1d32 --- /dev/null +++ b/buildtools/qmake/disablesubprojectdlgbase.ui @@ -0,0 +1,126 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>DisableSubprojectDlgBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>DisableSubprojectDlgBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>512</width> + <height>282</height> + </rect> + </property> + <property name="caption"> + <string>Select Subprojects to disable</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KListView"> + <column> + <property name="text"> + <string>Subprojects</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>subprojects_view</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>O&K</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>DisableSubprojectDlgBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>DisableSubprojectDlgBase</receiver> + <slot>accept()</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistview.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/buildtools/qmake/kdevtmakeproject.desktop b/buildtools/qmake/kdevtmakeproject.desktop new file mode 100644 index 00000000..f1921523 --- /dev/null +++ b/buildtools/qmake/kdevtmakeproject.desktop @@ -0,0 +1,91 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=TMake Project +Comment[br]=Rektras TMake +Comment[ca]=Projecte TMake +Comment[da]=TMake-projekt +Comment[de]=TMake-Projekt für KDevelop +Comment[el]=Έργο TMake +Comment[es]=Proyecto TMake +Comment[et]=TMake projekt +Comment[eu]=TMake proiektua +Comment[fa]=پروژۀ TMake +Comment[fr]=Projet avec TMake +Comment[ga]=Comhad tionscadail TMake +Comment[gl]=Proxecto TMake +Comment[hi]=टी-मेक परियोजना +Comment[hu]=TMake-projekt +Comment[is]=TMake verkefni +Comment[it]=Progetto per TMake +Comment[ja]=TMake プロジェクト +Comment[ms]=Projek TMake +Comment[nds]=TMake-Projekt +Comment[ne]=TMake परियोजना +Comment[nl]=TMake-project +Comment[pl]=Projekt: TMake +Comment[pt]=Projecto TMake +Comment[pt_BR]=Projeto TMake +Comment[ru]=Проект TMake +Comment[sk]=TMake projekt +Comment[sl]=Projekt TMake +Comment[sr]=TMake пројекат +Comment[sr@Latn]=TMake projekat +Comment[sv]=Tmake-projekt +Comment[ta]=டிமேக் பிராஜக்ட் +Comment[tg]=Лоиҳаи TMake +Comment[tr]=TMake Projesi +Comment[zh_CN]=TMake 工程 +Comment[zh_TW]=TMake 專案 +Name=KDevTMakeProject +Name[da]=KDevelop TMake-projekt +Name[de]=TMake-Projekt (KDevelop) +Name[hi]=के-डेव-टी-मेक-परियोजना +Name[nds]=TMake-Projekt (KDevelop) +Name[ne]=KDevTMake परियोजना +Name[pl]=KDevProjektTMake +Name[sk]=KDevTMakeProjekt +Name[sv]=KDevelop Tmake-projekt +Name[ta]=கெடெவ் டிமேக் பிராஜக்ட் +Name[tg]=KDevTСохтани лоиҳа +Name[zh_TW]=KDevelop TMake 專案 +GenericName=TMake Project +GenericName[br]=Raktres TMake +GenericName[ca]=Projecte TMake +GenericName[da]=TMake-projekt +GenericName[de]=TMake-Projekt +GenericName[el]=Έργο TMake +GenericName[es]=Proyecto TMake +GenericName[et]=TMake projekt +GenericName[eu]=TMake proiektua +GenericName[fa]=پروژۀ TMake +GenericName[fr]=Projet avec TMake +GenericName[ga]=Tionscadal TMake +GenericName[gl]=Proxecto TMake +GenericName[hi]=टी-मेक परियोजना +GenericName[hu]=TMake-projekt +GenericName[it]=Progetto per TMake +GenericName[ja]=TMake プロジェクト +GenericName[ms]=Projek TMake +GenericName[nds]=TMake-Projekt +GenericName[ne]=TMake परियोजना +GenericName[nl]=TMake-project +GenericName[pl]=Projekt: TMake +GenericName[pt]=Projecto TMake +GenericName[pt_BR]=Projeto TMake +GenericName[ru]=Проект TMake +GenericName[sk]=TMake projekt +GenericName[sl]=Projekt TMake +GenericName[sr]=TMake пројекат +GenericName[sr@Latn]=TMake projekat +GenericName[sv]=Tmake-projekt +GenericName[ta]=டிமேக் பிராஜக்ட் +GenericName[tg]=Лоиҳаи TMake +GenericName[tr]=TMake Projesi +GenericName[zh_CN]=TMake 工程 +GenericName[zh_TW]=TMake 專案 +ServiceTypes=KDevelop/Project +X-KDE-Library=libkdevtrollproject +X-KDevelop-Version=5 +X-KDevelop-Args=TMake + diff --git a/buildtools/qmake/kdevtrollproject.desktop b/buildtools/qmake/kdevtrollproject.desktop new file mode 100644 index 00000000..5debaf34 --- /dev/null +++ b/buildtools/qmake/kdevtrollproject.desktop @@ -0,0 +1,95 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=QMake Project +Comment[br]=Raktres QMake +Comment[ca]=Projecte QMake +Comment[da]=QMake-projekt +Comment[de]=QMake-Projekt für KDevelop +Comment[el]=Έργο QMake +Comment[es]=Proyecto QMake +Comment[et]=QMake projekt +Comment[eu]=QMake proiektua +Comment[fa]=پروژۀ QMake +Comment[fr]=Projet avec QMake +Comment[ga]=Tionscadal QMake +Comment[gl]=Proxecto QMake +Comment[hi]=क्यू-मेक परियोजना +Comment[hu]=QMake-projekt +Comment[is]=QMake verkefni +Comment[it]=Progetto per QMake +Comment[ja]=QMake プロジェクト +Comment[ms]=Projek QMake +Comment[nds]=QMake-Projekt +Comment[ne]=QMake परियोजना +Comment[nl]=QMake-project +Comment[pa]=QMake ਪ੍ਰੋਜੈਕਟ +Comment[pl]=Projekt: QMake +Comment[pt]=Projecto QMake +Comment[pt_BR]=Projeto QMake +Comment[ru]=Проект QMake +Comment[sk]=QMake projekt +Comment[sl]=Projekt QMake +Comment[sr]=QMake пројекат +Comment[sr@Latn]=QMake projekat +Comment[sv]=Qmake-projekt +Comment[ta]=க்யுமேக் பிராஜக்ட் +Comment[tg]=Лоиҳаи QMake +Comment[tr]=QMake Projesi +Comment[uz]=QMake loyihasi +Comment[uz@cyrillic]=QMake лойиҳаси +Comment[zh_CN]=QMake 工程 +Comment[zh_TW]=QMake 專案 +Name=KDevTrollProject +Name[da]=KDevelop Troll-projekt +Name[de]=QMake-Projekt (KDevelop) +Name[hi]=के-डेव-ट्रॉल-परियोजना +Name[nds]=QMake-Projekt (KDevelop) +Name[ne]=KDevTroll परियोजना +Name[pl]=KDevProjektTroll +Name[sk]=KDevTrollProjekt +Name[sv]=KDevelop Troll-projekt +Name[ta]=கெடெவ் டிரால் பிராஜக்ட் +Name[zh_TW]=KDevelop Troll 專案 +GenericName=QMake Project +GenericName[br]=Raktres QMake +GenericName[ca]=Projecte QMake +GenericName[da]=QMake-projekt +GenericName[de]=QMake-Projekt +GenericName[el]=Έργο QMake +GenericName[es]=Proyecto QMake +GenericName[et]=QMake projekt +GenericName[eu]=QMake proiektua +GenericName[fa]=پروژۀ QMake +GenericName[fr]=Projet avec QMake +GenericName[ga]=Tionscadal QMake +GenericName[gl]=Proxecto QMake +GenericName[hi]=क्यू-मेक परियोजना +GenericName[hu]=QMake-projekt +GenericName[it]=Progetto per QMake +GenericName[ja]=QMake プロジェクト +GenericName[ms]=Projek QMake +GenericName[nds]=QMake-Projekt +GenericName[ne]=QMake परियोजना +GenericName[nl]=QMake-project +GenericName[pa]=QMake ਪ੍ਰੋਜੈਕਟ +GenericName[pl]=Projekt: QMake +GenericName[pt]=Projecto QMake +GenericName[pt_BR]=Projeto QMake +GenericName[ru]=Проект QMake +GenericName[sk]=QMake projekt +GenericName[sl]=Projekt QMake +GenericName[sr]=QMake пројекат +GenericName[sr@Latn]=QMake projekat +GenericName[sv]=Qmake-projekt +GenericName[ta]=க்யுமேக் பிராஜக்ட் +GenericName[tg]=Лоиҳаи QMake +GenericName[tr]=QMake Projesi +GenericName[uz]=QMake loyihasi +GenericName[uz@cyrillic]=QMake лойиҳаси +GenericName[zh_CN]=QMake 工程 +GenericName[zh_TW]=QMake 專案 +ServiceTypes=KDevelop/Project +X-KDE-Library=libkdevtrollproject +X-KDevelop-Version=5 +X-KDevelop-Args= diff --git a/buildtools/qmake/kdevtrollproject.rc b/buildtools/qmake/kdevtrollproject.rc new file mode 100644 index 00000000..8f6e0048 --- /dev/null +++ b/buildtools/qmake/kdevtrollproject.rc @@ -0,0 +1,33 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KDevTrollProject" version="3"> +<MenuBar> + <Menu name="build" > + <Action name="build_build_project" /> + <Action name="build_install_project" /> + <Action name="build_rebuild_project" /> + <Action name="build_execute_project" /> + <Action name="build_clean_project" /> + <Action name="build_distclean_project" /> + <Separator/> + <Action name="build_build_target" /> + <Action name="build_install_target" /> + <Action name="build_rebuild_target" /> + <Action name="build_execute_target" /> + <Action name="build_clean_target" /> + <Action name="build_distclean_target" /> + <Separator/> + <Action name="build_compilefile" /> + </Menu> +</MenuBar> +<ToolBar name="buildToolBar" noMerge="1"> + <Action name="build_build_project" group="build_operations" /> + <Action name="build_rebuild_project" group="build_operations" /> + <Action name="build_execute_project" group="build_operations" /> + <Separator group="build_operations"/> + <Action name="build_build_target" group="build_operations" /> + <Action name="build_rebuild_target" group="build_operations" /> + <Action name="build_execute_target" group="build_operations" /> + <Separator group="build_operations"/> + <Action name="build_compilefile" group="build_operations" /> +</ToolBar> +</kpartgui> diff --git a/buildtools/qmake/newwidgetdlg.cpp b/buildtools/qmake/newwidgetdlg.cpp new file mode 100644 index 00000000..7be62acd --- /dev/null +++ b/buildtools/qmake/newwidgetdlg.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2002 by Jakob Simon-Gaarde * + * jsgaarde@tdcspace.dk * + * * + * 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 "newwidgetdlg.h" +#include <qradiobutton.h> +#include <qstringlist.h> +#include <qcheckbox.h> +#include <qmessagebox.h> +#include <kfiledialog.h> +#include <klineedit.h> +#include <kpushbutton.h> +#include <domutil.h> +#include <qdom.h> +#include <kstdguiitem.h> + +#define WIDGET_CAPTION_NAME "widget/property|name=caption/string" +#define WIDGET_CLASS_NAME "class" +#define WIDGET_SLOTS "slots" + +NewWidgetDlg::NewWidgetDlg(QStringList &newFileNames,QWidget* parent, const char* name, bool modal, WFlags fl) +: NewWidgetDlgBase(parent,name,modal,fl), +m_newFileNames(newFileNames) +//================================================= +{ +// Remove in kde 3.4 support + okayButton->setGuiItem(KStdGuiItem::ok()); + cancelButton->setGuiItem(KStdGuiItem::cancel()); +} + + +NewWidgetDlg::~NewWidgetDlg() +//============================================== +{ +} + + +void NewWidgetDlg::subclassingPressed() +//===================================== +{ + QMessageBox::information(0,"subclassing",""); +} + + +void NewWidgetDlg::templateSelChanged() +//===================================== +{ + QMessageBox::information(0,"template",""); +} + +void NewWidgetDlg::accept() +//========================= +{ + QDomDocument doc; + DomUtil::openDOMFile(doc,"/home/jsgaarde/programming/kdevelop/domapp/clean_dialog.ui"); + DomUtil::replaceText(doc,WIDGET_CLASS_NAME,"TestClass"); + DomUtil::replaceText(doc,WIDGET_CAPTION_NAME,"Test Dialog"); + QDomElement slotsElem = DomUtil::elementByPathExt(doc,WIDGET_SLOTS); + QDomNodeList slotnodes = slotsElem.childNodes(); + for (unsigned int i=0; i<slotnodes.count();i++) + { + QString msg; + QDomElement slotelem = slotnodes.item(i).toElement(); + msg.sprintf("Slotname: %s\nReturns: %s\nAccess: %s", + slotelem.text().ascii(), + slotelem.attributeNode("returnType").value().ascii(), + slotelem.attributeNode("access").value().ascii()); + QMessageBox::information(0,"Slots",msg); + } + DomUtil::saveDOMFile(doc,"/home/jsgaarde/programming/kdevelop/domapp/clean_dialog2.ui"); + NewWidgetDlgBase::accept(); +} + diff --git a/buildtools/qmake/newwidgetdlg.h b/buildtools/qmake/newwidgetdlg.h new file mode 100644 index 00000000..e8420df2 --- /dev/null +++ b/buildtools/qmake/newwidgetdlg.h @@ -0,0 +1,38 @@ +/*************************************************************************** + * Copyright (C) 2002 by Jakob Simon-Gaarde * + * jsgaarde@tdcspace.dk * + * * + * 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 NEWWIDGETDLG_H +#define NEWWIDGETDLG_H + +#include "newwidgetdlgbase.h" +#include "trollprojectwidget.h" + +class QStringList; +class QDomDocument; + +class NewWidgetDlg : public NewWidgetDlgBase +{ +public: + NewWidgetDlg(QStringList &newFileNames,QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~NewWidgetDlg(); + + +public slots: + virtual void subclassingPressed(); + virtual void templateSelChanged(); + virtual void accept(); + +protected: + QStringList &m_newFileNames; +}; + +#endif + diff --git a/buildtools/qmake/newwidgetdlgbase.ui b/buildtools/qmake/newwidgetdlgbase.ui new file mode 100644 index 00000000..7c3730ca --- /dev/null +++ b/buildtools/qmake/newwidgetdlgbase.ui @@ -0,0 +1,229 @@ +<!DOCTYPE UI><UI version="3.2" stdsetdef="1"> +<class>NewWidgetDlgBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>NewWidgetDlgBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>650</width> + <height>474</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>New Widget</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KPushButton" row="1" column="2"> + <property name="name"> + <cstring>cancelButton</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + <widget class="QGroupBox" row="0" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>GroupBox2</cstring> + </property> + <property name="title"> + <string>Widget Properties</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>subclassingCb</cstring> + </property> + <property name="text"> + <string>Subclassing</string> + </property> + </widget> + <widget class="QLayoutWidget" row="1" column="1" rowspan="2" colspan="1"> + <property name="name"> + <cstring>Layout5</cstring> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>captionLb</cstring> + </property> + <property name="text"> + <string>Caption:</string> + </property> + </widget> + <widget class="KLineEdit" row="2" column="1"> + <property name="name"> + <cstring>subclassnameEd</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>TextLabel4</cstring> + </property> + <property name="text"> + <string>Subclass name:</string> + </property> + </widget> + <widget class="KLineEdit" row="1" column="1"> + <property name="name"> + <cstring>captionEd</cstring> + </property> + </widget> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>ui_classnameEd</cstring> + </property> + <property name="minimumSize"> + <size> + <width>120</width> + <height>0</height> + </size> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>classnameLb</cstring> + </property> + <property name="text"> + <string>Class name:</string> + </property> + </widget> + </grid> + </widget> + <widget class="QLabel" row="0" column="1"> + <property name="name"> + <cstring>previewLb</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>2</hsizetype> + <vsizetype>2</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>160</height> + </size> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <widget class="QListBox" row="0" column="0" rowspan="2" colspan="1"> + <item> + <property name="text"> + <string>New Item</string> + </property> + </item> + <property name="name"> + <cstring>templateList</cstring> + </property> + </widget> + </grid> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>310</width> + <height>0</height> + </size> + </property> + </spacer> + <widget class="KPushButton" row="1" column="1"> + <property name="name"> + <cstring>okayButton</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + </widget> + </grid> +</widget> +<images> + <image name="image0"> + <data format="XPM.GZ" length="27539">789cdd5c577362cb767e3fbf62eaf6db2d571ba148b9fc80028a244584cb0f9d480221b22497ffbb57afd06c103aa399a3721dfb72f7814f9bdddd2b876ee65ffff9a3512bfff8e7bffe31999a69d7fd701d33fef14f3f1b0cdefee33ffffdbffef8c7562ef7235e3b3bdb3ff2fff8973ffea1fc0ff743e5f07f88e7091f20ae09dec2fba69530dd778c77f8f959c274ff40303f7f9730ddb78c0fe879f39e30de770bc1fc7c89b1a3efbb7dc25bbc7ef7ca98d7632e111f24fa7209d3fc8f8279fce384e9fe94b1d0d74c98ee5705f3f36f09d3fd0963a64fd513a6fb05c1f4bced254cf49f09ced3f8278c997e7396307edf68c1349e3b4f18ef7b599fa3f15485b0f0cfdb84697d5b8c857ec398e9f13cdf16afc7aa88b792fcfc8031dff71709d37a5f05d37a7d8fb0ac271405337fde13a6e7f705333d0dc6bcde6004f3f3e78c451e0bc6c2cf36e13ccf6f4e190bfd63c4895e1308cbf77583317f5f3f30e6f9f43d637e3ee0f7f369fc304f98f897eeb37e2d18f378e13061d297316359df3de16dd1ffc098e7f3c78c793c37445c90efeb47c6f2fd66c2a41f79c662bf3dc6629ffcfd1d9127fa8bed2d19cf6e3116fedc3196f5ef254cf21e1296f1743361bc6feb8c793c8bf6b55d90e75d8fb03cefa709e3fdd0144cfc56fb8c65bdc58489fe9160febe622cf39f254ceb97fbc29f838469fd4f11ef6cc9f7435e30db8762cccfabd78489bea260d6774d7857f8759b307e5fe704f3fa5b8c77993faf82e97ea8332e307d57888d3c6f04f3f36e37615a9f15ccfee892318fa7b712267ed404f3fccf09d3fd05e1bd2d9e1fe5b79bdff5ccbf53c1ccbf47c1f902dedf26bcb7c5f33505f37c0f09d3fd57c1e46f429931f3c7dd33e6f92deaf36e5a5f7817bcbd85f79f19f3f3ea21615aff93609acf0e19337f5459303daf6f12a6f90f04f37a2d63e1cf96605eff7bc224afb9607ade05c2fbcc2f7f2698d77f9d30e9fbae607ade9f3016f923fd7bf9bdc236cac37518f3fcbe2d989f2f0ba6efab6dc269be5bc1fcfdd384697ccf98f96dca09d3f345c1fcfc3861d2971a63d6573f17ccfc7a13ccfc427ddb03fa49defe29615a4f9d31cfe74e13a6fb53c1ac2f8631cfa7af05f3f38384f179db15ccf3df244cfc6b3366f99bf384899e1dc1cc8f56c2f8bc1f09e6f12b840f581e6120989f47feed6fcbfabc134ccf872a6399af9330f1e34a30cf774758e6332f82e9799d4f98e84df7e979374a18ef9b29639647d009d3fc15c1f4bc318c999e702298e9a1f1ac3caf3463be6f1e1833bd6a2f6192df9b601eef967081e9f58782e9fbe646308f8ff67fb09dee3f0b667dba60ccf4eaba60e6cf56c2f4fc2363a6576f0be6f9761226f91e1136ec1f2c7fdfb0fd595cff8195f94c25617ade08dea1fb5dc6a2cfa58489ff82995fba9030c9ef52308d175a848df0e74930d37f9c303d9f632cfa712598e5f39830c90ff5adb023e3bb13c6c25f9d30cd5f154cebf3216183fad1616c985fdb09d3f81782e979f79c303e1f468c03eb575e30ebc37ec234dead601acf5608db3cc7f707c1cc8f90303d9f17ccf2d863bcc7cf1f254cfe662698e3a560c3f9ce5dc2a4ffbb82397ea1fc0a4ef8158e19337fc2a560a6679e307edf5e33667ea8ab84493e1dc1fc7c59f02ed6d3a14d38d1bb9330d94b4d30ebf375c224df73c6c28f8260e6877c7f8ffde34c30cf779a30f99b1bc1349fea33667e9a79c2c44f998ff9a95f13a67ce25230fb8b9260e6cf11e3c0f9dc4bc214af268279fc69c2e4bf9d60ce777612267dcd1176ac7fba97308d3f13ccf9c861c2c4cf3bc6ac7ff621618a571dc1fc3cf3d3317f1cd263923d98026191a71a264cfad4174cfae1cf198bfc1e0433ff6a82d97e0f13c6f15c5b308d675b8c595ebe9830c96b2c98f3839b84491f4f04b37e9e0966faea09937ebe09667af619b3bc552f61e29711ccfcdc4998d61704f3faaa09d37a8e05337f6682993f9384717d8671d28f61c2a41f5dc1ac7f8384e9fe5830eb773161f2670dc1ec2f4f13a678f52298d7779d30ae4f5718b3fee99030cdaf04f3fa5cc2747f2498ede32461b28f92608e47321edbbb6e254ce379c13c5f3f61aa2f647cd61f9f672cf23e4a98ec47e86779dbbd8449de587f1827faecbb8c59ffecbd60bedf17ccfa564f98eeef31667d315b8299fe8b84697c2798e4a30f1226fdc90966fb9a12167db1ed84899e8960d697fd84495fb605b37fde4d98d63b12ccf6964f98ec2d7d9fe3cb59c214dfee188b3fab264ceb3b16ccf2b50993fc851ed627bd4898d63716cceb3f4c98ecf34830f3f33c61f27f8f8279fd3b8c25fe0c12a6f518c1b4defa3461badf11ccf9727a9efd455930e7478d84291ebe0be6f55e244cfc147a257ebd254cf3cf05b33f3b4b98ee3f09667ebe274cf9475f30e717c584e93eebbf677fa58e05f37ca58449be0dc15c4fa13ddbe46ffc4430f1df29c62c4feb1326fb1809e6fca693308db710ccf6789030c5a71a6396573817ccfe232798f35f9730e99bac87e5a39e13267d9a09e6f9ab09d3fab6184b3e712198e5514d98e81d0866fdbe4a98f4e55630d70b9384c93e9f088b7cec4dc2a40fcf8239be9513267afb82591ebb09d3fc5dc15c0fdc274cf4ee30667bf55782391e61fcb3deeded917edf3066fe865ec2743f2798edb59230cd772d787f1bf16dc216d77fc458fcef2261a2e75e30fbdb43c1ac9f7b09d37aba82f768bf8ae4e9855fae9430f9dbbe60e6d776c2147f2f05337daf0993fef27c9efda1b18239ff6a0966fd7b4f98d6eb190b7fd17fb85d170e905fe188b08ca72e05f37a860993bedf326679d4a75a69a3d5efbe6bab1d5cebef3fbbe8d9ccf557d781b250dffe725fb8e2cbeb00d737cd4a71eb2ff32464aef477bc677f22d36f92497cff16b904dd42fe662ffafbf74bfc2772f90e9e2439988f57f63ecb6a69376dedbe63fe6fb417a757ed407d90d167df779967be412e7f992719dff4996cf8fa60577f3b7bd9eca33ef29be4d45ab3af6f92cab7d98b179f559fc2a70e6a4e37da027eb6681378c5bfc37b37ce4deff8c4dfc95e94eec1baba280b79efc01c4fbacf36d1d503b82ce027f8348814216dddbf99bd3cc30a15ad0e71570fd10e228543fd827fa35547bf35826ba0c748d184a8fa5bd98b42ad899ae6d1b2e96f434d31e625ca0aa530d05378454a46ac8933d2b7ef92cb5fcec786b0e239fade177c714e86abb7ac631d58fd026818eb57944b9449179f7bfb2e5ff62d7269c18a5ab8a2b8ea77586f115e87f03ad2c7fa4497e03ad567f03ad717fa12fe7ea5cb2897397ab46ff265df622f735dc1f53ce92aacf210565cd3757dad6ff4adbed3f7fa4137e07ad08fbaa9737a4be7f5b6ded1bbf0dd77a067ef7f35be50ec96f8ed327f979831048dd9072a0e74016e28fda88cb2cae1e594cf5cf16f16ee06d5526dd5d147aa8bd633c071b373b8b555ace3dfb21798a105974ffe9572a8aeea69a39e541f3e0dd4b31aaa1735526358ed04d7ecd494df676a0e97c76b4951bc16ea555fab37f5ae8aea500fd5913ad6bd7af40e237502144eb453a54c5da4b2b9c56fd80bc66a758a3c136ac06ed5997e51e7f07ea12ed5952a832c2ab07aafaab0f21a5c73f89cbd3cbed3ab0674d5912aa047dfab6b75a36e61ed33f0e271960efa3c075aabd49dfe4a4ef1557b11b91035f4a4c1d870a5ee754d3de83bd56019444a1ee16ac24aa749361ea98cef39a4845ed524a32d9557604340cf15f839a00238a550fa1d9827238fbf682f3e632f74b540ee4a81f5aa5db5a7f6515f68e5f58c1cdc868b6473c0b4cc819aa62ac0522245c6c4ffdf186b1c7aeb18a7ba20abea4fedf957eca59fb90c7ad117bd301e2ce4c104584513d65480ff3679b5510659b988bd084573a48234112ed382ff16a27c4c5bdf980e8c3c80b9233506e4d2f92cf7fecdf8229ae5c1fbb6c0daabfac874f52de846e428ad26aeb09ef15bcbd52fed67796f96b19d1a3e7f007f07eb313df3a4774d1f5608be0566ec26ddf8495efd257b8916cf323103786f0325cf60eb16f95e4f3cf688a34ce6c96eaa19fba8a17ce691dd20078fa8c074d5f01dbd81199a17333231631b9a81996caa797ed35ec47f88ddb4f5a199ea06f2b7ce16d084753493ad08bfe76bafa52dcdf8bdc0eb772b76e654de1833839cc7821e543ef412c287f57ddd5e3af8fd9656660ee31fe96bb3483e09a831af448179636da921752ef9ae498a9ae01dcc3b0cb9a46f66ded3f78803e4a9c7a6680ed5c01c61be36446d33baa7fa7fd15e623c8959e00bdac9543fe0cc05d40db2802893a8f7c7a0f5d5f4576b4e4c4955c0a21be61424b98008e4e465ced86666186b2cda5a93e509583f9a73b09b0ba026ad247a6af4d6bf6f2f1db0bfa8e451bb9e99921c4ac59b4bd2fb2893a585030d01d67265caa662aaa6069eb66eaee1d38dce9b5b88250b96d3ccdcb1dd57d97eaa38ce0ca9bd370f10bfc65cd57563bc9118b3eedbbe6c2f2fe622d685a6611ec1e21dc77689e59ef9db645dafc01a9ae6d9e44047ee81b35b90332fe055d665d3006ee4cdb6d931bb660f640663997d8c3873b623d2bc038aa1face1ca84ba0c6a5573753ef848f72f999bd809540fe67c6a600c1d7a24c222dde2ab08418556aaa091a833aa5e03fd65a67bddeb7c1b66cbb3e351758c9c42aba873ce9ab5bdb3155db85fc6d413edbf630428907885a3781d1ac7db27dc859c758c175b026edacf7a27fc95ebc99db813eb7cf104f7c8aed31168a078655989259d8a17db1233bb690dfd8b6eeda295a2de5d301fb2f2dc403e38cb7333bb70b8cb61ec79de1b8758eb41e680129db5733b2548f8e309f7ecaf8ae95fedb57ec45c50cefd9bee1ac53f24b682739b217fb1ee7b5457b08741c45dbb2c7f569bc8083167522d4a75c41f771051e32ae437b624bf6d474ec993d477a482ef5943fd4316b58d80b5db6037b895569ac0f36f4e13eb117b782806e73a42e4c07f2aee82b27c94a3cdbc80429b9b265a037d88aad9a23886f437b8cba1d3b16432db943acef6325ed319ebfe8be3a01ddedd81ada8e63bbab27df1865ee6cdd5eeb2b1b50cf62b5bdb63eb19bacbde085392970f5065710b32f63dbf6d6de61e6b8cc5222d7c06ea24c40f3b6ed3dc49d05ca213b16d51d31cf7e025feae0d3dc3ec46aa13ee5ee6bd736ccd83e4234016ae0a1038e4d8e3d74f435d63675940a4818a59d1ddf6fb017d23b8ef178778833e7e0d3425dd92dcce76b1cd5a6999aa4a2ae6d5e455f35415e0f3ff898168cd243b94ce0d55103bb6d77ec2ef0b96ff7e089992eda7d7b80d167b692b771be600b40b882da2f44fdd5215e5a313756ec654d2e0e31d002fc9beba133ea5e95a13e89d1718e71708a7491079e386beaaa68636745adea70b2b73398fd06fe0b3ecc393373def45cd067e09f5ec9c3aa43d7726d18a994ea50d1308cbcf6dc75c01681578e7b6ff529cba5bfc15e967ae770fc1e7e07b206e0770da3ca947936656e45adb6aee79eec295684d421f2cc896c8f1fb20f5582bf4f5ddfe4dc007b010b5384eaa7ab5fcd857d80e7c6fadc3ddbb3186739cecc967251ce0ddd0b649bedfa34c517d6a13f970b522b18aa093742e94f52fd4eb92fe8b11bebbaedb07605f6bea2bfcbdc760e79c80b54f0b76ee2a61851a21731a66867ceb959e401e459afaea5eb6e8c5c9bb3ddd01575a1a25e6ccc36bba05fd9fd9bfea7f642f4ced07b7a908983ec2e0f114d6ac6097b9b98cd3bd08832483ea0a70afa0dac62c8fd61b7d6cf1feaa9eaaa5d37c78a07b2140714b957f7a6cf80db90ed458b5210c3dc3b663712ff4536e0715cd11d02e547988f59b615b936ca85fd4bbf4e7de10e3c7d8cdebf4039125a7d0db2afc8ab7d77e24a9015185809d59b5d8864129703d43a1419a3b4ae6025a75126e6dd9d012de7902958fde006e0c3c6ea10b40c9eb6bbeec2f4909a6ab219cf9e6dec2e21beb6d0fa891aaa799de4672bf145ecc5215fa3d779b7a74ae3c833b5eca550d7a1628d812801f16480eb35dc4319f058ad5883f298637de6aec04e809254db78d6b45b88ff25eca70757d627aec2fd03a973a4d6713aaf9ed5ce8a0f53eb72f910473ba8fd91f6a23e5731ebaaa5de8a64e5608d9076555d6d59f7896fc15a7daedfa25c30aa94ad737594ee2ce5f9527581a69aa2bbb6bb205f18c1dda837f43413c964f81df233b56f3b9019058cc24eabac5c32f6e256628cc34c307e2eba5b1c59b2f959e2a9354dc82027c8a5a5cfa2712287ef7485ec07e27accf31729bf2e485586b137f2bbe1eedd036827f0cf9e981964012798c32efb3971e65803d420cfab6204eb7e2e17d171de59205db4aea1ebe841973279441979a8fb9eadb76d57dbb00719fbcb6ff08a9ea06c46ee1129b1189fb836e14c32c60f882aaee9727680dcacea63b765dae899e7ecc3880b1efcf8237832ca5497e706d6ed45e4d2c2cfb1c3463a79e8de507b853f73aeb840c34c4eef6b6b8f5132ab7b906f6829b11b78a58fcd0b7af45449732e2c7950acdcdacebb3ce8738c155db76deadc1759e6169eba346ec78cd1b2b2f6dd5f938b9c4f21deb6317f0bb1dfa26f60d4a9f229bb8f72c9c1a8bb6e0fbc31ed3d9a9578425e00bc30d46e79b7c3da2575499573e13952073c77fb3aaf4b9003d09eda8b5ec0c89a39982a3ea86f7ccccb20da19b67ee911adc797a55c025acb13e87afc74e40e567af52417c88bc102ee5dc192e7cec679b29b2ec8f6ca4dd4b6a75535590acb6a8b2cda99606ecdcc34ec896ec7c8015135f6fab6d7e432a728e09519a99db59d34af3fb117b81cd6d74394cbb1becb7458a72c97b939f1062aa4367ccbe28e6ad259b4b70e585c19f2ae9d4889b7cc893a6b19ad0ef32c13bc53bb503d2bee21473f02551a58e916e7c9443dd16255de7b1b2be6e8cb643ebfa17e71593f06fcf130fe09772a66ab7251151fa08e076b513de45236fe3a3d76db6ee25bd16b002533b68dd57e7ff44b25df062dbc01bbf290cf4d584307ae01d592e1e82fcf92958e4ddd62ee9ff1639bea4a976229f9ee21c8e5047b7a32a678e48969aba12e9a0bb63ec87780a78677ec604ac856a6c8598b598fc4a41c5b402d5a8a3df71ddf059b8b73cf40effb3cce047cd519cc40f34e1217d17bdb7b4b3eac8d6b0d1fea1791c720c9867cc408c63c5dd55bf29240e10dcc083516e4b8f1bb3daa3fd1c38cad4bf1a4c97ce52e385102763cf73dffe4fbd6c72e2b6618919a58c9f8a8a160416db6fda5adc24b3720c2ecc78a2cee3669c5be73935c9856cedae3b98953d0319f6a71910bd062eae01da98e8f7ade5367aa046b993807d94a9dfb11d2eb9fb34ca2a6e648f7fdc03ffb2154d52dacf97a2897aeba437e2efc4b461fa48e454f01fab0bf2e97157b913c4ce412efcfa2de03171ed2484bb9007fa0a629933470155023c49d39756b6a7e04d98a8508a839ffc8fa2ea9150be065cfcd2de49b55f0b10fee0e2ae7125bcd087c1ae918d9a97468638c825a0a79a878adad757b497d40b297c05d4e17f516339855eb8fef0b53055a869c27807d41a93e55b76ad78f31efaa638ccfc17f0b240b5e158d95c34eba530d73eba3249dcd410c883b54313fef40d6b38d3a3a632d937c3946e83acbc57e622fe27f5cb2178be7572093d2cd157ba1cfb13779631aa0539427f8b8df672c545a735a037ad079eafdcf33cf4b4f7f869da910a95183a8a52ce5ae1e012d076e1f75f380b9d8241efa29d2a230eb77595b59938b4bb4aad8b7859834864a2ec7d5572ee3cbea31ff8648dd055aa29697f42cfa2edb454f1af763a8435e55d2bb8fcf7b257bcbe4639be8e3c6beed67fa1d32cbd8f5807c01e63df473ec95d7388f957cc1aa57bf203f96d9b3db54bf2ce5d283911d8c39d597fe1533d65477630c7e0769cf416633ac5c14f8b227338378829516f7ed675c7bc8cab3fb6213b5dc9d9840ce3f056acae89762ded086d85ec6fe127d676975d6d6a0d619a7b82f76bea9aeb4c98f7571cf6504b9658533a31af590e30c71af543f9a0e64b65849838694637a01df3bf0a45d13f663a4a1d10b8b9cbc92be175dd3989199b27f37635fc4a8d6f11eabfe264b257579210bac9811d475d9b3b59beb7d95b117dec5370d7fc815fa9c77e864d7c5e80258cc007939f347fe1869a69dbc3ad252672df7ecd10a5c8165f7cea4ba5c78a85b629f052365b47c9faa64e9ca38b5e54bd82757985d66fa79abf165ad37d68fbd4b90cec274cc3dcc55e5fdf819f7c8c0e7fa53fb0879ba43af5cf4d18b5ab770e7e47ba09aaf2baa4fd063f91ef277861ca11a556a22f2070bc843176029e7766421073497ac9753e482f717e8c56a2eeabecde8d1267bc9d6d0333c21721673567bea2f15755f97fb8f3eee50983d53852c30d23ef390139b629420dcc18cd8bcb32c3cf2f3c997d5183fcf9092b5fd7fcc3f17a6acdeec0c62ce38555fcd94c94d807f2d88ad7472216b2b7f2e173af91575b7afaf7c85b3f60c35d1fa4dc9767d15e25a0fabb743fbe8c76e1f4fee5074e1fa04f2d09aaffb6b778a6733ea6acedae3d2fe3ff9280bdfbcf1b7306a0f635153e5403a3945f5ce1434e1cef5d50eee1e28aeb33ef6c7a4672972910aab027173e04ed28e025123bbd94e8ddcb32d61efdee9577f6f67a608b907f5b7a4660cfed43f580f1cbd872c6dbc127165af9fb516e4d3f08fbe99bc9dec20e25826b8139f3373bf855c0f18fb47ebf125d593cb33c60ebf1d6bdd01d4eb45b665ca3eb0978275dec22eec29ea63ec09bd9a0664fa1df4159eec4437dc95c9c7fa13f2ae7d3f416a265ca72e7725a29c9b98a7d18eed257cbe54d48bcbb10c27ae683bd8513219b98c3ef493b3bde4e5157c5e57dc91dfc61e9d679b218ecfd4818d7ad68ef991df8138d7d3cf1eaa2afb087562097d53ec16c5ac660faac581df77c6397fe0db2b75aaf4bf3c7a851a72c82305cb1c90bc4705c6b5be907691e39a1dca65a3bd6cdaa385cf45df076bb460d51287a38c649f64df5c9b317ab3987fcf6c09a939053a4e2137385303b641f2a06575032a20fb46b27b2e14496e3157d96c36f62d9c3d33dbfa8af2dfd87f3383a0b006b61ffa637ff61ad911d4df9518f34c4bc9ee1b65215e356c0d328078926dae8e22352e6ada996bfa337d6a77b587ac2066bf3d7c3d417c3f058f07194230187bce56f270c9da9aca67fe6e4d2958882cf184739f7bfbcb9ee807b9fcc97ea573ce1442e464016879645bacb24638a8fddb66dbb5f448f56186b9ee061f426885b67a072f17f78efba1837add03aade4d2374d53558955dd1b666e6dd73dca12bd60f3d7762fa7a6873d807b52b7af32bfbfb56ed849eebe06e528deb7df169b4021b9e5c5b9feb29f66e8399eb4ee81bdac7a65346b1fa2d01277b71efc296628726c656eee8adcb6599937b1e7f003986d395a0300288bffd8dfd7d48f316eec53ee1e892472d3d74ecdb6d8567f71c86601d5d9b8b7d0fdc05838ad3de70b61ac20b5013772fe229bab25fb837f47805ecb77d944d73498b5761e4ca3617c6d80b5dd62ebfb1bf6f0620994998a6ae9d64f39c5721b925b0ce1b90cd15eebf2bac46e26cb1e3d3b20f61861d6a1f6bae1819c0aa0edd34cc39be6f7a516fd341fd59c55c89f60dfccafece87fae567fbfb71d7322cfc83bee13d2d393122d56f3c6b143b9063a804aafac46dc7332c51abc182700737bc207506e51269ecba6a780d6fe11d7de2267bf1d83b77a1180e5ddb35a422c8d84bf8757bb1c7e6c81e83648ec2b1ca533ce6bd07c731146b4d3c256155de55dca18995da3e584bcc32bafa055780792078b436bc16fa085638f5cd0d5e4c2ca5c99fc7e1c4e4819a57aca0973dcb0fbf79fada79fefad419b5e35c28b95e92cc9ce79af0994ad2711b4fe4d82664e707e61032971148097f07a3069081348c371ee27f379cbab18f63e592947dfaafc85cec06e26438d347317fc02cd1a6b812b01a345fb7173d08e71a7b4ce1c2bcd8ad14e99aa2d3c98e6a8c2aba0114695336cfe152efc433fd1025afd49e3f0b6588bc8bf48cf8c58f92c99c35376dd0de9cba05afd1036f223d23957ee7f4e5f8a2db76e26a16f2533bb00e1ea29caac95926adbea9e8ac6e15abcae86d21c241846fd873a0ab611670058c2a48059fa799731ebcecb5f81599905c22c716fe1434f72ae58bcbdfff855f892f404bc0bd6890ae19c77cd70d71451395faf56ad9095cefb92cdfe97301655a4b75e33473afce1ab62a971966070b3f3723dc7fa475498cd9b8bfffd97bb4563c41751cadc6fa5009d598a1a909cc5150cb7d78b9aadcb958e2033eed963d554a19249ddb5ada4a7d835ca0c28b72d60fa16643e63c8c59cd1fbf622fbea0abdac63d1c1bfbfa166c7864e2b9f7e52f0f64cf57e423a73f2406656a5296256a156ada261ff6e1cc39686bcccaeae17a997fadc8e78bf1054f3a44c9c41dbdaaaea8beb90837e600328106dacd2347cfa95a9e4f4ebb79c0d333aa4fb07eab738f46f6da72fc3dde6d0ac58ced64fb01b182e8855bc84d2799fdea5f8e2f7ecbcce17501686826e12edcfb7d888697e63a3c70cd99958bec98644fc4bb957bcb6e77532dbb802ec6f8d0c05f9dacf93188fd25736f20fbd0639685cbd8cb86f3639fdacbeac57b9aaeaa77adb317b68eddc0cc09a9150f2bbb0e2233cab267a95e21ff57c7ce8e3255d78645d1ce4d3afd0bf50664cae1112829c61c2fb3ae95fdeb2f9ee75f3bb31d3bd8e011c67637f4f5692887a69273e475ae1357f6053299bd74a57cc68791fe0cc248175dd5e4cd2e7640cf3cd1037edc28f3a48ff0345c2fed0f7df8bdf3577f2fb67275b1af3982ace215f4f730e440e01d88a10d96411dfbbf55dbb33d3cb79cdd89aae2abee2fc06e2698f954ec59d882faa4e1cab1ea750d7fe0e65177e33da2d31d87219eefefc73317ebb5ef2fc497e52b5b2fe0af0ce31948b8dad1b3854b370879888713deadcdca65dd57f1efc6ccc215a1a2ded6875069c53dd29843bfaa779373733c2361ddbeb977c7fa08aba1e5997197f55f59b9fc3c1f5bf5e37cde78807a06f117a24e0fdeafcca1effb921b28981f4f867ffcf51bfdf22dfef62def2fcd7968d98ebdc53a7e0895d638e0ef4d6d50b790cd9debfb28135d473b19f3391b857d9895dfa4ff4a7cf9c003fa55ee047f6535897591adaa1ee44a4520cb9b43db3135f3e876c2b65790378f3187092083b19faa575bd3795f32b53051b73ea776207ab958c105e5f331b7c21ed54e3c7b126a104f6ea3ef021c6532e49330ebbf25fc157bc9fc1b23743682cf823fc51e22f5055dd75cd8b63ab72d88a9f177ad0b33365e1f796fef21eba9411d5030757de01776663bfad06d836ec62a349e4119d4a7bc52ac47f1f30034f8125e033c011fcf1078f63a935f389fbc49266b1756c05ddd8ffa1b730acbfbfc985f809784881aebad98f18ce115a096d9078ddfc773f121ee52c15ab903c17b5c74ce93cf7ae289e22e563df48bc13ef646e3aed984bbf7abbeecebf165eddf7ff9d4c7595a199f5791735eddcc6f2357ff7d98ecef2557ffeed6f462e5b9cfd6f90bf6b27e65e20ef256f1ea48a387994ba8fbf09e7af6ab7b29ab7d96e59ccbb37c1bedf8977e8fbc41362bbd10e19d4bab240da2dfec679fcbc66b3997b9cc29f8df27d9a013cbded81afe727c59fa8a55b9acc6dde5bdd57f2bc1613f7ef0e1391977d9835cf65696673eb3e76c5c668c0d31e68bf9585897cd8a5c3ef9379236c5e71519b613ffc3fa3cebb12d53e367f1cab85f944b6b03ffb3325bb7a3d51c61f5dcdf92c724afd1da5c9ffd8e72b34c7eadde8fef2dfd718f66c913f99d325db28718dfe9372fd95f00f3fd956bdd6fd17cab72cdcc9be402df0b3be157ed6595a7eb79c0f2f7ca2ef1dcf1af76567fcfbc49861ffd53d66e3eca7e2927f85e50ab72f96a8efc2b79dbbace7ff5fe67f36db4a1aceffb7a7cf93ff1faa67f7fec6ff1feff4a2efffd6f7ffc0f54dd11fd</data> + </image> +</images> +<connections> + <connection> + <sender>okayButton</sender> + <signal>pressed()</signal> + <receiver>NewWidgetDlgBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>cancelButton</sender> + <signal>pressed()</signal> + <receiver>NewWidgetDlgBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>templateList</sender> + <signal>selectionChanged()</signal> + <receiver>NewWidgetDlgBase</receiver> + <slot>templateSelChanged()</slot> + </connection> + <connection> + <sender>subclassingCb</sender> + <signal>pressed()</signal> + <receiver>NewWidgetDlgBase</receiver> + <slot>subclassingPressed()</slot> + </connection> +</connections> +<tabstops> + <tabstop>templateList</tabstop> + <tabstop>subclassingCb</tabstop> + <tabstop>ui_classnameEd</tabstop> + <tabstop>captionEd</tabstop> + <tabstop>subclassnameEd</tabstop> + <tabstop>okayButton</tabstop> + <tabstop>cancelButton</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> + <include location="global" impldecl="in implementation">kpushbutton.h</include> +</includes> +<slots> + <slot>subclassingPressed()</slot> + <slot>templateSelChanged()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +</UI> diff --git a/buildtools/qmake/projectconfigurationdlg.cpp b/buildtools/qmake/projectconfigurationdlg.cpp new file mode 100644 index 00000000..b76fc3a5 --- /dev/null +++ b/buildtools/qmake/projectconfigurationdlg.cpp @@ -0,0 +1,2174 @@ +/*************************************************************************** +* Copyright (C) 2002 by Jakob Simon-Gaarde * +* jsgaarde@tdcspace.dk * +* Copyright (C) 2002-2003 by Alexander Dymo * +* cloudtemple@mksat.net * +* Copyright (C) 2003 by Thomas Hasart * +* thasart@gmx.de * +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 "projectconfigurationdlg.h" +#include <qradiobutton.h> +#include <qbuttongroup.h> +#include <qcheckbox.h> +#include <qmessagebox.h> +#include <kfiledialog.h> +#include <knotifyclient.h> +#include <klineedit.h> +#include <kinputdialog.h> +#include <kurlrequesterdlg.h> +#include <kurlrequester.h> +#include <kurlcompletion.h> +#include <kdebug.h> +#include <kiconloader.h> +#include <ktextedit.h> + +#include <qdialog.h> +#include <qpushbutton.h> +#include <qbuttongroup.h> +#include <qlistview.h> +#include <qlabel.h> +#include <iostream> +#include <qregexp.h> +#include <qvalidator.h> +#include <qtabwidget.h> +#include <kpushbutton.h> +#include <kcombobox.h> +#include <klocale.h> +#include <kmessagebox.h> + +#include "trollprojectwidget.h" +#include "trollprojectpart.h" +#include "qmakescopeitem.h" +#include "scope.h" +#include "urlutil.h" + +InsideCheckListItem::InsideCheckListItem( QListView *parent, QMakeScopeItem *item, ProjectConfigurationDlg *config ) : + QCheckListItem( parent, item->relativePath().endsWith("/") ? item->relativePath().right( item->relativePath().length() - 1 ) : item->relativePath(), QCheckListItem::CheckBox ) +{ + prjItem = item; + m_config = config; +} + +InsideCheckListItem::InsideCheckListItem( QListView *parent, QListViewItem *after, QMakeScopeItem *item, ProjectConfigurationDlg *config ) : + QCheckListItem( parent, + after, + item->relativePath(), QCheckListItem::CheckBox ) +{ + prjItem = item; + m_config = config; +} + +//check or uncheck dependency to currently checked or unchecked library +void InsideCheckListItem::stateChange( bool state ) +{ + if ( listView() == m_config->insidelib_listview ) + { + QListViewItemIterator it( m_config->intDeps_view ); + while ( it.current() ) + { + InsideCheckListItem * chi = dynamic_cast<InsideCheckListItem*>( it.current() ); + if ( chi ) + if ( chi->prjItem == prjItem ) + chi->setOn( state ); + ++it; + } + } +} + +CustomVarListItem::CustomVarListItem(QListView* parent, unsigned int id, QMap<QString, QString> var) + : KListViewItem(parent), m_key(id) +{ + setText(0, var["var"]); + setText(1, var["op"]); + setText(2, var["values"]); +} + +QString CustomVarListItem::key(int column, bool ascending) const +{ + if( column == 0) + return QString::number(m_key); + return KListViewItem::key(column, ascending); +} + +ProjectConfigurationDlg::ProjectConfigurationDlg( QListView *_prjList, TrollProjectWidget* _prjWidget, QWidget* parent, const char* name, bool modal, WFlags fl ) + : ProjectConfigurationDlgBase( parent, name, modal, fl | Qt::WStyle_Tool ), myProjectItem(0) +{ + prjList = _prjList; + prjWidget = _prjWidget; + // m_projectConfiguration = conf; + m_targetLibraryVersion->setValidator( new QRegExpValidator( + QRegExp( "\\d+(\\.\\d+)?(\\.\\d+)" ), this ) ); + customVariables->setSortColumn(0); + customVariables->setSortOrder(Qt::Ascending); + mocdir_url->completionObject()->setMode(KURLCompletion::DirCompletion); + mocdir_url->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + objdir_url->completionObject()->setMode(KURLCompletion::DirCompletion); + objdir_url->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + rccdir_url->completionObject()->setMode(KURLCompletion::DirCompletion); + rccdir_url->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + uidir_url->completionObject()->setMode(KURLCompletion::DirCompletion); + uidir_url->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + m_CWDEdit->completionObject()->setMode(KURLCompletion::DirCompletion); + m_CWDEdit->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + m_targetPath->completionObject()->setMode(KURLCompletion::DirCompletion); + m_targetPath->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); +} + +void ProjectConfigurationDlg::updateSubproject( QMakeScopeItem* _item ) +{ + if ( myProjectItem && myProjectItem->scope ) + { + switch ( prjWidget->dialogSaveBehaviour() ) + { + case TrollProjectWidget::AlwaysSave: + apply(); + break; + case TrollProjectWidget::NeverSave: + break; + case TrollProjectWidget::Ask: + if ( !buttonApply->isEnabled() ) + break; + if ( KMessageBox::questionYesNo( 0, i18n( "Save the current subproject's configuration?" ), + i18n( "Save Configuration?" ) ) == KMessageBox::Yes ) + apply(); + break; + } + } + myProjectItem = _item; + updateControls(); + buttonApply->setEnabled( false ); +} + +ProjectConfigurationDlg::~ProjectConfigurationDlg() +{} + +void ProjectConfigurationDlg::updateProjectConfiguration() +{ + // Template + if ( myProjectItem->scope->scopeType() == Scope::ProjectScope ) + { + if ( radioApplication->isChecked() ) + { + if( myProjectItem->scope->variableValues("TEMPLATE").findIndex("app") == -1 ) + { + addAppDeps(); + removeSharedLibDeps(); + removeStaticLibDeps(); + } + myProjectItem->scope->setEqualOp( "TEMPLATE", "app" ); + if( myProjectItem->scope->variableValues( "CONFIG" ).findIndex( "staticlib" ) != -1 ) + myProjectItem->scope->removeFromPlusOp( "CONFIG", "staticlib" ); + if( myProjectItem->scope->variableValues( "CONFIG" ).findIndex( "dll" ) != -1 ) + myProjectItem->scope->removeFromPlusOp( "CONFIG", "dll" ); + myProjectItem->setPixmap( 0, SmallIcon( "qmake_app" ) ); + QString targetname = prjWidget->getCurrentOutputFilename(); + if( targetname.findRev("/") != -1 ) + targetname = targetname.right( targetname.length() - targetname.findRev("/") - 1 ); + DomUtil::writeEntry( *prjWidget->m_part->projectDom(), + "/kdevtrollproject/run/runarguments/"+targetname, m_editRunArguments->text() ); + DomUtil::writeEntry( *prjWidget->m_part->projectDom(), + "/kdevtrollproject/run/cwd/"+targetname, m_CWDEdit->url() ); + DomUtil::writeEntry( *prjWidget->m_part->projectDom(), + "/kdevtrollproject/run/debugarguments/"+targetname, m_editDebugArguments->text() ); + + } + else if ( radioLibrary->isChecked() ) + { + myProjectItem->scope->setEqualOp( "TEMPLATE", "lib" ); + if ( staticRadio->isOn() ) + { + if( myProjectItem->scope->variableValues("CONFIG").findIndex("dll") != -1 ) + { + addStaticLibDeps(); + removeSharedLibDeps(); + } + myProjectItem->addValue( "CONFIG", "staticlib" ); + myProjectItem->removeValue( "CONFIG", "dll" ); + if ( !myProjectItem->scope->listIsEmpty( myProjectItem->scope->variableValues( "VERSION" ) ) ) + { + myProjectItem->scope->removeVariable( "VERSION", "=" ); + myProjectItem->scope->removeVariable( "VERSION", "+=" ); + myProjectItem->scope->removeVariable( "VERSION", "-=" ); + } + } + if ( sharedRadio->isOn() ) + { + kdDebug(9024) << "Activating debug lib:" << myProjectItem->scope->variableValues("CONFIG") << endl; + if( myProjectItem->scope->variableValues("CONFIG").findIndex("dll") == -1 ) + { + addSharedLibDeps(); + removeStaticLibDeps(); + } + myProjectItem->addValue( "CONFIG", "dll" ); + myProjectItem->scope->setEqualOp( "VERSION", m_targetLibraryVersion->text() ); + if ( myProjectItem->scope->variableValues( "CONFIG" ).findIndex( "staticlib" ) != -1 ) + myProjectItem->removeValue( "CONFIG", "staticlib" ); + } + if ( checkPlugin->isOn() ) + myProjectItem->addValue( "CONFIG", "plugin" ); + else + myProjectItem->removeValue( "CONFIG", "plugin" ); + if ( checkDesigner->isChecked() ) + myProjectItem->addValue( "CONFIG", "designer" ); + else + myProjectItem->removeValue( "CONFIG", "designer" ); + + myProjectItem->setPixmap( 0, SmallIcon( "qmake_lib" ) ); + removeAppDeps(); + } + else if ( radioSubdirs->isChecked() ) + { + if( myProjectItem->scope->variableValues("TEMPLATE").findIndex("subdirs") == -1 ) + { + removeSharedLibDeps(); + removeStaticLibDeps(); + removeAppDeps(); + } + if( myProjectItem->scope->variableValues( "CONFIG" ).findIndex( "dll" ) != -1 ) + myProjectItem->scope->removeFromPlusOp( "CONFIG", "dll" ); + if( myProjectItem->scope->variableValues( "CONFIG" ).findIndex( "staticlib" ) != -1 ) + myProjectItem->scope->removeFromPlusOp( "CONFIG", "staticlib" ); + myProjectItem->scope->setEqualOp( "TEMPLATE", "subdirs" ); + myProjectItem->setPixmap( 0, SmallIcon( "folder" ) ); + } + } + + // Buildmode + int releaseidx = myProjectItem->scope->variableValues( "CONFIG" ).findIndex( "release" ); + int debugidx = myProjectItem->scope->variableValues( "CONFIG" ).findIndex( "debug" ); + if ( radioReleaseMode->isChecked() ) + { + if( releaseidx != -1 && releaseidx < debugidx ) + myProjectItem->removeValue( "CONFIG", "debug" ); + else if( debugidx != -1 ) + myProjectItem->removeValue( "CONFIG", "debug" ); + myProjectItem->addValue( "CONFIG", "release" ); + }else if( !checkDebugReleaseMode->isChecked() ) + myProjectItem->removeValue( "CONFIG", "release" ); + + if ( radioDebugMode->isChecked() ) + { + if( debugidx != -1 && debugidx < releaseidx ) + myProjectItem->removeValue( "CONFIG", "release" ); + else if( releaseidx != -1 ) + myProjectItem->removeValue( "CONFIG", "release" ); + myProjectItem->addValue( "CONFIG", "debug" ); + }else if( !checkDebugReleaseMode->isChecked() ) + myProjectItem->removeValue( "CONFIG", "debug" ); + + // requirements + if ( exceptionCheck->isChecked() ) + myProjectItem->addValue( "CONFIG", "exceptions" ); + else + myProjectItem->removeValue( "CONFIG", "exceptions" ); + if ( stlCheck->isChecked() ) + myProjectItem->addValue( "CONFIG", "stl" ); + else + myProjectItem->removeValue( "CONFIG", "stl" ); + if ( rttiCheck->isChecked() ) + myProjectItem->addValue( "CONFIG", "rtti" ); + else + myProjectItem->removeValue( "CONFIG", "rtti" ); + if ( checkQt->isChecked() ) + myProjectItem->addValue( "CONFIG", "qt" ); + else + myProjectItem->removeValue( "CONFIG", "qt" ); + if ( checkOpenGL->isChecked() ) + myProjectItem->addValue( "CONFIG", "opengl" ); + else + myProjectItem->removeValue( "CONFIG", "opengl" ); + if ( checkThread->isChecked() ) + myProjectItem->addValue( "CONFIG", "thread" ); + else + myProjectItem->removeValue( "CONFIG", "thread" ); + if ( checkX11->isChecked() ) + myProjectItem->addValue( "CONFIG", "x11" ); + else + myProjectItem->removeValue( "CONFIG", "x11" ); + if ( checkOrdered->isChecked() ) + myProjectItem->addValue( "CONFIG", "ordered" ); + else + myProjectItem->removeValue( "CONFIG", "ordered" ); + if ( checkLibtool->isChecked() ) + myProjectItem->addValue( "CONFIG", "compile_libtool" ); + else + myProjectItem->removeValue( "CONFIG", "compile_libtool" ); + + if ( checkConsole->isChecked() ) + myProjectItem->addValue( "CONFIG", "console" ); + else + myProjectItem->removeValue( "CONFIG", "console" ); + if ( checkPCH->isChecked() ) + myProjectItem->addValue( "CONFIG", "precompile_header" ); + else + myProjectItem->removeValue( "CONFIG", "precompile_header" ); + // Warnings + if ( checkWarning->isChecked() ) + { + myProjectItem->addValue( "CONFIG", "warn_on" ); + myProjectItem->removeValue( "CONFIG", "warn_off" ); + } + else + { + myProjectItem->addValue( "CONFIG", "warn_off" ); + myProjectItem->removeValue( "CONFIG", "warn_on" ); + } + if ( checkWindows->isChecked() ) + myProjectItem->addValue( "CONFIG", "windows" ); + else + myProjectItem->removeValue( "CONFIG", "windows" ); + + //Qt4 libs + if ( prjWidget->m_part->isQt4Project() ) + { + if ( checkDebugReleaseMode->isChecked() ) + myProjectItem->addValue( "CONFIG", "debug_and_release" ); + else + myProjectItem->removeValue( "CONFIG", "debug_and_release" ); + + if ( checkTestlib->isChecked() ) + myProjectItem->addValue( "CONFIG", "qtestlib" ); + else + myProjectItem->removeValue( "CONFIG", "qtestlib" ); + if ( checkAssistant->isChecked() ) + myProjectItem->addValue( "CONFIG", "assistant" ); + else + myProjectItem->removeValue( "CONFIG", "assistant" ); + if ( checkUiTools->isChecked() ) + myProjectItem->addValue( "CONFIG", "uitools" ); + else + myProjectItem->removeValue( "CONFIG", "uitools" ); + if ( checkQDBus->isChecked() ) + myProjectItem->addValue( "CONFIG", "dbus" ); + else + myProjectItem->removeValue( "CONFIG", "dbus" ); + if ( checkBuildAll->isChecked() ) + myProjectItem->addValue( "CONFIG", "build_all" ); + else + myProjectItem->removeValue( "CONFIG", "build_all" ); + if ( checkQtHelp->isChecked() ) + myProjectItem->addValue( "CONFIG", "help" ); + else + myProjectItem->removeValue( "CONFIG", "help" ); + + if ( checkQt4Core->isChecked() ) + myProjectItem->addValue( "QT", "core" ); + else + myProjectItem->removeValue( "QT", "core" ); + if ( checkQt4Gui->isChecked() ) + myProjectItem->addValue( "QT", "gui" ); + else + myProjectItem->removeValue( "QT", "gui" ); + if ( checkQt4SQL->isChecked() ) + myProjectItem->addValue( "QT", "sql" ); + else + myProjectItem->removeValue( "QT", "sql" ); + if ( checkQt4SVG->isChecked() ) + myProjectItem->addValue( "QT", "svg" ); + else + myProjectItem->removeValue( "QT", "svg" ); + if ( checkQt4XML->isChecked() ) + myProjectItem->addValue( "QT", "xml" ); + else + myProjectItem->removeValue( "QT", "xml" ); + if ( checkQt4Network->isChecked() ) + myProjectItem->addValue( "QT", "network" ); + else + myProjectItem->removeValue( "QT", "network" ); + if ( checkQt3Support->isChecked() ) + myProjectItem->addValue( "QT", "qt3support" ); + else + myProjectItem->removeValue( "QT", "qt3support" ); + if ( checkQt4OpenGL->isChecked() ) + myProjectItem->addValue( "QT", "opengl" ); + else + myProjectItem->removeValue( "QT", "opengl" ); + if ( checkQtScript->isChecked() ) + myProjectItem->addValue( "QT", "script" ); + else + myProjectItem->removeValue( "QT", "script" ); + if ( checkQtWebKit->isChecked() ) + myProjectItem->addValue( "QT", "webkit" ); + else + myProjectItem->removeValue( "QT", "webkit" ); + if ( checkQtXmlPatterns->isChecked() ) + myProjectItem->addValue( "QT", "xmlpatterns" ); + else + myProjectItem->removeValue( "QT", "xmlpatterns" ); + if ( checkPhonon->isChecked() ) + myProjectItem->addValue( "QT", "phonon" ); + else + myProjectItem->removeValue( "QT", "phonon" ); + } + + QStringList confValues = myProjectItem->scope->variableValues( "CONFIG" ); + QStringList extraValues = QStringList::split( " ", editConfigExtra->text() ); + for ( QStringList::iterator it = confValues.begin() ; it != confValues.end() ; ++it ) + { + if ( Scope::KnownConfigValues.findIndex( *it ) == -1 && extraValues.findIndex( *it ) == -1 ) + { + myProjectItem->scope->removeFromPlusOp( "CONFIG", *it ); + } + } + + for ( QStringList::iterator it = extraValues.begin() ; it != extraValues.end() ; ++it ) + { + if ( confValues.findIndex( *it ) == -1 ) + myProjectItem->scope->addToPlusOp( "CONFIG", *it ); + } + + QString targetpath = m_targetPath->url(); +// if( !QFileInfo( targetpath ).isRelative() ) +// targetpath = URLUtil::getRelativePath( myProjectItem->scope->projectDir(), targetpath ); + if( myProjectItem->scope->scopeType() == Scope::FunctionScope || myProjectItem->scope->scopeType() == Scope::SimpleScope ) + { + if( myProjectItem->scope->variableValues("TARGET").findIndex( m_targetOutputFile->text() ) == -1 ) + myProjectItem->scope->setEqualOp( "TARGET", QStringList( m_targetOutputFile->text() ) ); + if( myProjectItem->scope->variableValues("DESTDIR").findIndex( targetpath ) == -1 ) + myProjectItem->scope->setEqualOp( "DESTDIR", QStringList( targetpath ) ); + }else + { + myProjectItem->scope->setEqualOp( "TARGET", QStringList( m_targetOutputFile->text() ) ); + myProjectItem->scope->setEqualOp( "DESTDIR", QStringList( targetpath ) ); + } + + myProjectItem->updateValues( "DEFINES", QStringList::split( " ", m_defines->text() ) ); + myProjectItem->updateValues( "QMAKE_CXXFLAGS_DEBUG", QStringList::split( " ", m_debugFlags->text() ) ); + myProjectItem->updateValues( "QMAKE_CXXFLAGS_RELEASE", QStringList::split( " ", m_releaseFlags->text() ) ); + + //add selected includes + QStringList values; + InsideCheckListItem *insideItem = ( InsideCheckListItem * ) insideinc_listview->firstChild(); + while ( insideItem ) + { + if ( insideItem->isOn() ) + { + QString tmpInc = insideItem->prjItem->getIncAddPath( myProjectItem->scope->projectDir() ); + tmpInc = QDir::cleanDirPath( tmpInc ); + values << tmpInc; + + } + insideItem = ( InsideCheckListItem* ) insideItem->itemBelow(); + } + + QCheckListItem *outsideItem = ( QCheckListItem * ) outsideinc_listview->firstChild(); + while ( outsideItem ) + { + values << outsideItem->text( 0 ); + outsideItem = ( QCheckListItem* ) outsideItem->itemBelow(); + } +// myProjectItem->removeValues( "INCLUDEPATH", values ); + myProjectItem->updateValues( "INCLUDEPATH", values ); + + //target.install + if ( checkInstallTarget->isChecked() == true ) + { + myProjectItem->addValue( "INSTALLS", "target" ); + myProjectItem->scope->setEqualOp( "target.path", QStringList( m_InstallTargetPath->text() ) ); + } + else + { + myProjectItem->removeValue( "INSTALLS", "target" ); + myProjectItem->scope->removeVariable( "target.path", "=" ); + } + + //makefile + myProjectItem->scope->setEqualOp( "MAKEFILE", QStringList( makefile_url->url() ) ); + + //add libs to link + + values.clear(); + QStringList libPaths; + + //inside libs to link + insideItem = ( InsideCheckListItem * ) insidelib_listview->firstChild(); + while ( insideItem ) + { + if ( insideItem->isOn() ) + { + + QString tmpLib = insideItem->prjItem->getLibAddObject( myProjectItem->scope->projectDir() ); + if ( insideItem->prjItem->scope->variableValues( "CONFIG" ).findIndex( "dll" ) != -1 ) + { + //add path if shared lib is linked + QString tmpPath = insideItem->prjItem->getLibAddPath( + myProjectItem->scope->projectDir() ); + if ( tmpPath != "" ) + { + values << ("-L"+tmpPath) ; + } + } + values << tmpLib ; + + } + insideItem = ( InsideCheckListItem* ) insideItem->itemBelow(); + } + + //extra lib paths + QListViewItem *lvItem = outsidelibdir_listview->firstChild(); + while ( lvItem ) + { + values << ( "-L"+lvItem->text( 0 ) ); + lvItem = lvItem->itemBelow(); + } + + + //outside libs to link + outsideItem = ( QCheckListItem * ) outsidelib_listview->firstChild(); + while ( outsideItem ) + { + values << outsideItem->text( 0 ); + outsideItem = ( QCheckListItem* ) outsideItem->itemBelow(); + } + + +// myProjectItem->removeValues( "LIBS", values ); + myProjectItem->updateValues( "LIBS", values ); + + values.clear(); + + //external project dependencies + QListViewItem *depItem = extDeps_view->firstChild(); + while ( depItem ) + { + values << depItem->text( 0 ); + depItem = depItem->itemBelow(); + } + + //internal project dependencies + insideItem = dynamic_cast<InsideCheckListItem *>( intDeps_view->firstChild() ); + while ( insideItem ) + { + if ( insideItem->isOn() ) + { + if ( insideItem->prjItem->scope->variableValues( "CONFIG" ).findIndex( "staticlib" ) != -1 + || ( insideItem->prjItem->scope->variableValues( "CONFIG" ).findIndex("dll") == -1 + && insideItem->prjItem->scope->variableValues( "TEMPLATE" ).findIndex("lib") != -1 ) ) + { + values << insideItem->prjItem->getLibAddObject( + myProjectItem->scope->projectDir() ); + } + else if ( insideItem->prjItem->scope->variableValues( "CONFIG" ).findIndex( "dll" ) != -1 ) + { + values << insideItem->prjItem->getSharedLibAddObject( + myProjectItem->scope->projectDir() ); + } + else + { + values << insideItem->prjItem->getApplicationObject( + myProjectItem->scope->projectDir() ); + } + } + insideItem = dynamic_cast<InsideCheckListItem *>( insideItem->itemBelow() ); + } +// myProjectItem->removeValues( "TARGETDEPS", values ); + myProjectItem->updateValues( "TARGETDEPS", values ); + + values.clear(); + //change build order + lvItem = buildorder_listview->firstChild(); + if ( lvItem && lvItem->itemBelow() && myProjectItem->scope->variableValues("TEMPLATE").findIndex("subdirs") != -1 ) + { + + while ( lvItem ) + { + values << lvItem->text( 0 ); + lvItem = lvItem->itemBelow(); + } + + if( values != myProjectItem->scope->variableValues("SUBDIRS") ) + { + if ( myProjectItem->scope->isVariableReset( "SUBDIRS" ) ) + { + myProjectItem->scope->removeVariable( "SUBDIRS", "=" ); + myProjectItem->scope->setEqualOp( "SUBDIRS", values ); + } + else + { + myProjectItem->scope->removeVariable( "SUBDIRS", "+=" ); + myProjectItem->scope->setPlusOp( "SUBDIRS", values ); + } + } + } + + // intermediate locations + myProjectItem->scope->setEqualOp( "OBJECTS_DIR", QStringList( objdir_url->url() ) ); + myProjectItem->scope->setEqualOp( "UI_DIR", QStringList( uidir_url->url() ) ); + myProjectItem->scope->setEqualOp( "MOC_DIR", QStringList( mocdir_url->url() ) ); + myProjectItem->scope->setEqualOp( "RCC_DIR", QStringList( rccdir_url->url() ) ); + + //CORBA + myProjectItem->scope->setEqualOp( "IDL_COMPILER", QStringList( idlCmdEdit->url() ) ); + myProjectItem->updateValues( "IDL_OPTIONS", QStringList::split( " ", idlCmdOptionsEdit->text() ) ); + + QListViewItemIterator iter(customVariables); + for( ; iter.current() ; iter++ ) + { + QListViewItem* item = iter.current(); + myProjectItem->scope->updateCustomVariable( item->key(0, true).toUInt(), item->text(0), item->text(1), item->text(2) ); + } +} + +void ProjectConfigurationDlg::accept() +{ + if( buttonApply->isEnabled() ) + apply(); + myProjectItem = 0; + QDialog::accept(); +} + +void ProjectConfigurationDlg::reject() +{ + myProjectItem = 0; + QDialog::reject(); +} + + + +void ProjectConfigurationDlg::updateControls() +{ + // Project template + groupLibraries->setEnabled( false ); + if( myProjectItem->scope->scopeType() != Scope::ProjectScope ) + groupTemplate->setEnabled( false ); + else + groupTemplate->setEnabled( true ); + + //cache the value of the some variables + QStringList configValues = myProjectItem->scope->variableValues( "CONFIG" ); + QStringList templateValues = myProjectItem->scope->variableValues( "TEMPLATE" ); + //if( !myProjectItem->isScope ) + //{ + if ( templateValues.findIndex( "lib" ) != -1 ) + { + groupLibraries->setEnabled( true ); + + radioLibrary->setChecked( true ); + staticRadio->setChecked( true ); //default + + if ( configValues.findIndex( "staticlib" ) != -1 ) + { + staticRadio->setChecked( true ); + checkPlugin->setEnabled( false ); + checkDesigner->setEnabled( false ); + } + else + staticRadio->setChecked( false ); + if ( configValues.findIndex( "dll" ) != -1 ) + { + sharedRadio->setChecked( true ); + checkPlugin->setEnabled( true ); + if( prjWidget->m_part->isQt4Project() ) + checkDesigner->setEnabled( true ); + m_targetLibraryVersion->setText( myProjectItem->scope->variableValues( "VERSION" ).front() ); + } + else + { + sharedRadio->setChecked( false ); + m_targetLibraryVersion->setText( "" ); + } + + if( !staticRadio->isChecked() && !sharedRadio->isChecked() ) + { + staticRadio->setChecked( true ); + checkPlugin->setEnabled( false ); + checkDesigner->setEnabled( false ); + } + + if ( configValues.findIndex( "plugin" ) != -1 ) + checkPlugin->setChecked( true ); + else + checkPlugin->setChecked( false ); + if ( configValues.findIndex( "designer" ) != -1 ) + checkDesigner->setChecked( true ); + else + checkDesigner->setChecked( false ); + if ( configValues.findIndex( "compile_libtool" ) != -1 ) + checkLibtool->setChecked( true ); + else + checkLibtool->setChecked( false ); + } + else if ( templateValues.findIndex( "subdirs" ) != -1 ) + { + radioSubdirs->setChecked( true ); + }else + { + //Default is app mode + radioApplication->setChecked( true ); + if ( configValues.findIndex( "console" ) != -1 ) + { + checkConsole->setChecked( true ); + } + QString targetname = prjWidget->getCurrentOutputFilename(); + if( targetname.findRev("/") != -1 ) + targetname = targetname.right( targetname.length() - targetname.findRev("/") - 1 ); + m_editRunArguments->setText( DomUtil::readEntry( *prjWidget->m_part->projectDom(), "/kdevtrollproject/run/runarguments/"+targetname, "" ) ); + + QString dir = DomUtil::readEntry( *prjWidget->m_part->projectDom(), "/kdevtrollproject/run/cwd/"+targetname, "" ); + if( QFileInfo(dir).isRelative() ) + { + m_CWDEdit->completionObject()->setDir( myProjectItem->scope->projectDir() ); + m_CWDEdit->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + + m_CWDEdit->completionObject()->setDir( dir); + m_CWDEdit->fileDialog()->setURL( KURL( dir ) ); + } + m_CWDEdit->setURL( dir ); + + if( m_CWDEdit->url().isEmpty() ) + { + QString destdir = myProjectItem->m_widget->getCurrentDestDir(); + if( !destdir.startsWith( "/" ) ) + destdir = myProjectItem->m_widget->projectDirectory()+"/"+destdir; + m_CWDEdit->setURL( destdir.left( destdir.findRev("/") ) ); + m_CWDEdit->fileDialog()->setURL( KURL::fromPathOrURL( destdir.left( destdir.findRev("/") ) ) ); + } + m_editDebugArguments->setText( DomUtil::readEntry( *prjWidget->m_part->projectDom(), "/kdevtrollproject/run/debugarguments/"+targetname, "" ) ); + } + + // Buildmode + int debugidx = configValues.findIndex( "debug" ); + int releaseidx = configValues.findIndex( "release" ); + if ( debugidx != -1 && debugidx > releaseidx ) + { + radioDebugMode->setChecked( true ); + } + if ( releaseidx != -1 && releaseidx > debugidx ) + { + radioReleaseMode->setChecked( true ); + } + if ( configValues.findIndex( "debug_and_release" ) != -1 ) + { + checkDebugReleaseMode->setChecked( true ); + } + + // Requirements + if ( configValues.findIndex( "qt" ) != -1 ) + checkQt->setChecked( true ); + else + checkQt->setChecked( false ); + if ( configValues.findIndex( "opengl" ) != -1 ) + checkOpenGL->setChecked( true ); + else + checkOpenGL->setChecked( false ); + if ( configValues.findIndex( "thread" ) != -1 ) + checkThread->setChecked( true ); + else + checkThread->setChecked( false ); + if ( configValues.findIndex( "x11" ) != -1 ) + checkX11->setChecked( true ); + else + checkX11->setChecked( false ); + if ( configValues.findIndex( "ordered" ) != -1 ) + checkOrdered->setChecked( true ); + else + checkOrdered->setChecked( false ); + if ( configValues.findIndex( "exceptions" ) != -1 ) + exceptionCheck->setChecked( true ); + else + exceptionCheck->setChecked( false ); + if ( configValues.findIndex( "stl" ) != -1 ) + stlCheck->setChecked( true ); + else + stlCheck->setChecked( false ); + if ( configValues.findIndex( "rtti" ) != -1 ) + rttiCheck->setChecked( true ); + else + rttiCheck->setChecked( false ); + if ( configValues.findIndex( "precompile_header" ) != -1 ) + checkPCH->setChecked( true ); + else + checkPCH->setChecked( false ); + // Warnings + if ( configValues.findIndex( "warn_on" ) != -1 ) + { + checkWarning->setChecked( true ); + } + if ( configValues.findIndex( "warn_off" ) != -1 ) + { + checkWarning->setChecked( false ); + } + + if ( configValues.findIndex( "windows" ) != -1 ) + checkWindows->setChecked( true ); + else + checkWindows->setChecked( false ); + + //Qt4 libs + if ( prjWidget->m_part->isQt4Project() ) + { + + if ( configValues.findIndex( "assistant" ) != -1 ) + checkAssistant->setChecked( true ); + else + checkAssistant->setChecked( false ); + if ( configValues.findIndex( "qtestlib" ) != -1 ) + checkTestlib->setChecked( true ); + else + checkTestlib->setChecked( false ); + if ( configValues.findIndex( "uitools" ) != -1 ) + checkUiTools->setChecked( true ); + else + checkUiTools->setChecked( false ); + if ( configValues.findIndex( "dbus" ) != -1 ) + checkQDBus->setChecked( true ); + else + checkQDBus->setChecked( false ); + if ( configValues.findIndex( "build_all" ) != -1 ) + checkBuildAll->setChecked( true ); + else + checkBuildAll->setChecked( false ); + if ( configValues.findIndex( "help" ) != -1 ) + checkQtHelp->setChecked( true ); + else + checkQtHelp->setChecked( false ); + + QStringList qtLibs = myProjectItem->scope->variableValues( "QT" ); + if ( qtLibs.findIndex( "core" ) != -1 ) + checkQt4Core->setChecked( true ); + else + checkQt4Core->setChecked( false ); + if ( qtLibs.findIndex( "gui" ) != -1 ) + checkQt4Gui->setChecked( true ); + else + checkQt4Gui->setChecked( false ); + if ( qtLibs.findIndex( "sql" ) != -1 ) + checkQt4SQL->setChecked( true ); + else + checkQt4SQL->setChecked( false ); + if ( qtLibs.findIndex( "xml" ) != -1 ) + checkQt4XML->setChecked( true ); + else + checkQt4XML->setChecked( false ); + if ( qtLibs.findIndex( "network" ) != -1 ) + checkQt4Network->setChecked( true ); + else + checkQt4Network->setChecked( false ); + if ( qtLibs.findIndex( "svg" ) != -1 ) + checkQt4SVG->setChecked( true ); + else + checkQt4SVG->setChecked( false ); + if ( qtLibs.findIndex( "opengl" ) != -1 ) + checkQt4OpenGL->setChecked( true ); + else + checkQt4OpenGL->setChecked( false ); + if ( qtLibs.findIndex( "qt3support" ) != -1 ) + checkQt3Support->setChecked( true ); + else + checkQt3Support->setChecked( false ); + if ( qtLibs.findIndex( "script" ) != -1 ) + checkQtScript->setChecked( true ); + else + checkQtScript->setChecked( false ); + if ( qtLibs.findIndex( "phonon" ) != -1 ) + checkPhonon->setChecked( true ); + else + checkPhonon->setChecked( false ); + if ( qtLibs.findIndex( "webkit" ) != -1 ) + checkQtWebKit->setChecked( true ); + else + checkQtWebKit->setChecked( false ); + if ( qtLibs.findIndex( "xmlpatterns" ) != -1 ) + checkQtXmlPatterns->setChecked( true ); + else + checkQtXmlPatterns->setChecked( false ); + + checkDebugReleaseMode->setEnabled( true ); + checkBuildAll->setEnabled( true ); + groupQt4Libs->setEnabled( checkQt->isChecked() ); + rccdir_url->setEnabled( true ); + rccdir_label->setEnabled( true ); + } + + //fill the custom config edit + QStringList extraValues; + for ( QStringList::const_iterator it = configValues.begin() ; it != configValues.end() ; ++it ) + { + if ( Scope::KnownConfigValues.findIndex( *it ) == -1 ) + { + extraValues << *it; + } + } + editConfigExtra->setText( extraValues.join( " " ) ); + + QString dir = myProjectItem->scope->variableValues( "MAKEFILE" ).front(); + if( QFileInfo(dir).isRelative() ) + { + makefile_url->completionObject()->setDir( myProjectItem->scope->projectDir() ); + makefile_url->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + makefile_url->completionObject()->setDir( dir ); + makefile_url->fileDialog()->setURL( KURL( dir ) ); + } + makefile_url->setURL( dir ); + + if ( myProjectItem->scope->variableValues( "INSTALLS" ).findIndex( "target" ) != -1 ) + { + checkInstallTarget->setChecked( true ); + m_InstallTargetPath->setEnabled( true ); + } + else + { + checkInstallTarget->setChecked( false ); + m_InstallTargetPath->setEnabled( false ); + } + m_InstallTargetPath->setText( myProjectItem->scope->variableValues( "target.path" ).front() ); + + m_targetOutputFile->setText( myProjectItem->scope->variableValues( "TARGET" ).front() ); + + dir = myProjectItem->scope->variableValues( "DESTDIR" ).front(); + if( QFileInfo(dir).isRelative() ) + { + m_targetPath->completionObject()->setDir( myProjectItem->scope->projectDir() ); + m_targetPath->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + m_targetPath->completionObject()->setDir( dir ); + m_targetPath->fileDialog()->setURL( KURL( dir ) ); + } + m_targetPath->setURL( dir ); + + m_defines->setText( myProjectItem->scope->variableValues( "DEFINES" ).join( " " ) ); + m_debugFlags->setText( myProjectItem->scope->variableValues( "QMAKE_CXXFLAGS_DEBUG" ).join( " " ) ); + m_releaseFlags->setText( myProjectItem->scope->variableValues( "QMAKE_CXXFLAGS_RELEASE" ).join( " " ) ); + + updateIncludeControl(); + updateLibControls(); + updateBuildOrderControl(); + updateDependenciesControl(); + + dir = myProjectItem->scope->variableValues( "OBJECTS_DIR" ).front(); + if( QFileInfo(dir).isRelative() ) + { + objdir_url->completionObject()->setDir( myProjectItem->scope->projectDir() ); + objdir_url->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + objdir_url->completionObject()->setDir( dir ); + objdir_url->fileDialog()->setURL( KURL( dir ) ); + } + objdir_url->setURL( dir ); + dir = myProjectItem->scope->variableValues( "UI_DIR" ).front(); + if( QFileInfo(dir).isRelative() ) + { + uidir_url->completionObject()->setDir( myProjectItem->scope->projectDir() ); + uidir_url->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + uidir_url->completionObject()->setDir( dir ); + uidir_url->fileDialog()->setURL( KURL( dir ) ); + } + uidir_url->setURL( dir ); + dir = myProjectItem->scope->variableValues( "MOC_DIR" ).front(); + if( QFileInfo(dir).isRelative() ) + { + mocdir_url->completionObject()->setDir( myProjectItem->scope->projectDir() ); + mocdir_url->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + mocdir_url->completionObject()->setDir( dir ); + mocdir_url->fileDialog()->setURL( KURL( dir ) ); + } + mocdir_url->setURL( dir ); + dir = myProjectItem->scope->variableValues( "RC_DIR" ).front(); + if( QFileInfo(dir).isRelative() ) + { + rccdir_url->completionObject()->setDir( myProjectItem->scope->projectDir() ); + rccdir_url->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + rccdir_url->completionObject()->setDir( dir ); + rccdir_url->fileDialog()->setURL( KURL( dir ) ); + } + rccdir_url->setURL( dir ); + + + dir = myProjectItem->scope->variableValues( "IDL_COMPILER" ).front(); + if( QFileInfo(dir).isRelative() ) + { + idlCmdEdit->completionObject()->setDir( myProjectItem->scope->projectDir() ); + idlCmdEdit->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + idlCmdEdit->completionObject()->setDir( dir ); + idlCmdEdit->fileDialog()->setURL( KURL( dir ) ); + } + idlCmdEdit->setURL( dir ); + idlCmdOptionsEdit->setText( myProjectItem->scope->variableValues( "IDL_OPTIONS" ).join( " " ) ); + + customVariables->clear(); + customVariableName->setText(""); + customVariableData->setText(""); + customVariableOp->setCurrentItem( 0 ); + QMap<unsigned int, QMap<QString, QString> > customvars = myProjectItem->scope->customVariables(); + QMap<unsigned int, QMap<QString, QString> >::iterator idx = customvars.begin(); + for ( ; idx != customvars.end(); ++idx ) + { + CustomVarListItem* item = new CustomVarListItem( customVariables, idx.key(), idx.data() ); + item->setMultiLinesEnabled(true); + } + + groupTemplateChanged(0); +} + +QPtrList<QMakeScopeItem> ProjectConfigurationDlg::getAllProjects() +{ + QPtrList <QMakeScopeItem> tmpPrjList; + QMakeScopeItem *item = static_cast<QMakeScopeItem*>( prjList->firstChild() ); + while ( item ) + { + if ( item->scope->scopeType() == Scope::ProjectScope ) + { + if( item != myProjectItem ) + tmpPrjList.append( item ); + getAllSubProjects( item, &tmpPrjList ); + } + item = static_cast<QMakeScopeItem*>( item->nextSibling() ); + } + return ( tmpPrjList ); +} + +void ProjectConfigurationDlg::getAllSubProjects( QMakeScopeItem *item, QPtrList <QMakeScopeItem> *itemList ) +{ + + QMakeScopeItem * subItem = static_cast<QMakeScopeItem*>( item->firstChild() ); + while ( subItem ) + { + if ( subItem->scope->scopeType() == Scope::ProjectScope ) + { + if ( subItem != myProjectItem ) + itemList->append( subItem ); + getAllSubProjects( subItem, itemList ); + } + subItem = static_cast<QMakeScopeItem*>( subItem->nextSibling() ); + } +} + +void ProjectConfigurationDlg::updateIncludeControl() +{ + insideinc_listview->setSorting( -1, false ); + outsideinc_listview->setSorting( -1, false ); + insideinc_listview->clear(); + outsideinc_listview->clear(); + + QStringList incList = myProjectItem->scope->variableValues( "INCLUDEPATH" ); + QStringList intIncList = incList; + QMap<QString, InsideCheckListItem*> items; + QPtrList <QMakeScopeItem> itemList = getAllProjects(); + QMakeScopeItem *item = itemList.first(); + while ( item ) + { + if ( item->scope->variableValues( "TEMPLATE" ).findIndex( "lib" ) != -1 || + item->scope->variableValues( "TEMPLATE" ).findIndex( "app" ) != -1 ) + { + QString tmpInc = item->getIncAddPath( myProjectItem->scope->projectDir() ); + tmpInc = QDir::cleanDirPath( tmpInc ); + InsideCheckListItem *newItem = new InsideCheckListItem( insideinc_listview, + insideinc_listview->lastItem(), item, this ); + + items[tmpInc] = newItem; + if ( incList.findIndex( tmpInc ) != -1 ) + { + incList.remove( tmpInc ); + newItem->setOn( true ); + } + } + // item=(ProjectItem*)item->itemBelow(); + item = itemList.next(); + } + + + //all other in incList are outside incs + outsideinc_listview->clear(); + QStringList::Iterator it1 = incList.begin(); + for ( ;it1 != incList.end();++it1 ) + { + intIncList.remove(*it1); + new QListViewItem( outsideinc_listview, outsideinc_listview->lastItem(), ( *it1 ) ); + } + for( QStringList::const_iterator it = intIncList.begin(); it != intIncList.end(); ++it ) + { + insideinc_listview->insertItem( items[*it] ); + items.remove(*it); + } + for( QMap<QString,InsideCheckListItem*>::ConstIterator it3 = items.begin(); it3 != items.end(); it3++ ) + { + insideinc_listview->insertItem( it3.data() ); + } +} + +void ProjectConfigurationDlg::updateLibControls() +{ + + QPtrList <QMakeScopeItem> itemList = getAllProjects(); + + insidelib_listview->setSorting( -1, false ); + outsidelib_listview->setSorting( -1, false ); + outsidelibdir_listview->setSorting( -1, false ); + insidelib_listview->clear(); + outsidelib_listview->clear(); + outsidelibdir_listview->clear(); + //update librarys + //temp strlist + QStringList libList = myProjectItem->scope->variableValues( "LIBS" ); + QStringList intLibList = libList; + QMap<QString, InsideCheckListItem*> items; + QMakeScopeItem* item = itemList.first(); + while ( item ) + { + if ( item->scope->variableValues( "TEMPLATE" ).findIndex( "lib" ) != -1 ) + { + if ( item != myProjectItem ) + { + // create lib string + QString tmpLib = item->getLibAddObject( myProjectItem->scope->projectDir() ); + + InsideCheckListItem * newItem = new InsideCheckListItem( insidelib_listview, + insidelib_listview->lastItem(), item, this ); + insidelib_listview->takeItem( newItem ); + items[tmpLib] = newItem; + QString tmpLibDir = item->getLibAddPath( myProjectItem->scope->projectDir() ); + kdDebug(9024) << "lib:" << tmpLib << " dir:" << tmpLibDir << "|" << libList << endl; + if ( libList.findIndex( "-L" + tmpLibDir ) != -1 ) + { + libList.remove( "-L" + tmpLibDir ); + } + if ( libList.findIndex( tmpLib ) != -1 ) + { + libList.remove( tmpLib ); + newItem->setOn( true ); + } + } + } + item = itemList.next(); + } + + //all other in libList are outside libs + QStringList::Iterator it1 = libList.begin(); + for ( ;it1 != libList.end();++it1 ) + { + intLibList.remove( *it1 ); + if ( ( *it1 ).startsWith( "-L" ) ) + new QListViewItem( outsidelibdir_listview, outsidelibdir_listview->lastItem(), ( *it1 ).mid( 2 ) ); + else + { + new QListViewItem( outsidelib_listview, outsidelib_listview->lastItem(), ( *it1 ) ); + } + } + + for( QStringList::const_iterator it = intLibList.begin(); it != intLibList.end(); ++it ) + { + QString lib = *it; + if( !lib.startsWith( "-L" ) ) + { + insidelib_listview->insertItem( items[lib] ); + items.remove(lib); + } + } + for( QMap<QString,InsideCheckListItem*>::ConstIterator it3 = items.begin(); it3 != items.end(); it3++ ) + { + insidelib_listview->insertItem( it3.data() ); + } +} + +void ProjectConfigurationDlg::updateDependenciesControl( ) +{ + QPtrList <QMakeScopeItem> itemList = getAllProjects(); + + intDeps_view->setSorting( -1, false ); + extDeps_view->setSorting( -1, false ); + intDeps_view->clear(); + extDeps_view->clear(); + + QStringList depsList = myProjectItem->scope->variableValues( "TARGETDEPS" ); + QStringList intDepList = depsList; + QMap<QString,InsideCheckListItem*> items; + QMakeScopeItem *item = itemList.first(); + while ( item ) + { + QStringList templateval = item->scope->variableValues( "TEMPLATE" ); + if ( templateval.findIndex( "lib" ) != -1 + || templateval.findIndex( "app" ) != -1 ) + { + QString tmpLib; + QStringList values = item->scope->variableValues( "CONFIG" ); + if ( templateval.findIndex( "lib" ) != -1 && values.findIndex( "dll" ) != -1 ) + tmpLib = item->getSharedLibAddObject( myProjectItem->scope->projectDir() ); + else if ( templateval.findIndex( "lib" ) != -1 ) + tmpLib = item->getLibAddObject( myProjectItem->scope->projectDir() ); + else + tmpLib = item->getApplicationObject( myProjectItem->scope->projectDir() ); + InsideCheckListItem * newItem = new InsideCheckListItem( intDeps_view, intDeps_view->lastItem(), item, this ); + items[tmpLib] = newItem; + if ( depsList.findIndex( tmpLib ) != -1 ) + { + depsList.remove( tmpLib ); + newItem->setOn( true ); + } + + } + item = itemList.next(); + } + + //add all other prj in itemList unchecked + + extDeps_view->clear(); + for ( QStringList::Iterator it1 = depsList.begin();it1 != depsList.end();++it1 ) + { + intDepList << *it1; + new QListViewItem( extDeps_view, extDeps_view->lastItem(), ( *it1 ) ); + } + + + for( QStringList::const_iterator it = intDepList.begin(); it != intDepList.end(); ++it ) + { + intDeps_view->insertItem( items[*it] ); + items.remove(*it); + } + + for( QMap<QString,InsideCheckListItem*>::ConstIterator it2 = items.begin(); it2 != items.end(); it2++ ) + { + intDeps_view->insertItem( it2.data() ); + } +} + + +void ProjectConfigurationDlg::updateBuildOrderControl() +{ + //sort build order only if subdirs + if ( myProjectItem->scope->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) != -1 ) + { + + QPtrList <QMakeScopeItem> itemList; + + QMakeScopeItem *item = static_cast<QMakeScopeItem*>( myProjectItem->firstChild() ); + while ( item ) + { + itemList.append( item ); + item = static_cast<QMakeScopeItem*>( item->nextSibling() ); + } + + incaddTab->setEnabled( false ); + buildorder_listview->setSorting( -1, false ); + buildorder_listview->clear(); + QStringList buildList = myProjectItem->scope->variableValues( "SUBDIRS" ); + QStringList::Iterator it1 = buildList.begin(); + for ( ;it1 != buildList.end();++it1 ) + { + item = itemList.first(); + while ( item ) + { + if ( item->scope->scopeType() == Scope::ProjectScope ) + { + if ( item->text( 0 ) == ( *it1 ) ) + { + new QListViewItem( buildorder_listview, buildorder_listview->lastItem(), item->text( 0 ) ); + itemList.take(); + break; + } + } + item = itemList.next();; + } + } + }else + buildorder_listview->clear(); +} + +//build order buttons +void ProjectConfigurationDlg::buildorderMoveUpClicked() +{ + if ( buildorder_listview->currentItem() == buildorder_listview->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = buildorder_listview->firstChild(); + while ( item->nextSibling() != buildorder_listview->currentItem() ) + item = item->nextSibling(); + item->moveItem( buildorder_listview->currentItem() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::buildorderMoveDownClicked() +{ + if ( buildorder_listview->currentItem() == 0 || buildorder_listview->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + buildorder_listview->currentItem() ->moveItem( buildorder_listview->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + + +//Include dir buttons +void ProjectConfigurationDlg::insideIncMoveUpClicked() +{ + if ( insideinc_listview->currentItem() == insideinc_listview->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = insideinc_listview->firstChild(); + while ( item->nextSibling() != insideinc_listview->currentItem() ) + item = item->nextSibling(); + item->moveItem( insideinc_listview->currentItem() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::insideIncMoveDownClicked() +{ + if ( insideinc_listview->currentItem() == 0 || insideinc_listview->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + insideinc_listview->currentItem() ->moveItem( insideinc_listview->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideIncMoveUpClicked() +{ + if ( outsideinc_listview->currentItem() == outsideinc_listview->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = outsideinc_listview->firstChild(); + while ( item->nextSibling() != outsideinc_listview->currentItem() ) + item = item->nextSibling(); + item->moveItem( outsideinc_listview->currentItem() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideIncMoveDownClicked() +{ + if ( outsideinc_listview->currentItem() == 0 || outsideinc_listview->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + outsideinc_listview->currentItem() ->moveItem( outsideinc_listview->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideIncAddClicked() +{ + KURLRequesterDlg dialog( "", i18n( "Add include directory:" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::Directory | KFile::LocalOnly ); + dialog.urlRequester() ->setURL( QString::null ); + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir() ) ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString dir = dialog.urlRequester() ->url(); + if ( !dir.isEmpty() ) + { + new QListViewItem( outsideinc_listview, dir ); + activateApply( 0 ); + } +} + + +void ProjectConfigurationDlg::outsideIncRemoveClicked() +{ + delete outsideinc_listview->currentItem(); + activateApply( 0 ); +} + +//libadd buttons +void ProjectConfigurationDlg::insideLibMoveUpClicked() +{ + if ( insidelib_listview->currentItem() == insidelib_listview->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = insidelib_listview->firstChild(); + while ( item->nextSibling() != insidelib_listview->currentItem() ) + item = item->nextSibling(); + item->moveItem( insidelib_listview->currentItem() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::insideLibMoveDownClicked() +{ + if ( insidelib_listview->currentItem() == 0 || insidelib_listview->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + insidelib_listview->currentItem() ->moveItem( insidelib_listview->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideLibMoveUpClicked() +{ + if ( outsidelib_listview->currentItem() == outsidelib_listview->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = outsidelib_listview->firstChild(); + while ( item->nextSibling() != outsidelib_listview->currentItem() ) + item = item->nextSibling(); + item->moveItem( outsidelib_listview->currentItem() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideLibMoveDownClicked() +{ + if ( outsidelib_listview->currentItem() == 0 || outsidelib_listview->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + outsidelib_listview->currentItem() ->moveItem( outsidelib_listview->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideLibAddClicked() +{ + KURLRequesterDlg dialog( "", i18n( "Add Library: Either choose the .a/.so file or give -l<libname>" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly ); + dialog.urlRequester() ->setFilter( "*.so|"+i18n("Shared Library (*.so)")+"\n*.a|"+i18n("Static Library (*.a)") ); + dialog.urlRequester() ->setURL( QString::null ); + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir() ) ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString file = dialog.urlRequester() ->url(); + if ( !file.isEmpty() ) + { + if( file.startsWith("-l") ) + { + new QListViewItem( outsidelib_listview, file ); + activateApply( 0 ); + } + else + { + QFileInfo fi(file); + if( !fi.exists() ) + { + new QListViewItem( outsidelib_listview, file );; + activateApply( 0 ); + } + if( fi.extension(false) == "a" ) + { + new QListViewItem( outsidelib_listview, file ); + activateApply( 0 ); + }else if ( fi.extension(false) == "so" ) + { + QString path = fi.dirPath( true ); + QString name = fi.fileName(); + if( name.startsWith( "lib" ) ) + name = name.mid(3); + name = "-l"+name.left( name.length() - 3 ); + new QListViewItem( outsidelib_listview, name ); + new QListViewItem( outsidelibdir_listview, path ); + activateApply( 0 ); + }else + return; + } + + } +} + + +void ProjectConfigurationDlg::outsideLibRemoveClicked() +{ + delete outsidelib_listview->currentItem(); + activateApply( 0 ); +} + +//lib paths buttons +void ProjectConfigurationDlg::outsideLibDirMoveUpClicked() +{ + if ( outsidelibdir_listview->currentItem() == outsidelibdir_listview->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = outsidelibdir_listview->firstChild(); + while ( item->nextSibling() != outsidelibdir_listview->currentItem() ) + item = item->nextSibling(); + item->moveItem( outsidelibdir_listview->currentItem() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideLibDirMoveDownClicked() +{ + if ( outsidelibdir_listview->currentItem() == 0 || outsidelibdir_listview->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + outsidelibdir_listview->currentItem() ->moveItem( outsidelibdir_listview->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideLibDirAddClicked() +{ + KURLRequesterDlg dialog( "", i18n( "Add library directory:" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::Directory | KFile::LocalOnly ); + dialog.urlRequester() ->setURL( QString::null ); + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir() ) ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString dir = dialog.urlRequester() ->url(); + if ( !dir.isEmpty() ) + { + new QListViewItem( outsidelibdir_listview, dir ); + activateApply( 0 ); + } +} + + +void ProjectConfigurationDlg::outsideLibDirRemoveClicked() +{ + delete outsidelibdir_listview->currentItem(); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::outsideIncEditClicked() +{ + QListViewItem * item = outsideinc_listview->currentItem(); + if ( item == NULL ) return ; + QString text = item->text( 0 ); + + KURLRequesterDlg dialog( text, i18n( "Change include directory:" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::Directory | KFile::LocalOnly ); + if( QFileInfo(text).isRelative() ) + { + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir()+"/"+text ) ); + } + else + { + dialog.urlRequester() ->completionObject() ->setDir( text ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( text ) ); + } + dialog.urlRequester() ->setURL( text ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString dir = dialog.urlRequester() ->url(); + if ( !dir.isEmpty() ) + { + item->setText( 0, dir ); + activateApply( 0 ); + } +} + +void ProjectConfigurationDlg::outsideLibEditClicked() +{ + QListViewItem *item = outsidelib_listview->currentItem(); + if ( item == NULL ) return ; + QString text = item->text( 0 ); + + KURLRequesterDlg dialog( text, i18n( "Change Library:" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly ); + if( QFileInfo(text).isRelative() ) + { + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir()+"/"+text ) ); + }else + { + dialog.urlRequester() ->completionObject() ->setDir( text ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( text ) ); + } + dialog.urlRequester() ->setURL( text ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString file = dialog.urlRequester() ->url(); + if ( !file.isEmpty() ) + { + if( file.startsWith("-l") ) + { + item->setText( 0, file ); + activateApply( 0 ); + } + else + { + QFileInfo fi(file); + if( !fi.exists() ) + { + item->setText( 0, file ); + activateApply( 0 ); + } + if( fi.extension(false) == "a" ) + { + item->setText( 0, file ); + activateApply( 0 ); + }else if ( fi.extension(false) == "so" ) + { + QString path = fi.dirPath( true ); + QString name = fi.fileName(); + if( name.startsWith( "lib" ) ) + name = name.mid(3); + name = "-l"+name.left( name.length() - 3 ); + item->setText( 0, name ); + new QListViewItem( outsidelibdir_listview, path ); + activateApply( 0 ); + }else + return; + } + } +} + +void ProjectConfigurationDlg::outsideLibDirEditClicked() +{ + QListViewItem * item = outsidelibdir_listview->currentItem(); + if ( item == NULL ) return ; + QString text = item->text( 0 ); + + KURLRequesterDlg dialog( text, i18n( "Change library directory:" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::Directory | KFile::LocalOnly ); + + if( QFileInfo(text).isRelative() ) + { + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir()+"/"+text ) ); + } + else + { + dialog.urlRequester() ->completionObject() ->setDir( text ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( text ) ); + } + dialog.urlRequester() ->setURL( text ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString dir = dialog.urlRequester() ->url(); + if ( !dir.isEmpty() ) + { + item->setText( 0, dir ); + activateApply( 0 ); + } +} + + +void ProjectConfigurationDlg::extAdd_button_clicked( ) +{ + KURLRequesterDlg dialog( "", i18n( "Add target:" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::File | KFile::LocalOnly ); + dialog.urlRequester() ->setURL( QString::null ); + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir() ) ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString path = dialog.urlRequester() ->url(); + if ( !path.isEmpty() ) + { + new QListViewItem( extDeps_view, path ); + activateApply( 0 ); + } +} + +void ProjectConfigurationDlg::extEdit_button_clicked( ) +{ + QListViewItem * item = extDeps_view->currentItem(); + if ( item == NULL ) return ; + QString text = item->text( 0 ); + + KURLRequesterDlg dialog( text, i18n( "Change target:" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::File | KFile::LocalOnly ); + if( QFileInfo(text).isRelative() ) + { + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir()+"/"+text ) ); + } + else + { + dialog.urlRequester() ->completionObject() ->setDir( text ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( text ) ); + } + dialog.urlRequester() ->setURL( text ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString path = dialog.urlRequester() ->url(); + if ( !path.isEmpty() ) + { + item->setText( 0, path ); + activateApply( 0 ); + } +} + +void ProjectConfigurationDlg::extMoveDown_button_clicked( ) +{ + if ( extDeps_view->currentItem() == 0 || extDeps_view->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + extDeps_view->currentItem() ->moveItem( extDeps_view->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::extMoveUp_button_clicked( ) +{ + if ( extDeps_view->currentItem() == extDeps_view->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = extDeps_view->firstChild(); + while ( item->nextSibling() != extDeps_view->currentItem() ) + item = item->nextSibling(); + item->moveItem( extDeps_view->currentItem() ); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::extRemove_button_clicked( ) +{ + delete extDeps_view->currentItem(); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::intMoveDown_button_clicked( ) +{ + if ( intDeps_view->currentItem() == 0 || intDeps_view->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + intDeps_view->currentItem() ->moveItem( intDeps_view->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::intMoveUp_button_clicked( ) +{ + if ( intDeps_view->currentItem() == intDeps_view->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = intDeps_view->firstChild(); + while ( item->nextSibling() != intDeps_view->currentItem() ) + item = item->nextSibling(); + item->moveItem( intDeps_view->currentItem() ); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::addCustomValueClicked() +{ + QMap<QString, QString> customvar; + customvar["var"] = i18n("Name"); + customvar["op"] = "="; + customvar["values"] = i18n("Value"); + unsigned int key = myProjectItem->scope->addCustomVariable( customvar["var"], customvar["op"], customvar["values"] ); + CustomVarListItem* item = new CustomVarListItem( customVariables, key, customvar ); + item->setMultiLinesEnabled(true); + customVariables->setSelected( item, true ); + newCustomVariableActive(); + customVariables->sort(); + activateApply( 0 ); +} +void ProjectConfigurationDlg::removeCustomValueClicked() +{ + QListViewItem * item = customVariables->currentItem(); + if ( item ) + { + myProjectItem->scope->removeCustomVariable( item->key(0, true).toUInt() ); + delete item; + } + if( customVariables->firstChild() ) + { + customVariables->setSelected( customVariables->firstChild(), true ); + newCustomVariableActive(); + }else + { + customVariableName->setText( "" ); + customVariableData->setText( "" ); + customVariableOp->setCurrentItem( 0 ); + customVariableName->setFocus(); + } + customVariables->sort(); + + activateApply( 0 ); +} + +void ProjectConfigurationDlg::upCustomValueClicked() +{ + // custom vars + QListViewItem * item = customVariables->firstChild(); + if ( customVariables->currentItem() == item ) + { + KNotifyClient::beep(); + return ; + } + while ( item->nextSibling() != customVariables->currentItem() ) + item = item->nextSibling(); + item->moveItem( customVariables->currentItem() ); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::downCustomValueClicked() +{ + if ( customVariables->currentItem() == 0 || customVariables->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + customVariables->currentItem() ->moveItem( customVariables->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::newCustomVariableActive( ) +{ + customVariableOp->blockSignals(true); + customVariableName->blockSignals(true); + customVariableData->blockSignals(true); + QListViewItem * item = customVariables->currentItem(); + if ( item ) + { + customVariableName->setText( item->text( 0 ) ); + customVariableData->setText( item->text( 2 ) ); + customVariableOp->setCurrentText( item->text( 1 ) ); + customVariableName->setFocus(); + } + customVariableOp->blockSignals(false); + customVariableName->blockSignals(false); + customVariableData->blockSignals(false); +} + +void ProjectConfigurationDlg::groupLibrariesChanged( int ) +{ + if ( staticRadio->isChecked() ) + { + checkPlugin->setEnabled( false ); + checkDesigner->setEnabled( false ); + } + else if ( sharedRadio->isChecked() ) + { + checkPlugin->setEnabled( true ); + checkDesigner->setEnabled( checkPlugin->isChecked() ); + } + else if ( checkPlugin->isChecked() && prjWidget->m_part->isQt4Project() ) + { + checkDesigner->setEnabled( true ); + } + else + { + checkDesigner->setEnabled( false ); + } + activateApply( 0 ); +} + +void ProjectConfigurationDlg::groupTemplateChanged( int ) +{ + + if ( radioSubdirs->isChecked() ) + { + TabBuild->setTabEnabled( custVarsTab, true ); + TabBuild->setTabEnabled( libAddTab, false ); + TabBuild->setTabEnabled( incaddTab, false ); + TabBuild->setTabEnabled( buildOptsTab, false ); + TabBuild->setTabEnabled( configTab, false ); + TabBuild->setTabEnabled( depTab, true ); + intDeps_view->setEnabled( false ); + intMoveUp_button->setEnabled( false ); + intMoveDown_button->setEnabled( false ); + extAdd_button->setEnabled( false ); + extRemove_button->setEnabled( false ); + extEdit_button->setEnabled( false ); + extMoveUp_button->setEnabled( false ); + extMoveDown_button->setEnabled( false ); + extDeps_view->setEnabled( false ); + buildorder_listview->setEnabled( checkOrdered->isOn() ); + buildmoveup_button->setEnabled( checkOrdered->isOn() ); + buildmovedown_button->setEnabled( checkOrdered->isOn() ); + targetGroupbox->setEnabled( false ); + targetInstGroupbox->setEnabled( false ); + checkOrdered->setEnabled( true ); + } + else if ( radioLibrary->isChecked() ) + { + // staticRadio->setChecked(true); + TabBuild->setTabEnabled( custVarsTab, true ); + TabBuild->setTabEnabled( depTab, true ); + TabBuild->setTabEnabled( libAddTab, true ); + TabBuild->setTabEnabled( incaddTab, true ); + TabBuild->setTabEnabled( buildOptsTab, true ); + TabBuild->setTabEnabled( configTab, true ); + intDeps_view->setEnabled( true ); + intMoveUp_button->setEnabled( true ); + intMoveDown_button->setEnabled( true ); + extAdd_button->setEnabled( true ); + extRemove_button->setEnabled( true ); + extEdit_button->setEnabled( true ); + extMoveUp_button->setEnabled( true ); + extMoveDown_button->setEnabled( true ); + extDeps_view->setEnabled( true ); + buildorder_listview->setEnabled( false ); + buildmoveup_button->setEnabled( false ); + buildmovedown_button->setEnabled( false ); + groupLibraries->setEnabled( true ); + targetGroupbox->setEnabled( true ); + targetInstGroupbox->setEnabled( true ); + checkOrdered->setEnabled( false ); + } + else if ( radioApplication->isChecked() ) + { + TabBuild->setTabEnabled( custVarsTab, true ); + TabBuild->setTabEnabled( depTab, true ); + TabBuild->setTabEnabled( libAddTab, true ); + TabBuild->setTabEnabled( incaddTab, true ); + TabBuild->setTabEnabled( buildOptsTab, true ); + TabBuild->setTabEnabled( configTab, true ); + intDeps_view->setEnabled( true ); + intMoveUp_button->setEnabled( true ); + intMoveDown_button->setEnabled( true ); + extAdd_button->setEnabled( true ); + extRemove_button->setEnabled( true ); + extEdit_button->setEnabled( true ); + extMoveUp_button->setEnabled( true ); + extMoveDown_button->setEnabled( true ); + extDeps_view->setEnabled( true ); + buildorder_listview->setEnabled( false ); + buildmoveup_button->setEnabled( false ); + buildmovedown_button->setEnabled( false ); + groupLibraries->setEnabled( false ); + targetGroupbox->setEnabled( true ); + targetInstGroupbox->setEnabled( true ); + checkConsole->setEnabled( true ); + checkWindows->setEnabled( true ); + checkOrdered->setEnabled( false ); + } + activateApply( 0 ); +} + +void ProjectConfigurationDlg::groupRequirementsChanged( int ) +{ + if ( checkQt->isChecked() && prjWidget->m_part->isQt4Project() ) + { + groupQt4Libs->setEnabled( true ); + } + else + { + groupQt4Libs->setEnabled( false ); + } + activateApply( 0 ); +} + +void ProjectConfigurationDlg::targetInstallChanged( bool checked ) +{ + if ( checked ) + { + m_InstallTargetPath->setEnabled( true ); + } + else + { + m_InstallTargetPath->setEnabled( false ); + } + activateApply( 0 ); +} + +void ProjectConfigurationDlg::apply() +{ +// if( buttonApply->isEnabled() ) + if( !myProjectItem || !myProjectItem->scope ) + { + buttonApply->setEnabled( false ); + return; + } + updateProjectConfiguration(); + myProjectItem->scope->saveToFile(); + // prjWidget->updateProjectConfiguration( myProjectItem ); + prjWidget->setupContext(); + buttonApply->setEnabled( false ); +} + +void ProjectConfigurationDlg::activateApply( int ) +{ + buttonApply->setEnabled( true ); +} +void ProjectConfigurationDlg::activateApply( const QString& ) +{ + buttonApply->setEnabled( true ); +} + +void ProjectConfigurationDlg::activateApply( QListViewItem* ) +{ + buttonApply->setEnabled( true ); +} + +void ProjectConfigurationDlg::removeSharedLibDeps() +{ + QListViewItemIterator it(myProjectItem->listView()); + for( ; it.current() ; ++it ) + { + QMakeScopeItem* prjItem = static_cast<QMakeScopeItem*>( it.current() ); + if( prjItem == myProjectItem || !prjItem->isEnabled() ) + continue; + + QMap<QString, QString> infos = myProjectItem->getLibInfos(prjItem->scope->projectDir()); + + if( prjItem->scope->variableValues("LIBS").findIndex(infos["shared_lib"]) != -1 ) + prjItem->scope->removeFromPlusOp("LIBS", infos["shared_lib"]); + if( prjItem->scope->variableValues("LIBS").findIndex(infos["shared_libdir"]) != -1 ) + prjItem->scope->removeFromPlusOp("LIBS", infos["shared_libdir"]); + if( prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["shared_depend"]) != -1 ) + { + prjItem->scope->removeFromPlusOp("TARGETDEPS", infos["shared_depend"]); + + prjItem->scope->saveToFile(); + } + } +} + +void ProjectConfigurationDlg::addStaticLibDeps() +{ + QListViewItemIterator it(myProjectItem->listView()); + for( ; it.current() ; ++it ) + { + QMakeScopeItem* prjItem = static_cast<QMakeScopeItem*>( it.current() ); + if( prjItem == myProjectItem || !prjItem->isEnabled() ) + continue; + + QMap<QString, QString> infos = myProjectItem->getLibInfos(prjItem->scope->projectDir()); + + if( prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["app_depend"]) != -1 + || prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["shared_depend"]) != -1 ) + { + prjItem->scope->addToPlusOp("LIBS", infos["static_lib"]); + prjItem->scope->addToPlusOp("TARGETDEPS", infos["static_depend"]); + prjItem->scope->saveToFile(); + } + } +} + +void ProjectConfigurationDlg::removeStaticLibDeps() +{ + QListViewItemIterator it(myProjectItem->listView()); + for( ; it.current() ; ++it ) + { + QMakeScopeItem* prjItem = static_cast<QMakeScopeItem*>( it.current() ); + if( prjItem == myProjectItem || !prjItem->isEnabled() ) + continue; + + + QMap<QString, QString> infos = myProjectItem->getLibInfos(prjItem->scope->projectDir()); + + if( prjItem->scope->variableValues("LIBS").findIndex(infos["static_lib"]) != -1 ) + prjItem->scope->removeFromPlusOp("LIBS", infos["static_lib"]); + if( prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["static_depend"]) != -1 ) + { + prjItem->scope->removeFromPlusOp("TARGETDEPS", infos["static_depend"]); + prjItem->scope->saveToFile(); + } + } +} + +void ProjectConfigurationDlg::addSharedLibDeps() +{ + QListViewItemIterator it(myProjectItem->listView()); + for( ; it.current() ; ++it ) + { + QMakeScopeItem* prjItem = static_cast<QMakeScopeItem*>( it.current() ); + if( prjItem == myProjectItem || !prjItem->isEnabled() ) + continue; + + QMap<QString, QString> infos = myProjectItem->getLibInfos(prjItem->scope->projectDir()); + if( prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["app_depend"]) != -1 + || prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["static_depend"]) != -1 ) + { + prjItem->scope->addToPlusOp("LIBS", infos["shared_lib"]); + prjItem->scope->addToPlusOp("LIBS", infos["shared_libdir"]); + prjItem->scope->addToPlusOp("TARGETDEPS", infos["shared_depend"]); + prjItem->scope->saveToFile(); + } + } +} + +void ProjectConfigurationDlg::removeAppDeps() +{ + QListViewItemIterator it(myProjectItem->listView()); + for( ; it.current() ; ++it ) + { + QMakeScopeItem* prjItem = static_cast<QMakeScopeItem*>( it.current() ); + if( prjItem == myProjectItem || !prjItem->isEnabled() ) + continue; + + QMap<QString, QString> infos = myProjectItem->getLibInfos(prjItem->scope->projectDir()); + + if( prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["app_depend"]) != -1 ) + { + prjItem->scope->removeFromPlusOp("TARGETDEPS", infos["app_depend"]); + prjItem->scope->saveToFile(); + } + } +} + +void ProjectConfigurationDlg::addAppDeps() +{ + QListViewItemIterator it(myProjectItem->listView()); + for( ; it.current() ; ++it ) + { + QMakeScopeItem* prjItem = static_cast<QMakeScopeItem*>( it.current() ); + if( prjItem == myProjectItem || !prjItem->isEnabled() ) + continue; + + QMap<QString, QString> infos = myProjectItem->getLibInfos(prjItem->scope->projectDir()); + + if( prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["shared_depend"]) != -1 + || prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["static_depend"]) != -1 ) + { + prjItem->scope->addToPlusOp("TARGETDEPS", infos["app_depend"]); + + prjItem->scope->saveToFile(); + } + } +} + +void ProjectConfigurationDlg::customVarChanged() +{ + QListViewItem * item = customVariables->currentItem(); + if ( item ) + { + item->setText( 0, customVariableName->text() ); + item->setText( 1, customVariableOp->currentText() ); + item->setText( 2, customVariableData->text() ); + } + activateApply( 0 ); +} + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/projectconfigurationdlg.h b/buildtools/qmake/projectconfigurationdlg.h new file mode 100644 index 00000000..246fb388 --- /dev/null +++ b/buildtools/qmake/projectconfigurationdlg.h @@ -0,0 +1,145 @@ +/*************************************************************************** +* Copyright (C) 2002 by Jakob Simon-Gaarde * +* jsgaarde@tdcspace.dk * +* Copyright (C) 2002-2003 by Alexander Dymo * +* cloudtemple@mksat.net * +* Copyright (C) 2003 by Thomas Hasart * +* thasart@gmx.de * +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 PROJECTCONFIGURATIONDLG_H +#define PROJECTCONFIGURATIONDLG_H + +#include "projectconfigurationdlgbase.h" +//#include "trollprojectwidget.h" +#include <kdeversion.h> +#include <qlistview.h> +#include <klistview.h> +#include <qmap.h> + +class QMakeScopeItem; +class KListViewItem; +class qProjectItem; +class ProjectConfigurationDlg; +class TrollProjectWidget; + +class InsideCheckListItem : public QCheckListItem +{ +public: + InsideCheckListItem( QListView *parent, QMakeScopeItem *item, ProjectConfigurationDlg *config ); + + InsideCheckListItem( QListView *parent, QListViewItem *after, QMakeScopeItem *item, ProjectConfigurationDlg *config ); + QMakeScopeItem *prjItem; + ProjectConfigurationDlg *m_config; + +protected: + virtual void stateChange ( bool state ); +}; + +class CustomVarListItem : public KListViewItem +{ + public: + CustomVarListItem( QListView*, unsigned int, QMap<QString, QString> ); + QString key(int column, bool ascending) const; + private: + unsigned int m_key; +}; + +class ProjectConfigurationDlg : public ProjectConfigurationDlgBase +{ +public: + ProjectConfigurationDlg( QListView *_prjList, TrollProjectWidget* _prjWidget, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~ProjectConfigurationDlg(); + void updateControls(); + void updateSubproject( QMakeScopeItem* _item ); + QMakeScopeItem* currentProjectItem() { return myProjectItem; } + +public slots: + // virtual void radioLibrarytoggled(bool); + virtual void updateProjectConfiguration(); + + virtual void buildorderMoveUpClicked(); + virtual void buildorderMoveDownClicked(); + + virtual void insideIncMoveUpClicked(); + virtual void insideIncMoveDownClicked(); + virtual void outsideIncMoveUpClicked(); + virtual void outsideIncMoveDownClicked(); + virtual void outsideIncAddClicked(); + virtual void outsideIncRemoveClicked(); + virtual void outsideIncEditClicked(); + + virtual void insideLibMoveUpClicked(); + virtual void insideLibMoveDownClicked(); + virtual void outsideLibMoveUpClicked(); + virtual void outsideLibMoveDownClicked(); + virtual void outsideLibAddClicked(); + virtual void outsideLibRemoveClicked(); + virtual void outsideLibEditClicked(); + + virtual void outsideLibDirMoveUpClicked(); + virtual void outsideLibDirMoveDownClicked(); + virtual void outsideLibDirAddClicked(); + virtual void outsideLibDirRemoveClicked(); + virtual void outsideLibDirEditClicked(); + + virtual void extAdd_button_clicked(); + virtual void extEdit_button_clicked(); + virtual void extMoveDown_button_clicked(); + virtual void extMoveUp_button_clicked(); + virtual void extRemove_button_clicked(); + virtual void intMoveDown_button_clicked(); + virtual void intMoveUp_button_clicked(); + + virtual void addCustomValueClicked(); + virtual void removeCustomValueClicked(); + virtual void upCustomValueClicked(); + virtual void downCustomValueClicked(); + + virtual void newCustomVariableActive(); + + virtual void groupLibrariesChanged( int ); + virtual void groupRequirementsChanged( int ); + virtual void groupTemplateChanged( int ); + virtual void targetInstallChanged( bool ); + virtual void accept(); + virtual void reject(); + virtual void apply(); + virtual void activateApply( int ); + virtual void activateApply( const QString& ); + + + void updateIncludeControl(); + void updateLibControls(); + void updateBuildOrderControl(); + void updateDependenciesControl(); + virtual void activateApply(QListViewItem*); + virtual void customVarChanged(); + +protected: + QListView *prjList; + QMakeScopeItem *myProjectItem; + QPtrList <QMakeScopeItem> getAllProjects(); + TrollProjectWidget* prjWidget; + void getAllSubProjects( QMakeScopeItem *item, QPtrList<QMakeScopeItem> *itemList ); + +private: + void removeSharedLibDeps(); + void removeStaticLibDeps(); + void addSharedLibDeps(); + void addStaticLibDeps(); + void removeAppDeps(); + void addAppDeps(); +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/projectconfigurationdlgbase.ui b/buildtools/qmake/projectconfigurationdlgbase.ui new file mode 100644 index 00000000..d447210d --- /dev/null +++ b/buildtools/qmake/projectconfigurationdlgbase.ui @@ -0,0 +1,2897 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ProjectConfigurationDlgBase</class> +<author>Jakob Simon-Gaarde</author> +<widget class="QDialog"> + <property name="name"> + <cstring>ProjectConfigurationDlgBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>746</width> + <height>694</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>QMake Subproject Configuration</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KPushButton" row="1" column="3"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + </widget> + <widget class="KPushButton" row="1" column="1"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <spacer row="1" column="0"> + <property name="name"> + <cstring>Spacer1_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>260</width> + <height>16</height> + </size> + </property> + </spacer> + <widget class="KPushButton" row="1" column="2"> + <property name="name"> + <cstring>buttonApply</cstring> + </property> + <property name="text"> + <string>&Apply</string> + </property> + </widget> + <widget class="QTabWidget" row="0" column="0" rowspan="1" colspan="4"> + <property name="name"> + <cstring>TabBuild</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>buildTab</cstring> + </property> + <attribute name="title"> + <string>Basics</string> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>groupTemplate</cstring> + </property> + <property name="title"> + <string>Template</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton" row="1" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>radioLibrary</cstring> + </property> + <property name="text"> + <string>Librar&y</string> + </property> + <property name="toolTip" stdset="0"> + <string>Create a library</string> + </property> + </widget> + <widget class="QRadioButton" row="2" column="0"> + <property name="name"> + <cstring>radioSubdirs</cstring> + </property> + <property name="text"> + <string>&Subdirectories</string> + </property> + <property name="toolTip" stdset="0"> + <string>This project holds subdirectories</string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="1"> + <property name="name"> + <cstring>checkOrdered</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Ordered</string> + </property> + <property name="toolTip" stdset="0"> + <string>Build the subprojects in the order they are listed in the .pro file</string> + </property> + </widget> + <spacer row="2" column="2"> + <property name="name"> + <cstring>spacer15</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>101</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QRadioButton" row="0" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>radioApplication</cstring> + </property> + <property name="backgroundOrigin"> + <enum>WidgetOrigin</enum> + </property> + <property name="text"> + <string>A&pplication</string> + </property> + <property name="toolTip" stdset="0"> + <string>Create an application</string> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>targetGroupbox</cstring> + </property> + <property name="title"> + <string>Target</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1_2</cstring> + </property> + <property name="text"> + <string>Path:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>m_targetPath</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>Output file:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>m_targetOutputFile</cstring> + </property> + </widget> + <widget class="KLineEdit" row="1" column="1"> + <property name="name"> + <cstring>m_targetOutputFile</cstring> + </property> + </widget> + <widget class="KURLRequester" row="0" column="1"> + <property name="name"> + <cstring>m_targetPath</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>targetInstGroupbox</cstring> + </property> + <property name="title"> + <string>Target Installation</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KLineEdit" row="0" column="2"> + <property name="name"> + <cstring>m_InstallTargetPath</cstring> + </property> + </widget> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>checkInstallTarget</cstring> + </property> + <property name="text"> + <string>I&nstall</string> + </property> + </widget> + <widget class="QLabel" row="0" column="1"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>Installation path:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>m_InstallTargetPath</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox6</cstring> + </property> + <property name="title"> + <string>Makefile</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KURLRequester" row="0" column="0"> + <property name="name"> + <cstring>makefile_url</cstring> + </property> + </widget> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>argumentsGroupBox</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="title"> + <string>Arguments</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel1_6</cstring> + </property> + <property name="text"> + <string>Run arguments:</string> + </property> + </widget> + <widget class="KLineEdit" row="0" column="1"> + <property name="name"> + <cstring>m_editRunArguments</cstring> + </property> + </widget> + <widget class="KLineEdit" row="1" column="1"> + <property name="name"> + <cstring>m_editDebugArguments</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>textLabel2_2</cstring> + </property> + <property name="text"> + <string>Debug Arguments:</string> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel2_2_2</cstring> + </property> + <property name="text"> + <string>Working Directory:</string> + </property> + </widget> + <widget class="KURLRequester" row="2" column="1"> + <property name="name"> + <cstring>m_CWDEdit</cstring> + </property> + </widget> + </grid> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer3</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>120</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>configTab</cstring> + </property> + <attribute name="title"> + <string>Configuration</string> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>groupBuildMode</cstring> + </property> + <property name="title"> + <string>Build Mode</string> + </property> + <property name="selectedId" stdset="0"> + <number>-1</number> + </property> + <property name="toolTip" stdset="0"> + <string>Set project to be built in release mode</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout147</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>radioDebugMode</cstring> + </property> + <property name="text"> + <string>Debug</string> + </property> + <property name="toolTip" stdset="0"> + <string>Set project to be built in debug mode</string> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>radioReleaseMode</cstring> + </property> + <property name="text"> + <string>Release</string> + </property> + <property name="toolTip" stdset="0"> + <string>Set project to be built in release mode</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkDebugReleaseMode</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Debug && Release</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="toolTip" stdset="0"> + <string>Set project to be built in debug_and_release mode</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout30</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkWarning</cstring> + </property> + <property name="text"> + <string>Enable warnings</string> + </property> + <property name="toolTip" stdset="0"> + <string>Show compiler warnings</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkBuildAll</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Build All</string> + </property> + <property name="toolTip" stdset="0"> + <string>Builds Debug and Release version if Debug&Release is configured</string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>groupRequirements</cstring> + </property> + <property name="title"> + <string>Requirements</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="1" column="0"> + <property name="name"> + <cstring>checkOpenGL</cstring> + </property> + <property name="text"> + <string>OpenGL</string> + </property> + <property name="toolTip" stdset="0"> + <string>Requires the OpenGL (or Mesa) headers/libraries</string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>stlCheck</cstring> + </property> + <property name="text"> + <string>STL</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="1"> + <property name="name"> + <cstring>checkThread</cstring> + </property> + <property name="text"> + <string>Thread</string> + </property> + <property name="toolTip" stdset="0"> + <string>Requires support for multi-threaded application or library.</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>checkQt</cstring> + </property> + <property name="text"> + <string>Qt</string> + </property> + <property name="toolTip" stdset="0"> + <string>Requires the Qt header files/library</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="1"> + <property name="name"> + <cstring>checkX11</cstring> + </property> + <property name="text"> + <string>X11</string> + </property> + <property name="toolTip" stdset="0"> + <string>Support required for X11 application or library</string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="2"> + <property name="name"> + <cstring>checkPCH</cstring> + </property> + <property name="text"> + <string>Precompiled headers</string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="1"> + <property name="name"> + <cstring>rttiCheck</cstring> + </property> + <property name="text"> + <string>RTTI</string> + </property> + </widget> + <widget class="QCheckBox" row="3" column="0"> + <property name="name"> + <cstring>checkWindows</cstring> + </property> + <property name="text"> + <string>Windows</string> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>textLabel1_4</cstring> + </property> + <property name="text"> + <string>Custom Configuration</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="2"> + <property name="name"> + <cstring>exceptionCheck</cstring> + </property> + <property name="text"> + <string>Exceptions </string> + </property> + </widget> + <widget class="KLineEdit" row="4" column="1" rowspan="1" colspan="2"> + <property name="name"> + <cstring>editConfigExtra</cstring> + </property> + </widget> + <widget class="QCheckBox" row="1" column="2"> + <property name="name"> + <cstring>checkConsole</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Console</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="toolTip" stdset="0"> + <string>Check to build a win32 console app</string> + </property> + </widget> + </grid> + </widget> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>groupQt4Libs</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="title"> + <string>Qt4 Libraries</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox" row="1" column="0"> + <property name="name"> + <cstring>checkQt4Gui</cstring> + </property> + <property name="text"> + <string>Gui</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QCheckBox" row="2" column="0"> + <property name="name"> + <cstring>checkQt4XML</cstring> + </property> + <property name="text"> + <string>XML</string> + </property> + </widget> + <widget class="QCheckBox" row="3" column="0"> + <property name="name"> + <cstring>checkQt4Network</cstring> + </property> + <property name="text"> + <string>Network</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="0"> + <property name="name"> + <cstring>checkQt4Core</cstring> + </property> + <property name="text"> + <string>Core</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QCheckBox" row="0" column="1"> + <property name="name"> + <cstring>checkQt4OpenGL</cstring> + </property> + <property name="text"> + <string>OpenGL</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="1"> + <property name="name"> + <cstring>checkUiTools</cstring> + </property> + <property name="text"> + <string>QtUiTools</string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="1"> + <property name="name"> + <cstring>checkQt4SQL</cstring> + </property> + <property name="text"> + <string>SQL</string> + </property> + </widget> + <widget class="QCheckBox" row="3" column="1"> + <property name="name"> + <cstring>checkQt4SVG</cstring> + </property> + <property name="text"> + <string>SVG</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="2"> + <property name="name"> + <cstring>checkTestlib</cstring> + </property> + <property name="text"> + <string>QtTest</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="2"> + <property name="name"> + <cstring>checkQt3Support</cstring> + </property> + <property name="text"> + <string>Qt3 Support</string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="2"> + <property name="name"> + <cstring>checkQDBus</cstring> + </property> + <property name="text"> + <string>QDBus (Qt4.2)</string> + </property> + </widget> + <widget class="QCheckBox" row="3" column="2"> + <property name="name"> + <cstring>checkAssistant</cstring> + </property> + <property name="text"> + <string>QtAssistant</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="3"> + <property name="name"> + <cstring>checkQtScript</cstring> + </property> + <property name="text"> + <string>QtScript (Qt4.3)</string> + </property> + </widget> + <widget class="QCheckBox" row="1" column="3"> + <property name="name"> + <cstring>checkQtWebKit</cstring> + </property> + <property name="text"> + <string>QtWebKit (Qt4.4)</string> + </property> + </widget> + <widget class="QCheckBox" row="2" column="3"> + <property name="name"> + <cstring>checkQtXmlPatterns</cstring> + </property> + <property name="text"> + <string>QtXmlPatterns (Qt4.4)</string> + </property> + </widget> + <widget class="QCheckBox" row="3" column="3"> + <property name="name"> + <cstring>checkPhonon</cstring> + </property> + <property name="text"> + <string>Phonon (Qt4.4)</string> + </property> + </widget> + <widget class="QCheckBox" row="0" column="4"> + <property name="name"> + <cstring>checkQtHelp</cstring> + </property> + <property name="text"> + <string>QtHelp (Qt4.4)</string> + </property> + </widget> + </grid> + </widget> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>groupLibraries</cstring> + </property> + <property name="title"> + <string>Library Options</string> + </property> + <property name="exclusive"> + <bool>false</bool> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout69</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>staticRadio</cstring> + </property> + <property name="text"> + <string>Build as static library</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkPlugin</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Plugin</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkLibtool</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Make libtool archive</string> + </property> + <property name="toolTip" stdset="0"> + <string>Support required for X11 application or library</string> + </property> + </widget> + </vbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer34</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>41</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout68</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>sharedRadio</cstring> + </property> + <property name="text"> + <string>Build as shared library</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkDesigner</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Designer Plugin</string> + </property> + <property name="accel"> + <string></string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout67</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>Library version:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>m_targetLibraryVersion</cstring> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>m_targetLibraryVersion</cstring> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>16</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>incaddTab</cstring> + </property> + <attribute name="title"> + <string>Includes</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="1" column="1"> + <property name="name"> + <cstring>Layout9</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="KPushButton"> + <property name="name"> + <cstring>insideIncMoveUpBtn</cstring> + </property> + <property name="text"> + <string>Move Up</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>insideIncMoveDownBtn</cstring> + </property> + <property name="text"> + <string>Move Down</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer3_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QListView" row="3" column="0"> + <column> + <property name="text"> + <string>Directories Outside Project</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>outsideinc_listview</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QListView" row="1" column="0"> + <column> + <property name="text"> + <string>Directories Inside Project</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>insideinc_listview</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QLayoutWidget" row="3" column="1"> + <property name="name"> + <cstring>layout8</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideIncAddBtn</cstring> + </property> + <property name="text"> + <string>Add...</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideIncRemoveBtn</cstring> + </property> + <property name="text"> + <string>Remove</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideIncEditBtn</cstring> + </property> + <property name="text"> + <string>Edit</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideIncMoveUpBtn</cstring> + </property> + <property name="text"> + <string>Move Up</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideIncMoveDownBtn</cstring> + </property> + <property name="text"> + <string>Move Down</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>70</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>libAddTab</cstring> + </property> + <attribute name="title"> + <string>Libraries</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="1" column="0"> + <property name="name"> + <cstring>layout12</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QListView"> + <column> + <property name="text"> + <string>External Library Dirs</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>outsidelibdir_listview</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout10</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideLibDirAddBtn</cstring> + </property> + <property name="text"> + <string>Add...</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideLibDirRemoveBtn</cstring> + </property> + <property name="text"> + <string>Remove</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideLibDirEditBtn</cstring> + </property> + <property name="text"> + <string>Edit</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideLibDirMoveUpBtn</cstring> + </property> + <property name="text"> + <string>Move Up</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideLibDirMoveDownBtn</cstring> + </property> + <property name="text"> + <string>Move Down</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer2_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>70</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="1" column="1"> + <property name="name"> + <cstring>layout11</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QListView"> + <column> + <property name="text"> + <string>External Libraries</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>outsidelib_listview</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout9</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideLibAddBtn</cstring> + </property> + <property name="text"> + <string>Add...</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideLibRemoveBtn</cstring> + </property> + <property name="text"> + <string>Remove</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideLibEditBtn</cstring> + </property> + <property name="text"> + <string>Edit</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideLibMoveUpBtn</cstring> + </property> + <property name="text"> + <string>Move Up</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>outsideLibMoveDownBtn</cstring> + </property> + <property name="text"> + <string>Move Down</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer8_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>64</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget" row="0" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>layout10</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QListView"> + <column> + <property name="text"> + <string>Link Convenience Libraries Inside Project</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>insidelib_listview</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout9_3</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KPushButton"> + <property name="name"> + <cstring>insideLibMoveUpBtn</cstring> + </property> + <property name="text"> + <string>Move Up</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>insideLibMoveDownBtn</cstring> + </property> + <property name="text"> + <string>Move Down</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer6_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </hbox> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>depTab</cstring> + </property> + <attribute name="title"> + <string>Dependencies</string> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout26</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QListView"> + <column> + <property name="text"> + <string>Targets in Project</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>intDeps_view</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout9_3_2</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="KPushButton"> + <property name="name"> + <cstring>intMoveUp_button</cstring> + </property> + <property name="text"> + <string>Move Up</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>intMoveDown_button</cstring> + </property> + <property name="text"> + <string>Move Down</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer6_2_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout27</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QListView"> + <column> + <property name="text"> + <string>Miscellaneous Targets</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>extDeps_view</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout9_2</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KPushButton"> + <property name="name"> + <cstring>extAdd_button</cstring> + </property> + <property name="text"> + <string>Add...</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>extRemove_button</cstring> + </property> + <property name="text"> + <string>Remove</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>extEdit_button</cstring> + </property> + <property name="text"> + <string>Edit</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>extMoveUp_button</cstring> + </property> + <property name="text"> + <string>Move Up</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>extMoveDown_button</cstring> + </property> + <property name="text"> + <string>Move Down</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer8_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>64</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout28_2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QListView"> + <column> + <property name="text"> + <string>Order in Which Sub Projects Are Built</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>buildorder_listview</cstring> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout9_2</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="KPushButton"> + <property name="name"> + <cstring>buildmoveup_button</cstring> + </property> + <property name="text"> + <string>Move Up</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>buildmovedown_button</cstring> + </property> + <property name="text"> + <string>Move Down</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer3_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </hbox> + </widget> + </vbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>buildOptsTab</cstring> + </property> + <attribute name="title"> + <string>Build Options</string> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>GroupBox2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Compiler Options</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout26</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout23</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2_2</cstring> + </property> + <property name="text"> + <string>Debug flags:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>m_debugFlags</cstring> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel2_2_2</cstring> + </property> + <property name="text"> + <string>Release flags:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>m_releaseFlags</cstring> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>Defines:</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout24</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KLineEdit"> + <property name="name"> + <cstring>m_debugFlags</cstring> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>m_releaseFlags</cstring> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>m_defines</cstring> + </property> + </widget> + </vbox> + </widget> + </hbox> + </widget> + </grid> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox8</cstring> + </property> + <property name="title"> + <string>Intermediate File Directories</string> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout84</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>mocdir_label</cstring> + </property> + <property name="text"> + <string>MOC files:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>mocdir_url</cstring> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>uidir_label</cstring> + </property> + <property name="text"> + <string>UI files:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>uidir_url</cstring> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>objdir_label</cstring> + </property> + <property name="text"> + <string>Object files:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>objdir_url</cstring> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>rccdir_label</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>RCC files:</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout85</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KURLRequester"> + <property name="name"> + <cstring>mocdir_url</cstring> + </property> + </widget> + <widget class="KURLRequester"> + <property name="name"> + <cstring>uidir_url</cstring> + </property> + </widget> + <widget class="KURLRequester"> + <property name="name"> + <cstring>objdir_url</cstring> + </property> + </widget> + <widget class="KURLRequester"> + <property name="name"> + <cstring>rccdir_url</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </vbox> + </widget> + </hbox> + </widget> + <widget class="QGroupBox"> + <property name="name"> + <cstring>idlGroup</cstring> + </property> + <property name="title"> + <string>Corba</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>TextLabel2_3</cstring> + </property> + <property name="text"> + <string>Compiler options:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>idlCmdOptionsEdit</cstring> + </property> + </widget> + <widget class="KLineEdit" row="1" column="1"> + <property name="name"> + <cstring>idlCmdOptionsEdit</cstring> + </property> + </widget> + <widget class="KURLRequester" row="0" column="1"> + <property name="name"> + <cstring>idlCmdEdit</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1_2_2</cstring> + </property> + <property name="text"> + <string>IDL compiler:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>idlCmdEdit</cstring> + </property> + </widget> + </grid> + </widget> + <spacer> + <property name="name"> + <cstring>spacer29</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>21</height> + </size> + </property> + </spacer> + </vbox> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>custVarsTab</cstring> + </property> + <attribute name="title"> + <string>Custom Variables</string> + </attribute> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout24</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KListView"> + <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>Operator</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + <property name="clickable"> + <bool>true</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>customVariables</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>6</verstretch> + </sizepolicy> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="defaultRenameAction"> + <enum>Accept</enum> + </property> + <property name="fullWidth"> + <bool>true</bool> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout23</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout22</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="KPushButton"> + <property name="name"> + <cstring>varAdd_button</cstring> + </property> + <property name="text"> + <string>New</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>varRemove_button</cstring> + </property> + <property name="text"> + <string>Remove</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>varMoveUp_button</cstring> + </property> + <property name="text"> + <string>Move Up</string> + </property> + </widget> + <widget class="KPushButton"> + <property name="name"> + <cstring>varMoveDown_button</cstring> + </property> + <property name="text"> + <string>Move Down</string> + </property> + </widget> + </vbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer8_2_2_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>106</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout33</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_3</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Name:</string> + </property> + </widget> + <widget class="KLineEdit"> + <property name="name"> + <cstring>customVariableName</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>3</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout32</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_5</cstring> + </property> + <property name="text"> + <string>Operator</string> + </property> + </widget> + <widget class="KComboBox"> + <item> + <property name="text"> + <string>+=</string> + </property> + </item> + <item> + <property name="text"> + <string>-=</string> + </property> + </item> + <item> + <property name="text"> + <string>=</string> + </property> + </item> + <item> + <property name="text"> + <string>*=</string> + </property> + </item> + <item> + <property name="text"> + <string>~=</string> + </property> + </item> + <property name="name"> + <cstring>customVariableOp</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="currentItem"> + <number>0</number> + </property> + <property name="duplicatesEnabled"> + <bool>false</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer17</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>250</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout34</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Value:</string> + </property> + <property name="alignment"> + <set>AlignTop</set> + </property> + </widget> + <widget class="KTextEdit"> + <property name="name"> + <cstring>customVariableData</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>2</verstretch> + </sizepolicy> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>idlCmdEdit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>idlCmdEdit</sender> + <signal>urlSelected(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>idlCmdOptionsEdit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>makefile_url</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>makefile_url</sender> + <signal>urlSelected(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>m_debugFlags</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>m_defines</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>m_InstallTargetPath</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>mocdir_url</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>mocdir_url</sender> + <signal>urlSelected(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>m_releaseFlags</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>m_targetLibraryVersion</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>m_targetOutputFile</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>objdir_url</sender> + <signal>urlSelected(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>objdir_url</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>rccdir_url</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>rccdir_url</sender> + <signal>urlSelected(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>uidir_url</sender> + <signal>urlSelected(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>editConfigExtra</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>m_editRunArguments</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>m_editDebugArguments</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>groupBuildMode</sender> + <signal>clicked(int)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(int)</slot> + </connection> + <connection> + <sender>groupQt4Libs</sender> + <signal>clicked(int)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(int)</slot> + </connection> + <connection> + <sender>insideinc_listview</sender> + <signal>clicked(QListViewItem*)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(QListViewItem*)</slot> + </connection> + <connection> + <sender>insideinc_listview</sender> + <signal>spacePressed(QListViewItem*)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(QListViewItem*)</slot> + </connection> + <connection> + <sender>insidelib_listview</sender> + <signal>clicked(QListViewItem*)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(QListViewItem*)</slot> + </connection> + <connection> + <sender>insidelib_listview</sender> + <signal>spacePressed(QListViewItem*)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(QListViewItem*)</slot> + </connection> + <connection> + <sender>intDeps_view</sender> + <signal>clicked(QListViewItem*)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(QListViewItem*)</slot> + </connection> + <connection> + <sender>intDeps_view</sender> + <signal>spacePressed(QListViewItem*)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(QListViewItem*)</slot> + </connection> + <connection> + <sender>varAdd_button</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>addCustomValueClicked()</slot> + </connection> + <connection> + <sender>buttonApply</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>apply()</slot> + </connection> + <connection> + <sender>buildmovedown_button</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>buildorderMoveDownClicked()</slot> + </connection> + <connection> + <sender>buildmoveup_button</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>buildorderMoveUpClicked()</slot> + </connection> + <connection> + <sender>customVariableName</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>customVarChanged()</slot> + </connection> + <connection> + <sender>customVariableOp</sender> + <signal>activated(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>customVarChanged()</slot> + </connection> + <connection> + <sender>customVariableData</sender> + <signal>textChanged()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>customVarChanged()</slot> + </connection> + <connection> + <sender>varMoveUp_button</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>downCustomValueClicked()</slot> + </connection> + <connection> + <sender>extAdd_button</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>extAdd_button_clicked()</slot> + </connection> + <connection> + <sender>extEdit_button</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>extEdit_button_clicked()</slot> + </connection> + <connection> + <sender>extMoveDown_button</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>extMoveDown_button_clicked()</slot> + </connection> + <connection> + <sender>extMoveUp_button</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>extMoveUp_button_clicked()</slot> + </connection> + <connection> + <sender>extRemove_button</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>extRemove_button_clicked()</slot> + </connection> + <connection> + <sender>groupLibraries</sender> + <signal>clicked(int)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>groupLibrariesChanged(int)</slot> + </connection> + <connection> + <sender>groupRequirements</sender> + <signal>clicked(int)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>groupRequirementsChanged(int)</slot> + </connection> + <connection> + <sender>groupTemplate</sender> + <signal>clicked(int)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>groupTemplateChanged(int)</slot> + </connection> + <connection> + <sender>insideIncMoveDownBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>insideIncMoveDownClicked()</slot> + </connection> + <connection> + <sender>insideIncMoveUpBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>insideIncMoveUpClicked()</slot> + </connection> + <connection> + <sender>insideLibMoveDownBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>insideLibMoveDownClicked()</slot> + </connection> + <connection> + <sender>insideLibMoveUpBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>insideLibMoveUpClicked()</slot> + </connection> + <connection> + <sender>intMoveDown_button</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>intMoveDown_button_clicked()</slot> + </connection> + <connection> + <sender>intMoveUp_button</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>intMoveUp_button_clicked()</slot> + </connection> + <connection> + <sender>customVariables</sender> + <signal>selectionChanged()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>newCustomVariableActive()</slot> + </connection> + <connection> + <sender>outsideIncAddBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideIncAddClicked()</slot> + </connection> + <connection> + <sender>outsideIncEditBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideIncEditClicked()</slot> + </connection> + <connection> + <sender>outsideIncMoveDownBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideIncMoveDownClicked()</slot> + </connection> + <connection> + <sender>outsideIncMoveUpBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideIncMoveUpClicked()</slot> + </connection> + <connection> + <sender>outsideIncRemoveBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideIncRemoveClicked()</slot> + </connection> + <connection> + <sender>outsideLibAddBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideLibAddClicked()</slot> + </connection> + <connection> + <sender>outsideLibDirAddBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideLibDirAddClicked()</slot> + </connection> + <connection> + <sender>outsideLibDirEditBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideLibDirEditClicked()</slot> + </connection> + <connection> + <sender>outsideLibDirMoveDownBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideLibDirMoveDownClicked()</slot> + </connection> + <connection> + <sender>outsideLibDirMoveUpBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideLibDirMoveUpClicked()</slot> + </connection> + <connection> + <sender>outsideLibDirRemoveBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideLibDirRemoveClicked()</slot> + </connection> + <connection> + <sender>outsideLibEditBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideLibEditClicked()</slot> + </connection> + <connection> + <sender>outsideLibMoveDownBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideLibMoveDownClicked()</slot> + </connection> + <connection> + <sender>outsideLibMoveUpBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideLibMoveUpClicked()</slot> + </connection> + <connection> + <sender>outsideLibRemoveBtn</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>outsideLibRemoveClicked()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>varRemove_button</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>removeCustomValueClicked()</slot> + </connection> + <connection> + <sender>checkOrdered</sender> + <signal>toggled(bool)</signal> + <receiver>buildmovedown_button</receiver> + <slot>setDisabled(bool)</slot> + </connection> + <connection> + <sender>checkOrdered</sender> + <signal>toggled(bool)</signal> + <receiver>buildmoveup_button</receiver> + <slot>setDisabled(bool)</slot> + </connection> + <connection> + <sender>checkOrdered</sender> + <signal>toggled(bool)</signal> + <receiver>buildorder_listview</receiver> + <slot>setDisabled(bool)</slot> + </connection> + <connection> + <sender>radioApplication</sender> + <signal>toggled(bool)</signal> + <receiver>argumentsGroupBox</receiver> + <slot>setEnabled(bool)</slot> + </connection> + <connection> + <sender>checkInstallTarget</sender> + <signal>toggled(bool)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>targetInstallChanged(bool)</slot> + </connection> + <connection> + <sender>varMoveDown_button</sender> + <signal>clicked()</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>upCustomValueClicked()</slot> + </connection> + <connection> + <sender>m_targetPath</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>m_targetPath</sender> + <signal>returnPressed(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>m_targetPath</sender> + <signal>urlSelected(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>uidir_url</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>m_CWDEdit</sender> + <signal>textChanged(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> + <connection> + <sender>m_CWDEdit</sender> + <signal>urlSelected(const QString&)</signal> + <receiver>ProjectConfigurationDlgBase</receiver> + <slot>activateApply(const QString&)</slot> + </connection> +</connections> +<tabstops> + <tabstop>TabBuild</tabstop> + <tabstop>radioApplication</tabstop> + <tabstop>radioLibrary</tabstop> + <tabstop>radioSubdirs</tabstop> + <tabstop>checkOrdered</tabstop> + <tabstop>m_targetOutputFile</tabstop> + <tabstop>checkInstallTarget</tabstop> + <tabstop>m_InstallTargetPath</tabstop> + <tabstop>makefile_url</tabstop> + <tabstop>radioDebugMode</tabstop> + <tabstop>radioReleaseMode</tabstop> + <tabstop>checkDebugReleaseMode</tabstop> + <tabstop>checkWarning</tabstop> + <tabstop>checkBuildAll</tabstop> + <tabstop>checkQt</tabstop> + <tabstop>checkOpenGL</tabstop> + <tabstop>stlCheck</tabstop> + <tabstop>checkWindows</tabstop> + <tabstop>checkThread</tabstop> + <tabstop>checkX11</tabstop> + <tabstop>rttiCheck</tabstop> + <tabstop>exceptionCheck</tabstop> + <tabstop>checkConsole</tabstop> + <tabstop>checkPCH</tabstop> + <tabstop>editConfigExtra</tabstop> + <tabstop>checkQt4Core</tabstop> + <tabstop>checkQt4Gui</tabstop> + <tabstop>checkQt4XML</tabstop> + <tabstop>checkQt4Network</tabstop> + <tabstop>checkQt4OpenGL</tabstop> + <tabstop>checkUiTools</tabstop> + <tabstop>checkQt4SQL</tabstop> + <tabstop>checkQt4SVG</tabstop> + <tabstop>checkTestlib</tabstop> + <tabstop>checkQt3Support</tabstop> + <tabstop>checkQDBus</tabstop> + <tabstop>checkAssistant</tabstop> + <tabstop>checkQtScript</tabstop> + <tabstop>checkQtWebKit</tabstop> + <tabstop>checkQtXmlPatterns</tabstop> + <tabstop>checkPhonon</tabstop> + <tabstop>checkQtHelp</tabstop> + <tabstop>staticRadio</tabstop> + <tabstop>checkPlugin</tabstop> + <tabstop>checkLibtool</tabstop> + <tabstop>sharedRadio</tabstop> + <tabstop>checkDesigner</tabstop> + <tabstop>m_targetLibraryVersion</tabstop> + <tabstop>insideinc_listview</tabstop> + <tabstop>insideIncMoveUpBtn</tabstop> + <tabstop>insideIncMoveDownBtn</tabstop> + <tabstop>outsideinc_listview</tabstop> + <tabstop>outsideIncAddBtn</tabstop> + <tabstop>outsideIncRemoveBtn</tabstop> + <tabstop>outsideIncEditBtn</tabstop> + <tabstop>outsideIncMoveUpBtn</tabstop> + <tabstop>outsideIncMoveDownBtn</tabstop> + <tabstop>insidelib_listview</tabstop> + <tabstop>insideLibMoveUpBtn</tabstop> + <tabstop>insideLibMoveDownBtn</tabstop> + <tabstop>outsidelibdir_listview</tabstop> + <tabstop>outsideLibDirAddBtn</tabstop> + <tabstop>outsideLibDirRemoveBtn</tabstop> + <tabstop>outsideLibDirEditBtn</tabstop> + <tabstop>outsideLibDirMoveUpBtn</tabstop> + <tabstop>outsideLibDirMoveDownBtn</tabstop> + <tabstop>outsidelib_listview</tabstop> + <tabstop>outsideLibAddBtn</tabstop> + <tabstop>outsideLibRemoveBtn</tabstop> + <tabstop>outsideLibEditBtn</tabstop> + <tabstop>outsideLibMoveUpBtn</tabstop> + <tabstop>outsideLibMoveDownBtn</tabstop> + <tabstop>intDeps_view</tabstop> + <tabstop>intMoveUp_button</tabstop> + <tabstop>intMoveDown_button</tabstop> + <tabstop>extDeps_view</tabstop> + <tabstop>extAdd_button</tabstop> + <tabstop>extRemove_button</tabstop> + <tabstop>extEdit_button</tabstop> + <tabstop>extMoveUp_button</tabstop> + <tabstop>extMoveDown_button</tabstop> + <tabstop>buildorder_listview</tabstop> + <tabstop>buildmoveup_button</tabstop> + <tabstop>buildmovedown_button</tabstop> + <tabstop>m_debugFlags</tabstop> + <tabstop>m_releaseFlags</tabstop> + <tabstop>m_defines</tabstop> + <tabstop>mocdir_url</tabstop> + <tabstop>uidir_url</tabstop> + <tabstop>objdir_url</tabstop> + <tabstop>rccdir_url</tabstop> + <tabstop>idlCmdEdit</tabstop> + <tabstop>idlCmdOptionsEdit</tabstop> + <tabstop>customVariables</tabstop> + <tabstop>varAdd_button</tabstop> + <tabstop>varRemove_button</tabstop> + <tabstop>varMoveUp_button</tabstop> + <tabstop>varMoveDown_button</tabstop> + <tabstop>customVariableName</tabstop> + <tabstop>customVariableOp</tabstop> + <tabstop>customVariableData</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonApply</tabstop> + <tabstop>buttonCancel</tabstop> +</tabstops> +<includes> + <include location="global" impldecl="in implementation">klineedit.h</include> + <include location="global" impldecl="in implementation">kdialog.h</include> + <include location="global" impldecl="in implementation">kpushbutton.h</include> +</includes> +<slots> + <slot>updateProjectConfiguration()</slot> + <slot>buildorderMoveUpClicked()</slot> + <slot>buildorderMoveDownClicked()</slot> + <slot>outsideIncMoveUpClicked()</slot> + <slot>outsideIncMoveDownClicked()</slot> + <slot>insideIncMoveUpClicked()</slot> + <slot>insideIncMoveDownClicked()</slot> + <slot>outsideLibMoveUpClicked()</slot> + <slot>outsideLibMoveDownClicked()</slot> + <slot>insideLibMoveUpClicked()</slot> + <slot>insideLibMoveDownClicked()</slot> + <slot>outsideIncAddClicked()</slot> + <slot>outsideIncRemoveClicked()</slot> + <slot>outsideLibAddClicked()</slot> + <slot>outsideLibRemoveClicked()</slot> + <slot>outsideLibDirMoveDownClicked()</slot> + <slot>outsideLibDirMoveUpClicked()</slot> + <slot>outsideLibDirAddClicked()</slot> + <slot>outsideLibDirRemoveClicked()</slot> + <slot>outsideLibDirEditClicked()</slot> + <slot>outsideLibEditClicked()</slot> + <slot>outsideIncEditClicked()</slot> + <slot>intMoveUp_button_clicked()</slot> + <slot>intMoveDown_button_clicked()</slot> + <slot>extAdd_button_clicked()</slot> + <slot>extRemove_button_clicked()</slot> + <slot>extEdit_button_clicked()</slot> + <slot>extMoveUp_button_clicked()</slot> + <slot>extMoveDown_button_clicked()</slot> + <slot>removeCustomValueClicked()</slot> + <slot>upCustomValueClicked()</slot> + <slot>downCustomValueClicked()</slot> + <slot>newCustomVariableActive()</slot> + <slot>addCustomValueClicked()</slot> + <slot>groupRequirementsChanged( int )</slot> + <slot>groupLibrariesChanged( int )</slot> + <slot>groupTemplateChanged( int )</slot> + <slot>targetInstallChanged( bool )</slot> + <slot>apply()</slot> + <slot>activateApply( int )</slot> + <slot>activateApply( const QString & )</slot> + <slot>activateApply( QListViewItem * )</slot> + <slot>customVarChanged()</slot> +</slots> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +<includehints> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kurlrequester.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>klistview.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kpushbutton.h</includehint> + <includehint>kcombobox.h</includehint> + <includehint>ktextedit.h</includehint> +</includehints> +</UI> diff --git a/buildtools/qmake/qmakedefaultopts.cpp b/buildtools/qmake/qmakedefaultopts.cpp new file mode 100644 index 00000000..14ca7aa0 --- /dev/null +++ b/buildtools/qmake/qmakedefaultopts.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 "qmakedefaultopts.h" + +#include <kdebug.h> +#include <ktempfile.h> +#include <qregexp.h> +#include <kprocess.h> + +#include <blockingkprocess.h> + +QMakeDefaultOpts::QMakeDefaultOpts() +{ + +} + +void QMakeDefaultOpts::readVariables( const QString& qmake, const QString& projdir ) +{ + KTempFile makefile (projdir+"/", ".mf"); + KTempFile qmakefile(projdir+"/", ".pro"); + if ( makefile.status() == 0 && qmakefile.status() == 0 ) + { + makefile.close(); + qmakefile.close(); + + BlockingKProcess proc; + kdDebug(9024) << "KProc Working dir:" << projdir << endl; + proc.setWorkingDirectory( projdir ); + proc << qmake; + proc << "-d"; + proc << "-o"; + proc << makefile.name(); + proc << qmakefile.name(); + kdDebug(9024) << "Executing:" << proc.args() << endl; + proc.start( KProcess::NotifyOnExit, KProcess::Stderr ); + if( !proc.isRunning() && !proc.normalExit() ) + { + kdDebug(9024) << "Couldn't execute qmake: " << proc.args() << endl; + makefile.unlink(); + qmakefile.unlink(); + m_variables.clear(); + m_keys.clear(); + }else + { + makefile.unlink(); + qmakefile.unlink(); + QStringList lines = QStringList::split( "\n", proc.stdErr() ); + kdDebug(9024) << "Got " << lines.count() << " lines" << endl; + for ( QStringList::const_iterator it = lines.begin(); it != lines.end(); ++it) + { + QString line = *it; + QRegExp re( "DEBUG 1: ([^ =:]+) === (.*)" ); + if ( re.exactMatch( line ) ) + { + QString var = re.cap( 1 ); + QStringList values = QStringList::split( " :: ", re.cap( 2 ) ); + m_variables[var] = values; + m_keys.append( var ); + } + } + } + } +} + +QMakeDefaultOpts::~QMakeDefaultOpts() +{ +} + +const QStringList QMakeDefaultOpts::variableValues( const QString& var ) const +{ +// QStringList result; + if ( m_variables.contains(var) ) + return m_variables[var]; + return QStringList(); +} + +const QStringList& QMakeDefaultOpts::variables() const +{ + return m_keys; +} + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/qmakedefaultopts.h b/buildtools/qmake/qmakedefaultopts.h new file mode 100644 index 00000000..63bab54b --- /dev/null +++ b/buildtools/qmake/qmakedefaultopts.h @@ -0,0 +1,49 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 QMAKEDEFAULTOPTS_H +#define QMAKEDEFAULTOPTS_H + +#include <qmap.h> +#include <qstringlist.h> +// #include <qobject.h> + +// class KTempFile; +// class BlockingKProcess; + +class QMakeDefaultOpts +{ +public: + QMakeDefaultOpts( ); + + ~QMakeDefaultOpts(); + + void readVariables( const QString& qtdir, const QString& projdir ); + + const QStringList variableValues( const QString& ) const; + const QStringList& variables() const; + +// signals: +// void variablesRead(); + +// private slots: +// void slotReadStderr( KProcess*, char*, int ); +// void slotFinished( KProcess* ); + +private: + QMap<QString, QStringList> m_variables; + QStringList m_keys; +}; + +#endif + + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/qmakeoptionswidget.cpp b/buildtools/qmake/qmakeoptionswidget.cpp new file mode 100644 index 00000000..89f63c1e --- /dev/null +++ b/buildtools/qmake/qmakeoptionswidget.cpp @@ -0,0 +1,63 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 "qmakeoptionswidget.h" + +#include <qcheckbox.h> +#include <kcombobox.h> +#include <qbuttongroup.h> +#include <kurlrequester.h> + +#include <domutil.h> +#include <kdebug.h> + +QMakeOptionsWidget::QMakeOptionsWidget( const QString& projectdir, QDomDocument &dom, const QString &configGroup, + QWidget *parent, const char *name ) + : QMakeOptionsWidgetBase( parent, name ), + m_dom( dom ), m_configGroup( configGroup ), m_projectDir( projectdir ) +{ + groupBehaviour->setButton( DomUtil::readIntEntry( dom, configGroup+"/qmake/savebehaviour", 2) ); + checkReplacePaths->setChecked( DomUtil::readBoolEntry( dom, configGroup+"/qmake/replacePaths", false ) ); + checkDisableDefaultOpts->setChecked( DomUtil::readBoolEntry( dom, configGroup+"/qmake/disableDefaultOpts", true ) ); + checkFilenamesOnly->setChecked( DomUtil::readBoolEntry( dom, configGroup+"/qmake/enableFilenamesOnly", false ) ); + showVariablesInTree->setChecked( DomUtil::readBoolEntry( dom, configGroup+"/qmake/showVariablesInTree", true ) ); + checkShowParseErrors->setChecked( DomUtil::readBoolEntry( dom, + configGroup+"/qmake/showParseErrors", true ) ); + qmakeProjectFile->setURL( DomUtil::readEntry( dom, configGroup+"/qmake/projectfile", "" ) ); + qmakeProjectFile->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly ); + qmakeProjectFile->setFilter( "*.pro *.pri" ); + if( qmakeProjectFile->url().isEmpty() ) + { + qmakeProjectFile->setURL( projectdir ); + } +} + + +QMakeOptionsWidget::~QMakeOptionsWidget() +{} + + +void QMakeOptionsWidget::accept() +{ + DomUtil::writeIntEntry( m_dom, m_configGroup + "/qmake/savebehaviour", groupBehaviour->selectedId() ); + DomUtil::writeBoolEntry( m_dom, m_configGroup + "/qmake/replacePaths", checkReplacePaths->isChecked() ); + DomUtil::writeBoolEntry( m_dom, m_configGroup + "/qmake/disableDefaultOpts", checkDisableDefaultOpts->isChecked() ); + DomUtil::writeBoolEntry( m_dom, m_configGroup + "/qmake/enableFilenamesOnly", checkFilenamesOnly->isChecked() ); + DomUtil::writeBoolEntry( m_dom, m_configGroup + "/qmake/showVariablesInTree", showVariablesInTree->isChecked() ); + DomUtil::writeBoolEntry( m_dom, m_configGroup + "/qmake/showParseErrors", checkShowParseErrors->isChecked() ); + QString projfile = qmakeProjectFile->url(); + if( projfile != m_projectDir && QFileInfo( projfile ).isFile() && ( projfile.endsWith( ".pro" ) || projfile.endsWith( ".pri" ) ) ) + DomUtil::writeEntry( m_dom, m_configGroup + "/qmake/projectfile", projfile ); +} + +#include "qmakeoptionswidget.moc" + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/qmakeoptionswidget.h b/buildtools/qmake/qmakeoptionswidget.h new file mode 100644 index 00000000..c50e4b44 --- /dev/null +++ b/buildtools/qmake/qmakeoptionswidget.h @@ -0,0 +1,39 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 QMAKEOPTIONSWIDGET_H +#define QMAKEOPTIONSWIDGET_H + +#include "qmakeoptionswidgetbase.h" + +#include <qdom.h> + +class QMakeOptionsWidget : public QMakeOptionsWidgetBase +{ + Q_OBJECT +public: + QMakeOptionsWidget( const QString& projectdir, QDomDocument &dom, const QString &configGroup, + QWidget *parent = 0, const char *name = 0 ); + ~QMakeOptionsWidget(); + +public slots: + void accept(); +private: + QDomDocument &m_dom; + QString m_configGroup; + QString m_projectDir; +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + + diff --git a/buildtools/qmake/qmakeoptionswidgetbase.ui b/buildtools/qmake/qmakeoptionswidgetbase.ui new file mode 100644 index 00000000..0ad833d1 --- /dev/null +++ b/buildtools/qmake/qmakeoptionswidgetbase.ui @@ -0,0 +1,217 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>QMakeOptionsWidgetBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>QMakeOptionsWidgetBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>738</width> + <height>523</height> + </rect> + </property> + <property name="caption"> + <string>QMake Manager Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="text"> + <string>- Also look into C++/Qt to define the QMake, Qt and Designer paths. +- Environment variables that should be resolved during parsing can be set on the Make Options page. +- For changes on this page to take effect the project needs to be reloaded.</string> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_3</cstring> + </property> + <property name="text"> + <string>QMake Project File:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>qmakeProjectFile</cstring> + </property> + </widget> + <widget class="KURLRequester"> + <property name="name"> + <cstring>qmakeProjectFile</cstring> + </property> + <property name="toolTip" stdset="0"> + <string>This is the top level qmake project file, from which the project manager will be populated. +Leave this empty to automatically search for a .pro file in the project directory.</string> + </property> + </widget> + </hbox> + </widget> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>groupBehaviour</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Behaviour on Subproject Change</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="text"> + <string>The following settings determine what the project configuration dialog should do when another subproject is selected while the dialog is still open.</string> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter</set> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>radioAlwaysSave</cstring> + </property> + <property name="text"> + <string>&Always Save</string> + </property> + <property name="toolTip" stdset="0"> + <string>Always save the configuration when changing the project.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Always save the project configuration when selecting a another sub project.</string> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>radioNeverSave</cstring> + </property> + <property name="text"> + <string>&Never Save (Warning: This can lead to loss of setting changes)</string> + </property> + <property name="toolTip" stdset="0"> + <string>Never save the configuration when changing the project.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Never save the project configuration when selecting a another sub project.</string> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>radioAsk</cstring> + </property> + <property name="text"> + <string>As&k</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="toolTip" stdset="0"> + <string>Ask whether the configuration should be saved when switching the project.</string> + </property> + <property name="whatsThis" stdset="0"> + <string>Always ask whether the configuration should be saved when selecting another subproject.</string> + </property> + </widget> + </vbox> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkReplacePaths</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Repla&ce File Paths with matching Variables when adding files</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="toolTip" stdset="0"> + <string>This replaces the relative paths of added files with existing custom variables if the value assigned to it is the same as the path.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>showVariablesInTree</cstring> + </property> + <property name="text"> + <string>Show variables in filenames in the QMake projectmanager view.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkFilenamesOnly</cstring> + </property> + <property name="text"> + <string>Display only filenames in the QMake Manager (Project reload is needed after changing this setting)</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkDisableDefaultOpts</cstring> + </property> + <property name="text"> + <string>Do not use the QMake Default Options +This disables the reading of any .qmake.cache files or mkspecs.</string> + </property> + </widget> + <widget class="QCheckBox"> + <property name="name"> + <cstring>checkShowParseErrors</cstring> + </property> + <property name="text"> + <string>Show parse error in message box</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <spacer> + <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>50</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>kurlrequester.h</includehint> + <includehint>klineedit.h</includehint> + <includehint>kpushbutton.h</includehint> +</includehints> +</UI> diff --git a/buildtools/qmake/qmakescopeitem.cpp b/buildtools/qmake/qmakescopeitem.cpp new file mode 100644 index 00000000..66fa3c3f --- /dev/null +++ b/buildtools/qmake/qmakescopeitem.cpp @@ -0,0 +1,928 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* Part of this file is taken from Qt Designer. * +* * +* 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 "qmakescopeitem.h" + +#include <qdir.h> +#include <qregexp.h> + +#include <kiconloader.h> +#include <klocale.h> +#include <kdebug.h> +#include <kdirwatch.h> + +#include "scope.h" +#include "urlutil.h" +#include "trollprojectwidget.h" +/* + * Class qProjectItem + */ + +qProjectItem::qProjectItem( Type type, QListView *parent, const QString &text ) + : QListViewItem( parent, text ), typ( type ) +{} + + +qProjectItem::qProjectItem( Type type, qProjectItem *parent, const QString &text ) + : QListViewItem( parent, text ), typ( type ) +{} + + + +/* + * Class GroupItem + */ + +GroupItem::GroupItem( QListView *lv, GroupType type, const QString &text, QMakeScopeItem* spitem ) + : qProjectItem( Group, lv, text ) +{ + this->owner = spitem; + groupType = type; +// files.setAutoDelete( true ); + setPixmap( 0, SmallIcon( "tar" ) ); +} + +GroupItem::GroupType GroupItem::groupTypeForExtension( const QString &ext ) +{ + if ( ext == "cpp" || ext == "cc" || ext == "c" || ext == "C" || ext == "c++" || ext == "cxx" || ext == "ocl" ) + return Sources; + else if ( ext == "hpp" || ext == "h" || ext == "hxx" || ext == "hh" || ext == "h++" || ext == "H" ) + return Headers; + else if ( ext == "ui" ) + return Forms; + else if ( ext == "jpg" || ext == "jpeg" || ext == "png" || ext == "xpm" || ext == "gif" || ext == "bmp" ) + return Images; + else if ( ext == "idl" ) + return IDLs; + else if ( ext == "l" || ext == "ll" || ext == "lxx" || ext == "l++" ) + return Lexsources; + else if ( ext == "y" || ext == "yy" || ext == "yxx" || ext == "y++" ) + return Yaccsources; + else if ( ext == "ts" ) + return Translations; + else if ( ext == "qrc" ) + return Resources; + else + return Distfiles; +} + +void GroupItem::groupTypeMeanings( GroupItem::GroupType type, QString& title, QString& ext ) +{ + switch ( type ) + { + case GroupItem::Sources: + title = i18n( "Sources" ); + ext = "*.cpp *.c"; + break; + case GroupItem::Headers: + title = i18n( "Headers" ); + ext = "*.h *.hpp"; + break; + case GroupItem::Forms: + title = i18n( "Forms" ); + ext = "*.ui"; + break; + case GroupItem::IDLs: + title = i18n( "Corba IDLs" ); + ext = "*.idl *.kidl"; + break; + case GroupItem::Lexsources: + title = i18n( "Lexsources" ); + ext = "*.l *.ll *.lxx *.l++"; + break; + case GroupItem::Yaccsources: + title = i18n( "Yaccsources" ); + ext = "*.y *.yy *.yxx *.y++"; + break; + case GroupItem::Images: + title = i18n( "Images" ); + ext = "*.jpg *.jpeg *.png *.xpm *.gif *.bmp"; + break; + case GroupItem::Resources: + title = i18n( "Resources" ); + ext = "*.qrc"; + break; + case GroupItem::Distfiles: + title = i18n( "Distfiles" ); + ext = "*"; + break; + case GroupItem::Translations: + title = i18n( "Translations" ); + ext = "*.ts"; + break; + case GroupItem::InstallRoot: + title = i18n( "Installs" ); + ext = "*"; + break; + case GroupItem::InstallObject: + title = i18n( "Install object" ); + ext = "*"; + break; + + default: // just give back source files, et all + title = i18n( "Source Files" ); + ext = "*.cpp *.cc *.ocl *.c *.hpp *.h *.ui"; + } +} + +void GroupItem::paintCell( QPainter* p, const QColorGroup& c, int column, int width, int align ) +{ + QColorGroup cg( c ); + if ( !firstChild() ) + { + cg.setColor( QColorGroup::Text, cg.mid() ); + } + + qProjectItem::paintCell( p, cg, column, width, align ); +} + +void GroupItem::addFileToScope( const QString& filename ) +{ + QString file = filename; + + QPtrListIterator<FileItem> it( files ); + while ( it.current() != 0 ) + { + if ( it.current() ->text( 0 ) == file ) //File already exists in this subproject + return ; + ++it; + } + + FileItem *fitem = owner->createFileItem( file ); + + fitem->uiFileLink = owner->m_widget->getUiFileLink( owner->relativePath() + QString( QChar( QDir::separator() ) ), owner->scope->resolveVariables( filename ) ); + files.append( fitem ); + switch ( groupType ) + { + case GroupItem::Sources: + owner->addValue( "SOURCES", file ); + break; + case GroupItem::Headers: + owner->addValue( "HEADERS", file ); + break; + case GroupItem::Forms: + if( owner->m_widget->isTMakeProject() ) + owner->addValue( "INTERFACES", file ); + else + owner->addValue( "FORMS", file ); + break; + case GroupItem::IDLs: + owner->addValue( "IDLS", file ); + break; + case GroupItem::Lexsources: + owner->addValue( "LEXSOURCES", file ); + break; + case GroupItem::Yaccsources: + owner->addValue( "YACCSOURCES", file ); + break; + case GroupItem::Images: + owner->addValue( "IMAGES", file ); + break; + case GroupItem::Resources: + owner->addValue( "RESOURCES", file ); + break; + case GroupItem::Distfiles: + owner->addValue( "DISTFILES", file ); + break; + case GroupItem::Translations: + owner->addValue( "TRANSLATIONS", file ); + break; + case GroupItem::InstallObject: + owner->addValue( text( 0 ) + ".files", file ); + break; + default: + break; + } + owner->scope->saveToFile(); +} + +void GroupItem::removeFileFromScope( const QString& filename ) +{ + QString filePath; + + QPtrListIterator<FileItem> it( files ); + while ( it.current() != 0 ) + { + if ( it.current() ->text( 0 ) == filename ) //File already exists in this subproject + { + FileItem * fitem = it.current(); + filePath = fitem->localFilePath; + files.remove( it ); + delete fitem; + break; + } + ++it; + } + + if ( groupType == GroupItem::Sources ) + { + owner->removeValue( "SOURCES", filePath ); + } + else if ( groupType == GroupItem::Headers ) + { + owner->removeValue( "HEADERS", filePath ); + } + else if ( groupType == GroupItem::Forms ) + { + owner->removeValue( "FORMS", filePath ); + } + else if ( groupType == GroupItem::Images ) + { + owner->removeValue( "IMAGES", filePath ); + } + else if ( groupType == GroupItem::Resources ) + { + owner->removeValue( "RESOURCES", filePath ); + } + else if ( groupType == GroupItem::Lexsources ) + { + owner->removeValue( "LEXSOURCES", filePath ); + } + else if ( groupType == GroupItem::Yaccsources ) + { + owner->removeValue( "YACCSOURCES", filePath ); + } + else if ( groupType == GroupItem::Translations ) + { + owner->removeValue( "TRANSLATIONS", filePath ); + } + else if ( groupType == GroupItem::IDLs ) + { + owner->removeValue( "IDL", filePath ); + } + else if ( groupType == GroupItem::Distfiles ) + { + owner->removeValue( "DISTFILES", filePath ); + } + else if ( groupType == GroupItem::InstallObject ) + { + owner->removeValue( text( 0 ) + ".files", filePath ); + } + owner->scope->saveToFile(); +} + +void GroupItem::addInstallObject( const QString& objectname ) +{ + GroupItem * objitem = owner->createGroupItem( GroupItem::InstallObject, objectname, owner ); + owner->addValue( "INSTALLS", objectname ); + owner->scope->saveToFile(); + installs.append( objitem ); +} + +void GroupItem::removeInstallObject( GroupItem* item ) +{ + owner->removeValue( "INSTALLS", item->text(0) ); + owner->scope->saveToFile(); + installs.remove( item ); + delete item; +} + +/* + * Class FileItem + */ + +FileItem::FileItem( QListView *lv, const QString &text ) + : qProjectItem( File, lv, text ), uiFileLink( "" ) +{ + // if excluded is set the file is excluded in the subproject/project. + // by default excluded is set to false, thus file is included + // excluded = exclude; + setPixmap( 0, SmallIcon( "document" ) ); +} + + +/* + * Class QMakeScopeItem + */ + +QMakeScopeItem::QMakeScopeItem( QListView *parent, const QString &text, Scope* s, TrollProjectWidget* widget ) + : qProjectItem( Subproject, parent, text ), scope( s ), m_widget( widget ) +{ + // configuration.m_template = QTMP_APPLICATION; + init(); +} + + +QMakeScopeItem::QMakeScopeItem( QMakeScopeItem *parent, const QString &text, Scope* s ) + : qProjectItem( Subproject, parent, text ), scope( s ), m_widget( parent->m_widget ) +{ + init(); +} + +QMakeScopeItem::~QMakeScopeItem() +{ + QMap<GroupItem::GroupType, GroupItem*>::iterator it; + for ( it = groups.begin() ; it != groups.end() ; ++it ) + { + GroupItem* s = it.data(); + delete s; + } + groups.clear(); + +} + +QString QMakeScopeItem::relativePath() +{ + if( !scope || !scope->parent() ) + return ""; + if( scope->scopeType() == Scope::ProjectScope ) + { + if( scope->parent() && scope->parent()->variableValues("SUBDIRS").contains( URLUtil::relativePathToFile( scope->parent()->projectDir(), scope->projectDir()+"/"+scope->fileName() ) ) ) + { + return URLUtil::relativePathToFile( scope->parent()->projectDir(), scope->projectDir()+"/"+scope->fileName() ); + }else + { + return URLUtil::getRelativePath( m_widget->projectDirectory(), scope->projectDir() ); + } + }else + return static_cast<QMakeScopeItem*>( parent() ) ->relativePath(); +// if( !scope->parent() ) +// return ""; +// else if ( !scope->parent()->parent() || scope->scopeType() != Scope::ProjectScope ) +// return scope->scopeName(); +// else if ( scope->scopeType() == Scope::ProjectScope ) +// return ( static_cast<QMakeScopeItem*>( parent() ) ->relativePath() +// + QString( QChar( QDir::separator() ) ) + scope->scopeName() ); +// else +// return ( static_cast<QMakeScopeItem*>( parent() ) ->relativePath() ); +} + +QString QMakeScopeItem::getSharedLibAddObject( QString basePath ) +{ + if ( scope->variableValues( "CONFIG" ).findIndex( "dll" ) != -1 ) + { + QString tmpPath = URLUtil::getRelativePath(basePath, scope->projectDir() ); + if ( !scope->variableValues( "DESTDIR" ).front().isEmpty() ) + { + if ( QDir::isRelativePath( scope->variableValues( "DESTDIR" ).front() ) ) + tmpPath += QString( QChar( QDir::separator() ) ) + scope->variableValues( "DESTDIR" ).front(); + else + tmpPath = scope->variableValues( "DESTDIR" ).front(); + } + else + { + tmpPath += QString( QChar( QDir::separator() ) ); + } + + tmpPath = QDir::cleanDirPath( tmpPath ); + + QString libString; + if ( !scope->variableValues( "TARGET" ).front().isEmpty() ) + { + libString = tmpPath + QString( QChar( QDir::separator() ) ) + "lib" + scope->variableValues( "TARGET" ).front() + ".so"; + + } + else + { + libString = tmpPath + QString( QChar( QDir::separator() ) ) + "lib" + scope->projectName() + ".so"; + + } + return ( libString ); + } + return ""; +} + +QString QMakeScopeItem::getApplicationObject( QString basePath ) +{ + QString tmpPath = URLUtil::getRelativePath(basePath, scope->projectDir() ); + QString destdir = scope->resolveVariables( scope->variableValues( "DESTDIR" ).front() ); + + if ( !destdir.isEmpty() ) + { + if ( QDir::isRelativePath( destdir ) ) + tmpPath += QString( QChar( QDir::separator() ) ) + destdir; + else + tmpPath = destdir; + } + else + { + tmpPath += QString( QChar( QDir::separator() ) ); + } + + tmpPath = QDir::cleanDirPath( tmpPath ); + + QString target = scope->resolveVariables( scope->variableValues( "TARGET" ).front() ); + + if ( target.isEmpty() ) + return tmpPath + QString( QChar( QDir::separator() ) ) + scope->projectName(); + else + return tmpPath + QString( QChar( QDir::separator() ) ) + target; +} + +QString QMakeScopeItem::getLibAddObject( QString basePath ) +{ + if ( scope->variableValues( "CONFIG" ).findIndex( "dll" ) != -1 ) + { + QString target = scope->resolveVariables( scope->variableValues( "TARGET" ).front() ); + if ( !target.isEmpty() ) + { + return ( "-l" + target ); + } + else + { + return ( "-l" + scope->projectName() ); + } + } + else if ( scope->variableValues( "CONFIG" ).findIndex( "staticlib" ) != -1 + || scope->variableValues("TEMPLATE").findIndex("lib") != -1 ) + { + QString tmpPath = URLUtil::getRelativePath(basePath, scope->projectDir() ); + QString destdir = scope->resolveVariables( scope->variableValues( "DESTDIR" ).front() ); + if ( !destdir.isEmpty() ) + { + if ( QDir::isRelativePath( destdir ) ) + tmpPath += QString( QChar( QDir::separator() ) ) + destdir; + else + tmpPath = destdir; + } + else + { + tmpPath += QString( QChar( QDir::separator() ) ); + } + + tmpPath = QDir::cleanDirPath( tmpPath ); + + QString libString; + QString target = scope->resolveVariables( scope->variableValues( "TARGET" ).front() ); + if ( !target.isEmpty() ) + { + libString = tmpPath + QString( QChar( QDir::separator() ) ) + "lib" + target + ".a"; + + } + else + { + libString = tmpPath + QString( QChar( QDir::separator() ) ) + "lib" + scope->projectName() + ".a"; + + } + return ( libString ); + } + + return ( "" ); +} +QString QMakeScopeItem::getLibAddPath( QString basePath ) +{ + + //PATH only add if shared lib + if ( scope->variableValues( "CONFIG" ).findIndex( "dll" ) == -1 ) return ( "" ); + + QString tmpPath = URLUtil::getRelativePath(basePath, scope->projectDir() ); + QString destdir = scope->resolveVariables( scope->variableValues( "DESTDIR" ).front() ); + if ( !destdir.isEmpty() ) + { + if ( QDir::isRelativePath( destdir ) ) + tmpPath += QString( QChar( QDir::separator() ) ) + destdir; + else + tmpPath = destdir; + } + else + { + tmpPath += QString( QChar( QDir::separator() ) ); + } + + tmpPath = QDir::cleanDirPath( tmpPath ); + + return ( tmpPath ); + +} + +QString QMakeScopeItem::getIncAddPath( QString basePath ) +{ + QString tmpPath = URLUtil::getRelativePath( basePath, scope->projectDir() ); + tmpPath = QDir::cleanDirPath( tmpPath ); + + return ( tmpPath ); +} + +void QMakeScopeItem::buildSubTree() +{ + QValueList<Scope*>::const_iterator it; + + sortChildItems( 0, false ); + + QValueList<Scope*> scopes = scope->scopesInOrder(); + + for ( it = scopes.begin(); it != scopes.end(); ++it ) + { + if( (*it)->scopeType() != Scope::InvalidScope ) + new QMakeScopeItem( this, ( *it )->scopeName(), ( *it ) ); + else + kdDebug( 9024 ) << "No QMakeScopeItem created" << endl; + } +} + + +void QMakeScopeItem::init() +{ + if ( scope->scopeType() == Scope::SimpleScope ) + { + setPixmap( 0, SmallIcon( "qmake_scope" ) ); + } + else if ( scope->scopeType() == Scope::FunctionScope ) + { + setPixmap( 0, SmallIcon( "qmake_func_scope" ) ); + } + else if ( scope->scopeType() == Scope::IncludeScope ) + { + setPixmap( 0, SmallIcon( "qmake_inc_scope" ) ); + } + else + { + QStringList tmp = scope->variableValues( "TEMPLATE" ); + if( scope->isEnabled() ) + { + if ( tmp.findIndex( "subdirs" ) != -1 ) + setPixmap( 0, SmallIcon( "folder" ) ); + else if ( tmp.findIndex( "lib" ) != -1 ) + setPixmap( 0, SmallIcon( "qmake_lib" ) ); + else + setPixmap( 0, SmallIcon( "qmake_app" ) ); + }else + { + if ( tmp.findIndex( "subdirs" ) != -1 ) + setPixmap( 0, SmallIcon( "folder_grey" ) ); + else if ( tmp.findIndex( "lib" ) != -1 ) + setPixmap( 0, SmallIcon( "qmake_lib_disabled" ) ); + else + setPixmap( 0, SmallIcon( "qmake_app_disabled" ) ); + } + } + + setEnabled( scope->isEnabled() ); + if( scope->isEnabled() ) + { + buildGroups(); + buildSubTree(); + } +} + +GroupItem* QMakeScopeItem::createGroupItem( GroupItem::GroupType type, const QString& label, QMakeScopeItem* scopeitem ) +{ + GroupItem * item = new GroupItem( scopeitem->listView(), type, label, scopeitem ); + scopeitem->listView() ->takeItem( item ); + return item; +} + +FileItem* QMakeScopeItem::createFileItem( const QString& name ) +{ + QString display = name; + if( m_widget->showFilenamesOnly() ) + { + int dirSepPos = name.findRev( QChar( QDir::separator() ) ); + if ( dirSepPos != - 1 ) + display = name.mid( dirSepPos + 1 ); + } + if( !m_widget->showVariablesInTree() ) + { + display = scope->resolveVariables( display ); + } + FileItem * fitem = new FileItem( listView(), display ); + listView() ->takeItem( fitem ); + + fitem->localFilePath = name; + + return fitem; +} + +void QMakeScopeItem::buildGroups() +{ + if( scope->variableValues("TEMPLATE").findIndex("subdirs") != -1 ) + return; + QStringList values; + + GroupItem* item; + QStringList::iterator it; + + values = scope->variableValues( "INSTALLS" ); + item = createGroupItem( GroupItem::InstallRoot, "INSTALLS", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + if ( ( *it ) == "target" ) + continue; + + QString path = scope->variableValues( *it + ".path" ).front(); + GroupItem* installitem = createGroupItem( GroupItem::InstallObject, *it, this ); + item->installs.append( installitem ); + QStringList files = scope -> variableValues( *it + ".files" ); + if ( !files.isEmpty() ) + { + QStringList::iterator filesit = files.begin(); + for ( ;filesit != files.end(); ++filesit ) + { + installitem->files.append( createFileItem( *filesit ) ); + } + } + } + + values = scope->variableValues( "LEXSOURCES" ); + item = createGroupItem( GroupItem::Lexsources, "LEXSOURCES", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + + values = scope->variableValues( "YACCSOURCES" ); + item = createGroupItem( GroupItem::Yaccsources, "YACCSOURCES", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + + values = scope->variableValues( "DISTFILES" ); + item = createGroupItem( GroupItem::Distfiles, "DISTFILES", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + + if ( scope->isQt4Project() ) + { + values = scope->variableValues( "RESOURCES" ); + item = createGroupItem( GroupItem::Resources, "RESOURCES", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + } + values = scope->variableValues( "IMAGES" ); + item = createGroupItem( GroupItem::Images, "IMAGES", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + + values = scope->variableValues( "TRANSLATIONS" ); + item = createGroupItem( GroupItem::Translations, "TRANSLATIONS", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + + values = scope->variableValues( "IDLS" ); + item = createGroupItem( GroupItem::IDLs, "Corba IDL", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + + if ( m_widget->isTMakeProject() ) + { + values = scope->variableValues( "INTERFACES" ); + item = createGroupItem( GroupItem::Forms, "INTERFACES", this ); + } + else + { + values = scope->variableValues( "FORMS" ); + item = createGroupItem( GroupItem::Forms, "FORMS", this ); + } + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + + values = scope->variableValues( "SOURCES" ); + item = createGroupItem( GroupItem::Sources, "SOURCES", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + FileItem* fitem = createFileItem( *it ); + fitem->uiFileLink = m_widget->getUiFileLink( relativePath() + QString( QChar( QDir::separator() ) ), scope->resolveVariables( *it ) ); + item->files.append( fitem ); + } + + values = scope->variableValues( "HEADERS" ); + item = createGroupItem( GroupItem::Headers, "HEADERS", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + FileItem* fitem = createFileItem( *it ); + fitem->uiFileLink = m_widget->getUiFileLink( relativePath() + QString( QChar( QDir::separator() ) ), scope->resolveVariables( *it ) ); + item->files.append( fitem ); + } + +} + +void QMakeScopeItem::removeValues( const QString& var, const QStringList& values ) +{ + for( QStringList::const_iterator it = values.begin() ; it != values.end(); ++it ) + { + removeValue( var, *it ); + } +} + +void QMakeScopeItem::addValues( const QString& var, const QStringList& values ) +{ + for( QStringList::const_iterator it = values.begin() ; it != values.end(); ++it ) + { + addValue( var, *it ); + } +} + +void QMakeScopeItem::removeValue( const QString& var, const QString& value ) +{ + if( scope->scopeType() != Scope::IncludeScope && scope->variableValues( var ).findIndex( value ) != -1 ) + { + if( scope->variableValuesForOp( var, "+=" ).findIndex(value) != -1 ) + { + scope->removeFromPlusOp( var, QStringList( value ) ); + if( scope->variableValues( var ).findIndex( value ) != -1 ) + { + scope->addToMinusOp( var, QStringList( value ) ); + } + }else + scope->addToMinusOp( var, QStringList( value ) ); + }else if( scope->scopeType() == Scope::IncludeScope ) + { + scope->addToMinusOp( var, QStringList( value ) ); + } +} + +void QMakeScopeItem::addValue( const QString& var, const QString& value ) +{ + if( scope->scopeType() != Scope::IncludeScope && scope->variableValues( var ).findIndex( value ) == -1 ) + { + if( scope->variableValuesForOp( var, "-=" ).findIndex(value) != -1 ) + scope->removeFromMinusOp( var, QStringList( value ) ); + else + scope->addToPlusOp( var, QStringList( value ) ); + }else if( scope->scopeType() == Scope::IncludeScope ) + { + scope->addToPlusOp( var, QStringList( value ) ); + } +} + +void QMakeScopeItem::updateValues( const QString& var, const QStringList& values ) +{ + QStringList curValues = scope->variableValues( var, (scope->scopeType() != Scope::IncludeScope) ); + QStringList scopeValues = scope->variableValuesForOp( var, "+=" ); + for( QStringList::const_iterator it = curValues.begin(); it != curValues.end(); ++it ) + { + if ( values.findIndex( *it ) == -1 ) + { + if( scopeValues.findIndex( *it ) != -1 ) + { + scope->removeFromPlusOp( var, QStringList( *it ) ); + scopeValues.remove( *it ); + }else + scope->addToMinusOp( var, QStringList( *it ) ); + } + } + for( QStringList::const_iterator it = values.begin(); it != values.end(); ++it ) + { + if ( scopeValues.findIndex( *it ) != -1 ) + { + scopeValues.remove(*it); + } + } +// kdDebug(9024) << "--------------" << var << "------------------" << endl; +// kdDebug(9024) << "values: " << values << "| scope:" << scopeValues << endl; + scopeValues += values; +// kdDebug(9024) << "values: " << values << "| scope:" << scopeValues << endl; + scope->setPlusOp( var, scopeValues ); +// QStringList tmp = scope->variableValuesForOp( var, "+=" ); +// kdDebug(9024) << "result:" << tmp << endl; +// kdDebug(9024) << "---------------------------------------" << endl; +} + +QMakeScopeItem* QMakeScopeItem::projectFileItem() +{ + if( scope->scopeType() != Scope::ProjectScope ) + { + QMakeScopeItem* parentitem = dynamic_cast<QMakeScopeItem*>(parent()); + if( parentitem ) + return parentitem->projectFileItem(); + } + return this; +} + +void QMakeScopeItem::reloadProject() +{ + kdDebug(9024) << "Reloading Project" << endl; + QListViewItem* item = firstChild(); + while( item ) + { + QListViewItem* olditem = item; + item = olditem->nextSibling(); + delete olditem; + } + QMap<GroupItem::GroupType, GroupItem*>::iterator it; + for ( it = groups.begin() ; it != groups.end() ; ++it ) + { + GroupItem* s = it.data(); + QListView* l = s->listView(); + if(l) + l->removeItem(s); + delete s; + } + groups.clear(); + scope->reloadProject(); + init(); +} + +void QMakeScopeItem::disableSubprojects( const QStringList& dirs ) +{ + QStringList::const_iterator it = dirs.begin(); + for( ; it != dirs.end() ; ++it) + { + if( scope->variableValues("SUBDIRS").findIndex(*it) != -1 ) + { + Scope* s = scope->disableSubproject(*it); + if( !s ) + return; + else + { + QMakeScopeItem* newitem = new QMakeScopeItem( this, s->scopeName(), s ); + QListViewItem* lastitem = firstChild(); + while( lastitem && lastitem->nextSibling() ) + lastitem = lastitem->nextSibling(); + if( lastitem ) + newitem->moveItem(lastitem); + } + } + } + +} + +int QMakeScopeItem::compare( QListViewItem* i, int , bool ) const +{ + QMakeScopeItem* other = dynamic_cast<QMakeScopeItem*>(i); + if( !i ) + return -1; + if( other->scope->getNum() < scope->getNum() ) + return 1; + else if ( other->scope->getNum() > scope->getNum() ) + return -1; + else + return 0; +} + +QMap<QString, QString> QMakeScopeItem::getLibInfos( QString basePath ) +{ + + QMap<QString, QString> result; + if ( scope->variableValues( "TARGET" ).front().isEmpty() ) + result["shared_lib"] = "-l"+scope->projectName(); + else + result["shared_lib"] = "-l"+scope->variableValues( "TARGET" ).front(); + + QString tmpPath = URLUtil::getRelativePath(basePath, scope->projectDir() ); + if ( !scope->variableValues( "DESTDIR" ).front().isEmpty() ) + { + if ( QDir::isRelativePath( scope->variableValues( "DESTDIR" ).front() ) ) + tmpPath += QString( QChar( QDir::separator() ) ) + scope->variableValues( "DESTDIR" ).front(); + else + tmpPath = scope->variableValues( "DESTDIR" ).front(); + } + else + { + tmpPath += QString( QChar( QDir::separator() ) ); + } + + tmpPath = QDir::cleanDirPath( tmpPath ); + + result["shared_libdir"] = "-L"+tmpPath; + + if ( scope->variableValues( "TARGET" ).front().isEmpty() ) + result["shared_depend"] = tmpPath+QString(QChar(QDir::separator()))+"lib"+scope->projectName()+".so"; + else + result["shared_depend"] = tmpPath+QString(QChar(QDir::separator()))+"lib"+scope->variableValues( "TARGET" ).front()+".so"; + + + if ( scope->variableValues( "TARGET" ).front().isEmpty() ) + result["static_lib"] = tmpPath+QString(QChar(QDir::separator()))+"lib"+scope->projectName()+".a"; + else + result["static_lib"] = tmpPath+QString(QChar(QDir::separator()))+"lib"+scope->variableValues( "TARGET" ).front()+".a"; + + result["static_depend"] = result["static_lib"]; + + if ( scope->variableValues( "TARGET" ).front().isEmpty() ) + result["app_depend"] = tmpPath + QString( QChar( QDir::separator() ) ) + scope->projectName(); + else + result["app_depend"] = tmpPath + QString( QChar( QDir::separator() ) ) + scope->variableValues( "TARGET" ).front(); + + QString map; + for( QMap<QString, QString>::const_iterator it = result.begin(); it != result.end(); ++it ) + map += "["+it.key() + "=>" +it.data() + "],"; + kdDebug(9024) << "Running getLibInfo for" << scope->projectName() << "|" << map << endl; + return result; +} + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/qmakescopeitem.h b/buildtools/qmake/qmakescopeitem.h new file mode 100644 index 00000000..b2c84345 --- /dev/null +++ b/buildtools/qmake/qmakescopeitem.h @@ -0,0 +1,128 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 _QMAKESCOPEITEM_H_ +#define _QMAKESCOPEITEM_H_ + +#include <qlistview.h> +#include <qstring.h> + +class Scope; +class QMakeScopeItem; +class FileItem; +class TrollProjectWidget; + +/** + * Base class for all items appearing in ProjectOverview and ProjectDetails. + */ +class qProjectItem : public QListViewItem +{ +public: + enum Type { Subproject, Group, File }; + + qProjectItem( Type type, QListView *parent, const QString &text ); + qProjectItem( Type type, qProjectItem *parent, const QString &text ); + + QString scopeString; + Type type() + { return typ; } + +private: + Type typ; + void init(); + +}; + + +class GroupItem : public qProjectItem +{ +public: + enum GroupType {NoType, Sources, Headers, Forms, Distfiles, Images, Resources, Lexsources, Yaccsources, Translations, IDLs, InstallRoot, InstallObject, MaxTypeEnum }; + + static GroupType groupTypeForExtension( const QString &ext ); + static void groupTypeMeanings( GroupItem::GroupType type, QString& title, QString& ext ); + + GroupItem( QListView *lv, GroupType type, const QString &text, QMakeScopeItem* spitem ); + + void removeFileFromScope( const QString& filename); + void addFileToScope( const QString& filename); + void addInstallObject( const QString& objectname); + void removeInstallObject( GroupItem* item ); + + // qmake INSTALLS support + QPtrList<GroupItem> installs; + QPtrList<FileItem> files; + +// QStringList str_files; +// QStringList str_files_exclude; + // end qmake INSTALLS support + GroupType groupType; + QMakeScopeItem* owner; + +protected: + void paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align ); +}; + + +// Not sure if this complexity is really necessary... +class FileItem : public qProjectItem +{ +public: + FileItem( QListView *lv, const QString &text ); + + QString uiFileLink; + QString localFilePath; +}; + +/** + * Stores one Scope + */ +class QMakeScopeItem : public qProjectItem +{ +public: + QMakeScopeItem( QListView *parent, const QString &text, Scope *s, TrollProjectWidget* widget ); + QMakeScopeItem( QMakeScopeItem *parent, const QString &text, Scope* ); + void updateValues( const QString& var, const QStringList& values ); + void addValue( const QString& var, const QString& value ); + void removeValue( const QString& var, const QString& value ); + void addValues( const QString& var, const QStringList& values ); + void removeValues( const QString& var, const QStringList& values ); + void disableSubprojects( const QStringList& ); + void reloadProject(); + int compare( QListViewItem* i, int col, bool ascending ) const; + ~QMakeScopeItem(); + + QMap<GroupItem::GroupType, GroupItem*> groups; + + Scope* scope; + QString relativePath(); + QString getLibAddPath( QString ); + QString getLibAddObject( QString ); + QString getSharedLibAddObject( QString ); + QString getApplicationObject( QString ); + QString getIncAddPath( QString downDirs ); + FileItem* createFileItem(const QString& file); + GroupItem* createGroupItem(GroupItem::GroupType type, const QString& name, QMakeScopeItem* scopeitem); + QMap<QString, QString> getLibInfos( QString ); + + QMakeScopeItem* projectFileItem(); + + TrollProjectWidget* m_widget; +private: + void init(); + void buildSubTree(); + void buildGroups(); +}; + + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/scope.cpp b/buildtools/qmake/scope.cpp new file mode 100644 index 00000000..c090861b --- /dev/null +++ b/buildtools/qmake/scope.cpp @@ -0,0 +1,1710 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 "scope.h" + +#include <kdebug.h> + +#include <qfile.h> +#include <qfileinfo.h> +#include <qdir.h> +#include <qpair.h> +#include <qmakedriver.h> +#include <qregexp.h> +#include <qtimer.h> + +#include <kdirwatch.h> + +#include <kmessagebox.h> +#include <klocale.h> +#include <stdlib.h> + +#include "urlutil.h" +#include "trollprojectpart.h" +#include "qmakedefaultopts.h" + +const QStringList Scope::KnownVariables = QStringList() << "QT" << "CONFIG" << "TEMPLATE" << "SUBDIRS" << "VERSION" << "LIBS" << "target.path" << "INSTALLS" << "MAKEFILE" << "TARGETDEPS" << "INCLUDEPATH" << "TARGET" << "DESTDIR" << "DEFINES" << "QMAKE_CXXFLAGS_DEBUG" << "QMAKE_CXXFLAGS_RELEASE" << "OBJECTS_DIR" << "UI_DIR" << "MOC_DIR" << "IDL_COMPILER" << "IDL_OPTIONS" << "RCC_DIR" << "IDLS" << "RESOURCES" << "IMAGES" << "LEXSOURCES" << "DISTFILES" << "YACCSOURCES" << "TRANSLATIONS" << "HEADERS" << "SOURCES" << "INTERFACES" << "FORMS" ; + +const QStringList Scope::KnownConfigValues = QStringList() << "debug" << "release" << "debug_and_release" << "warn_on" << "warn_off" << "staticlib" << "dll" << "plugin" << "designer" << "create_pkgconf" << "create_libtool" << "qt" << "console" << "windows" << "x11" << "thread" << "exceptions" << "stl" << "rtti" << "opengl" << "thread" << "ordered" << "precompile_header" << "qtestlib" << "uitools" << "dbus" << "assistant" << "build_all" << "help"; + +Scope::Scope( const QMap<QString, QString>& env, const QString &filename, TrollProjectPart* part ) + : m_root( 0 ), m_incast( 0 ), m_parent( 0 ), m_num(0), m_isEnabled( true ), m_part(part), m_defaultopts(0), m_environment( env ) +{ + if ( !loadFromFile( filename ) ) + { + if( !QFileInfo( filename ).exists() ) + { + m_root = new QMake::ProjectAST(); + m_root->setFileName( filename ); + }else + { + delete m_root; + m_root = 0; + } + } + loadDefaultOpts(); + if( m_root ) + { + m_part->dirWatch()->addFile(filename); + } + init(); +} + +Scope::~Scope() +{ + QMap<unsigned int, Scope*>::iterator it; + for ( it = m_scopes.begin() ; it != m_scopes.end() ; ++it ) + { + Scope* s = it.data(); + delete s; + } + m_scopes.clear(); + + m_customVariables.clear(); + if ( m_root && m_root->isProject() && !m_incast ) + { + delete m_root; + m_root = 0; + delete m_defaultopts; + m_defaultopts = 0; + } + +} + +// Simple/Function Scopes +Scope::Scope( const QMap<QString, QString>& env, unsigned int num, Scope* parent, QMake::ProjectAST* scope, + QMakeDefaultOpts* defaultopts, TrollProjectPart* part ) + : m_root( scope ), m_incast( 0 ), m_parent( parent ), m_num(num), m_isEnabled( true ), + m_part(part), m_defaultopts(defaultopts), m_environment( env ) +{ + init(); +} + +//Subdirs +Scope::Scope( const QMap<QString, QString>& env, unsigned int num, Scope* parent, const QString& filename, + TrollProjectPart* part, bool isEnabled ) + : m_root( 0 ), m_incast( 0 ), m_parent( parent ), m_num(num), m_isEnabled( isEnabled ), + m_part(part), m_defaultopts(0), m_environment( env ) +{ + if ( !loadFromFile( filename ) ) + { + if( !QFileInfo( filename ).exists() && QFileInfo( QFileInfo( filename ).dirPath( true ) ).exists() ) + { + m_root = new QMake::ProjectAST(); + m_root->setFileName( filename ); + }else + { + delete m_root; + m_root = 0; + m_isEnabled = false; + } + } + loadDefaultOpts(); + if( m_root ) + m_part->dirWatch()->addFile(filename); + init(); +} + +//Include Scope +Scope::Scope( const QMap<QString, QString>& env, unsigned int num, Scope* parent, QMake::IncludeAST* incast, const QString& path, + const QString& incfile, QMakeDefaultOpts* defaultopts, TrollProjectPart* part ) + : m_root( 0 ), m_incast( incast ), m_parent( parent ), m_num(num), m_isEnabled( true ), + m_part(part), m_defaultopts(defaultopts), m_environment( env ) +{ + QString absfilename; + QString tmp = incfile.stripWhiteSpace(); + if( tmp.contains(")" ) ) + tmp = tmp.mid(0, tmp.find(")") ); + + if( tmp.startsWith( "\"" ) ) + tmp = tmp.mid( 1, tmp.length()-2 ); + + if( QFileInfo(tmp).isRelative() ) + { + absfilename = QDir::cleanDirPath( path + QString( QChar( QDir::separator() ) ) + tmp ); + }else + absfilename = QDir::cleanDirPath( tmp ); + if ( !loadFromFile( absfilename ) ) + { + if( !QFileInfo( absfilename ).exists() && QFileInfo( QFileInfo( absfilename ).dirPath( true ) ).exists() ) + { + m_root = new QMake::ProjectAST(); + m_root->setFileName( absfilename ); + }else + { + delete m_root; + m_root = 0; + m_isEnabled = false; + } + } + if( m_root ) + m_part->dirWatch()->addFile( m_root->fileName() ); + init(); +} + +bool Scope::loadFromFile( const QString& filename ) +{ + if ( !QFileInfo(filename).exists() || QMake::Driver::parseFile( filename, &m_root, 0 ) != 0 ) + { + kdDebug( 9024 ) << "Couldn't parse project: " << filename << endl; + if( DomUtil::readBoolEntry( *m_part->projectDom(), + "/kdevtrollproject/qmake/showParseErrors", true ) ) + { + KMessageBox::error( 0, i18n( "Could not parse project file: %1" ).arg( filename ), + i18n( "Could not parse project file" ) ); + } + m_root = 0; + return false; + } +// init(); + return true; +} + +void Scope::saveToFile() const +{ + if ( !m_root ) + return ; + + if ( scopeType() != ProjectScope && scopeType() != IncludeScope ) + { + m_parent->saveToFile(); + return; + } + + QString filename; + if ( scopeType() == ProjectScope ) + filename = m_root->fileName() ; + else if ( scopeType() == IncludeScope ) + filename = m_parent->projectDir() + QString( QChar( QDir::separator() ) ) + m_incast->projectName; + if ( filename.isEmpty() ) + return ; + m_part->dirWatch()->stopScan(); + QFile file( filename ); + if ( file.open( IO_WriteOnly ) ) + { + + QTextStream out( &file ); + QString astbuffer; + m_root->writeBack( astbuffer ); + out << astbuffer; + file.close(); + }else + { + KMessageBox::error( 0, i18n( "Could not write project file: %1" ).arg( filename ), + i18n( "Could not write project file" ) ); + } +#ifdef DEBUG + Scope::PrintAST pa; + pa.processProject(m_root); +#endif + m_part->dirWatch()->startScan(); +} + +void Scope::addToPlusOp( const QString& variable, const QStringList& values ) +{ + if ( !m_root ) + return ; + + updateVariable( variable, "+=", values, false ); +} + +void Scope::removeFromPlusOp( const QString& variable, const QStringList& values ) +{ + if ( !m_root ) + return ; + + updateVariable( variable, "+=", values, true ); +} + + +void Scope::addToMinusOp( const QString& variable, const QStringList& values ) +{ + if ( !m_root ) + return ; + + updateVariable( variable, "-=", values, false ); +} + +void Scope::removeFromMinusOp( const QString& variable, const QStringList& values ) +{ + if ( !m_root ) + return ; + + updateVariable( variable, "-=", values, true ); +} + +void Scope::addToEqualOp( const QString& variable, const QStringList& values ) +{ + if ( !m_root ) + return ; + + updateVariable( variable, "=", values, false ); +} + +void Scope::removeFromEqualOp( const QString& variable, const QStringList& values ) +{ + if ( !m_root ) + return ; + + updateVariable( variable, "=", values, true ); +} + +void Scope::setPlusOp( const QString& variable, const QStringList& values ) +{ + if( !m_root || Scope::listsEqual(values, variableValuesForOp(variable, "+=") ) ) + return; + + updateVariable( variable, "+=", variableValuesForOp( variable, "+=" ), true ); + updateVariable( variable, "+=", values, false ); +} + +void Scope::setEqualOp( const QString& variable, const QStringList& values ) +{ + if( !m_root || Scope::listsEqual(values, variableValuesForOp(variable, "=") ) ) + return; + + updateVariable( variable, "=", variableValuesForOp( variable, "=" ), true ); + updateVariable( variable, "=", values, false ); +} + +void Scope::setMinusOp( const QString& variable, const QStringList& values ) +{ + if( !m_root || Scope::listsEqual(values, variableValuesForOp(variable, "-=") ) ) + return; + + updateVariable( variable, "-=", variableValuesForOp( variable, "-=" ), true ); + updateVariable( variable, "-=", values, false ); +} + +QStringList Scope::variableValuesForOp( const QString& variable , const QString& op ) const +{ + QStringList result; + + if( !m_root ) + return result; + + QValueList<QMake::AST*>::const_iterator it; + for ( it = m_root->m_children.begin(); it != m_root->m_children.end(); ++it ) + { + QMake::AST* ast = *it; + if ( ast->nodeType() == QMake::AST::AssignmentAST ) + { + QMake::AssignmentAST * assign = static_cast<QMake::AssignmentAST*>( ast ); + if ( assign->scopedID == variable && assign->op == op ) + { + result += assign->values; + } + } + } + result = cleanStringList(result); + return result; +} + +QStringList Scope::variableValues( const QString& variable, bool checkIncParent, bool fetchFromParent, bool evaluateSubScopes ) +{ + QStringList result; + + if ( !m_root ) + return result; + + if( m_varCache.contains( variable ) && fetchFromParent && ( checkIncParent || scopeType() != Scope::IncludeScope ) ) + { + return m_varCache[variable]; + } + + calcValuesFromStatements( variable, result, checkIncParent, 0, fetchFromParent, true, evaluateSubScopes ); + result = cleanStringList(result); + if( ( scopeType() != Scope::IncludeScope || checkIncParent ) && fetchFromParent ) + { + m_varCache[ variable ] = result; + } + return result; +} + +void Scope::calcValuesFromStatements( const QString& variable, QStringList& result, bool checkIncParent, QMake::AST* stopHere, bool fetchFromParent, bool setDefault, bool evaluateSubScopes ) const +{ + if( !m_root ) + return; + + /* For variables that we don't know and which are not QT/CONFIG find the default value */ + if( setDefault && m_defaultopts + && m_defaultopts->variables().findIndex(variable) != -1 + && ( variable == "TEMPLATE" || variable == "QT" || KnownVariables.findIndex(variable) == -1 || variable == "CONFIG" ) ) + { + result = m_defaultopts->variableValues(variable); + } + + if ( ( scopeType() == FunctionScope || scopeType() == SimpleScope ) && fetchFromParent ) + { + m_parent->calcValuesFromStatements( variable, result, checkIncParent, this->m_root, fetchFromParent, setDefault, evaluateSubScopes ); + } + else if ( scopeType() == IncludeScope && checkIncParent && fetchFromParent ) + { + m_parent->calcValuesFromStatements( variable, result, true, this->m_incast, fetchFromParent, setDefault, evaluateSubScopes ); + } + + QValueList<QMake::AST*>::const_iterator it; + for ( it = m_root->m_children.begin(); it != m_root->m_children.end(); ++it ) + { + if ( stopHere && *it == stopHere ) + return ; + QMake::AST* ast = *it; + if ( ast->nodeType() == QMake::AST::AssignmentAST ) + { + QMake::AssignmentAST * assign = static_cast<QMake::AssignmentAST*>( ast ); + if ( assign->scopedID == variable ) + { + if ( assign->op == "=" ) + { + result = assign->values; + } + else if ( assign->op == "+=" ) + { + for ( QStringList::const_iterator sit = assign->values.begin(); sit != assign->values.end() ; ++sit ) + { + if ( result.findIndex( *sit ) == -1 ) + result.append( *sit ); + } + } + else if ( assign->op == "-=" ) + { + for ( QStringList::const_iterator sit = assign->values.begin(); sit != assign->values.end() ; ++sit ) + { + if ( result.findIndex( *sit ) != -1 ) + result.remove( *sit ); + } + } + } + }else if( evaluateSubScopes ) + { + if( ast->nodeType() == QMake::AST::IncludeAST ) + { + QMake::IncludeAST* iast = static_cast<QMake::IncludeAST*>(ast); + QValueList<unsigned int> l = m_scopes.keys(); + for( unsigned int i = 0; i < l.count(); ++i ) + { + int num = l[ i ]; + if( m_scopes.contains( num ) ) + { + Scope* s = m_scopes[num]; + if( s && s->scopeType() == IncludeScope && s->m_incast == iast ) + { + s->calcValuesFromStatements( variable, result, false, 0, false, false, evaluateSubScopes ); + } + } + } + + } + else if( ast->nodeType() == QMake::AST::ProjectAST ) + { + QMake::ProjectAST* past = static_cast<QMake::ProjectAST*>(ast); + if( past->isFunctionScope() || past->isScope() ) + { + QValueList<unsigned int> l = m_scopes.keys(); + for( unsigned int i = 0; i < l.count(); ++i ) + { + int num = l[ i ]; + if( m_scopes.contains( num ) ) + { + Scope* s = m_scopes[num]; + if( s && s->m_root == past && s->m_root->scopedID == past->scopedID ) + { + s->calcValuesFromStatements( variable, result, false, 0, false, false, evaluateSubScopes ); + } + } + } + } + } + } + } + + result = cleanStringList( result ); + return ; +} + +Scope::ScopeType Scope::scopeType() const +{ + if ( !m_root ) + return InvalidScope; + else if ( m_incast ) + return IncludeScope; + else if ( m_root->isProject() ) + return ProjectScope; + else if ( m_root->isScope() ) + return SimpleScope; + else if ( m_root->isFunctionScope() ) + return FunctionScope; + return InvalidScope; +} + +QString Scope::scopeName() const +{ + if ( !m_root ) + return ""; + if ( m_incast ) + return "include<" + m_incast->projectName + ">"; + else if ( m_root->isFunctionScope() ) + return funcScopeKey( m_root ); + else if ( m_root->isScope() ) + return m_root->scopedID; + else if ( m_root->isProject() ) + { + if( m_parent && QDir::cleanDirPath( m_parent->projectDir() ) != QDir::cleanDirPath( projectDir() ) ) + { + return URLUtil::getRelativePath( m_parent->projectDir(), projectDir() ); + }else if ( m_parent && QDir::cleanDirPath( m_parent->projectDir() ) == QDir::cleanDirPath( projectDir() ) ) + { + return fileName(); + }else + return QFileInfo( projectDir() ).fileName() ; + } + return QString(); +} + +QString Scope::fileName() const +{ + if( !m_root ) + return ""; + if ( m_incast ) + return m_incast->projectName; + else if ( m_root->isProject() ) + return QFileInfo( m_root->fileName() ).fileName(); + else + return m_parent->fileName(); +} + +Scope* Scope::createFunctionScope( const QString& funcName, const QString& args ) +{ + if ( !m_root ) + return 0; + + QMake::ProjectAST* ast = new QMake::ProjectAST( QMake::ProjectAST::FunctionScope ); + ast->scopedID = funcName; + ast->args = args; + ast->setDepth( m_root->depth() ); + ast->addChildAST( new QMake::NewLineAST() ); + m_root->addChildAST( ast ); + m_root->addChildAST( new QMake::NewLineAST() ); + Scope* funcScope = new Scope( m_environment, getNextScopeNum(), this, ast, m_defaultopts, m_part ); + if( funcScope->scopeType() != Scope::InvalidScope ) + { + m_scopes.insert( getNextScopeNum(), funcScope ); + return funcScope; + }else + delete funcScope; + return 0; +} + +Scope* Scope::createSimpleScope( const QString& scopename ) +{ + if ( !m_root ) + return 0; + + QMake::ProjectAST* ast = new QMake::ProjectAST( QMake::ProjectAST::Scope ); + ast->scopedID = scopename; + ast->addChildAST( new QMake::NewLineAST() ); + ast->setDepth( m_root->depth() ); + m_root->addChildAST( ast ); + m_root->addChildAST( new QMake::NewLineAST() ); + /* We can't unconditionally add the scope name to CONFIG, scope might be win32 which may only be in CONFIG under windows. + if ( m_part->isQt4Project() ) + addToPlusOp( "CONFIG", QStringList( scopename ) ); + */ + Scope* simpleScope = new Scope( m_environment, getNextScopeNum(), this, ast, m_defaultopts, m_part ); + + if( simpleScope->scopeType() != Scope::InvalidScope ) + { + m_scopes.insert( getNextScopeNum(), simpleScope ); + return simpleScope; + }else + delete simpleScope; + return 0; + +} + +Scope* Scope::createIncludeScope( const QString& includeFile, bool negate ) +{ + if ( !m_root ) + return 0; + + Scope* funcScope; + if ( negate ) + { + funcScope = createFunctionScope( "!include", includeFile ); + } + else + { + funcScope = createFunctionScope( "include", includeFile ); + } + if( funcScope == 0 ) + return 0; + + QMake::IncludeAST* ast = new QMake::IncludeAST(); + ast->setDepth( m_root->depth() ); + ast->projectName = includeFile; + Scope* incScope = new Scope( m_environment, funcScope->getNextScopeNum(), funcScope, ast, projectDir(), resolveVariables( ast->projectName ), m_defaultopts, m_part ); + if ( incScope->scopeType() != InvalidScope ) + { + funcScope->m_root->addChildAST( ast ); + funcScope->m_scopes.insert( funcScope->getNextScopeNum(), incScope ); + return funcScope; + } + else + { + deleteFunctionScope( m_scopes.keys().last() ); + delete incScope; + } + return 0; + +} + +Scope* Scope::createSubProject( const QString& projname ) +{ + if( !m_root ) + return 0; + + if( variableValuesForOp( "SUBDIRS", "-=").findIndex( projname ) != -1 ) + removeFromMinusOp( "SUBDIRS", projname ); + + QString realprojname = resolveVariables(projname); + + if( variableValuesForOp( "SUBDIRS", "-=").findIndex( realprojname ) != -1 ) + removeFromMinusOp( "SUBDIRS", realprojname ); + + QDir curdir( projectDir() ); + + if ( variableValues("TEMPLATE").findIndex( "subdirs" ) != -1 ) + { + QString filename; + if( !realprojname.endsWith(".pro") ) + { + if ( !curdir.exists( realprojname ) ) + if ( !curdir.mkdir( realprojname ) ) + return 0; + curdir.cd( realprojname ); + QStringList entries = curdir.entryList("*.pro", QDir::Files); + + if ( !entries.isEmpty() && entries.findIndex( curdir.dirName()+".pro" ) == -1 ) + filename = curdir.absPath() + QString(QChar(QDir::separator()))+entries.first(); + else + filename = curdir.absPath() + QString(QChar(QDir::separator()))+curdir.dirName()+".pro"; + }else + filename = curdir.absPath() + QString(QChar(QDir::separator())) + realprojname; + + kdDebug( 9024 ) << "Creating subproject with filename:" << filename << endl; + + Scope* s = new Scope( m_environment, getNextScopeNum(), this, filename, m_part ); + s->loadDefaultOpts(); + if ( s->scopeType() != InvalidScope ) + { + if( s->variableValues("TEMPLATE").isEmpty() ) + s->setEqualOp("TEMPLATE", QStringList("app")); + s->saveToFile(); + addToPlusOp( "SUBDIRS", QStringList( realprojname ) ); + m_scopes.insert( getNextScopeNum(), s ); + return s; + } else + { + delete s; + } + } + + return 0; +} + +bool Scope::deleteFunctionScope( unsigned int num ) +{ + if ( !m_root || !m_scopes.contains( num ) ) + return false; + + Scope* funcScope = m_scopes[ num ]; + if ( funcScope ) + { + QMake::AST* ast = m_root->m_children[ m_root->m_children.findIndex( funcScope->m_root ) ]; + if( !ast ) + return false; + m_scopes.remove( num ); + m_root->removeChildAST( funcScope->m_root ); + delete funcScope; + delete ast; + return true; + } + return false; +} + +bool Scope::deleteSimpleScope( unsigned int num ) +{ + if ( !m_root || !m_scopes.contains( num ) ) + return false; + + Scope* simpleScope = m_scopes[ num ]; + if ( simpleScope ) + { + QMake::AST* ast = m_root->m_children[ m_root->m_children.findIndex( simpleScope->m_root ) ]; + if( !ast ) + return false; + m_scopes.remove( num ); + removeFromPlusOp( "CONFIG", simpleScope->m_root->scopedID ); + m_root->removeChildAST( simpleScope->m_root ); + delete simpleScope; + delete ast; + return true; + } + return false; +} + +bool Scope::deleteIncludeScope( unsigned int num ) +{ + if ( !m_root || !m_scopes.contains( num ) ) + return false; + + Scope * incScope = m_scopes[ num ]; + if( !incScope ) + return false; + QMake::AST* ast = incScope->m_incast; + if( !ast ) + return false; + m_scopes.remove( num ); + m_root->removeChildAST( incScope->m_incast); + delete incScope; + delete ast; + + return m_parent->deleteFunctionScope( getNum() ); +} + +bool Scope::deleteSubProject( unsigned int num, bool deleteSubdir ) +{ + if ( !m_root || !m_scopes.contains( num ) ) + return false; + + QValueList<QMake::AST*>::iterator it = findExistingVariable( "TEMPLATE" ); + if ( it != m_root->m_children.end() ) + { + QMake::AssignmentAST * tempast = static_cast<QMake::AssignmentAST*>( *it ); + if ( tempast->values.findIndex( "subdirs" ) != -1 || findExistingVariable( "TEMPLATE" ) != m_root->m_children.end() ) + { + Scope* project = m_scopes[ num ]; + if( !project ) + return false; + + QString projdir = project->scopeName(); + if ( deleteSubdir ) + { + QDir projdir = QDir( projectDir() ); + QString dir = project->scopeName(); + if( !dir.endsWith(".pro") ) + { + QDir subdir = QDir( projectDir() + QString( QChar( QDir::separator() ) ) + dir ); + if ( subdir.exists() ) + { + QStringList entries = subdir.entryList(); + for ( QStringList::iterator eit = entries.begin() ; eit != entries.end() ; ++eit ) + { + if( *eit == "." || *eit == ".." ) + continue; + if( !subdir.remove( *eit ) ) + kdDebug( 9024 ) << "Couldn't delete " << *eit << " from " << subdir.absPath() << endl; + } + if( !projdir.rmdir( dir ) ) + kdDebug( 9024 ) << "Couldn't delete " << dir << " from " << projdir.absPath() << endl; + } + }else + { + QDir d( project->projectDir() ); + kdDebug(9024) << "removed subproject?:" << d.remove( dir ) << endl; + } + } + QValueList<QMake::AST*>::iterator foundit = findExistingVariable( "SUBDIRS" ); + if ( foundit != m_root->m_children.end() ) + { + QMake::AssignmentAST * ast = static_cast<QMake::AssignmentAST*>( *foundit ); + updateValues( ast->values, QStringList( projdir ), true, ast->indent ); + if( m_varCache.contains( "SUBDIRS" ) ) + m_varCache.erase( "SUBDIRS" ); + }else + return false; + m_scopes.remove( num ); + delete project; + return true; + } + } + return false; +} + +void Scope::updateValues( QStringList& origValues, const QStringList& newValues, bool remove, QString indent ) +{ + if( !m_root ) + return; + + for ( QStringList::const_iterator it = newValues.begin(); it != newValues.end() ; ++it ) + { + if ( origValues.findIndex( *it ) == -1 && !remove ) + { + while ( !origValues.isEmpty() && origValues.last() == getLineEndingString() ) + origValues.pop_back(); + if ( origValues.count() > 0 && !containsContinue( origValues.last() ) && !isComment( origValues.last() ) ) + { + origValues.append( " " ); + origValues.append( "\\"+getLineEndingString() ); + if( indent != "" ) + origValues.append( indent ); + }else if ( !origValues.isEmpty() && containsContinue( origValues.last() ) && !isComment( origValues.last() ) ) + { + if( indent != "" ) + origValues.append( indent ); + }else if ( !origValues.isEmpty() && isComment( origValues.last() ) ) + { + origValues[origValues.count()-1] = "\\ "+origValues[origValues.count()-1]; + if( indent != "" ) + origValues.append( indent ); + }else if ( origValues.isEmpty() ) + origValues.append(" "); + QString newval = *it; + QRegExp re("([^$])\\$([^$\\(\\)\\{\\} /]*)( |\\)|/)"); + newval.replace(re, "\\1$(\\2)\\3"); + if( (newval).contains(" ") || (newval).contains("\t") || (newval).contains( getLineEndingString() ) || (newval).contains("#") ) + origValues.append( "\""+newval+"\"" ); + else + origValues.append( newval ); + origValues.append( getLineEndingString() ); + } else if ( origValues.findIndex( *it ) != -1 && remove ) + { + QStringList::iterator posit = origValues.find( *it ); + posit = origValues.remove( posit ); + while( posit != origValues.end() && ( (*posit).find( QRegExp("\\\\[\\s]*"+getLineEndingString() ) ) != -1 + || (*posit).stripWhiteSpace() == "" ) ) + { + posit = origValues.remove( posit ); + } + } + } + while( !origValues.isEmpty() && (origValues.last() == "\\"+getLineEndingString() + || origValues.last() == getLineEndingString() + || origValues.last().stripWhiteSpace() == "" ) && !origValues.isEmpty() ) + origValues.pop_back(); + if( !origValues.isEmpty() && origValues.last().find( QRegExp("\\\\[ \t]*#") ) != -1 ) + origValues[origValues.count()-1] = origValues[origValues.count()-1].mid(origValues[origValues.count()-1].find( "#") ); + if( !origValues.isEmpty() && origValues.last().find( getLineEndingString() ) == -1 ) + origValues.append(getLineEndingString()); +} + +void Scope::updateVariable( const QString& variable, const QString& op, const QStringList& values, bool removeFromOp ) +{ + if ( !m_root || listIsEmpty( values ) ) + return ; + + if( m_varCache.contains( variable ) ) + m_varCache.erase( variable ); + + for ( int i = m_root->m_children.count() - 1; i >= 0; --i ) + { + if ( m_root->m_children[ i ] ->nodeType() == QMake::AST::AssignmentAST ) + { + QMake::AssignmentAST * assignment = static_cast<QMake::AssignmentAST*>( m_root->m_children[ i ] ); + if ( assignment->scopedID == variable && Scope::isCompatible( assignment->op, op ) ) + { + updateValues( assignment->values, values, removeFromOp, assignment->indent ); + if ( removeFromOp && listIsEmpty( assignment->values ) ) + { + m_root->removeChildAST( assignment ); + delete assignment; + } + return ; + } + else if ( assignment->scopedID == variable && !Scope::isCompatible( assignment->op, op ) ) + { + for ( QStringList::const_iterator it = values.begin() ; it != values.end() ; ++it ) + { + if ( op == "+=" && !removeFromOp && assignment->values.findIndex( *it ) != -1 ) + { + if ( assignment->op == "=" ) + { + updateValues( assignment->values, values, false, assignment->indent ); + return ; + } + else if ( assignment->op == "-=" ) + { + updateValues( assignment->values, QStringList( *it ), true, assignment->indent ); + if ( listIsEmpty( assignment->values ) ) + { + m_root->removeChildAST( assignment ); + delete assignment; + break; + } + } + } + else if ( op == "-=" && !removeFromOp && assignment->values.findIndex( *it ) != -1 ) + { + updateValues( assignment->values, QStringList( *it ), true, assignment->indent ); + if ( listIsEmpty( assignment->values ) ) + { + m_root->removeChildAST( assignment ); + delete assignment; + break; + } + } + else if ( op == "=" ) + { + if ( !removeFromOp ) + { + m_root->removeChildAST( assignment ); + delete assignment; + } + else if ( assignment->op == "+=" && assignment->values.findIndex( *it ) != -1 ) + { + updateValues( assignment->values, QStringList( *it ), true, assignment->indent ); + if ( listIsEmpty( assignment->values ) ) + { + m_root->removeChildAST( assignment ); + delete assignment; + break; + } + } + } + } + } + } + } + + if ( !removeFromOp ) + { + QMake::AssignmentAST * ast = new QMake::AssignmentAST(); + ast->scopedID = variable; + ast->op = op; + updateValues( ast->values, values ); + if( scopeType() == ProjectScope ) + ast->setDepth( m_root->depth() ); + else + ast->setDepth( m_root->depth()+1 ); + m_root->addChildAST( ast ); + if ( values.findIndex( getLineEndingString() ) == -1 ) + { + ast->values.append( getLineEndingString() ); + } + } +} + +QValueList<QMake::AST*>::iterator Scope::findExistingVariable( const QString& variable ) +{ + QValueList<QMake::AST*>::iterator it; + QStringList ops; + ops << "=" << "+="; + + for ( it = m_root->m_children.begin(); it != m_root->m_children.end() ; ++it ) + { + if ( ( *it ) ->nodeType() == QMake::AST::AssignmentAST ) + { + QMake::AssignmentAST * assignment = static_cast<QMake::AssignmentAST*>( *it ); + if ( assignment->scopedID == variable && ops.findIndex( assignment->op ) != -1 ) + { + return it; + } + } + } + return m_root->m_children.end(); +} + +void Scope::init() +{ + if( !m_root ) + return; + + kdDebug(9024) << "Initializing Scope: " << scopeName() << this << endl; + m_maxCustomVarNum = 1; + + QValueList<QMake::AST*>::const_iterator it; + for ( it = m_root->m_children.begin(); it != m_root->m_children.end(); ++it ) + { + if ( ( *it ) ->nodeType() == QMake::AST::ProjectAST ) + { + QMake::ProjectAST * p = static_cast<QMake::ProjectAST*>( *it ); + m_scopes.insert( getNextScopeNum(), new Scope( m_environment, getNextScopeNum(), this, p, m_defaultopts, m_part ) ); + } + else if ( ( *it ) ->nodeType() == QMake::AST::IncludeAST ) + { + QMake::IncludeAST * i = static_cast<QMake::IncludeAST*>( *it ); + QString filename = i->projectName; + if( i->projectName.stripWhiteSpace().startsWith("$") ) + { + filename = resolveVariables(i->projectName, *it); + } + m_scopes.insert( getNextScopeNum(), new Scope( m_environment, getNextScopeNum(), this, i, projectDir(), filename, m_defaultopts, m_part ) ); + } + else if ( ( *it ) ->nodeType() == QMake::AST::AssignmentAST ) + { + QMake::AssignmentAST * m = static_cast<QMake::AssignmentAST*>( *it ); + // Check wether TEMPLATE==subdirs here too! + if ( m->scopedID == "SUBDIRS" && variableValues("TEMPLATE").findIndex("subdirs") != -1 ) + { + for ( QStringList::const_iterator sit = m->values.begin() ; sit != m->values.end(); ++sit ) + { + QString str = *sit; + if ( containsContinue( str ) || isComment( str ) || str == getLineEndingString() || str == "." || str == "./" || (str).stripWhiteSpace() == "" ) + continue; + QDir subproject; + QString projectfile; + kdDebug(9024) << "reading subproject: " << str << endl; + if( str.startsWith("$") ) + str = resolveVariables(str, *it); + if( str.endsWith(".pro") ) + { + subproject = QDir( projectDir(), "*.pro", QDir::Name | QDir::IgnoreCase, QDir::Files ); + projectfile = str; + }else + { + QString dir = str; + if( QFileInfo( dir ).isRelative() ) + dir = projectDir() + QString( QChar( QDir::separator() ) ) + dir; + subproject = QDir( dir, + "*.pro", QDir::Name | QDir::IgnoreCase, QDir::Files ); + if( !subproject.exists() ) + { + kdDebug(9024) << "Project Dir doesn't exist, trying to find name.subdir variable:" << str << endl; + if( !variableValues(str+".subdir").isEmpty() ) + { + kdDebug(9024) << "Found name.subdir variable for " << str << endl; + subproject = QDir( projectDir() + QString( QChar( QDir::separator() ) ) + + variableValues(str+".subdir").first(), + "*.pro", QDir::Name | QDir::IgnoreCase, QDir::Files ); + }else + continue; + } + if ( subproject.entryList().isEmpty() || subproject.entryList().findIndex( str + ".pro" ) != -1 ) + projectfile = (str) + ".pro"; + else + projectfile = subproject.entryList().first(); + + } + kdDebug( 9024 ) << "Parsing subproject: " << projectfile << endl; + m_scopes.insert( getNextScopeNum(), new Scope( m_environment, getNextScopeNum(), this, + subproject.absFilePath( projectfile ), + m_part, ( m->op != "-=" )) ); + } + } + else + { + if ( !( + KnownVariables.findIndex( m->scopedID ) != -1 + && ( m->op == "=" || m->op == "+=" || m->op == "-=") + ) + && !( + ( m->scopedID.contains( ".files" ) || m->scopedID.contains( ".path" ) ) + && variableValues("INSTALLS").findIndex(m->scopedID.left( m->scopedID.findRev(".") != -1 ) ) + ) + && !( + ( m->scopedID.contains( ".subdir" ) ) + && variableValues("SUBDIRS").findIndex(m->scopedID.left( m->scopedID.findRev(".") != -1 ) ) + ) + ) + { + m_customVariables[ m_maxCustomVarNum++ ] = m; + } + } + } + } +} + +QString Scope::projectName() const +{ + if( !m_root ) + return ""; + + return QFileInfo( projectDir() ).fileName(); +} + +QString Scope::projectDir() const +{ + if( !m_root ) + return ""; + if ( m_root->isProject() ) + { + return QFileInfo( m_root->fileName() ).dirPath( true ); + } + else + { + return m_parent->projectDir(); + } +} + +const QMap<unsigned int, QMap<QString, QString> > Scope::customVariables() const +{ + QMap<unsigned int, QMap<QString, QString> > result; + if( !m_root ) + return result; + + QMap<unsigned int, QMake::AssignmentAST*>::const_iterator it = m_customVariables.begin(); + for ( ; it != m_customVariables.end(); ++it ) + { + QMap<QString,QString> temp; + temp[ "var" ] = it.data()->scopedID; + temp[ "op" ] = it.data()->op; + temp[ "values" ] = it.data()->values.join("").stripWhiteSpace(); + result[ it.key() ] = temp; + } + return result; +} + +void Scope::updateCustomVariable( unsigned int id, const QString& name, const QString& newop, const QString& newvalues ) +{ + if( !m_root ) + return; + if ( id > 0 && m_customVariables.contains( id ) ) + { + m_customVariables[ id ] ->values.clear(); + updateValues( m_customVariables[ id ] ->values, newvalues.stripWhiteSpace() ); + if( m_varCache.contains( m_customVariables[ id ]->scopedID ) ) + m_varCache.erase( m_customVariables[ id ]->scopedID ); + m_customVariables[ id ] ->op = newop; + m_customVariables[ id ] ->scopedID = name; + } +} + +unsigned int Scope::addCustomVariable( const QString& var, const QString& op, const QString& values ) +{ + QMake::AssignmentAST* newast = new QMake::AssignmentAST(); + newast->scopedID = var; + newast->op = op; + newast->values.append(values.stripWhiteSpace()); + if( scopeType() == ProjectScope ) + newast->setDepth( m_root->depth() ); + else + newast->setDepth( m_root->depth()+1 ); + m_root->addChildAST( newast ); + m_customVariables[ m_maxCustomVarNum++ ] = newast; + return (m_maxCustomVarNum-1); +} + +void Scope::removeCustomVariable( unsigned int id ) +{ + if( m_customVariables.contains(id) ) + { + QMake::AssignmentAST* m = m_customVariables[id]; + m_customVariables.remove(id); + m_root->m_children.remove( m ); + } +} + +bool Scope::isVariableReset( const QString& var ) +{ + bool result = false; + if( !m_root ) + return result; + QValueList<QMake::AST*>::const_iterator it = m_root->m_children.begin(); + for ( ; it != m_root->m_children.end(); ++it ) + { + if ( ( *it ) ->nodeType() == QMake::AST::AssignmentAST ) + { + QMake::AssignmentAST * ast = static_cast<QMake::AssignmentAST*>( *it ); + if ( ast->scopedID == var && ast->op == "=" ) + { + result = true; + break; + } + } + } + return result; +} + +void Scope::removeVariable( const QString& var, const QString& op ) +{ + if ( !m_root ) + return ; + + QMake::AssignmentAST* ast = 0; + + QValueList<QMake::AST*>::iterator it = m_root->m_children.begin(); + for ( ; it != m_root->m_children.end(); ++it ) + { + if ( ( *it ) ->nodeType() == QMake::AST::AssignmentAST ) + { + ast = static_cast<QMake::AssignmentAST*>( *it ); + if ( ast->scopedID == var && ast->op == op ) + { + m_root->m_children.remove( ast ); + it = m_root->m_children.begin(); + } + } + } +} + +bool Scope::listIsEmpty( const QStringList& values ) +{ + if ( values.size() < 1 ) + return true; + for ( QStringList::const_iterator it = values.begin(); it != values.end(); ++it ) + { + if ( ( *it ).stripWhiteSpace() != "" && ( *it ).stripWhiteSpace() != "\\" ) + return false; + } + return true; +} + +bool Scope::isCompatible( const QString& op1, const QString& op2) +{ + if( op1 == "+=" ) + return ( op2 == "+=" || op2 == "=" ); + else if ( op1 == "-=" ) + return ( op2 == "-=" ); + else if ( op1 == "=" ) + return ( op2 == "=" || op2 == "+=" ); + return false; +} + +bool Scope::listsEqual(const QStringList& l1, const QStringList& l2) +{ + QStringList left = l1; + QStringList right = l2; +// left.sort(); +// right.sort(); + return (left == right); +} + +QStringList Scope::cleanStringList(const QStringList& list) const +{ + QStringList result; + for( QStringList::const_iterator it = list.begin(); it != list.end(); ++it ) + { + QString s = *it; + if( s.stripWhiteSpace() != "" + && !containsContinue(s) + && s.stripWhiteSpace() != getLineEndingString() + && !isComment(s) ) + result.append(s); + } + return result; +} + +bool Scope::isQt4Project() const +{ + return m_part->isQt4Project(); +} + +void Scope::reloadProject() +{ + if ( !m_root || !m_root->isProject() ) + return; + + QString filename = m_root->fileName(); + QMap<unsigned int, Scope*>::iterator it; + for ( it = m_scopes.begin() ; it != m_scopes.end() ; ++it ) + { + Scope* s = it.data(); + delete s; + } + m_scopes.clear(); + + m_customVariables.clear(); + + m_varCache.clear(); + + if ( m_root->isProject() ) + delete m_root; + if ( !loadFromFile( filename ) && !QFileInfo( filename ).exists() ) + { + m_root = new QMake::ProjectAST(); + m_root->setFileName( filename ); + } + init(); +} + +Scope* Scope::disableSubproject( const QString& dir) +{ + if( !m_root || ( m_root->isProject() && !m_incast ) ) + return 0; + + if( scopeType() != Scope::IncludeScope && variableValuesForOp( "SUBDIRS", "+=").findIndex( dir ) != -1 ) + removeFromPlusOp( "SUBDIRS", dir ); + else if( scopeType() != Scope::IncludeScope ) + removeFromPlusOp( "SUBDIRS", dir ); + + QDir curdir( projectDir() ); + + if ( variableValues("TEMPLATE").findIndex( "subdirs" ) != -1 ) + { + curdir.cd(dir); + QString filename; + QStringList entries = curdir.entryList("*.pro", QDir::Files); + + if ( !entries.isEmpty() && entries.findIndex( curdir.dirName()+".pro" ) != -1 ) + filename = curdir.absPath() + QString(QChar(QDir::separator()))+entries.first(); + else + filename = curdir.absPath() + QString(QChar(QDir::separator()))+curdir.dirName()+".pro"; + + kdDebug( 9024 ) << "Disabling subproject with filename:" << filename << endl; + + Scope* s = new Scope( m_environment, getNextScopeNum(), this, filename, m_part, false ); + addToMinusOp( "SUBDIRS", QStringList( dir ) ); + m_scopes.insert( getNextScopeNum(), s ); + return s; + } + + return 0; +} + +QString Scope::resolveVariables( const QString& value ) const +{ + return resolveVariables(QStringList(value), 0).front(); +} + + +QString Scope::resolveVariables( const QString& value, QMake::AST* stopHere ) const +{ + return resolveVariables(QStringList(value), stopHere).front(); +} + +QStringList Scope::variableValues( const QString& variable, QMake::AST* stopHere, bool fetchFromParent ) const +{ + QStringList result; + + if ( !m_root ) + return result; + + calcValuesFromStatements( variable, result, true, stopHere, fetchFromParent ); + result = cleanStringList(result); + return result; +} + +QStringList Scope::resolveVariables( const QStringList& values, QMake::AST* stopHere ) const +{ + QStringList result = values; + QMap<QString, QStringList> variables; + for( QStringList::iterator it = result.begin(); it != result.end(); ++it ) + { + QRegExp re("\\$\\$([^{}\\) /]*)( |\\)|/|$)"); + int pos = 0; + while( pos >= 0 ) + { + pos = re.search( (*it), pos ); + if( pos > -1 ) + { + if( !variables.contains( re.cap(1) ) ) + { + variables[re.cap(1)] = resolveVariables( variableValues( re.cap(1), stopHere ) ); + if( variables[re.cap(1)].isEmpty() && re.cap(1) == "TARGET" ) + { + variables[re.cap(1)] = QFileInfo( fileName() ).baseName(); + } + } + pos += re.matchedLength(); + } + } + re = QRegExp("\\$\\$\\{([^\\)\\}]*)\\}"); + pos = 0; + while( pos >= 0 ) + { + pos = re.search( (*it), pos ); + if( pos > -1 ) + { + if( !variables.contains( re.cap(1) ) ) + { + variables[re.cap(1)] = resolveVariables( variableValues( re.cap(1), stopHere ) ); + if( variables[re.cap(1)].isEmpty() && re.cap(1) == "TARGET" ) + { + variables[re.cap(1)] = QFileInfo( fileName() ).baseName(); + } + } + pos += re.matchedLength(); + } + } + re = QRegExp("\\$\\$\\(([^\\)\\}]*)\\)"); + pos = 0; + QMap<QString, QString> envvars; + while( pos >= 0 ) + { + pos = re.search( (*it), pos ); + if( pos > -1 ) + { + if( !envvars.contains( re.cap(1) ) ) + if( m_environment.contains( re.cap(1) ) != -1 ) + envvars[re.cap(1)] = m_environment[ re.cap(1) ]; + else if ( ::getenv( re.cap(1).local8Bit() ) != 0 ) + envvars[re.cap(1)] = QString::fromLocal8Bit( ::getenv( re.cap(1).local8Bit() ) ); + pos += re.matchedLength(); + } + } + for( QMap<QString, QString>::const_iterator it2 = envvars.begin(); it2 != envvars.end(); ++it2 ) + { + (*it).replace("$$("+it2.key()+")", it2.data() ); + } + for( QMap<QString, QStringList>::const_iterator it2 = variables.begin(); it2 != variables.end(); ++it2 ) + { + for( QStringList::const_iterator it3 = it2.data().begin(); it3 != it2.data().end(); ++it3 ) + { + (*it).replace("$$"+it2.key(), *it3 ); + (*it).replace("$${"+it2.key()+"}", *it3 ); + } + } + } + return result; +} + +void Scope::allFiles( const QString& projectDirectory, std::set<QString>& res ) +{ + + QString myRelPath = URLUtil::getRelativePath( projectDirectory, projectDir() ); + QString file; + QStringList values; + QString header = ""; + if( variableValues("TEMPLATE",false ).findIndex("subdirs") == -1 ) + { + values = variableValues( "INSTALLS" ,false, false ); + QStringList::const_iterator it; + for ( it = values.begin(); it != values.end(); ++it ) + { + if ( ( *it ) == "target" ) + continue; + + QStringList files = variableValues( *it + ".files" ,false, false ); + QStringList::iterator filesit = files.begin(); + for ( ;filesit != files.end(); ++filesit ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *filesit; + file = resolveVariables( file ); + if( file.contains("*") ) + { + QFileInfo fi( projectDirectory + QString( QChar( QDir::separator() ) ) + file ); + QDir absDir = fi.dir( true ); + absDir.setNameFilter( fi.fileName() ); + absDir.setFilter( QDir::Files | QDir::Readable | QDir::NoSymLinks ); + QStringList list = absDir.entryList(); + for( QStringList::const_iterator it = list.begin(); it != list.end(); ++it ) + { + res.insert( QDir::cleanDirPath( URLUtil::getRelativePath( projectDirectory, absDir.path()+QString( QChar( QDir::separator() ) )+*it ) ) ); + } + } + else + { + res.insert( QDir::cleanDirPath( file ) ); + } + } + } + + values = variableValues( "LEXSOURCES" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + + values = variableValues( "YACCSOURCES" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + + values = variableValues( "DISTFILES" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + if( file.contains("*") ) + { + QFileInfo fi( projectDirectory + QString( QChar( QDir::separator() ) ) + file ); + QDir absDir = fi.dir( true ); + absDir.setNameFilter( fi.fileName() ); + absDir.setFilter( QDir::Files | QDir::Readable | QDir::NoSymLinks ); + QStringList list = absDir.entryList(); + for( QStringList::const_iterator it = list.begin(); it != list.end(); ++it ) + { + res.insert( QDir::cleanDirPath( URLUtil::getRelativePath( projectDirectory, absDir.path()+QString( QChar( QDir::separator() ) )+*it ) ) ); + } + } + else + { + res.insert( QDir::cleanDirPath( file ) ); + } + } + + if ( isQt4Project() ) + { + values = variableValues( "RESOURCES" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + } + values = variableValues( "IMAGES" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + + values = variableValues( "TRANSLATIONS" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + + values = variableValues( "IDLS" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + + if ( m_part->isTMakeProject() ) + { + values = variableValues( "INTERFACES" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + if( QFileInfo(projectDir()+QString(QChar(QDir::separator())) + *it+".h").exists() ) + res.insert( QDir::cleanDirPath( file+".h" ) ); + } + } + else + { + values = variableValues( "FORMS" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + + if( !m_part->isQt4Project()) + { + header = projectDir()+QString(QChar(QDir::separator())) + *it+".h"; + if( QFileInfo(header).exists() ) + res.insert( QDir::cleanDirPath( header ) ); + header = projectDir()+QString(QChar(QDir::separator())) + *it+".cpp"; + if( QFileInfo(header).exists() ) + res.insert( QDir::cleanDirPath( header ) ); + } + else + { + header = projectDir()+QString(QChar(QDir::separator())) + "ui_" +*it; + header.replace(QRegExp("\\.ui$"),".h"); + if( QFileInfo(header).exists() ) + res.insert( QDir::cleanDirPath( header ) ); + } + } + } + + values = variableValues( "SOURCES" ,false, false ); + kdDebug(9024) << "scope:" << scopeType() << " found values: " << values << endl; + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + + values = variableValues( "HEADERS" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + } + QMap<unsigned int, Scope*>::const_iterator it = m_scopes.begin(); + for( ; it != m_scopes.end(); ++it ) + { + it.data()->allFiles( projectDirectory, res ); + } +} + +QStringList Scope::allFiles( const QString& projectDir ) +{ + QStringList result; + std::set<QString> files; + allFiles( projectDir, files ); + for( std::set<QString>::const_iterator it = files.begin(); it != files.end() ; ++it ) + result.append( *it ); + kdDebug(9024) << "all files: " << result << endl; + return result; +} + +QString Scope::findCustomVarForPath( const QString& path ) +{ + QString result; + if( !m_root ) + return result; + + QMap<unsigned int, QMake::AssignmentAST*>::const_iterator it = m_customVariables.begin(); + for( ; it != m_customVariables.end(); ++it ) + { + kdDebug(9024) << "Checking " << path << " against " << cleanStringList(it.data()->values) << endl; + if( !it.data()->values.isEmpty() && cleanStringList(it.data()->values).front() == path ) + { + return it.data()->scopedID; + } + } + if( scopeType() != ProjectScope ) + { + return parent()->findCustomVarForPath( path ); + } + return result; +} + +void Scope::loadDefaultOpts() +{ + if( !m_defaultopts && m_root ) + { + m_defaultopts = new QMakeDefaultOpts(); + if( DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/disableDefaultOpts", true ) ) + { + m_defaultopts->readVariables( m_part->qmakePath(), QFileInfo( m_root->fileName() ).dirPath( true ) ); + } + } +} + +QString Scope::getLineEndingString() const +{ + + if( scopeType() == ProjectScope ) + { + switch( m_root->lineEnding() ) + { + case QMake::ProjectAST::Windows: + return QString("\r\n"); + break; + case QMake::ProjectAST::MacOS: + return QString("\r"); + break; + case QMake::ProjectAST::Unix: + return QString("\n"); + break; + } + }else if( m_parent ) + { + return m_parent->getLineEndingString(); + } + return "\n"; +} + +QString Scope::replaceWs(QString s) +{ + return s.replace( getLineEndingString(), "%nl").replace("\t", "%tab").replace(" ", "%spc"); +} + +bool Scope::containsContinue(const QString& s ) const +{ + return( s.find( QRegExp( "\\\\\\s*"+getLineEndingString() ) ) != -1 + || s.find( QRegExp( "\\\\\\s*#" ) ) != -1 ); +} + +bool Scope::isComment( const QString& s) const +{ + return s.startsWith("#"); +} + +#ifdef DEBUG +void Scope::printTree() +{ + PrintAST p; + p.processProject(m_root); +} + +Scope::PrintAST::PrintAST() : QMake::ASTVisitor() +{ + indent = 0; +} + +void Scope::PrintAST::processProject( QMake::ProjectAST* p ) +{ + QMake::ASTVisitor::processProject(p); +} + +void Scope::PrintAST::enterRealProject( QMake::ProjectAST* p ) +{ + kdDebug(9024) << getIndent() << "--------- Entering Project: " << replaceWs(p->fileName()) << " --------------" << endl; + indent += 4; + QMake::ASTVisitor::enterRealProject(p); +} + +void Scope::PrintAST::leaveRealProject( QMake::ProjectAST* p ) +{ + indent -= 4; + kdDebug(9024) << getIndent() << "--------- Leaving Project: " << replaceWs(p->fileName()) << " --------------" << endl; + QMake::ASTVisitor::leaveRealProject(p); +} + +void Scope::PrintAST::enterScope( QMake::ProjectAST* p ) +{ + kdDebug(9024) << getIndent() << "--------- Entering Scope: " << replaceWs(p->scopedID) << " --------------" << endl; + indent += 4; + QMake::ASTVisitor::enterScope(p); +} + +void Scope::PrintAST::leaveScope( QMake::ProjectAST* p ) +{ + indent -= 4; + kdDebug(9024) << getIndent() << "--------- Leaving Scope: " << replaceWs(p->scopedID) << " --------------" << endl; + QMake::ASTVisitor::leaveScope(p); +} + +void Scope::PrintAST::enterFunctionScope( QMake::ProjectAST* p ) +{ + kdDebug(9024) << getIndent() << "--------- Entering FunctionScope: " << replaceWs(p->scopedID) << "(" << replaceWs(p->args) << ")"<< " --------------" << endl; + indent += 4; + QMake::ASTVisitor::enterFunctionScope(p); +} + +void Scope::PrintAST::leaveFunctionScope( QMake::ProjectAST* p ) +{ + indent -= 4; + kdDebug(9024) << getIndent() << "--------- Leaving FunctionScope: " << replaceWs(p->scopedID) << "(" << replaceWs(p->args) << ")"<< " --------------" << endl; + QMake::ASTVisitor::leaveFunctionScope(p); +} + +QString Scope::PrintAST::replaceWs(QString s) +{ + return s.replace("\n", "%nl").replace("\t", "%tab").replace(" ", "%spc"); +} + +void Scope::PrintAST::processAssignment( QMake::AssignmentAST* a) +{ + kdDebug(9024) << getIndent() << "Assignment: " << replaceWs(a->scopedID) << " " << replaceWs(a->op) << " " + << replaceWs(a->values.join("|"))<< endl; + QMake::ASTVisitor::processAssignment(a); +} + +void Scope::PrintAST::processNewLine( QMake::NewLineAST* n) +{ + kdDebug(9024) << getIndent() << "Newline " << endl; + QMake::ASTVisitor::processNewLine(n); +} + +void Scope::PrintAST::processComment( QMake::CommentAST* a) +{ + kdDebug(9024) << getIndent() << "Comment: " << replaceWs(a->comment) << endl; + QMake::ASTVisitor::processComment(a); +} + +void Scope::PrintAST::processInclude( QMake::IncludeAST* a) +{ + kdDebug(9024) << getIndent() << "Include: " << replaceWs(a->projectName) << endl; + QMake::ASTVisitor::processInclude(a); +} + +QString Scope::PrintAST::getIndent() +{ + QString ind; + for( int i = 0 ; i < indent ; i++) + ind += " "; + return ind; +} +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/scope.h b/buildtools/qmake/scope.h new file mode 100644 index 00000000..e8f40eb9 --- /dev/null +++ b/buildtools/qmake/scope.h @@ -0,0 +1,308 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 _SCOPE_H_ +#define _SCOPE_H_ + +#include <qstring.h> +#include <qstringlist.h> +#include <qmap.h> +#include <set> + +#include "qmakeast.h" +#include "qmakedefaultopts.h" + +#ifdef DEBUG +#include "qmakeastvisitor.h" +#endif + +class Scope; +class TrollProjectPart; + +class Scope +{ +public: + + enum ScopeType { + ProjectScope, + FunctionScope, + SimpleScope, + IncludeScope, + InvalidScope + }; + static const QStringList KnownVariables; + static const QStringList KnownConfigValues; + + Scope( const QMap<QString, QString>& env, const QString &filename, TrollProjectPart* part ); + ~Scope(); + + void saveToFile() const; + + // Changing variable values + void addToPlusOp( const QString& variable, const QStringList& values ); + void removeFromPlusOp( const QString& variable, const QStringList& values ); + void addToMinusOp( const QString& variable, const QStringList& values ); + void removeFromMinusOp( const QString& variable, const QStringList& values ); + void addToEqualOp( const QString& variable, const QStringList& values ); + void removeFromEqualOp( const QString& variable, const QStringList& values ); + void setPlusOp( const QString& variable, const QStringList& values ); + void setEqualOp( const QString& variable, const QStringList& values ); + void setMinusOp( const QString& variable, const QStringList& values ); + + // Checks wether a line like VAR = exists in this subscope + bool isVariableReset( const QString& var ); + + // Fetch the valuelist for the variable op combination inside this scope + QStringList variableValuesForOp( const QString& variable, const QString& op ) const; + + // Fetch the variable values by running over the statements and adding/removing/setting + // as the encountered op's say, begin with the parent projects variableValues list + QStringList variableValues( const QString& variable, bool checkIncParent = true, bool fetchFromParent = true, bool evaluateSubScopes = false ); + + // Remove a variable+Op combination from the scope, if existant + void removeVariable( const QString& var, const QString& op ); + + // Getting to know what type of scope this is + ScopeType scopeType() const; + + // This returns the function+args, the scopename or the pro/pri file + // depending on the type of scope + QString scopeName() const; + + // Returns the projectName for this scope, this is equal to the last part of the projectDir() + QString projectName() const; + + // Returns just the filename of this project's .pro file + QString fileName() const; + + // Returns the absolute path of the dir containing the .pro file + QString projectDir() const; + + // get the parent Scope + Scope* parent() const { return m_parent; } + + // Fetching sub-scopes + const QValueList<Scope*> scopesInOrder() const { return m_scopes.values(); } + // Working on SubScopes + /* + * creates a new function scope at the end of this (Sub-)AST and returns the Scope wrapping it + */ + Scope* createFunctionScope( const QString& funcName, const QString& args ); + /* + * creates a new simple scope at the end of this (Sub-)AST and returns the Scope wrapping it + */ + Scope* createSimpleScope( const QString& scopename ); + + /* + * creates a new function scope at the end of this (Sub-)AST + * and a new include scope inside the new function scope. + * It returns the Scope wrapping the include-AST, the function scope AST + * can be accessed easily using the parent() method. + */ + Scope* createIncludeScope( const QString& includeFile, bool negate = false ); + + /* + * creates a new subproject in dir (create's dir if necessary) + * If this scope is not a project scope the subproject will be added to this + * Scope only, i.e. it is not seen in the project-files list of subdirs + */ + Scope* createSubProject( const QString& dir ); + + /* delete the given function scope */ + bool deleteFunctionScope( unsigned int ); + /* delete the given simple scope */ + bool deleteSimpleScope( unsigned int ); + /* delete the given include scope */ + bool deleteIncludeScope( unsigned int ); + /* deletes the subproject (including the subdir if deleteSubdir is true) */ + bool deleteSubProject( unsigned int, bool deleteSubdir ); + + /* find out wether the project is Qt4 or Qt3 */ + bool isQt4Project() const ; + + /* Provide a Map of Custom variables */ + const QMap<unsigned int, QMap<QString, QString> > customVariables() const; + + unsigned int addCustomVariable( const QString& var, const QString& op, const QString& values ); + + /* Removes the variable with the given id if it exists */ + void removeCustomVariable( unsigned int ); + + /* Update the values of the variable/operation combo var+op to values */ + void updateCustomVariable( unsigned int, const QString&, const QString& , const QString& ); + + // Checks wether a QStringList contains any values that are not whitespace or \\n + static bool listIsEmpty( const QStringList& values ); + + /* returns wether this is an enabled subproject or a disabled one */ + bool isEnabled() { return m_isEnabled; } + + QStringList cleanStringList(const QStringList& list) const; + + /* Reload a project scope */ + void reloadProject(); + + /* creates a new disabled Scope child and add SUBDIRS -= dir to this scope */ + Scope* disableSubproject( const QString& ); + + /* return the "position" of this scope in the list of scopes */ + unsigned int getNum() { return m_num; } + + QStringList allFiles( const QString& ); + + QString resolveVariables( const QString& ) const; + + QString findCustomVarForPath( const QString& ); + +#ifdef DEBUG + void printTree(); +#endif + +private: + + // Builds the scope-lists and the customVariables list + void init(); + + /* + * Updates the given Variable+op with the values, if removeFromOp is true it removes the values, else it adds them + * this works it's way back through the current scope and changes the last occurence of op to + * include all new values. + * + * Depending on "op" it might end the search earlier (if op is += it also stops at =) + * + * This also removes the values from other assignments if the operation is not op, i.e. + * if op is += removes values from any occurence of -= + * if op is -= removes values from any occurence of = and += + * if op is = removes values frmo any occurence of -= + */ + void updateVariable( const QString& variable, const QString& op, const QStringList& values, bool removeFromOp ); + + /* + * Helper Function to change the origValues list with the values from newValues + * depending on the state of "remove" either adds or removes all entries from newValues + * to origValues if they didn't exist there yet + */ + void updateValues( QStringList& origValues, const QStringList& newValues, bool remove = false, QString indent = " " ); + + /* + * Finds an existing variable, returns the end() of the statemenst if it is not found + */ + QValueList<QMake::AST*>::iterator findExistingVariable( const QString& variable ); + + // Private constructors for easier subscope creation + /* + * just initializes the lists from the scope + */ + Scope( const QMap<QString, QString>& env, unsigned int num, Scope* parent, QMake::ProjectAST* root, QMakeDefaultOpts*, TrollProjectPart* part ); + /* + * reads the given filename and parses it. If it doesn't exist creates an empty + * ProjectAST with the given filename + */ + Scope( const QMap<QString, QString>& env, unsigned int num, Scope* parent, const QString& filename, TrollProjectPart* part, bool isEnabled = true ); + /* + * Creates a scope for an include statement, parses the file and initializes the Scope + * Create an empty ProjectAST if the file cannot be found or parsed. + */ + Scope( const QMap<QString, QString>& env, unsigned int num, Scope* parent, QMake::IncludeAST* incast, const QString& path, const QString& incfile, QMakeDefaultOpts*, TrollProjectPart* part ); + + + // runs through the statements until stopHere is found (or the end is reached, if stopHere is 0), + // using the given list as startvalue + // Changes the list using the +=, -=, = operations accordingly + void calcValuesFromStatements( const QString& variable, QStringList& result, bool, QMake::AST* stopHere = 0, bool fetchFromParent = true, bool setDefault = true, bool evaluateSubScopes = false ) const; + + // Check wether the two operators are compatible + static bool isCompatible( const QString& op1, const QString& op2); + + // Check wether the 2 lists are equal, regardless of element order. + static bool listsEqual(const QStringList& , const QStringList& ); + + // Load and Save project files, these only work on ProjectScope's + bool loadFromFile( const QString& filename ); + + QString funcScopeKey( QMake::ProjectAST* funcast ) const { return funcast->scopedID + "(" + funcast->args + ")"; } + + unsigned int getNextScopeNum() { if( m_scopes.isEmpty() ) return 0; else return (m_scopes.keys().last()+1); } + + QStringList lookupVariable( const QString& var ); + + QStringList resolveVariables( const QStringList&, QMake::AST* = 0 ) const; + QStringList variableValues( const QString& variable, QMake::AST*, bool fetchFromParent = true ) const; + QString resolveVariables( const QString& , QMake::AST* ) const; + + // This function determines the currently used String for fileending, it can be \n, \r or \r\n + QString getLineEndingString() const; + bool isComment( const QString& ) const; + bool containsContinue( const QString& ) const; + void allFiles( const QString&, std::set<QString>& ); + + void loadDefaultOpts(); + + QMake::ProjectAST* m_root; + QMake::IncludeAST* m_incast; + QMap<unsigned int, QMake::AssignmentAST*> m_customVariables; + QMap<unsigned int, Scope*> m_scopes; + Scope* m_parent; + unsigned int m_maxCustomVarNum; + + QString replaceWs(QString); + + + // The "position" inside the parent scope that this scope starts at + unsigned int m_num; + bool m_isEnabled; + TrollProjectPart* m_part; + QMakeDefaultOpts* m_defaultopts; + QMap<QString, QStringList> m_varCache; + QMap<QString,QString> m_environment; + +#ifdef DEBUG + class PrintAST : QMake::ASTVisitor + { + + public: + PrintAST(); + virtual void processProject( QMake::ProjectAST* p ); + virtual void enterRealProject( QMake::ProjectAST* p ); + + virtual void leaveRealProject( QMake::ProjectAST* p ); + + virtual void enterScope( QMake::ProjectAST* p ); + + virtual void leaveScope( QMake::ProjectAST* p ); + + virtual void enterFunctionScope( QMake::ProjectAST* p ); + + virtual void leaveFunctionScope( QMake::ProjectAST* p ); + + virtual void processAssignment( QMake::AssignmentAST* a); + + virtual void processNewLine( QMake::NewLineAST* n); + + virtual void processComment( QMake::CommentAST* a); + + virtual void processInclude( QMake::IncludeAST* a); + + QString replaceWs(QString); + + private: + QString getIndent(); + int indent; + + }; +#endif + +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + diff --git a/buildtools/qmake/trolllistview.cpp b/buildtools/qmake/trolllistview.cpp new file mode 100644 index 00000000..531bb3e8 --- /dev/null +++ b/buildtools/qmake/trolllistview.cpp @@ -0,0 +1,38 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * adymo@mksat.net * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "trolllistview.h" + + +TrollListView::TrollListView(TrollProjectWidget *widget, QWidget *parent, + TrollProjectWidget::TrollProjectView view, const char *name) + :KListView(parent, name), m_widget(widget), m_view(view) +{ +} + +TrollListView::~TrollListView() +{ +} + +void TrollListView::focusOutEvent( QFocusEvent */* e*/ ) +{ + m_widget->setLastFocusedView(m_view); +} + +#include "trolllistview.moc" diff --git a/buildtools/qmake/trolllistview.h b/buildtools/qmake/trolllistview.h new file mode 100644 index 00000000..0ee86abb --- /dev/null +++ b/buildtools/qmake/trolllistview.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * adymo@mksat.net * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef TROLLLISTVIEW_H +#define TROLLLISTVIEW_H + +#include <klistview.h> + +#include "trollprojectwidget.h" + +class TrollListView : public KListView +{ +Q_OBJECT +public: + TrollListView(TrollProjectWidget *widget, QWidget *parent, TrollProjectWidget::TrollProjectView view, const char *name = 0); + ~TrollListView(); +protected: + virtual void focusOutEvent(QFocusEvent *e); + +private: + TrollProjectWidget *m_widget; + TrollProjectWidget::TrollProjectView m_view; +}; + +#endif diff --git a/buildtools/qmake/trollprojectpart.cpp b/buildtools/qmake/trollprojectpart.cpp new file mode 100644 index 00000000..6d2f5b3a --- /dev/null +++ b/buildtools/qmake/trollprojectpart.cpp @@ -0,0 +1,931 @@ +/*************************************************************************** + * Copyright (C) 2003 by Thomas Hasart * + * thasart@gmx.de * + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2002 by Jakob Simon-Gaarde * + * jakob@jsg.dk * + * * + * 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 "trollprojectpart.h" + +#include <qdir.h> +#include <qfileinfo.h> +#include <qwhatsthis.h> +#include <kdeversion.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kdirwatch.h> +#include <kstatusbar.h> +#include <qmessagebox.h> +#include <kdevgenericfactory.h> +#include <kaction.h> +#include <kparts/part.h> +#include <kprocess.h> +#include <kconfig.h> +#include <kapplication.h> +#include <kurlrequesterdlg.h> +#include <kurlrequester.h> +#include <kurlcompletion.h> +#include <kfile.h> +#include <makeoptionswidget.h> + + +#include "domutil.h" +#include "kdevcore.h" +#include "kdevmainwindow.h" +#include "kdevmakefrontend.h" +#include "kdevappfrontend.h" +#include "kdevpartcontroller.h" +#include "trollprojectwidget.h" +#include "runoptionswidget.h" +#include "config.h" +#include "envvartools.h" +#include "qmakeoptionswidget.h" +#include "scope.h" + +#include <kdevplugininfo.h> +#include <urlutil.h> + +typedef KDevGenericFactory<TrollProjectPart> TrollProjectFactory; +static const KDevPluginInfo data("kdevtrollproject"); +K_EXPORT_COMPONENT_FACTORY( libkdevtrollproject, TrollProjectFactory( data ) ) + +TrollProjectPart::TrollProjectPart(QObject *parent, const char *name, const QStringList& args ) + : KDevBuildTool(&data, parent, name ? name : "TrollProjectPart") +{ + setInstance(TrollProjectFactory::instance()); + + if ( args.count() == 1 && args[0] == "TMake" ) + m_tmakeProject = true; + else + m_tmakeProject = false; + + setXMLFile("kdevtrollproject.rc"); + + m_executeProjectAfterBuild = false; + m_executeTargetAfterBuild = false; + + m_dirWatch = new KDirWatch(this); + + m_widget = new TrollProjectWidget(this); + m_widget->setIcon(SmallIcon("qmakerun")); + m_widget->setCaption(i18n("QMake Manager")); + QWhatsThis::add(m_widget, i18n("<b>QMake manager</b><p>" + "The QMake manager project tree consists of two parts. The 'overview' " + "in the upper half shows the subprojects, each one having a " + ".pro file. The 'details' view in the lower half shows the " + "list of files for the active subproject selected in the overview.")); + + mainWindow()->embedSelectViewRight(m_widget, i18n("QMake Manager"), i18n("QMake manager")); + + KAction *action; + + const QIconSet icon(SmallIcon("compfile")); + action = new KAction( i18n("Compile &File"), "compfile", 0, + m_widget, SLOT(slotBuildOpenFile()), + actionCollection(),"build_compilefile" ); + action->setToolTip(i18n("Compile file")); + action->setWhatsThis(i18n("<b>Compile file</b><p>Runs <b>make filename.o</b> command from the directory where 'filename' is the name of currently opened file.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + + + action = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8, + m_widget, SLOT(slotBuildProject()), + actionCollection(), "build_build_project" ); + action->setToolTip(i18n("Build project")); + action->setWhatsThis(i18n("<b>Build project</b><p>Runs <b>make</b> from the project directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + + action = new KAction( i18n("&Rebuild Project"),"rebuild" , 0, + m_widget, SLOT(slotRebuildProject()), + actionCollection(),"build_rebuild_project" ); + action->setToolTip(i18n("Rebuild project")); + action->setWhatsThis(i18n("<b>Rebuild project</b><p>Runs <b>make clean</b> and then <b>make</b> from the project directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + + action = new KAction( i18n("&Install Project"),"install" , 0, + m_widget, SLOT(slotInstallProject()), + actionCollection(),"build_install_project" ); + action->setToolTip(i18n("Install project")); + action->setWhatsThis(i18n("<b>Install project</b><p>Runs <b>make install</b> from the project directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + + action = new KAction( i18n("&Clean Project"), 0, + m_widget, SLOT(slotCleanProject()), + actionCollection(), "build_clean_project" ); + action->setToolTip(i18n("Clean project")); + action->setWhatsThis(i18n("<b>Clean project</b><p>Runs <b>make clean</b> command from the project directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + + action = new KAction( i18n("&Dist-Clean Project"), 0, + m_widget, SLOT(slotDistCleanProject()), + actionCollection(), "build_distclean_project" ); + action->setToolTip(i18n("Dist-Clean project")); + action->setWhatsThis(i18n("<b>Dist-Clean project</b><p>Runs <b>make distclean</b> command from the " + "project directory.<br>Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + + action = new KAction( i18n("Execute Main Program"), "exec", SHIFT+Key_F9, + this, SLOT(slotBuildAndExecuteProject()), + actionCollection(), "build_execute_project" ); + action->setToolTip(i18n("Execute main program")); + action->setWhatsThis(i18n("<b>Execute program</b><p>Executes the currently selected subproject if it is an application or the program specified in project settings, <b>Run Options</b> tab.")); + + action = new KAction( i18n("&Build Subproject"), "make_kdevelop", Key_F7, + m_widget, SLOT(slotBuildTarget()), + actionCollection(), "build_build_target" ); + action->setToolTip(i18n("Build subproject")); + action->setWhatsThis(i18n("<b>Build subproject</b><p>Runs <b>make</b> from the current subproject directory. " + "Current subproject is a subproject selected in <b>QMake manager</b> 'overview' window.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + + action = new KAction( i18n("&Rebuild Subproject"), "rebuild", 0, + m_widget, SLOT(slotRebuildTarget()), + actionCollection(),"build_rebuild_target" ); + action->setToolTip(i18n("Rebuild subproject")); + action->setWhatsThis(i18n("<b>Rebuild subproject</b><p>Runs <b>make clean</b> and then <b>make</b> from the current subproject directory. " + "Current subproject is a subproject selected in <b>QMake manager</b> 'overview' window.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + + action = new KAction( i18n("&Install Subproject"), "install", 0, + m_widget, SLOT(slotInstallTarget()), + actionCollection(),"build_install_target" ); + action->setToolTip(i18n("Install subproject")); + action->setWhatsThis(i18n("<b>Install subproject</b><p>Runs <b>make install</b> from the current subproject directory. " + "The current subproject is the subproject selected in the <b>QMake manager</b> 'overview' window.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + + action = new KAction( i18n("&Clean Subproject"), 0, + m_widget, SLOT(slotCleanTarget()), + actionCollection(), "build_clean_target" ); + action->setToolTip(i18n("Clean subproject")); + action->setWhatsThis(i18n("<b>Clean subproject</b><p>Runs <b>make clean</b> from the current subproject directory. " + "The current subproject is the subproject selected in the <b>QMake manager</b> 'overview' window.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + + action = new KAction( i18n("&Dist-Clean Subproject"), 0, + m_widget, SLOT(slotDistCleanTarget()), + actionCollection(), "build_distclean_target" ); + action->setToolTip(i18n("Dist-Clean subproject")); + action->setWhatsThis(i18n("<b>Dist-Clean subproject</b><p>Runs <b>make distclean</b> from the current" + " subproject directory. The current subproject is the subproject selected in the <b>QMake manager</b> 'overview' window.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab.")); + + action = new KAction( i18n("Execute Subproject"), "exec", 0, + this, SLOT(slotBuildAndExecuteTarget()), + actionCollection(), "build_execute_target" ); + action->setToolTip(i18n("Execute subproject")); + action->setWhatsThis(i18n("<b>Execute subproject</b><p>Executes the target program for the currently selected subproject. " + "This action is allowed only if a type of the subproject is 'application'. The type of the subproject can be " + "defined in <b>Subproject Settings</b> dialog (open it from the subproject context menu).")); + + connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), + this, SLOT(projectConfigWidget(KDialogBase*)) ); + + connect( makeFrontend(), SIGNAL(commandFinished(const QString&)), + this, SLOT(slotCommandFinished(const QString&)) ); + + QString m_defaultQtDir = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", ""); + QString m_qmakePath = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/qmake", ""); + QString qtversion = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/version", "3"); + + if( m_defaultQtDir.isEmpty() || !isValidQtDir( m_defaultQtDir ) ) + { + m_defaultQtDir = findQtDir(); + kdDebug(9024) << "Setting default dir to: " << m_defaultQtDir << endl; + DomUtil::writeEntry(*projectDom(), "/kdevcppsupport/qt/root", m_defaultQtDir ); + } + if( m_qmakePath.isEmpty() || !isExecutable( m_qmakePath ) ) + { + m_qmakePath = findExecutable( "qmake-qt"+qtversion ); + if( m_qmakePath.isEmpty() || !isExecutable( m_qmakePath ) ) + m_qmakePath = findExecutable( "qmake" ); + kdDebug(9024) << "Setting qmake binary to: " << m_qmakePath << endl; + DomUtil::writeEntry(*projectDom(), "/kdevcppsupport/qt/qmake", m_qmakePath ); + } +} + + +TrollProjectPart::~TrollProjectPart() +{ + if (m_widget) + mainWindow()->removeView(m_widget); + delete m_widget; +} + +QString TrollProjectPart::makeEnvironment() +{ + // Get the make environment variables pairs into the environstr string + // in the form of: "ENV_VARIABLE=ENV_VALUE" + // Note that we quote the variable value due to the possibility of + // embedded spaces + DomUtil::PairList envvars = + DomUtil::readPairListEntry(*projectDom(), "/kdevtrollproject/make/envvars", "envvar", "name", "value"); + + QString environstr; + DomUtil::PairList::ConstIterator it; + bool hasQtDir = false; + for (it = envvars.begin(); it != envvars.end(); ++it) { + if( (*it).first == "QTDIR" ) + hasQtDir = true; + + environstr += (*it).first; + environstr += "="; + environstr += EnvVarTools::quote((*it).second); + environstr += " "; + } + + if( !hasQtDir && !isQt4Project() && !DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", "").isEmpty() ) + { + environstr += QString( "QTDIR=" ) + EnvVarTools::quote( DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", "") ) + QString( " PATH=$QTDIR/bin:$PATH " ); + } + + KConfigGroup grp( kapp->config(), "MakeOutputView" ); + if( grp.readBoolEntry( "ForceCLocale", true ) ) + environstr += "LC_MESSAGES="+EnvVarTools::quote("C")+" "+" "+"LC_CTYPE="+EnvVarTools::quote("C")+" "; + + return environstr; +} + +void TrollProjectPart::projectConfigWidget(KDialogBase *dlg) +{ + QVBox *vbox; + vbox = dlg->addVBoxPage(i18n("Run Options"), i18n("Run Options"), BarIcon( "make", KIcon::SizeMedium )); + RunOptionsWidget *optdlg = new RunOptionsWidget(*projectDom(), "/kdevtrollproject", buildDirectory(), vbox); + + vbox = dlg->addVBoxPage(i18n("Make Options"), i18n("Make Options"), BarIcon( "make", KIcon::SizeMedium )); + MakeOptionsWidget *w4 = new MakeOptionsWidget(*projectDom(), "/kdevtrollproject", vbox); + + vbox = dlg->addVBoxPage(i18n("QMake Manager"), i18n("QMake Manager"), BarIcon( "make", KIcon::SizeMedium )); + QMakeOptionsWidget *qm = new QMakeOptionsWidget( projectDirectory(), *projectDom(), "/kdevtrollproject", vbox); + + + connect( dlg, SIGNAL(okClicked()), w4, SLOT(accept()) ); + connect( dlg, SIGNAL(okClicked()), qm, SLOT(accept()) ); + connect( dlg, SIGNAL(okClicked()), optdlg, SLOT(accept()) ); +} + + +void TrollProjectPart::openProject(const QString &dirName, const QString &projectName) +{ + mainWindow()->statusBar()->message( i18n("Loading Project...") ); + + QString defaultQtDir = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", ""); + if( !isQt4Project() && ( defaultQtDir.isEmpty() || !isValidQtDir( defaultQtDir ) ) ) + { + bool doask = true; + while( doask ) + { + KURLRequesterDlg dlg( i18n("Choose Qt3 directory"), + i18n("Choose the Qt3 directory to use. This directory needs to have an include directory containing qt.h.") + , m_widget, 0); + dlg.urlRequester() ->setMode( KFile::Directory | KFile::LocalOnly ); + dlg.urlRequester() ->setURL( QString::null ); + dlg.urlRequester() ->completionObject() ->setDir( "/" ); + + if ( dlg.exec() == QDialog::Accepted && !dlg.urlRequester() ->url().isEmpty() ) + { + QString qtdir = dlg.urlRequester()->url(); + if( !isValidQtDir( qtdir ) ) + { + if( KMessageBox::warningYesNo( m_widget, + i18n("The directory you gave is not a proper Qt directory, the " + "project might not work properly without one.\nPlease make " + "sure you give a directory that contains a bin with the " + "qmake binary in it and for Qt3 project also contains an " + "include directory with qt.h in it.\nDo you want to try " + "setting a Qt directory again?"), + i18n("Wrong Qt directory given")) + == KMessageBox::Yes + ) + doask = true; + else + doask = false; + }else + { + defaultQtDir = qtdir; + doask = false; + } + + }else + { + if( KMessageBox::warningYesNo( m_widget, + i18n("You did not specify a Qt directory, and the project might not " + "work properly without one.\nDo you want to try setting a Qt" + " directory again?"), + i18n("No Qt directory given")) + == KMessageBox::Yes + ) + doask = true; + else + doask = false; + } + } + } + QString qmakePath = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/qmake", ""); + if( qmakePath.isEmpty() || !isExecutable( qmakePath ) ) + { + bool doask = true; + while( doask ) + { + KURLRequesterDlg dlg( i18n("Choose QMake executable"), + i18n("Choose the QMake binary to use. QMake is used to generate Makefiles from the project files."), m_widget, 0); + dlg.urlRequester() ->setMode( KFile::Directory | KFile::LocalOnly ); + dlg.urlRequester() ->setURL( QString::null ); + dlg.urlRequester() ->completionObject() ->setDir( "/" ); + + if ( dlg.exec() == QDialog::Accepted && !dlg.urlRequester() ->url().isEmpty() ) + { + QString qmake = dlg.urlRequester()->url(); + if( !isExecutable( qmake ) ) + { + if( KMessageBox::warningYesNo( m_widget, + i18n("The binary you gave is not executable, the " + "project might not work properly.\nPlease make " + "sure you give a qmake binary that is executable.\nDo you want to try " + "setting the QMake binary again?"), + i18n("Wrong QMake binary given")) + == KMessageBox::Yes + ) + doask = true; + else + doask = false; + }else + { + qmakePath = qmake; + doask = false; + } + + }else + { + if( KMessageBox::warningYesNo( m_widget, + i18n("You did not specify a QMake binary, and the project might not " + "work properly without one.\nDo you want to try setting a QMake" + " binary again?"), + i18n("No QMake binary given")) + == KMessageBox::Yes + ) + doask = true; + else + doask = false; + } + } + } + DomUtil::writeEntry( *projectDom(), "/kdevcppsupport/qt/root", defaultQtDir ); + DomUtil::writeEntry( *projectDom(), "/kdevcppsupport/qt/qmake", qmakePath ); + + m_projectName = projectName; + + m_widget->openProject(dirName); + + + QDomDocument &dom = *projectDom(); + // Set the default directory radio to "executable" + if (DomUtil::readEntry(dom, "/kdevtrollproject/run/directoryradio") == "" ) { + DomUtil::writeEntry(dom, "/kdevtrollproject/run/directoryradio", "executable"); + } + + KDevProject::openProject( dirName, projectName ); +} + + +void TrollProjectPart::closeProject() +{ + m_widget->closeProject(); +} + + +QString TrollProjectPart::projectDirectory() const +{ + return m_widget->projectDirectory(); +} + + +QString TrollProjectPart::buildDirectory() const +{ + return m_widget->projectDirectory(); +} + +QString TrollProjectPart::projectName() const +{ + return m_projectName; +} + + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList TrollProjectPart::runEnvironmentVars() const +{ + return DomUtil::readPairListEntry(*projectDom(), "/kdevtrollproject/run/envvars", "envvar", "name", "value"); +} + +void TrollProjectPart::slotBuildAndExecuteProject() +{ + partController()->saveAllFiles(); + if (isDirty()) { + m_executeProjectAfterBuild = true; + m_widget->slotBuildProject(); + } else + m_widget->slotExecuteProject(); +} + +void TrollProjectPart::slotBuildAndExecuteTarget() +{ + partController()->saveAllFiles(); + if (isDirty()) { + m_executeTargetAfterBuild = true; + m_widget->slotBuildTarget(); + } else + m_widget->slotExecuteTarget(); +} + + +/** Retuns the currently selected run directory + * The returned string can be: + * if run/directoryradio == executable + * The directory where the executable is + * if run/directoryradio == build + * The directory where the executable is relative to build directory + * if run/directoryradio == custom + * The custom directory absolute path + */ +QString TrollProjectPart::runDirectory() const +{ + QDomDocument &dom = *projectDom(); + + QString cwd; + if( DomUtil::readBoolEntry(dom, "/kdevtrollproject/run/useglobalprogram", true) ) + { + cwd = defaultRunDirectory("kdevtrollproject"); + }else + { + QString name = m_widget->getCurrentOutputFilename(); + if( name.findRev("/") != -1 ) + name = name.right( name.length()-name.findRev("/")-1 ); + cwd = DomUtil::readEntry( dom, "/kdevtrollproject/run/cwd/" + name ); + } + if( cwd.isEmpty() ) + { + QString destpath = m_widget->getCurrentTarget(); + if( QDir::isRelativePath( destpath ) ) + { + destpath = m_widget->subprojectDirectory() + QString( QChar( QDir::separator() ) ) + destpath; + } + destpath = destpath.left( destpath.findRev("/") ); + cwd = destpath; + } + + return cwd; +} + + +/** Retuns the currently selected main program + * The returned string can be: + * if run/directoryradio == executable + * The executable name + * if run/directoryradio == build + * The path to executable relative to build directory + * if run/directoryradio == custom or relative == false + * The absolute path to executable + */ + + +QString TrollProjectPart::mainProgram() const +{ + + QDomDocument &dom = *projectDom(); + + if( DomUtil::readBoolEntry(dom, "/kdevtrollproject/run/useglobalprogram", false) ) + { + QString DomMainProgram = DomUtil::readEntry(dom, "/kdevtrollproject/run/mainprogram"); + + if ( DomMainProgram.isEmpty() ) return QString(); + + if ( DomMainProgram.startsWith("/") ) // assume absolute path + { + return DomMainProgram; + } + else // assume project relative path + { + return projectDirectory() + "/" + DomMainProgram; + } + }else + { + if( !m_widget->currentSubproject()) + { + KMessageBox::error( m_widget, "There's no selected subproject!\n" + "Unable to determine the main program", "No selected subproject found" ); + kdDebug ( 9020 ) << k_funcinfo << "Error! : There's no active target! -> Unable to determine the main program in TrollProjectPart::mainProgram()" << endl; + return QString::null; + } + + if ( m_widget->currentSubproject()->scope->variableValues("TEMPLATE").findIndex("app") == -1 ) + { + KMessageBox::error( m_widget, "Selected Subproject \""+m_widget->currentSubproject()->scope->projectName()+"\"isn't binary ( " + m_widget->currentSubproject()->scope->variableValues("TEMPLATE").join(" ") + " ) !\n" + "Unable to determine the main program. If you want this\n" + "to be the selected subproject, set a main program under\n" + "Project -> Project Options -> Run Options", "Selected subproject is not a library" ); + kdDebug ( 9020 ) << k_funcinfo << "Error! : Active target isn't binary (" << m_widget->currentSubproject()->scope->variableValues("TEMPLATE").join(" ") << ") ! -> Unable to determine the main program in TrollProjectPart::mainProgram()" << endl; + return QString::null; + } + + QString destpath = m_widget->getCurrentTarget(); + if( QDir::isRelativePath( destpath ) ) + { + destpath = m_widget->subprojectDirectory() + QString( QChar( QDir::separator() ) ) + destpath; + } + return destpath; + } +} + +QString TrollProjectPart::debugArguments() const +{ + if( DomUtil::readBoolEntry(*projectDom(), "/kdevtrollproject/run/useglobalprogram", true ) ) + { + return DomUtil::readEntry(*projectDom(), "/kdevtrollproject/run/globaldebugarguments"); + }else + { + return DomUtil::readEntry(*projectDom(), "/kdevtrollproject/run/debugarguments/"+m_widget->getCurrentOutputFilename() ); + } +} + +/** Retuns a QString with the run command line arguments */ +QString TrollProjectPart::runArguments() const +{ + if( DomUtil::readBoolEntry(*projectDom(), "/kdevtrollproject/run/useglobalprogram", true) ) + { + return DomUtil::readEntry(*projectDom(), "/kdevtrollproject/run/programargs"); + }else + { + return DomUtil::readEntry(*projectDom(), "/kdevtrollproject/run/runarguments/"+m_widget->getCurrentOutputFilename() ); + } +} + + +QString TrollProjectPart::activeDirectory() const +{ + QDomDocument &dom = *projectDom(); + + return DomUtil::readEntry(dom, "/kdevtrollproject/general/activedir"); +} + + +QStringList TrollProjectPart::allFiles() const +{ + return m_widget->allFiles(); +} + + +void TrollProjectPart::addFile(const QString &fileName) +{ + QStringList fileList; + fileList.append ( fileName ); + + this->addFiles ( QStringList( fileName ) ); +} + +void TrollProjectPart::addFiles ( const QStringList &fileList ) +{ + QStringList files = fileList; + for (QStringList::iterator it = files.begin(); it != files.end(); ++it) + { + if( !QFileInfo( *it ).isRelative() ) + { + *it = URLUtil::relativePathToFile( projectDirectory(), *it ); + } + } + m_widget->addFiles(files); + +} + +void TrollProjectPart::removeFile(const QString & /* fileName */) +{ + /// \FIXME +/* QStringList fileList; + fileList.append ( fileName ); + + this->removeFiles ( fileList );*/ +} + +void TrollProjectPart::removeFiles ( const QStringList& fileList ) +{ +/// \FIXME missing remove files functionality +// QStringList::ConstIterator it; +// +// it = fileList.begin(); +// +// for ( ; it != fileList.end(); ++it ) +// { +// FIXME +// } + + emit removedFilesFromProject ( fileList ); +} +/* +void TrollProjectPart::startMakeCommand(const QString &dir, const QString &target) +{ + partController()->saveAllFiles(); + + QFileInfo fi(dir + "/Makefile"); + if (!fi.exists()) { + int r = KMessageBox::questionYesNo(m_widget, i18n("There is no Makefile in this directory. Run qmake first?"), QString::null, i18n("Run qmake"), i18n("Do Not Run")); + if (r == KMessageBox::No) + return; + startQMakeCommand(dir); + } + QDomDocument &dom = *projectDom(); + + if (target=="clean") + { + QString cmdline = DomUtil::readEntry(dom, "/kdevtrollproject/make/makebin"); + if (cmdline.isEmpty()) + cmdline = MAKE_COMMAND; + cmdline += " clean"; + QString dircmd = "cd "; + dircmd += dir; + dircmd += " && "; + cmdline.prepend(makeEnvironment()); + makeFrontend()->queueCommand(dir, dircmd + cmdline); + } + + QString cmdline = DomUtil::readEntry(dom, "/kdevtrollproject/make/makebin"); + if (cmdline.isEmpty()) + cmdline = MAKE_COMMAND; + if (!DomUtil::readBoolEntry(dom, "/kdevtrollproject/make/abortonerror")) + cmdline += " -k"; + int jobs = DomUtil::readIntEntry(dom, "/kdevtrollproject/make/numberofjobs"); + if (jobs != 0) { + cmdline += " -j"; + cmdline += QString::number(jobs); + } + if (DomUtil::readBoolEntry(dom, "/kdevtrollproject/make/dontact")) + cmdline += " -n"; + + cmdline += " "; + cmdline += target; + + QString dircmd = "cd "; + dircmd += dir; + dircmd += " && "; + + cmdline.prepend(makeEnvironment()); + makeFrontend()->queueCommand(dir, dircmd + cmdline); +} +*/ + +void TrollProjectPart::startQMakeCommand(const QString &dir, bool recursive) +{ + QFileInfo fi(dir); + QString cmdline; + + if ( isTMakeProject() ) + { + cmdline = "tmake "; + }else + { + cmdline = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/qmake", "")+" "; + } + + if(isQt4Project() && recursive) + { + cmdline += " -recursive "; + } + + //QString cmdline = QString::fromLatin1( isTMakeProject() ? "tmake " : "qmake " ); +// cmdline += fi.baseName() + ".pro"; + QDir d(dir); + QStringList l = d.entryList("*.pro"); + + if( l.isEmpty() || ( l.count() && l.findIndex( projectName() + ".pro" ) != -1 ) ) + cmdline += projectName()+".pro"; + else if( l.isEmpty() || (l.count() && l.findIndex( fi.baseName() + ".pro" ) != -1 ) ) + cmdline += fi.baseName() + ".pro"; + else + cmdline += l[0]; + +// cmdline += QString::fromLatin1( " -o Makefile" ); + + QString dircmd = "cd "; + dircmd += KProcess::quote(dir); + dircmd += " && "; + + cmdline.prepend(makeEnvironment()); + makeFrontend()->queueCommand(dir, dircmd + cmdline); +} + +void TrollProjectPart::queueCmd(const QString &dir, const QString &cmd) +{ + makeFrontend()->queueCommand(dir, cmd); +} + +void TrollProjectPart::slotCommandFinished( const QString& command ) +{ + Q_UNUSED( command ); + +// if( m_buildCommand != command ) +// return; +// +// m_buildCommand = QString::null; + + m_timestamp.clear(); + QStringList fileList = allFiles(); + QStringList::Iterator it = fileList.begin(); + while( it != fileList.end() ){ + QString fileName = *it; + ++it; + + m_timestamp[ fileName ] = QFileInfo( projectDirectory(), fileName ).lastModified(); + } + + emit projectCompiled(); + + if( m_executeProjectAfterBuild ) + { + m_widget->slotExecuteProject(); + m_executeProjectAfterBuild = false; + }else if( m_executeTargetAfterBuild ) + { + m_widget->slotExecuteTarget(); + m_executeTargetAfterBuild = false; + } + +} + +bool TrollProjectPart::isDirty() +{ + QStringList fileList = allFiles(); + QStringList::Iterator it = fileList.begin(); + while( it != fileList.end() ){ + QString fileName = *it; + ++it; + + QMap<QString, QDateTime>::Iterator it = m_timestamp.find( fileName ); + QDateTime t = QFileInfo( projectDirectory(), fileName ).lastModified(); + if( it == m_timestamp.end() || *it != t ){ + return true; + } + } + + return false; +} + +KDevProject::Options TrollProjectPart::options( ) const +{ + return UsesQMakeBuildSystem; +} + +bool TrollProjectPart::isValidQtDir( const QString& path ) const +{ + QFileInfo inc( path + QString( QChar( QDir::separator() ) )+ + "include"+QString( QChar( QDir::separator() ) )+ + "qt.h" ); + return ( isQt4Project() || ( !isQt4Project() && inc.exists() ) ); +} + +void TrollProjectPart::buildBinDirs( QStringList & dirs ) const +{ + if( !isQt4Project() ) + { + QString m_defaultQtDir = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", ""); + if( !m_defaultQtDir.isEmpty() ) + dirs << (m_defaultQtDir + QString( QChar( QDir::separator() ) ) + "bin" ); + dirs << ( ::getenv("QTDIR") + QString( QChar( QDir::separator() ) ) + "bin" ); + } + QStringList paths = QStringList::split(":",::getenv("PATH")); + dirs += paths; + QString binpath = QDir::rootDirPath() + "bin"; + if( dirs.findIndex( binpath ) != -1 ) + dirs << binpath; + + binpath = QDir::rootDirPath() + "usr" + QString( QChar( QDir::separator() ) ) + "bin"; + if( dirs.findIndex( binpath ) != -1 ) + dirs << binpath; + binpath = QDir::rootDirPath() + "usr" + QString( QChar( QDir::separator() ) ) + "local" + QString( QChar( QDir::separator() ) ) + "bin"; + if( dirs.findIndex( binpath ) != -1 ) + dirs << binpath; +} + + +QString TrollProjectPart::findExecutable( const QString& execname ) const +{ + QStringList dirs; + buildBinDirs( dirs ); + + for( QStringList::Iterator it=dirs.begin(); it!=dirs.end(); ++it ) + { + QString designer = *it + QString( QChar( QDir::separator() ) ) + execname; + if( !designer.isEmpty() && isExecutable( designer ) ) + { + return designer; + } + } + return ""; +} + +bool TrollProjectPart::isExecutable( const QString& path ) const +{ + QFileInfo fi(path); + return( fi.exists() && fi.isExecutable() ); +} + +QString TrollProjectPart::findQtDir() +{ + QStringList qtdirs; + if( !isQt4Project() ) + qtdirs.push_back( ::getenv("QTDIR") ); + qtdirs.push_back( QDir::rootDirPath()+"usr"+QString( QChar( QDir::separator() ) )+"lib"+QString( QChar( QDir::separator() ) )+"qt"+QString("%1").arg( DomUtil::readEntry( *projectDom(), "/kdevcppsupport/qt/version", "3") ) ); + qtdirs.push_back( QDir::rootDirPath()+"usr"+QString( QChar( QDir::separator() ) )+"lib"+QString( QChar( QDir::separator() ) )+"qt"+QString( QChar( QDir::separator() ) )+QString("%1").arg( DomUtil::readEntry( *projectDom(), "/kdevcppsupport/qt/version", "3") ) ); + qtdirs.push_back( QDir::rootDirPath()+"usr"+QString( QChar( QDir::separator() ) )+"share"+QString( QChar( QDir::separator() ) )+"qt"+QString("%1").arg( DomUtil::readEntry( *projectDom(), "/kdevcppsupport/qt/version", "3") ) ); + qtdirs.push_back( QDir::rootDirPath()+"usr" ); + qtdirs.push_back( QDir::rootDirPath()+"usr"+QString( QChar( QDir::separator() ) )+"lib"+QString( QChar( QDir::separator() ) )+"qt" ); + + for( QStringList::Iterator it=qtdirs.begin(); it!=qtdirs.end(); ++it ) + { + QString qtdir = *it; + if( !qtdir.isEmpty() && isValidQtDir(qtdir) ) + { + return qtdir; + } + } + return ""; +} + + +QStringList recursiveProFind( const QString &currDir, const QString &baseDir ) +{ + QStringList fileList; + + if( !currDir.contains( QString( QChar ( QDir::separator() ) ) +".." ) + && !currDir.contains( QString( QChar( QDir::separator() ) )+".") ) + { + QDir dir(currDir); + QStringList dirList = dir.entryList(QDir::Dirs ); + QStringList::Iterator idx = dirList.begin(); + for( ; idx != dirList.end(); ++idx ) + { + fileList += recursiveProFind( currDir + QString( QChar( QDir::separator() ) ) + (*idx),baseDir ); + } + QStringList newFiles = dir.entryList("*.pro *.PRO"); + idx = newFiles.begin(); + for( ; idx != newFiles.end(); ++idx ) + { + QString file = currDir + QString( QChar( QDir::separator() ) ) + (*idx); + fileList.append( file.remove( baseDir ) ); + } + } + + + return fileList; +} + +/*! + \fn TrollProjectPart::distFiles() const + */ +QStringList TrollProjectPart::distFiles() const +{ + QStringList sourceList = allFiles(); + // Scan current source directory for any .pro files. + QString projectDir = projectDirectory(); + QStringList files = recursiveProFind( projectDir, projectDir + QString( QChar( QDir::separator() ) ) ); + return sourceList + files; +} + +bool TrollProjectPart::isQt4Project() const +{ + return ( DomUtil::readIntEntry( *projectDom(), "kdevcppsupport/qt/version", 3 ) == 4 ); +} + +KDirWatch* TrollProjectPart::dirWatch() +{ + return m_dirWatch; +} + +void TrollProjectPart::slotBuild() +{ + m_widget->slotBuildProject(); +} + +#include "trollprojectpart.moc" + +//kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + + diff --git a/buildtools/qmake/trollprojectpart.h b/buildtools/qmake/trollprojectpart.h new file mode 100644 index 00000000..3e571e85 --- /dev/null +++ b/buildtools/qmake/trollprojectpart.h @@ -0,0 +1,105 @@ +/*************************************************************************** + * Copyright (C) 2003 by Thomas Hasart * + * thasart@gmx.de * + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2002 by Jakob Simon-Gaarde * + * jakob@jsg.dk * + * * + * 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 _TROLLPROJECTPART_H_ +#define _TROLLPROJECTPART_H_ + +#include <qdict.h> +#include <qguardedptr.h> +#include <qmap.h> +#include <qdatetime.h> + +#include "kdevbuildtool.h" + +class KDialogBase; +class TrollProjectWidget; +class KDirWatch; +class QMakeDefaultOpts; + +class TrollProjectPart : public KDevBuildTool +{ + Q_OBJECT + +public: + TrollProjectPart( QObject *parent, const char *name, const QStringList &args ); + ~TrollProjectPart(); + + bool isTMakeProject() const { return m_tmakeProject; } + bool isQt4Project() const; + bool isDirty(); + KDirWatch* dirWatch(); + virtual Options options() const; + QStringList distFiles() const; + inline QString qmakePath() const { return DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/qmake", "");; } + +protected: + virtual void openProject(const QString &dirName, const QString &projectName); + virtual void closeProject(); + + virtual QString projectDirectory() const; + virtual QString projectName() const; + virtual QString mainProgram() const; + virtual QString activeDirectory() const; + virtual QStringList allFiles() const; + virtual void addFile(const QString &fileName); + virtual void addFiles ( const QStringList &fileList ); + virtual void removeFile(const QString &fileName); + virtual void removeFiles ( const QStringList &fileList ); + virtual QString buildDirectory() const; + virtual QString runDirectory() const; + virtual QString debugArguments() const; + virtual QString runArguments() const; + virtual DomUtil::PairList runEnvironmentVars() const; + +private slots: + void projectConfigWidget(KDialogBase *dlg); + void slotBuild(); +// void slotClean(); +// void slotExecute(); + void slotCommandFinished( const QString& command ); + void slotBuildAndExecuteProject(); + void slotBuildAndExecuteTarget(); + +private: +// void startMakeCommand(const QString &dir, const QString &target); + void startQMakeCommand(const QString &dir, bool recursive = false ); +// void execute(const QString &directory, const QString &command); + void queueCmd(const QString &dir, const QString &cmd); + QString makeEnvironment(); + + QString findQtDir(); + QString findExecutable( const QString& path ) const; + void buildBinDirs( QStringList& ) const; + bool isValidQtDir( const QString& path ) const; + bool isExecutable( const QString& path ) const; + + QGuardedPtr<TrollProjectWidget> m_widget; + QString m_projectName; + bool m_tmakeProject; + + QMap<QString, QDateTime> m_timestamp; + bool m_executeProjectAfterBuild; + bool m_executeTargetAfterBuild; + QString m_buildCommand; + + KDirWatch* m_dirWatch; + + friend class TrollProjectWidget; + friend class ProjectRunOptionsDlg; + friend class QMakeDefaultOpts; +}; + +#endif + diff --git a/buildtools/qmake/trollprojectwidget.cpp b/buildtools/qmake/trollprojectwidget.cpp new file mode 100644 index 00000000..7668dbd7 --- /dev/null +++ b/buildtools/qmake/trollprojectwidget.cpp @@ -0,0 +1,2547 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* Copyright (C) 2000-2001 by Trolltech AS. * +* info@trolltech.com * +* Copyright (C) 2002 by Jakob Simon-Gaarde * +* jakob@jsg.dk * +* Copyright (C) 2002-2003 by Alexander Dymo * +* cloudtemple@mksat.net * +* Copyright (C) 2003 by Thomas Hasart * +* thasart@gmx.de * +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* Part of this file is taken from Qt Designer. * +* * +* 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 "trollprojectwidget.h" + +#include <config.h> + +#include <qfile.h> +#include <qfileinfo.h> +#include <qheader.h> +#include <qsplitter.h> +#include <qptrstack.h> +#include <qtextstream.h> +#include <qcombobox.h> +#include <kprocess.h> +#include <qtimer.h> +#include <qdir.h> +#include <qregexp.h> +#include <qinputdialog.h> +#include <qwhatsthis.h> +#include <qvaluestack.h> +#include <kfiledialog.h> +#include <qtooltip.h> +#include <kdebug.h> +#include <klistview.h> +#include <kmessagebox.h> +#include <kpopupmenu.h> +#include <kregexp.h> +#include <kurl.h> +#include <qmessagebox.h> +#include <iostream> +#include <kparts/part.h> +#include <kaction.h> +#include <kprocess.h> +#include <kinputdialog.h> +#include <kdeversion.h> +#include <kdirwatch.h> +#include <kurlrequesterdlg.h> +#include <kurlrequester.h> +#include <kio/netaccess.h> +#include <kurlcompletion.h> + +#include "kdevcore.h" +#include "kdevpartcontroller.h" +#include "kdevmainwindow.h" +#include "trollprojectpart.h" +#include "kdevappfrontend.h" +#include "kdevmakefrontend.h" +#include "kdevlanguagesupport.h" +#include "kdevcreatefile.h" +#include "subclassesdlg.h" +#include "addfilesdialog.h" +#include "urlutil.h" +#include "trolllistview.h" +#include "projectconfigurationdlg.h" +#include "qmakescopeitem.h" +#include "scope.h" +#include "createscopedlg.h" +#include "disablesubprojectdlg.h" +#include <kapplication.h> + +TrollProjectWidget::TrollProjectWidget( TrollProjectPart *part ) + : QVBox( 0, "troll project widget" ), m_shownSubproject( 0 ), m_rootSubproject( 0 ), + m_rootScope ( 0 ), m_part ( part ), m_configDlg( 0 ), m_filesCached(false) +{ + + QSplitter * splitter = new QSplitter( Vertical, this ); + + ////////////////// + // PROJECT VIEW // + ////////////////// + + overviewContainer = new QVBox( splitter, "Projects" ); + overviewContainer->setMargin ( 2 ); + overviewContainer->setSpacing ( 2 ); + // overviewContainer->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); + // splitter->setResizeMode(overviewContainer, QSplitter::FollowSizeHint); + + projectTools = new QHBox( overviewContainer, "Project buttons" ); + projectTools->setMargin ( 2 ); + projectTools->setSpacing ( 2 ); + // Add subdir + addSubdirButton = new QToolButton ( projectTools, "Add subproject button" ); + addSubdirButton->setPixmap ( SmallIcon ( "folder_new" ) ); + addSubdirButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, addSubdirButton->sizePolicy().hasHeightForWidth() ) ); + addSubdirButton->setEnabled ( true ); + QToolTip::add( addSubdirButton, i18n( "Add subproject" ) ); + QWhatsThis::add( addSubdirButton, i18n( "<b>Add subproject</b><p>Creates a <i>new</i> or adds an <i>existing</i> subproject to a currently selected subproject. " + "This action is allowed only if a type of the subproject is 'subdirectories'. The type of the subproject can be " + "defined in <b>Subproject Settings</b> dialog (open it from the subproject context menu)." ) ); + // Create scope + createScopeButton = new QToolButton ( projectTools, "Create scope button" ); + createScopeButton->setPixmap ( SmallIcon ( "qmake_scopenew" ) ); + createScopeButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, createScopeButton->sizePolicy().hasHeightForWidth() ) ); + createScopeButton->setEnabled ( true ); + QToolTip::add( createScopeButton, i18n( "Create scope" ) ); + QWhatsThis::add( createScopeButton, i18n( "<b>Create scope</b><p>Creates QMake scope in the project file in case the subproject is selected or creates nested scope in case the scope is selected." ) ); + + // build + buildProjectButton = new QToolButton ( projectTools, "Make button" ); + buildProjectButton->setPixmap ( SmallIcon ( "make_kdevelop" ) ); + buildProjectButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, buildProjectButton->sizePolicy().hasHeightForWidth() ) ); + buildProjectButton->setEnabled ( true ); + QToolTip::add( buildProjectButton, i18n( "Build project" ) ); + QWhatsThis::add( buildProjectButton, i18n( "<b>Build project</b><p>Runs <b>make</b> from the project directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab." ) ); + // rebuild + rebuildProjectButton = new QToolButton ( projectTools, "Rebuild button" ); + rebuildProjectButton->setPixmap ( SmallIcon ( "rebuild" ) ); + rebuildProjectButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, rebuildProjectButton->sizePolicy().hasHeightForWidth() ) ); + rebuildProjectButton->setEnabled ( true ); + QToolTip::add( rebuildProjectButton, i18n( "Rebuild project" ) ); + QWhatsThis::add( rebuildProjectButton, i18n( "<b>Rebuild project</b><p>Runs <b>make clean</b> and then <b>make</b> from the project directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab." ) ); + + // run + executeProjectButton = new QToolButton ( projectTools, "Run button" ); + executeProjectButton->setPixmap ( SmallIcon ( "exec" ) ); + executeProjectButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, executeProjectButton->sizePolicy().hasHeightForWidth() ) ); + executeProjectButton->setEnabled ( true ); + QToolTip::add( executeProjectButton, i18n( "Execute main program" ) ); + QWhatsThis::add( executeProjectButton, i18n( "<b>Execute main program</b><p>Executes the main program specified in project settings, <b>Run Options</b> tab." ) ); + // spacer + QWidget *spacer = new QWidget( projectTools ); + projectTools->setStretchFactor( spacer, 1 ); + // Project configuration + projectconfButton = new QToolButton ( projectTools, "Project configuration button" ); + projectconfButton->setPixmap ( SmallIcon ( "configure" ) ); + projectconfButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, projectconfButton->sizePolicy().hasHeightForWidth() ) ); + projectconfButton->setEnabled ( true ); + QToolTip::add( projectconfButton, i18n( "Subproject settings" ) ); + QWhatsThis::add( projectconfButton, i18n( "<b>Subproject settings</b><p>Opens <b>QMake Subproject Configuration</b> dialog for the currently selected subproject. " + "It provides settings for:<br>subproject type and configuration,<br>include and library paths,<br>lists of dependencies and " + "external libraries,<br>build order,<br>intermediate files locations,<br>compiler options." ) ); + + // Project button connections + connect ( addSubdirButton, SIGNAL ( clicked () ), this, SLOT ( slotAddSubproject () ) ); + connect ( createScopeButton, SIGNAL ( clicked () ), this, SLOT ( slotCreateScope () ) ); + + + connect ( buildProjectButton, SIGNAL ( clicked () ), this, SLOT ( slotBuildProject () ) ); + connect ( rebuildProjectButton, SIGNAL ( clicked () ), this, SLOT ( slotRebuildProject () ) ); + connect ( executeProjectButton, SIGNAL ( clicked () ), m_part, SLOT ( slotBuildAndExecuteProject () ) ); + + + connect ( projectconfButton, SIGNAL ( clicked () ), this, SLOT ( slotConfigureProject () ) ); + + // Project tree + overview = new TrollListView( this, overviewContainer, SubprojectView, "project overview widget" ); +// overview->setResizeMode( QListView::LastColumn ); + overview->setSorting( -1 ); + overview->header() ->hide(); + overview->addColumn( QString::null ); + + // Project tree connections + connect( overview, SIGNAL( selectionChanged( QListViewItem* ) ), + this, SLOT( slotOverviewSelectionChanged( QListViewItem* ) ) ); + connect( overview, SIGNAL( contextMenu( KListView*, QListViewItem*, const QPoint& ) ), + this, SLOT( slotOverviewContextMenu( KListView*, QListViewItem*, const QPoint& ) ) ); + + + ///////////////// + // DETAIL VIEW // + ///////////////// + + // Details tree + detailContainer = new QVBox( splitter, "Details" ); + detailContainer->setMargin ( 2 ); + detailContainer->setSpacing ( 2 ); + // detailContainer->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + + // Details Toolbar + fileTools = new QHBox( detailContainer, "Detail buttons" ); + fileTools->setMargin ( 2 ); + fileTools->setSpacing ( 2 ); + + // Add new file button + newfileButton = new QToolButton ( fileTools, "Create new file" ); + newfileButton->setPixmap ( SmallIcon ( "filenew" ) ); + newfileButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, newfileButton->sizePolicy().hasHeightForWidth() ) ); + newfileButton->setEnabled ( true ); + QToolTip::add( newfileButton, i18n( "Create new file" ) ); + QWhatsThis::add( newfileButton, i18n( "<b>Create new file</b><p>Creates a new file and adds it to a currently selected group." ) ); + + // Add existing files button + addfilesButton = new QToolButton ( fileTools, "Add existing files" ); + addfilesButton->setPixmap ( SmallIcon ( "fileimport" ) ); + addfilesButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, addfilesButton->sizePolicy().hasHeightForWidth() ) ); + addfilesButton->setEnabled ( true ); + QToolTip::add( addfilesButton, i18n( "Add existing files" ) ); + QWhatsThis::add( addfilesButton, i18n( "<b>Add existing files</b><p>Adds existing files to a currently selected group. It is " + "possible to copy files to a current subproject directory, create symbolic links or " + "add them with the relative path." ) ); + + // remove file button + removefileButton = new QToolButton ( fileTools, "Remove file" ); + removefileButton->setPixmap ( SmallIcon ( "button_cancel" ) ); + removefileButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, removefileButton->sizePolicy().hasHeightForWidth() ) ); + removefileButton->setEnabled ( true ); + QToolTip::add( removefileButton, i18n( "Remove file" ) ); + QWhatsThis::add( removefileButton, i18n( "<b>Remove file</b><p>Removes file from a current group. Does not remove file from disk." ) ); + + // build selected file + buildFileButton = new QToolButton ( fileTools, "Make file button" ); + buildFileButton->setPixmap ( SmallIcon ( "compfile" ) ); + buildFileButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, buildFileButton->sizePolicy().hasHeightForWidth() ) ); + buildFileButton->setEnabled ( true ); + QToolTip::add( buildFileButton, i18n( "Compile file" ) ); + QWhatsThis::add( buildFileButton, i18n( "<b>Compile file</b><p>Runs <b>make filename.o</b> command from the directory where 'filename' is the name of currently opened file.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab." ) ); + + // build + buildTargetButton = new QToolButton ( fileTools, "Make sp button" ); + buildTargetButton->setPixmap ( SmallIcon ( "make_kdevelop" ) ); + buildTargetButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, buildTargetButton->sizePolicy().hasHeightForWidth() ) ); + buildTargetButton->setEnabled ( true ); + QToolTip::add( buildTargetButton, i18n( "Build subproject" ) ); + QWhatsThis::add( buildTargetButton, i18n( "<b>Build subproject</b><p>Runs <b>make</b> from the current subproject directory. " + "Current subproject is a subproject selected in <b>QMake manager</b> 'overview' window.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab." ) ); + // rebuild + rebuildTargetButton = new QToolButton ( fileTools, "Rebuild sp button" ); + rebuildTargetButton->setPixmap ( SmallIcon ( "rebuild" ) ); + rebuildTargetButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, rebuildTargetButton->sizePolicy().hasHeightForWidth() ) ); + rebuildTargetButton->setEnabled ( true ); + QToolTip::add( rebuildTargetButton, i18n( "Rebuild subproject" ) ); + QWhatsThis::add( rebuildTargetButton, i18n( "<b>Rebuild subproject</b><p>Runs <b>make clean</b> and then <b>make</b> from the current subproject directory. " + "Current subproject is a subproject selected in <b>QMake manager</b> 'overview' window.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab." ) ); + + // run + executeTargetButton = new QToolButton ( fileTools, "Run sp button" ); + executeTargetButton->setPixmap ( SmallIcon ( "exec" ) ); + executeTargetButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, executeTargetButton->sizePolicy().hasHeightForWidth() ) ); + executeTargetButton->setEnabled ( true ); + QToolTip::add( executeTargetButton, i18n( "Execute subproject" ) ); + QWhatsThis::add( executeTargetButton, i18n( "<b>Execute subproject</b><p>Executes the target program for the currently selected subproject. " + "This action is allowed only if a type of the subproject is 'application'. The type of the subproject can be " + "defined in <b>Subproject Settings</b> dialog (open it from the subproject context menu)." ) ); + + + // spacer + spacer = new QWidget( fileTools ); + projectTools->setStretchFactor( spacer, 1 ); + + // Configure file button + excludeFileFromScopeButton = new QToolButton ( fileTools, "Exclude file" ); + excludeFileFromScopeButton->setPixmap ( SmallIcon ( "configure_file" ) ); + excludeFileFromScopeButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, excludeFileFromScopeButton->sizePolicy().hasHeightForWidth() ) ); + excludeFileFromScopeButton->setEnabled ( true ); + QToolTip::add( excludeFileFromScopeButton , i18n( "Exclude file" ) ); + QWhatsThis::add( excludeFileFromScopeButton , i18n( "<b>Exclude file</b><p>Exclude the selected file from this scope." ) ); + + // detail tree + details = new TrollListView( this, detailContainer, DetailsView, "details widget" ); + details->setRootIsDecorated( true ); + details->setResizeMode( QListView::LastColumn ); + details->setSorting( -1 ); + details->header() ->hide(); + details->addColumn( QString::null ); + // Detail button connections + connect ( addfilesButton, SIGNAL ( clicked () ), this, SLOT ( slotAddFiles () ) ); + connect ( newfileButton, SIGNAL ( clicked () ), this, SLOT ( slotNewFile () ) ); + connect ( removefileButton, SIGNAL ( clicked () ), this, SLOT ( slotRemoveFile () ) ); + connect ( buildFileButton, SIGNAL ( clicked () ), this, SLOT ( slotBuildSelectedFile () ) ); + connect ( excludeFileFromScopeButton, SIGNAL ( clicked () ), this, SLOT ( slotExcludeFileFromScopeButton() ) ); + + // Detail tree connections + connect( details, SIGNAL( selectionChanged( QListViewItem* ) ), + this, SLOT( slotDetailsSelectionChanged( QListViewItem* ) ) ); + connect( details, SIGNAL( executed( QListViewItem* ) ), + this, SLOT( slotDetailsExecuted( QListViewItem* ) ) ); + connect( details, SIGNAL( contextMenu( KListView*, QListViewItem*, const QPoint& ) ), + this, SLOT( slotDetailsContextMenu( KListView*, QListViewItem*, const QPoint& ) ) ); + + connect ( buildTargetButton, SIGNAL ( clicked () ), this, SLOT ( slotBuildTarget () ) ); + connect ( rebuildTargetButton, SIGNAL ( clicked () ), this, SLOT ( slotRebuildTarget () ) ); + connect ( executeTargetButton, SIGNAL ( clicked () ), m_part, SLOT ( slotBuildAndExecuteTarget () ) ); + buildTargetButton->setEnabled( false ); + rebuildTargetButton->setEnabled( false ); + executeTargetButton->setEnabled( false ); + + m_configDlg = new ProjectConfigurationDlg( overview, this, this ); + + connect( m_part->dirWatch(), SIGNAL( dirty(const QString&) ), this, SLOT( slotProjectDirty(const QString&) ) ); +} + + +TrollProjectWidget::~TrollProjectWidget() +{ + delete m_configDlg; +} + + +void TrollProjectWidget::openProject( const QString &dirName ) +{ + QDomDocument & dom = *( m_part->projectDom() ); + m_subclasslist = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , + "subclass", "sourcefile", "uifile" ); + + QString projectfile = DomUtil::readEntry( dom, "/kdevtrollproject/qmake/projectfile", "" ); + + m_showFilenamesOnly = DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/enableFilenamesOnly", false ); + m_showVariablesInTree = DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/showVariablesInTree", true ); + + QString proname; + + if( projectfile.isEmpty() ) + { + QFileInfo fi( dirName ); + QDir dir( dirName ); + // QString proname = item->path + "/" + fi.baseName() + ".pro"; + + QStringList l = dir.entryList( "*.pro" ); + + QString profile; + if( l.count() && l.findIndex( m_part->projectName() + ".pro") != -1 ) + profile = m_part->projectName()+".pro"; + else if( l.isEmpty() || ( l.count() && l.findIndex( fi.baseName() + ".pro") != -1 ) ) + profile = fi.baseName()+".pro"; + else + profile = l[0]; + + proname = dirName + QString( QChar( QDir::separator() ) ) + profile; + } else + { + proname = projectfile; + } + + kdDebug( 9024 ) << "Parsing " << proname << endl; + + m_rootScope = new Scope( qmakeEnvironment(), proname, m_part ); + if( m_rootScope->scopeType() != Scope::InvalidScope ) + { + + m_rootSubproject = new QMakeScopeItem( overview, m_rootScope->scopeName(), m_rootScope, this ); + + + m_rootSubproject->setOpen( true ); + if ( m_rootSubproject->firstChild() && m_rootSubproject->scope->variableValues( "TEMPLATE" ).findIndex("subdirs") != -1 ) + { + overview->setSelected( m_rootSubproject->firstChild(), true ); + } + else + { + overview->setSelected( m_rootSubproject, true ); + } + }else + { + delete m_rootScope; + m_rootScope = 0; + } +// kdDebug(9024) << "Adding " << allFiles().count() << " Files" << endl; +// kdDebug(9024) << allFiles() << endl; + +} + +void TrollProjectWidget::createQMakeScopeItems() +{ + +} + +void TrollProjectWidget::closeProject() +{ + m_rootSubproject = 0; + overview->clear(); + details->clear(); + delete m_rootScope; +} + +QStringList TrollProjectWidget::allFiles() +{ + if( !m_rootScope ) + return QStringList(); + if( m_filesCached ) + return m_allFilesCache; + m_allFilesCache = m_rootScope->allFiles( m_rootScope->projectDir() ); + m_filesCached = true; + return m_allFilesCache; +} + +QString TrollProjectWidget::projectDirectory() +{ + if ( !m_rootScope ) + return QString::null; //confused + + return m_rootScope->projectDir(); +} + + +QString TrollProjectWidget::subprojectDirectory() +{ + if ( !m_shownSubproject ) + return QString::null; + + return m_shownSubproject->scope->projectDir(); +} + +void TrollProjectWidget::setupContext() +{ + if ( !m_shownSubproject ) + return ; + bool buildable = true; + bool runable = true; + bool fileconfigurable = true; + bool hasSourceFiles = true; + bool hasSubdirs = false; + + QStringList tmpl = m_shownSubproject->scope->variableValues( "TEMPLATE" ); + + if ( tmpl.findIndex( "lib" ) != -1 ) + { + runable = false; + } + else if ( tmpl.findIndex( "subdirs" ) != -1 ) + { + hasSubdirs = true; + runable = false; + hasSourceFiles = false; + fileconfigurable = false; + } + if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) + { + runable = false; + buildable = false; + } + + + // Setup toolbars according to context + addSubdirButton->setEnabled( hasSubdirs ); + buildTargetButton->setEnabled( buildable ); + m_part->actionCollection() ->action( "build_build_target" ) ->setEnabled( buildable ); + + rebuildTargetButton->setEnabled( buildable ); + m_part->actionCollection() ->action( "build_rebuild_target" ) ->setEnabled( buildable ); + + executeTargetButton->setEnabled( runable ); + m_part->actionCollection() ->action( "build_execute_target" ) ->setEnabled( runable ); + + excludeFileFromScopeButton->setEnabled( !hasSubdirs ); + newfileButton->setEnabled( !hasSubdirs ); + removefileButton->setEnabled( !hasSubdirs ); + addfilesButton->setEnabled( !hasSubdirs ); + buildFileButton->setEnabled( !hasSubdirs ); + + details->setEnabled( hasSourceFiles ); +} + +void TrollProjectWidget::slotOverviewSelectionChanged( QListViewItem *item ) +{ + QString olddir = m_part->activeDirectory(); + if ( !item ) + { + kdDebug(9024) << "Trying to select a non-existing item" << endl; + return ; + } + cleanDetailView( m_shownSubproject ); + m_shownSubproject = static_cast<QMakeScopeItem*>( item ); + setupContext(); + buildProjectDetailTree( m_shownSubproject, details ); + + QDomDocument &dom = *( m_part->projectDom() ); + DomUtil::writeEntry( dom, "/kdevtrollproject/general/activedir", m_shownSubproject->relativePath() ); + if ( m_configDlg && m_configDlg->isShown() ) + { + m_configDlg->updateSubproject( m_shownSubproject ); + } + emit m_part->activeDirectoryChanged( olddir, m_part->activeDirectory() ); +} + +QString TrollProjectWidget::getCurrentTarget() +{ + if ( !m_shownSubproject ) + return ""; + QString destdir = getCurrentDestDir(); + if ( destdir.isEmpty() ) + return getCurrentOutputFilename(); + else + return destdir + QString( QChar( QDir::separator() ) ) + getCurrentOutputFilename(); +} + +QString TrollProjectWidget::getCurrentDestDir() +{ + if ( !m_shownSubproject ) + return ""; + QStringList destdir = m_shownSubproject->scope->variableValues( "DESTDIR", true, true, true ); + return m_shownSubproject->scope->resolveVariables(m_shownSubproject->scope->variableValues( "DESTDIR", true, true, true ).front()); +} + +QString TrollProjectWidget::getCurrentOutputFilename() +{ + if ( !m_shownSubproject ) + return ""; + if ( m_shownSubproject->scope->variableValues( "TARGET", true, true, true ).isEmpty() ) + { + QString exe = m_shownSubproject->scope->resolveVariables(m_shownSubproject->scope->fileName()); + return exe.replace( QRegExp( "\\.pro$" ), "" ); + } + else + { + return m_shownSubproject->scope->resolveVariables(m_shownSubproject->scope->variableValues( "TARGET", true, true, true ).front()); + } +} + +void TrollProjectWidget::cleanDetailView( QMakeScopeItem *item ) +{ + // If no children in detailview + // it is a subdir template + if ( item && details->childCount() ) + { + QListViewItem* i = details->firstChild(); + while( i ) + { + QListViewItem* old = i; + i = i->nextSibling(); + details->takeItem(old); + } +// QMapIterator<GroupItem::GroupType, GroupItem*> it1 = item->groups.begin() ; +// for ( ; it1 != item->groups.end(); ++it1 ) +// { +// // After AddTargetDialog, it can happen that an +// // item is not yet in the list view, so better check... +// if ( it1.data() ->parent() ) +// while ( it1.data() ->firstChild() ) +// it1.data() ->takeItem( it1.data() ->firstChild() ); +// details->takeItem( it1.data() ); +// } + } +} + +void TrollProjectWidget::buildProjectDetailTree( QMakeScopeItem *item, KListView *listviewControl ) +{ + + // Insert all GroupItems and all of their children into the view + if ( !listviewControl || item->scope->variableValues( "TEMPLATE" ).findIndex("subdirs") != -1 ) + return ; + + QMapIterator<GroupItem::GroupType, GroupItem*> it2 = item->groups.begin(); + QListViewItem* lastItem = 0; + for ( ; it2 != item->groups.end(); ++it2 ) + { + listviewControl->insertItem( it2.data() ); + if(lastItem) + it2.data()->moveItem(lastItem); + lastItem = it2.data(); + if ( it2.key() == GroupItem::InstallRoot ) + { + QListViewItem* lastinstallitem = 0; + QPtrListIterator<GroupItem> it3( it2.data() ->installs ); + for ( ; it3.current(); ++it3 ) + { + it2.data() ->insertItem( *it3 ); + if ( lastinstallitem ) + it3.current()->moveItem(lastinstallitem); + lastinstallitem = it3.current(); + QPtrListIterator<FileItem> it4( ( *it3 ) ->files ); + QListViewItem* lastfileitem = 0; + for ( ; it4.current(); ++it4 ) + { + ( *it3 ) ->insertItem( *it4 ); + if ( lastfileitem ) + it4.current()->moveItem(lastfileitem); + lastfileitem = it4.current(); + } + ( *it3 ) ->setOpen( true ); + ( *it3 ) ->sortChildItems( 0, true ); + } + it2.data() ->setOpen( true ); + it2.data() ->sortChildItems( 0, true ); + } + else + { + QPtrListIterator<FileItem> it3( it2.data() ->files ); + QListViewItem* lastfileitem = 0; + for ( ; it3.current(); ++it3 ) + { + it2.data() ->insertItem( *it3 ); + if ( lastfileitem ) + it3.current()->moveItem(lastfileitem); + lastfileitem = it3.current(); + } + it2.data() ->setOpen( true ); + it2.data() ->sortChildItems( 0, true ); + } + } + listviewControl->setSelected( listviewControl->selectedItem(), false ); + listviewControl->setCurrentItem( 0 ); +} + +void TrollProjectWidget::slotDetailsExecuted( QListViewItem *item ) +{ + if ( !item ) + return ; + + // We assume here that ALL items in both list views + // are qProjectItem's + qProjectItem *pvitem = static_cast<qProjectItem*>( item ); + if ( pvitem->type() != qProjectItem::File ) + return ; + + FileItem *fitem = static_cast<FileItem*>( pvitem ); + + QString filePath; + if( m_shownSubproject->scope->scopeType() == Scope::IncludeScope ) + { + filePath = m_shownSubproject->scope->parent()->projectDir(); + }else + { + filePath = m_shownSubproject->scope->projectDir(); + } + filePath += QChar( QDir::separator() ) + m_shownSubproject->scope->resolveVariables( fitem->localFilePath ); + + bool isUiFile = QFileInfo( fitem->text( 0 ) ).extension() == "ui"; + kdDebug(9024) << "Opening file: " << filePath << endl; + if ( isTMakeProject() && isUiFile ) + { + // start designer in your PATH + KShellProcess proc; + proc << "designer" << filePath; + proc.start( KProcess::DontCare, KProcess::NoCommunication ); + } + else + m_part->partController() ->editDocument( KURL( filePath ) ); +} + + +void TrollProjectWidget::slotConfigureProject() +{ + m_configDlg->updateSubproject( m_shownSubproject ); + m_configDlg->show(); +} + +void TrollProjectWidget::slotExecuteTarget() +{ + //m_part->slotExecute(); + // no subproject selected + if ( !m_shownSubproject ) + return ; + + // can't build from scope + if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) + return ; + + + + // Only run application projects + if ( !m_shownSubproject->scope->variableValues( "TEMPLATE" ).isEmpty() && m_shownSubproject->scope->variableValues( "TEMPLATE" ).findIndex( "app" ) == -1 ) + return ; + + //only run once + if (m_part->appFrontend()->isRunning()) + { + if (KMessageBox::questionYesNo(this, i18n("Your application is currently running. Do you want to restart it?"), i18n("Application Already Running"), i18n("&Restart Application"), i18n("Do &Nothing")) == KMessageBox::No) + return; + m_part->appFrontend()->stopApplication(); + while(m_part->appFrontend()->isRunning()) + { + KApplication::kApplication()->processEvents(); + usleep(100); + } + } + + + QString program = KProcess::quote( "." + QString( QChar( QDir::separator() ) ) + getCurrentOutputFilename() ); + + // Build environment variables to prepend to the executable path + QString runEnvVars = QString::null; + DomUtil::PairList list = + DomUtil::readPairListEntry( *( m_part->projectDom() ), "/kdevtrollproject/run/envvars", "envvar", "name", "value" ); + + DomUtil::PairList::ConstIterator it; + for ( it = list.begin(); it != list.end(); ++it ) + { + const DomUtil::Pair &pair = ( *it ); + if ( ( !pair.first.isEmpty() ) && ( !pair.second.isEmpty() ) ) + runEnvVars += pair.first + "=" + pair.second + " "; + } + program.prepend( runEnvVars ); + + program.append( " " + m_part->runArguments() + " " ); + // std::cerr<<dircmd + "./"+program<<std::endl; + // m_part->execute(dircmd + "./"+program); + // m_part->appFrontend()->startAppCommand(dircmd +"./"+program,true); + + bool inTerminal = DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/run/terminal" ); + + m_part->appFrontend() ->startAppCommand( subprojectDirectory() + QString( QChar( QDir::separator() ) ) + getCurrentDestDir(), program, inTerminal ); + +} + +void TrollProjectWidget::slotBuildProject() +{ + if ( m_part->partController() ->saveAllFiles() == false ) + return ; //user cancelled + + QString dir = projectDirectory(); + + if ( !m_rootSubproject ) + return ; + + createMakefileIfMissing( dir, m_rootSubproject ); + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + QString dircmd = "cd " + KProcess::quote( dir ) + " && " ; + QString buildcmd = constructMakeCommandLine( m_rootSubproject->scope ); + m_part->queueCmd( dir, dircmd + buildcmd ); +} + +void TrollProjectWidget::slotInstallProject() +{ + if ( m_part->partController() ->saveAllFiles() == false ) + return ; //user cancelled + + QString dir = projectDirectory(); + + if ( !m_rootSubproject ) + return ; + + createMakefileIfMissing( dir, m_rootSubproject ); + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + QString dircmd = "cd " + KProcess::quote( dir ) + " && " ; + QString buildcmd = constructMakeCommandLine( m_rootSubproject->scope ) + " install"; + m_part->queueCmd( dir, dircmd + buildcmd ); +} + +void TrollProjectWidget::slotBuildTarget() +{ + // no subproject selected + m_part->partController() ->saveAllFiles(); + if ( !m_shownSubproject ) + return ; + // can't build from scope + if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) + return ; + QString dir = subprojectDirectory(); + createMakefileIfMissing( dir, m_shownSubproject ); + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + QString dircmd = "cd " + KProcess::quote( dir ) + " && " ; + QString buildcmd = constructMakeCommandLine( m_shownSubproject->scope ); + m_part->queueCmd( dir, dircmd + buildcmd ); +} + +void TrollProjectWidget::slotInstallTarget() +{ + // no subproject selected + m_part->partController() ->saveAllFiles(); + if ( !m_shownSubproject ) + return ; + // can't build from scope + if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) + return ; + QString dir = subprojectDirectory(); + createMakefileIfMissing( dir, m_shownSubproject ); + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + QString dircmd = "cd " + KProcess::quote( dir ) + " && " ; + QString buildcmd = constructMakeCommandLine( m_shownSubproject->scope ) + " install"; + m_part->queueCmd( dir, dircmd + buildcmd ); +} + +void TrollProjectWidget::slotRebuildProject() +{ + m_part->partController() ->saveAllFiles(); + QString dir = this-> projectDirectory(); + + if ( !m_rootSubproject ) + return ; + + createMakefileIfMissing( dir, m_rootSubproject ); + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + QString dircmd = "cd " + KProcess::quote( dir ) + " && " ; + QString rebuildcmd = constructMakeCommandLine( m_rootSubproject->scope ) + " clean && " + constructMakeCommandLine( m_rootSubproject->scope ); + m_part->queueCmd( dir, dircmd + rebuildcmd ); +} + +void TrollProjectWidget::slotRebuildTarget() +{ + // no subproject selected + m_part->partController() ->saveAllFiles(); + if ( !m_shownSubproject ) + return ; + // can't build from scope + if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) + return ; + + QString dir = subprojectDirectory(); + createMakefileIfMissing( dir, m_shownSubproject ); + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + QString dircmd = "cd " + KProcess::quote( dir ) + " && " ; + QString rebuildcmd = constructMakeCommandLine( m_shownSubproject->scope ) + " clean && " + constructMakeCommandLine( m_shownSubproject->scope ); + m_part->queueCmd( dir, dircmd + rebuildcmd ); +} + +void TrollProjectWidget::slotCreateScope( QMakeScopeItem *spitem ) +{ + if ( spitem == 0 && m_shownSubproject == 0 ) + return ; + else + spitem = m_shownSubproject; + CreateScopeDlg dlg( spitem, this ); + if ( dlg.exec() == QDialog::Accepted ) + { + spitem->scope->saveToFile( ); + spitem->sortChildItems( 0, true ); + } + return ; +} + +void TrollProjectWidget::slotAddSubproject( QMakeScopeItem *spitem ) +{ + if ( spitem == 0 && m_shownSubproject == 0 ) + return ; + else + spitem = m_shownSubproject; + + m_filesCached = false; + m_allFilesCache.clear(); + + QString projectdir = spitem->scope->projectDir(); + + KURLRequesterDlg dialog( i18n( "Add Subproject" ), i18n( "Please enter a name for the subproject: " ), this, 0 ); + KURLRequester* req = dialog.urlRequester(); + req->setMode( KFile::Directory | KFile::File | KFile::LocalOnly ); + req->setFilter( "*.pro|QMake Project Files (*.pro)" ); + req->setURL( QString() ); + req->fileDialog()->setURL( KURL::fromPathOrURL( projectdir ) ); + req->completionObject() ->setDir( projectdir ); + + if ( dialog.exec() == QDialog::Accepted && !dialog.urlRequester() ->url().isEmpty() ) + { + QString subdirname; + if ( !QDir::isRelativePath( dialog.urlRequester() ->url() ) ) + subdirname = URLUtil::getRelativePath( projectdir, dialog.urlRequester()->url() ); + else + subdirname = dialog.urlRequester()->url(); + + while( subdirname.endsWith( QString(QChar(QDir::separator())) ) ) + subdirname = subdirname.left(subdirname.length()-1); + if( !subdirname.endsWith(".pro") ) + { + kdDebug(9024) << "Cleaned subdirname: " << subdirname << endl; + QDir dir( projectdir ); + QString realdir = spitem->scope->resolveVariables( subdirname ); + if ( !dir.exists( realdir ) ) + { + if ( !dir.mkdir( realdir ) ) + { + KMessageBox::error( this, i18n( "Failed to create subdirectory. " + "Do you have write permission " + "in the project folder?" ) ); + return ; + }else + { + QFile f( dir.absPath()+"/"+realdir+"/"+realdir+".pro" ); + f.open( IO_WriteOnly ); + f.close(); + } + } + }else + { + QString realdir = spitem->scope->resolveVariables( subdirname ); + QFile f( projectdir+"/"+realdir ); + f.open( IO_WriteOnly ); + f.close(); + } + + addSubprojectToItem( spitem, subdirname ); + + } +} + +void TrollProjectWidget::addSubprojectToItem( QMakeScopeItem* spitem, const QString& subdirname ) +{ + QListViewItem* item = spitem->firstChild(); + while( item ) + { + QMakeScopeItem* sitem = static_cast<QMakeScopeItem*>(item); + if( sitem->scope->scopeName() == subdirname ) + { + if( sitem->scope->isEnabled() ) + { + return; + }else + { + spitem->scope->removeFromMinusOp( "SUBDIRS", subdirname ); + delete item; + if( spitem->scope->variableValues( "SUBDIRS" ).findIndex( subdirname ) != -1 ) + return; + } + } + item = item->nextSibling(); + } + + Scope* subproject = spitem->scope->createSubProject( subdirname ); + if( subproject ) + { + new QMakeScopeItem( spitem, subproject->scopeName(), subproject ); +// QListViewItem* lastitem = spitem->firstChild(); +// while( lastitem->nextSibling() != 0 ) +// lastitem = lastitem->nextSibling(); +// newitem->moveItem( lastitem ); + }else + { + KMessageBox::error(this, i18n("Could not create subproject. This means that either the project you wanted" + " to add a subproject to is not parsed correctly, or it is not a" + " subdirs-project."), i18n("Subproject creation failed") ); + } + spitem->scope->saveToFile(); + spitem->sortChildItems( 0, true ); +} + +void TrollProjectWidget::slotRemoveSubproject( QMakeScopeItem *spitem ) +{ + if ( spitem == 0 && m_shownSubproject == 0 ) + return ; + else if ( ( spitem = dynamic_cast<QMakeScopeItem *>( m_shownSubproject->parent() ) ) != NULL ) + { + + m_filesCached = false; + m_allFilesCache.clear(); + + bool delsubdir = false; + if ( KMessageBox::warningYesNo( this, i18n( "Delete the file/directory of the subproject from disk?" ), i18n( "Delete subdir?" ) ) == KMessageBox::Yes ) + delsubdir = true; + if( !spitem->scope->deleteSubProject( m_shownSubproject->scope->getNum(), delsubdir ) ) + { + KMessageBox::error(this, i18n("Could not delete subproject.\nThis is an internal error, please write a" + " bug report to bugs.kde.org and include the output of kdevelop when run" + "from a shell."),i18n("Subproject Deletion failed")); + return; + } + delete m_shownSubproject; + m_shownSubproject = spitem; + spitem->scope->saveToFile( ); + overview->setCurrentItem( m_shownSubproject ); + overview->setSelected( m_shownSubproject, true ); + } +} + +void TrollProjectWidget::slotOverviewContextMenu( KListView *, QListViewItem *item, const QPoint &p ) +{ + if ( !item ) + return ; + + QMakeScopeItem *spitem = static_cast<QMakeScopeItem*>( item ); + + KPopupMenu popup( this ); + popup.insertTitle( i18n( "Subproject %1" ).arg( item->text( 0 ) ) ); + + int idBuild = -2; + int idRebuild = -2; + int idClean = -2; + int idInstall = -2; + int idDistClean = -2; + int idQmake = -2; + int idQmakeRecursive = -2; + int idProjectConfiguration = -2; + int idAddSubproject = -2; + int idRemoveSubproject = -2; + int idDisableSubproject = -2; + int idRemoveScope = -2; + int idAddScope = -2; + + + if ( spitem->scope->scopeType() == Scope::ProjectScope && ( !spitem->scope->parent() || spitem->scope->parent()->scopeType() == Scope::ProjectScope ) ) + { + idBuild = popup.insertItem( SmallIcon( "make_kdevelop" ), i18n( "Build" ) ); + popup.setWhatsThis( idBuild, i18n( "<b>Build</b><p>Runs <b>make</b> from the selected subproject directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab." ) ); + idInstall = popup.insertItem( i18n( "Install" ) ); + popup.setWhatsThis( idBuild, i18n( "<b>Install</b><p>Runs <b>make install</b> from the selected subproject directory.<br>" + "Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab." ) ); + idClean = popup.insertItem( i18n( "Clean" ) ); + popup.setWhatsThis( idBuild, i18n( "<b>Clean project</b><p>Runs <b>make clean</b> command from the project " + "directory.<br> Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab." ) ); + idDistClean = popup.insertItem( i18n( "Dist-Clean" ) ); + popup.setWhatsThis( idBuild, i18n( "<b>Dist-Clean project</b><p>Runs <b>make distclean</b> command from the project " + "directory.<br> Environment variables and make arguments can be specified " + "in the project settings dialog, <b>Make Options</b> tab." ) ); + + idRebuild = popup.insertItem( SmallIcon( "rebuild" ), i18n( "Rebuild" ) ); + popup.setWhatsThis( idRebuild, i18n( "<b>Rebuild project</b><p>Runs <b>make clean</b> and then <b>make</b> from " + "the project directory.<br>Environment variables and make arguments can be " + "specified in the project settings dialog, <b>Make Options</b> tab." ) ); + idQmake = popup.insertItem( SmallIcon( "qmakerun" ), i18n( "Run qmake" ) ); + popup.setWhatsThis( idQmake, i18n( "<b>Run qmake</b><p>Runs <b>qmake</b> from the selected subproject directory. This creates or regenerates Makefile." ) ); + idQmakeRecursive = popup.insertItem( SmallIcon( "qmakerun" ), i18n( "Run qmake recursively" ) ); + popup.setWhatsThis( idQmakeRecursive, i18n( "<b>Run qmake recursively</b><p>Runs <b>qmake</b> from the selected " + "subproject directory and recurses into all subproject directories. " + "This creates or regenerates Makefile." ) ); + + popup.insertSeparator(); + idAddSubproject = popup.insertItem( SmallIcon( "folder_new" ), i18n( "Add Subproject..." ) ); + popup.setWhatsThis( idAddSubproject, i18n( "<b>Add subproject</b><p>Creates a <i>new</i> or adds an <i>existing</i> subproject to a currently selected subproject. " + "This action is allowed only if a type of the subproject is 'subdirectories'. The type of the subproject can be " + "defined in <b>Subproject Settings</b> dialog (open it from the subproject context menu)." ) ); + if ( spitem->scope->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) == -1 ) + popup.setItemEnabled( idAddSubproject, false ); + idRemoveSubproject = popup.insertItem( SmallIcon( "remove_subdir" ), i18n( "Remove Subproject..." ) ); + popup.setWhatsThis( idRemoveSubproject, i18n( "<b>Remove subproject</b><p>Removes currently selected subproject. Does not delete any file from disk. Deleted subproject can be later added by calling 'Add Subproject' action." ) ); + if ( spitem->parent() == NULL ) + popup.setItemEnabled( idRemoveSubproject, false ); + idAddScope = popup.insertItem( SmallIcon( "qmake_scopenew" ), i18n( "Create Scope..." ) ); + popup.setWhatsThis( idAddScope, i18n( "<b>Create scope</b><p>Creates QMake scope in the project file of the currently selected subproject." ) ); + popup.insertSeparator(); + idProjectConfiguration = popup.insertItem( SmallIcon( "configure" ), i18n( "Subproject Settings" ) ); + popup.setWhatsThis( idProjectConfiguration, i18n( "<b>Subproject settings</b><p>Opens <b>QMake Subproject Configuration</b> dialog. " + "It provides settings for:<br>subproject type and configuration,<br>include and library paths,<br>lists of dependencies and " + "external libraries,<br>build order,<br>intermediate files locations,<br>compiler options." ) ); + } + else + { + idAddScope = popup.insertItem( SmallIcon( "qmake_scopenew" ), i18n( "Create Scope..." ) ); + popup.setWhatsThis( idAddScope, i18n( "<b>Create Scope</b><p>Creates QMake scope in the currently selected scope." ) ); + idRemoveScope = popup.insertItem( SmallIcon( "editdelete" ), i18n( "Remove Scope" ) ); + popup.setWhatsThis( idRemoveScope, i18n( "<b>Remove Scope</b><p>Removes currently selected scope." ) ); + popup.insertSeparator(); + idAddSubproject = popup.insertItem( SmallIcon( "folder_new" ), i18n( "Add Subproject..." ) ); + popup.setWhatsThis( idAddSubproject, i18n( "<b>Add subproject</b><p>Creates a <i>new</i> or adds an <i>existing</i> subproject to the currently selected scope. " + "This action is allowed only if the type of the subproject is 'subdirectories'. The type of the subproject can be " + "defined in the <b>Subproject Settings</b> dialog (open it from the subproject context menu)." ) ); + if ( spitem->scope->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) == -1 ) + popup.setItemEnabled( idAddSubproject, false ); + idDisableSubproject = popup.insertItem( SmallIcon( "remove_subdir" ), i18n( "Disable Subproject..." ) ); + popup.setWhatsThis( idRemoveSubproject, i18n( "<b>Disable subproject</b><p>Disables the currently selected subproject when this scope is active. Does not delete the directory from disk. The deleted subproject can be later added by using the 'Add Subproject' action." ) ); + if( spitem->scope->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) == -1 && spitem->scope->parent()->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) == -1 ) + popup.setItemEnabled( idDisableSubproject, false ); + popup.insertSeparator(); + idProjectConfiguration = popup.insertItem( SmallIcon( "configure" ), i18n( "Scope Settings" ) ); + popup.setWhatsThis( idProjectConfiguration, i18n( "<b>Scope settings</b><p>Opens <b>QMake Subproject Configuration</b> dialog. " + "It provides settings for:<br>subproject type and configuration,<br>include and library paths,<br>lists of dependencies and " + "external libraries,<br>build order,<br>intermediate files locations,<br>compiler options." ) ); + } + + int r = popup.exec( p ); + + QString relpath = spitem->relativePath(); + if ( r == idAddSubproject ) + { + slotAddSubproject( spitem ); + } + if ( r == idRemoveSubproject ) + { + slotRemoveSubproject( spitem ); + } + if ( r == idDisableSubproject ) + { + slotDisableSubproject( spitem ); + } + if ( r == idAddScope ) + { + slotCreateScope( spitem ); + } + else if ( r == idRemoveScope ) + { + slotRemoveScope( spitem ); + } + else if ( r == idBuild ) + { + slotBuildTarget(); + // m_part->startMakeCommand(projectDirectory() + relpath, QString::fromLatin1("")); + } + else if ( r == idInstall ) + { + slotInstallTarget(); + // m_part->startMakeCommand(projectDirectory() + relpath, QString::fromLatin1("")); + } + else if ( r == idRebuild ) + { + slotRebuildTarget(); + } + else if ( r == idClean ) + { + slotCleanTarget(); + } + else if ( r == idDistClean ) + { + slotDistCleanTarget(); + } + + else if ( r == idQmake ) + { + m_part->startQMakeCommand( projectDirectory() + QString(QChar(QDir::separator())) + relpath ); + } + else if ( r == idQmakeRecursive ) + { + runQMakeRecursive( spitem ); + } + + else if ( r == idProjectConfiguration ) + { + m_configDlg->updateSubproject( spitem ); + m_configDlg->show(); + } +} + +void TrollProjectWidget::addFileToCurrentSubProject( GroupItem *titem, const QString &filename ) +{ + + m_filesCached = false; + m_allFilesCache.clear(); + titem->addFileToScope( filename ); +} + +void TrollProjectWidget::addFileToCurrentSubProject( GroupItem::GroupType gtype, const QString &filename ) +{ + if ( !m_shownSubproject ) + return ; + + m_filesCached = false; + m_allFilesCache.clear(); + + GroupItem *gitem = 0; + + if ( m_shownSubproject->groups.contains( gtype ) ) + gitem = m_shownSubproject->groups[ gtype ]; + + if ( !gitem ) + return ; + + gitem->addFileToScope( filename ); +} + +/** +* Method adds a file to the current project by grouped +* by file extension +*/ +void TrollProjectWidget::addFiles( QStringList &files, bool relativeToProjectRoot ) +{ + if ( !m_shownSubproject ) + return ; + kdDebug(9024) << "Files to add:"<<files << " " << relativeToProjectRoot <<endl; + m_filesCached = false; + m_allFilesCache.clear(); + + for ( QStringList::Iterator it = files.begin(); it != files.end(); ++it ) + { + QString fileName = *it; + kdDebug(9024) << "Adding file:" << fileName << " " << relativeToProjectRoot << endl; + + if ( m_shownSubproject->scope->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) != -1 && !fileName.endsWith(".pro") ) + { + ChooseSubprojectDlg dlg( this, false ); + if ( dlg.exec() == QDialog::Accepted ) + { + if ( dlg.selectedSubproject() && dlg.selectedSubproject()->scope->variableValues("TEMPLATE").findIndex( "subdirs" ) != -1 ) + { + fileName = URLUtil::getRelativePath( dlg.selectedSubproject()->scope->projectDir() , + QDir::cleanDirPath( + m_shownSubproject->scope->projectDir()+ + QString(QChar(QDir::separator()))+ + fileName ) ); + overview->setCurrentItem( dlg.selectedSubproject() ); + + } + } + else + { + KMessageBox::error( this, i18n("You did not select a subproject to add the file to, or select a subproject that has subdirs."), i18n( "File adding aborted" ) ); + } + } + + QFileInfo info( fileName ); + QString ext = info.extension( false ).simplifyWhiteSpace(); + + QString noPathFileName; + if( relativeToProjectRoot ) + noPathFileName = URLUtil::getRelativePath( m_shownSubproject->scope->projectDir(), QDir::cleanDirPath(projectDirectory()+QString(QChar(QDir::separator()))+fileName ) ); + else + noPathFileName = URLUtil::getRelativePath( m_shownSubproject->scope->projectDir(), QDir::cleanDirPath(m_shownSubproject->scope->projectDir()+QString(QChar(QDir::separator()))+fileName ) ); + + if( DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/replacePaths", false ) ) + { + QString var = m_shownSubproject->scope->findCustomVarForPath( QFileInfo( noPathFileName ).dirPath() ); + if( !var.isEmpty() ) + { + noPathFileName = "$${"+var+"}"+QString( QChar( QDir::separator() ) )+QFileInfo( noPathFileName ).fileName(); + } + } + + kdDebug(9024) << "calc filename:" << noPathFileName << endl; +// GroupItem *gitem = 0; +// GroupItem::GroupType gtype = GroupItem::groupTypeForExtension( ext ); +// if ( m_shownSubproject->groups.contains( gtype ) ) +// gitem = m_shownSubproject->groups[ gtype ]; + + + if( ext == "pro" ) + { + addSubprojectToItem( findSubprojectForPath( QFileInfo( fileName ).dirPath() ), QFileInfo( fileName ).fileName() ); + }else + { + addFileToCurrentSubProject( GroupItem::groupTypeForExtension( ext ), noPathFileName ); + slotOverviewSelectionChanged( m_shownSubproject ); + kdDebug(9024) << "emitting" << relativeToProjectRoot << " " << fileName << endl; + if( relativeToProjectRoot ) + emitAddedFile ( projectDirectory()+QString( QChar( QDir::separator() ) ) + fileName ); + else + emitAddedFile ( m_shownSubproject->scope->projectDir()+QString( QChar( QDir::separator() ) ) + fileName ); + } + } + +} + + +void TrollProjectWidget::slotAddFiles() +{ + static KURL lastVisited; + QString cleanSubprojectDir = QDir::cleanDirPath( m_shownSubproject->scope->projectDir() ); + QString title, filter; + QString otherTitle, otherFilter; + + GroupItem* item = dynamic_cast<GroupItem*>( details->selectedItem() ); + GroupItem::GroupType type = item ? item->groupType : GroupItem::NoType; + GroupItem::groupTypeMeanings( type, title, filter ); + filter += "|" + title; + + m_filesCached = false; + m_allFilesCache.clear(); + + for ( int i = GroupItem::NoType + 1; i < GroupItem::MaxTypeEnum; ++i ) + { + if ( type != i ) + { + GroupItem::groupTypeMeanings( static_cast<GroupItem::GroupType>( i ), otherTitle, otherFilter ); + filter += "\n" + otherFilter + "|" + otherTitle; + } + } + + filter += "\n*|" + i18n( "All Files" ); + + AddFilesDialog *dialog = new AddFilesDialog( cleanSubprojectDir, + filter, + this, + "Insert existing files", + true, new QComboBox( false ) ); + + dialog->setMode( KFile::Files | KFile::ExistingOnly | KFile::LocalOnly ); + + if ( !lastVisited.isEmpty() ) + { + dialog->setURL( lastVisited ); + } + + dialog->exec(); + QStringList files = dialog->selectedFiles(); + lastVisited = dialog->baseURL(); + + for ( unsigned int i = 0; i < files.count(); i++ ) + { + switch ( dialog->mode() ) + { + case AddFilesDialog::Copy: + { + // Copy selected files to current subproject folder + // and add them to the filelist + QString filename = KURL( files[ i ] ).fileName(); + KIO::NetAccess::file_copy( files[ i ], cleanSubprojectDir + QString( QChar( QDir::separator() ) ) + filename, -1, false, false, this ); + QFile testExist( cleanSubprojectDir + QString( QChar( QDir::separator() ) ) + filename ); + + if ( testExist.exists() ) + { + QStringList files( filename ); + addFiles( files, false ); + } + } + break; + + case AddFilesDialog::Link: + { + // Link selected files to current subproject folder + KProcess *proc = new KProcess( this ); + *proc << "ln"; + *proc << "-s"; + *proc << files[ i ]; + *proc << cleanSubprojectDir; + proc->start(KProcess::Block); + QString filename = files[ i ].right( files[ i ].length() - files[ i ].findRev( '/' ) - 1 ); + // and add them to the filelist + QFile testExist( cleanSubprojectDir + QString( QChar( QDir::separator() ) ) + filename ); + if ( testExist.exists() ) + { + QStringList files( filename ); + addFiles( files, false ); + } + } + break; + + case AddFilesDialog::Relative: + { + // Form relative path to current subproject folder + QString theFile = files[ i ]; + QStringList files( URLUtil::relativePathToFile( cleanSubprojectDir , theFile ) + ); + addFiles( files, false ); + } + break; + } + } +} + +GroupItem* TrollProjectWidget::getInstallRoot( QMakeScopeItem* item ) +{ + if ( item->groups.contains( GroupItem::InstallRoot ) ) + return item->groups[ GroupItem::InstallRoot ]; + return 0; +} + +GroupItem* TrollProjectWidget::getInstallObject( QMakeScopeItem* item, const QString& objectname ) +{ + GroupItem * instroot = getInstallRoot( item ); + if ( !instroot ) + return 0; + QPtrListIterator<GroupItem> it( instroot->installs ); + for ( ;it.current();++it ) + { + if ( ( *it ) ->groupType == GroupItem::InstallObject && + ( *it ) ->text( 0 ) == objectname ) + return * it; + } + return 0; + +} + +void TrollProjectWidget::slotNewFile() +{ + GroupItem * gitem = dynamic_cast<GroupItem*>( details->currentItem() ); + + m_filesCached = false; + m_allFilesCache.clear(); + + if( !gitem ) + { + gitem = dynamic_cast<GroupItem*>( details->currentItem()->parent() ); + } + + if ( gitem ) + { + if ( gitem->groupType == GroupItem::InstallObject ) + { + // QString relpath = m_shownSubproject->path.mid(projectDirectory().length()); + bool ok = FALSE; + QString filepattern = KInputDialog::getText( + i18n( "Insert New Filepattern" ), + i18n( "Please enter a filepattern relative the current " + "subproject (example docs/*.html):" ), + QString::null, &ok, this ); + if ( ok && !filepattern.isEmpty() ) + { + addFileToCurrentSubProject( gitem, filepattern ); + slotOverviewSelectionChanged( m_shownSubproject ); + } + return ; + } + if ( gitem->groupType == GroupItem::InstallRoot ) + { + // QString relpath = m_shownSubproject->path.mid(projectDirectory().length()); + bool ok = FALSE; + QString install_obj = KInputDialog::getText( + i18n( "Insert New Install Object" ), + i18n( "Please enter a name for the new object:" ), + QString::null, &ok, this ); + if ( ok && !install_obj.isEmpty() ) + { + gitem->addInstallObject( install_obj ); + //GroupItem * institem = createGroupItem( GroupItem::InstallObject, install_obj , m_shownSubproject ); + //gitem->owner->scope->addToPlusOp("INSTALLS", install_obj); + gitem->owner->scope->saveToFile(); + slotOverviewSelectionChanged( m_shownSubproject ); + } + return ; + } + } + KDevCreateFile * createFileSupport = m_part->extension<KDevCreateFile>( "KDevelop/CreateFile" ); + QString fcext; + if( gitem ) + { + switch ( gitem->groupType ) + { + case GroupItem::Sources: + fcext = "cpp"; + break; + case GroupItem::Headers: + fcext = "h"; + break; + case GroupItem::Forms: + if ( !m_part->isQt4Project() ) + fcext = "ui-widget"; + else + fcext = "ui-widget-qt4"; + break; + case GroupItem::Translations: + fcext = "ts"; + break; + case GroupItem::Lexsources: + fcext = "l"; + break; + case GroupItem::Yaccsources: + fcext = "y"; + break; + case GroupItem::Resources: + fcext = "qrc"; + break; + default: + fcext = QString::null; + } + } + KDevCreateFile::CreatedFile crFile = + createFileSupport->createNewFile( fcext, projectDirectory() + QString(QChar(QDir::separator()))+ m_shownSubproject->relativePath() ); +} + +void TrollProjectWidget::slotRemoveFile() +{ + QListViewItem * selectedItem = details->currentItem(); + if ( !selectedItem ) + return ; + + m_filesCached = false; + m_allFilesCache.clear(); + + qProjectItem *pvitem = static_cast<qProjectItem*>( selectedItem ); + // Check that it is a file (just in case) + if ( pvitem->type() != qProjectItem::File ) + return ; + FileItem *fitem = static_cast<FileItem*>( pvitem ); + removeFile( m_shownSubproject, fitem ); +} + +void TrollProjectWidget::slotExcludeFileFromScopeButton() +{ + QListViewItem * selectedItem = details->currentItem(); + if ( !selectedItem ) + return ; + qProjectItem *pvitem = static_cast<qProjectItem*>( selectedItem ); + // Check that it is a file (just in case) + if ( pvitem->type() != qProjectItem::File ) + return ; + FileItem *fitem = static_cast<FileItem*>( pvitem ); + + GroupItem *gitem = static_cast<GroupItem*>( fitem->parent() ); + + gitem->removeFileFromScope( fitem->text( 0 ) ); +} + +void TrollProjectWidget::slotDetailsSelectionChanged( QListViewItem *item ) +{ + if ( !item ) + { + removefileButton->setEnabled( false ); + excludeFileFromScopeButton->setEnabled( false ); + return ; + } + removefileButton->setEnabled( false ); + excludeFileFromScopeButton->setEnabled( false ); + + qProjectItem *pvitem = static_cast<qProjectItem*>( item ); + if ( pvitem->type() == qProjectItem::Group ) + { + GroupItem * gitem = static_cast<GroupItem*>( item ); + if ( gitem->groupType == GroupItem::InstallObject ) + { + excludeFileFromScopeButton->setEnabled( true ); + newfileButton->setEnabled( true ); + } + else if ( gitem->groupType == GroupItem::InstallRoot ) + { + newfileButton->setEnabled( true ); + } + else + { + addfilesButton->setEnabled( true ); + newfileButton->setEnabled( true ); + } + + + } + else if ( pvitem->type() == qProjectItem::File ) + { + removefileButton->setEnabled( true ); + excludeFileFromScopeButton->setEnabled( true ); + /* buildTargetButton->setEnabled(true); + rebuildTargetButton->setEnabled(true); + executeTargetButton->setEnabled(true);*/ + } +} + +void TrollProjectWidget::slotDetailsContextMenu( KListView *, QListViewItem *item, const QPoint &p ) +{ + if ( !item ) + return ; + + qProjectItem *pvitem = static_cast<qProjectItem*>( item ); + if ( pvitem->type() == qProjectItem::Group ) + { + GroupItem * titem = static_cast<GroupItem*>( pvitem ); + QString title, ext; + GroupItem::groupTypeMeanings( titem->groupType, title, ext ); + + KPopupMenu popup( this ); + popup.insertTitle( title ); + + int idInsExistingFile = -2; + int idInsNewFile = -2; + int idInsInstallObject = -2; + int idInsNewFilepatternItem = -2; + int idSetInstObjPath = -2; + int idLUpdate = -2; + int idLRelease = -2; + int idRemoveFile = -2; + + // int idFileProperties = popup.insertItem(SmallIconSet("filenew"),i18n("Properties...")); + if ( titem->groupType == GroupItem::InstallRoot ) + { + idInsInstallObject = popup.insertItem( SmallIconSet( "fileopen" ), i18n( "Add Install Object..." ) ); + popup.setWhatsThis( idInsInstallObject, i18n( "<b>Add install object</b><p>Creates QMake install object. " + "It is possible to define a list of files to install and installation locations for each object. Warning! " + "Install objects without path specified will not be saved to a project file." ) ); + } + else if ( titem->groupType == GroupItem::InstallObject ) + { + idSetInstObjPath = popup.insertItem( SmallIconSet( "fileopen" ), i18n( "Install Path..." ) ); + popup.setWhatsThis( idSetInstObjPath, i18n( "<b>Install path</b><p>Allows to choose the installation path for the current install object." ) ); + idInsNewFilepatternItem = popup.insertItem( SmallIconSet( "fileopen" ), i18n( "Add Pattern of Files to Install..." ) ); + popup.setWhatsThis( idInsNewFilepatternItem, i18n( "<b>Add pattern of files to install</b><p>Defines the pattern to match files which will be installed. " + "It is possible to use wildcards and relative paths like <i>docs/*</i>." ) ); + idRemoveFile = popup.insertItem( SmallIconSet( "editdelete" ), i18n( "Remove Install Object" ) ); + popup.setWhatsThis( idRemoveFile, i18n( "<b>Remove install object</b><p>Removes the install object the current group." ) ); + } + else if ( titem->groupType == GroupItem::Translations ) + { + idInsNewFile = popup.insertItem( SmallIconSet( "filenew" ), i18n( "Create New File..." ) ); + popup.setWhatsThis( idInsNewFile, i18n( "<b>Create new file</b><p>Creates a new translation file and adds it to a currently selected TRANSLATIONS group." ) ); + idInsExistingFile = popup.insertItem( SmallIconSet( "fileopen" ), i18n( "Add Existing Files..." ) ); + popup.setWhatsThis( idInsExistingFile, i18n( "<b>Add existing files</b><p>Adds existing translation (*.ts) files to a currently selected TRANSLATIONS group. It is " + "possible to copy files to a current subproject directory, create symbolic links or " + "add them with the relative path." ) ); + idLUpdate = popup.insertItem( SmallIconSet( "konsole" ), i18n( "Update Translation Files" ) ); + popup.setWhatsThis( idLUpdate, i18n( "<b>Update Translation Files</b><p>Runs <b>lupdate</b> command from the current subproject directory. It collects translatable " + "messages and saves them into translation files." ) ); + idLRelease = popup.insertItem( SmallIconSet( "konsole" ), i18n( "Release Binary Translations" ) ); + popup.setWhatsThis( idLRelease, i18n( "<b>Release Binary Translations</b><p>Runs <b>lrelease</b> command from the current subproject directory. It creates binary " + "translation files that are ready to be loaded at program execution." ) ); + } + else // File group containing files + { + idInsNewFile = popup.insertItem( SmallIconSet( "filenew" ), i18n( "Create New File..." ) ); + popup.setWhatsThis( idInsNewFile, i18n( "<b>Create new file</b><p>Creates a new file and adds it to a currently selected group." ) ); + idInsExistingFile = popup.insertItem( SmallIconSet( "fileopen" ), i18n( "Add Existing Files..." ) ); + popup.setWhatsThis( idInsExistingFile, i18n( "<b>Add existing files</b><p>Adds existing files to a currently selected group. It is " + "possible to copy files to a current subproject directory, create symbolic links or " + "add them with the relative path." ) ); + } + int r = popup.exec( p ); + QString cleanSubprojectPath = QDir::cleanDirPath( m_shownSubproject->scope->projectDir() ); + + if ( r == idSetInstObjPath ) + { + KURLRequesterDlg dialog( i18n( "Choose Install Path" ), i18n( "Enter a path " + "(example /usr/local/share/... ):" ), this, 0 ); + dialog.urlRequester() ->setMode( KFile::Directory ); + dialog.urlRequester() ->setURL( titem->owner->scope->variableValues( titem->text( 0 ) + ".path" ).front() ); + if ( dialog.exec() == QDialog::Accepted ) + { + titem->owner->scope->setEqualOp( titem->text( 0 ) + ".path", dialog.urlRequester() ->url() ); + titem->owner->scope->saveToFile( ); + } + } + else if ( r == idInsNewFilepatternItem ) + { + bool ok = FALSE; + QString filepattern = KInputDialog::getText( + i18n( "Add Pattern of Files to Install" ), + i18n( "Enter a pattern relative to the current " + "subproject (example docs/*.html):" ), + QString::null, &ok, this ); + if ( ok && !filepattern.isEmpty() ) + { + addFileToCurrentSubProject( titem, filepattern ); + slotOverviewSelectionChanged( m_shownSubproject ); + } + } + else if ( r == idInsExistingFile ) + { + AddFilesDialog * dialog = new AddFilesDialog( cleanSubprojectPath, + ext + "|" + title + " (" + ext + ")", + this, + "Add existing files", + true, new QComboBox( false ) ); + dialog->setMode( KFile::Files | KFile::ExistingOnly | KFile::LocalOnly ); + if ( dialog->exec() == QDialog::Rejected ) + return ; + QStringList files = dialog->selectedFiles(); + for ( unsigned int i = 0;i < files.count();++i ) + { + switch ( dialog->mode() ) + { + case AddFilesDialog::Copy: + { + // Copy selected files to current subproject folder + // and add them to the filelist + QString filename = KURL( files[ i ] ).fileName(); + KIO::NetAccess::file_copy( files[ i ], cleanSubprojectPath + QString( QChar( QDir::separator() ) ) + filename, -1, false, false, this ); + QFile testExist( cleanSubprojectPath + QString( QChar( QDir::separator() ) ) + filename ); + + if ( testExist.exists() ) + { + QStringList files( filename ); + addFiles( files, false ); + } + } + break; + + case AddFilesDialog::Link: + { + // Link selected files to current subproject folder + KProcess *proc = new KProcess( this ); + *proc << "ln"; + *proc << "-s"; + *proc << files[ i ]; + *proc << cleanSubprojectPath; + proc->start(KProcess::Block); + QString filename = files[ i ].right( files[ i ].length() - files[ i ].findRev( '/' ) - 1 ); + // and add them to the filelist + QFile testExist( cleanSubprojectPath + QString( QChar( QDir::separator() ) ) + filename ); + if ( testExist.exists() ) + { + QStringList files( filename ); + addFiles( files, false ); + } + } + break; + + case AddFilesDialog::Relative: + { + // Form relative path to current subproject folder + QString theFile = files[ i ]; + QStringList files( URLUtil::relativePathToFile( cleanSubprojectPath, theFile ) + ); + addFiles( files, false ); + } + break; + } + } + // Update project file + if ( titem && titem->owner ) + { + titem->owner->scope->saveToFile( ); + } + // Update subprojectview + slotOverviewSelectionChanged( m_shownSubproject ); + } + else if ( r == idInsNewFile ) + { + KDevCreateFile * createFileSupport = m_part->extension<KDevCreateFile>( "KDevelop/CreateFile" ); + QString fcext; + switch ( titem->groupType ) + { + case GroupItem::Sources: + fcext = "cpp"; + break; + case GroupItem::Headers: + fcext = "h"; + break; + case GroupItem::Forms: + if ( !m_part->isQt4Project() ) + fcext = "ui-widget"; + else + fcext = "ui-widget-qt4"; + break; + case GroupItem::Translations: + fcext = "ts"; + break; + case GroupItem::Lexsources: + fcext = "l"; + break; + case GroupItem::Yaccsources: + fcext = "y"; + break; + case GroupItem::Resources: + fcext = "qrc"; + break; + default: + fcext = QString::null; + } + KDevCreateFile::CreatedFile crFile = + createFileSupport->createNewFile( fcext, cleanSubprojectPath ); + + } + else if ( r == idInsInstallObject ) + { + bool ok = FALSE; + QString install_obj = KInputDialog::getText( + i18n( "Add Install Object" ), + i18n( "Enter a name for the new object:" ), + QString::null, &ok, this ); + if ( ok && !install_obj.isEmpty() ) + { + titem->addInstallObject( install_obj ); + slotOverviewSelectionChanged( m_shownSubproject ); + } + } + else if ( r == idLUpdate ) + { + QString cmd = "lupdate "; + cmd += m_shownSubproject->scope->fileName(); + m_part->appFrontend() ->startAppCommand( m_shownSubproject->scope->projectDir(), cmd, false ); + } + else if ( r == idLRelease ) + { + QString cmd = "lrelease "; + cmd += m_shownSubproject->scope->fileName(); + m_part->appFrontend() ->startAppCommand( m_shownSubproject->scope->projectDir(), cmd, false ); + }else if( r == idRemoveFile ) + { + static_cast<GroupItem*>(titem->parent())->removeInstallObject( titem ); + slotOverviewSelectionChanged( m_shownSubproject ); + } + } + else if ( pvitem->type() == qProjectItem::File ) + { + + removefileButton->setEnabled( true ); + FileItem *fitem = static_cast<FileItem*>( pvitem ); + GroupItem* gitem = static_cast<GroupItem*>( item->parent() ); + + KPopupMenu popup( this ); + if ( !( gitem->groupType == GroupItem::InstallObject ) ) + popup.insertTitle( i18n( "File: %1" ).arg( fitem->text( 0 ) ) ); + else + popup.insertTitle( i18n( "Pattern: %1" ).arg( fitem->text( 0 ) ) ); + + int idRemoveFile = -2; + int idSubclassWidget = -2; + int idUpdateWidgetclass = -2; + int idBuildFile = -2; + int idUISubclasses = -2; + int idViewUIH = -2; + int idFileProperties = -2; + int idEditInstallPattern = -2; + + if ( !fitem->uiFileLink.isEmpty() ) + { + idUpdateWidgetclass = popup.insertItem( SmallIconSet( "qmake_subclass" ), i18n( "Edit ui-Subclass..." ) ); + popup.setWhatsThis( idUpdateWidgetclass, i18n( "<b>Edit ui-subclass</b><p>Launches <b>Subclassing</b> wizard " + "and prompts to implement missing in childclass slots and functions." ) ); + } + if ( fitem->text( 0 ).contains( ".ui" ) ) + { + idSubclassWidget = popup.insertItem( SmallIconSet( "qmake_subclass" ), i18n( "Subclassing Wizard..." ) ); + popup.setWhatsThis( idSubclassWidget, i18n( "<b>Subclass widget</b><p>Launches <b>Subclassing</b> wizard. " + "It allows to create a subclass from the class defined in .ui file. " + "There is also possibility to implement slots and functions defined in the base class." ) ); + if ( !m_part->isQt4Project() ) + { + idViewUIH = popup.insertItem( SmallIconSet( "qmake_ui_h" ), i18n( "Open ui.h File" ) ); + popup.setWhatsThis( idViewUIH, i18n( "<b>Open ui.h file</b><p>Opens .ui.h file associated with the selected .ui." ) ); + } + idUISubclasses = popup.insertItem( SmallIconSet( "qmake_subclass" ), i18n( "List of Subclasses..." ) ); + popup.setWhatsThis( idUISubclasses, i18n( "<b>List of subclasses</b><p>Shows subclasses list editor. " + "There is possibility to add or remove subclasses from the list." ) ); + } + if ( !( gitem->groupType == GroupItem::InstallObject ) ) + { + idRemoveFile = popup.insertItem( SmallIconSet( "editdelete" ), i18n( "Remove File" ) ); + popup.setWhatsThis( idRemoveFile, i18n( "<b>Remove file</b><p>Removes file from a current group. For sources, this also removes the subclassing information." ) ); + idFileProperties = popup.insertItem( SmallIconSet( "configure_file" ), i18n( "Exclude File" ) ); + popup.setWhatsThis( idFileProperties, i18n( "<b>Exclude File</b><p>Excludes the file from this Scope. Does not touch subclassing information" ) ); + } + else + { + idEditInstallPattern = popup.insertItem( SmallIconSet( "configure_file" ), i18n( "Edit Pattern" ) ); + popup.setWhatsThis( idEditInstallPattern, i18n( "<b>Edit pattern</b><p>Allows to edit install files pattern." ) ); + idRemoveFile = popup.insertItem( SmallIconSet( "editdelete" ), i18n( "Remove Pattern" ) ); + popup.setWhatsThis( idRemoveFile, i18n( "<b>Remove pattern</b><p>Removes install files pattern from the current install object." ) ); + } + if ( !( gitem->groupType == GroupItem::InstallObject ) ) + { + KURL::List urls; + urls.append( m_shownSubproject->scope->projectDir() + QChar( QDir::separator() ) + m_shownSubproject->scope->resolveVariables( fitem->localFilePath ) ); + FileContext context( urls ); + m_part->core() ->fillContextMenu( &popup, &context ); + } + if ( gitem->groupType == GroupItem::Sources ) + { + idBuildFile = popup.insertItem( SmallIconSet( "make_kdevelop" ), i18n( "Build File" ) ); + popup.setWhatsThis( idBuildFile, i18n( "<b>Build File</b><p>Builds the object file for this source file." ) ); + } + + int r = popup.exec( p ); + if ( r == idRemoveFile ) + removeFile( m_shownSubproject, fitem ); + else if ( r == idFileProperties ) + { + slotExcludeFileFromScopeButton(); + } + else if ( r == idViewUIH ) + { + kdDebug(9024) << "Opening:" << fitem->text(0) << ";" << fitem->text(0).replace(".ui","") << endl; + m_part->partController() ->editDocument( KURL( m_shownSubproject->scope->projectDir() + QChar( QDir::separator() ) + + fitem->localFilePath.replace(".ui","") + ".h" ) ); + + } + else if ( r == idSubclassWidget ) + { + QStringList newFileNames; + newFileNames = m_part->languageSupport() ->subclassWidget( m_shownSubproject->scope->projectDir() + QChar( QDir::separator() ) + fitem->localFilePath ); + kdDebug(9024) << "got new filenames: " << newFileNames << endl; + if ( !newFileNames.empty() ) + { + QDomDocument & dom = *( m_part->projectDom() ); + for ( uint i = 0; i < newFileNames.count(); ++i ) + { + QString srcfile_relpath = URLUtil::getRelativePath( m_shownSubproject->scope->projectDir(), newFileNames[ i ] ) ; + newFileNames[i] = URLUtil::getRelativePath( projectDirectory(), newFileNames[ i ] ) ; + QString uifile_relpath = m_shownSubproject->relativePath() + QChar( QDir::separator() ) + fitem->localFilePath; + DomUtil::PairList list = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , + "subclass", "sourcefile", "uifile" ); + + list << DomUtil::Pair( srcfile_relpath, uifile_relpath ); + DomUtil::writePairListEntry( dom, "/kdevtrollproject/subclassing", "subclass", "sourcefile", "uifile", list ); + // newFileNames[i] = newFileNames[i].replace(QRegExp(projectDirectory()+"/"),""); + qWarning( "new file: %s", newFileNames[ i ].latin1() ); + } + m_subclasslist = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , + "subclass", "sourcefile", "uifile" ); + + m_part->addFiles( newFileNames ); + } + } + else if ( r == idUpdateWidgetclass ) + { + QString noext = fitem->text( 0 ); + if ( noext.findRev( '.' ) > -1 ) + noext = noext.left( noext.findRev( '.' ) ); + QStringList dummy; + QString uifile = fitem->uiFileLink; + if ( uifile.findRev( QString( QChar( QDir::separator() ) ) ) > -1 ) + { + QStringList uisplit = QStringList::split( QString( QChar( QDir::separator() ) ), uifile ); + uifile = uisplit[ uisplit.count() - 1 ]; + } + m_part->languageSupport() ->updateWidget( m_shownSubproject->scope->projectDir() + QString( QChar( QDir::separator() ) ) + uifile, noext ); + } + else if ( r == idUISubclasses ) + { + QDomDocument & dom = *( m_part->projectDom() ); + DomUtil::PairList list = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , + "subclass", "sourcefile", "uifile" ); + SubclassesDlg *sbdlg = new SubclassesDlg( m_shownSubproject->relativePath() + QChar( QDir::separator() ) + fitem->localFilePath, + list, projectDirectory() ); + + if ( sbdlg->exec() ) + { + QDomElement el = DomUtil::elementByPath( dom, "/kdevtrollproject" ); + QDomElement el2 = DomUtil::elementByPath( dom, "/kdevtrollproject/subclassing" ); + if ( ( !el.isNull() ) && ( !el2.isNull() ) ) + { + el.removeChild( el2 ); + } + + DomUtil::writePairListEntry( dom, "/kdevtrollproject/subclassing", "subclass", "sourcefile", "uifile", list ); + + m_subclasslist = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , + "subclass", "sourcefile", "uifile" ); + } + } + else if ( r == idEditInstallPattern ) + { + GroupItem * titem = static_cast<GroupItem*>( item->parent() ); + + bool ok = FALSE; + QString filepattern = KInputDialog::getText( + i18n( "Edit Pattern" ), + i18n( "Enter a pattern relative to the current " + "subproject (example docs/*.html):" ), + fitem->text( 0 ) , &ok, this ); + if ( ok && !filepattern.isEmpty() ) + { + removeFile( m_shownSubproject, fitem ); + addFileToCurrentSubProject( titem, filepattern ); + slotOverviewSelectionChanged( m_shownSubproject ); + } + } + else if ( r == idBuildFile ) + { + buildFile( m_shownSubproject, fitem ); + } + } +} + + +void TrollProjectWidget::removeFile( QMakeScopeItem *spitem, FileItem *fitem ) +{ + GroupItem * gitem = static_cast<GroupItem*>( fitem->parent() ); + + m_filesCached = false; + m_allFilesCache.clear(); + + QString realfilename = spitem->scope->resolveVariables( fitem->localFilePath ); + if ( KMessageBox::warningYesNo( this, + "<qt>" + + i18n( "Do you want to delete the file <strong>%1</strong> from the project and your disk?" ) + .arg( fitem->text( 0 ) ) + + "</qt>", + i18n( "Remove File" ), + KStdGuiItem::remove(), + KStdGuiItem::no(), + "deleteFileFromQMakeProject" ) == KMessageBox::No ) + { + return; + }else + { + kdDebug(9024) << "Deleting file as the user wished: " << spitem->scope->projectDir() + QString( QChar( QDir::separator() ) ) + realfilename << endl; + KIO::NetAccess::del( KURL::fromPathOrURL( spitem->scope->projectDir() + QString( QChar( QDir::separator() ) ) + realfilename ), 0 ); + } + + if ( gitem->groupType != GroupItem::InstallObject ) + { + QString removedFileName = spitem->relativePath() + QString( QChar( QDir::separator() ) ) + realfilename; + if ( removedFileName.startsWith( QDir::rootDirPath() ) ) + removedFileName = removedFileName.mid( 1 ); + emitRemovedFile( removedFileName ); + } + + + //remove subclassing info + QDomDocument &dom = *( m_part->projectDom() ); + DomUtil::PairList list = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , + "subclass", "sourcefile", "uifile" ); + QPtrList<DomUtil::Pair> pairsToRemove; + DomUtil::PairList::iterator it; + for ( it = list.begin(); it != list.end(); ++it ) + { + if ( ( ( *it ).first == realfilename ) || ( ( *it ).second == realfilename ) ) + { + pairsToRemove.append( &( *it ) ); + } + } + DomUtil::Pair *pair; + for ( pair = pairsToRemove.first(); pair; pair = pairsToRemove.next() ) + { + list.remove( *pair ); + } + QDomElement el = DomUtil::elementByPath( dom, "/kdevtrollproject" ); + QDomElement el2 = DomUtil::elementByPath( dom, "/kdevtrollproject/subclassing" ); + if ( ( !el.isNull() ) && ( !el2.isNull() ) ) + { + el.removeChild( el2 ); + } + DomUtil::writePairListEntry( dom, "/kdevtrollproject/subclassing", "subclass", "sourcefile", "uifile", list ); + + gitem->removeFileFromScope( fitem->text( 0 ) ); +} + +void TrollProjectWidget::emitAddedFile( const QString &fileName ) +{ + emit m_part->addedFilesToProject( QStringList( fileName ) ); +} + + +void TrollProjectWidget::emitRemovedFile( const QString &fileName ) +{ + emit m_part->removedFilesFromProject( QStringList( fileName ) ); +} + + +QString TrollProjectWidget::getUiFileLink( const QString &relpath, const QString& filename ) +{ + DomUtil::PairList::iterator it; + for ( it = m_subclasslist.begin();it != m_subclasslist.end(); ++it ) + { + if ( ( *it ).first == relpath + filename ) + return ( *it ).second; + } + return ""; +} + +void TrollProjectWidget::slotBuildOpenFile() +{ + KParts::ReadWritePart * part = dynamic_cast<KParts::ReadWritePart*>( m_part->partController() ->activePart() ); + if ( !part || !part->url().isLocalFile() ) + return ; + + QString fileName = part->url().path(); + QFileInfo fi( fileName ); + QString sourceDir = fi.dirPath(); + QString baseName = fi.baseName( true ); + kdDebug( 9024 ) << "Compiling " << fileName + << "in dir " << sourceDir + << " with baseName " << baseName << endl; + + + QString buildDir = sourceDir; + QString target = baseName + ".o"; + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + // m_part->startMakeCommand(buildDir, target); + + QPtrList<QMakeScopeItem> list = findSubprojectForFile( fi ); + + QMakeScopeItem *spitem; + for ( spitem = list.first(); spitem; spitem = list.next() ) + { + QString buildcmd = constructMakeCommandLine( spitem->scope ); + QString dircmd = "cd " + KProcess::quote( spitem->scope->projectDir() ) + " && " ; + kdDebug( 9024 ) << "builddir " << spitem->scope->projectDir() << ", cmd " << dircmd + buildcmd + " " + target << endl; + m_part->queueCmd( spitem->scope->projectDir(), dircmd + buildcmd + " " + target ); + } + + // startMakeCommand(buildDir, target); + +} + + +void TrollProjectWidget::slotExecuteProject() +{ + QString program = m_part->mainProgram(); + if ( program.isEmpty() ) + { + KMessageBox::sorry( this, i18n( "Please specify the executable name in the " + "project options dialog or select an application subproject in the QMake Manager." ), i18n( "No Executable Found" ) ); + return ; + } + + //only run once + if (m_part->appFrontend()->isRunning()) + { + if (KMessageBox::questionYesNo(this, i18n("Your application is currently running. Do you want to restart it?"), i18n("Application Already Running"), i18n("&Restart Application"), i18n("Do &Nothing")) == KMessageBox::No) + return; + m_part->appFrontend()->stopApplication(); + while(m_part->appFrontend()->isRunning()) + { + KApplication::kApplication()->processEvents(); + usleep(100); + } + } + + if ( !program.startsWith( QDir::rootDirPath() ) ) + program.prepend( "." + QString( QChar( QDir::separator() ) ) ); + + + // Build environment variables to prepend to the executable path + QString runEnvVars = QString::null; + DomUtil::PairList list = + DomUtil::readPairListEntry( *( m_part->projectDom() ), "/kdevtrollproject/run/envvars", "envvar", "name", "value" ); + + DomUtil::PairList::ConstIterator it; + for ( it = list.begin(); it != list.end(); ++it ) + { + const DomUtil::Pair &pair = ( *it ); + if ( ( !pair.first.isEmpty() ) && ( !pair.second.isEmpty() ) ) + runEnvVars += pair.first + "=" + pair.second + " "; + } + program.prepend( runEnvVars ); + program.append( " " + m_part->runArguments() + " " ); + + bool inTerminal = DomUtil::readBoolEntry( *( m_part->projectDom() ), "/kdevtrollproject/run/terminal" ); + m_part->appFrontend() ->startAppCommand( m_part->runDirectory(), program, inTerminal ); +} + + +void TrollProjectWidget::slotCleanProject() +{ + runClean(m_rootSubproject, "clean"); +} + +void TrollProjectWidget::slotCleanTarget() +{ + runClean(m_shownSubproject, "clean"); +} + +void TrollProjectWidget::slotDistCleanProject() +{ + runClean(m_rootSubproject, "distclean"); + +} + +void TrollProjectWidget::slotDistCleanTarget() +{ + runClean(m_shownSubproject, "distclean"); +} + +void TrollProjectWidget::runClean( QMakeScopeItem* item, const QString& cleantargetname ) +{ + // no subproject selected + m_part->partController() ->saveAllFiles(); + if ( !item ) + return ; + // can't build from scope + if ( item->scope->scopeType() != Scope::ProjectScope ) + return ; + + QString dir = item->scope->projectDir(); + createMakefileIfMissing( dir, item ); + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + QString dircmd = "cd " + KProcess::quote( dir ) + " && " ; + QString rebuildcmd = constructMakeCommandLine( item->scope ) + " "+cleantargetname; + m_part->queueCmd( dir, dircmd + rebuildcmd ); +} + +QString TrollProjectWidget::constructMakeCommandLine( Scope* s ) +{ + QString makeFileName; + if ( s ) + makeFileName = s->resolveVariables( s->variableValues( "MAKEFILE", true, true, true ).front() ); + + QDomDocument & dom = *( m_part->projectDom() ); + + QString cmdline = DomUtil::readEntry( dom, "/kdevtrollproject/make/makebin" ); + if ( cmdline.isEmpty() ) + cmdline = MAKE_COMMAND; + if ( !makeFileName.isEmpty() ) + { + cmdline += " -f " + makeFileName; + } + if ( !DomUtil::readBoolEntry( dom, "/kdevtrollproject/make/abortonerror" ) ) + cmdline += " -k"; + bool runmultiple = DomUtil::readBoolEntry(dom, "/kdevtrollproject/make/runmultiplejobs"); + int jobs = DomUtil::readIntEntry( dom, "/kdevtrollproject/make/numberofjobs" ); + if ( jobs != 0 && runmultiple ) + { + cmdline += " -j"; + cmdline += QString::number( jobs ); + } + if ( DomUtil::readBoolEntry( dom, "/kdevtrollproject/make/dontact" ) ) + cmdline += " -n"; + + cmdline += " "; + cmdline.prepend( m_part->makeEnvironment() ); + + return cmdline; +} + + +void TrollProjectWidget::createMakefileIfMissing( const QString &dir, QMakeScopeItem *item ) +{ + QFileInfo fi; + QFileInfo fi2; + kdDebug(9024) << "Makefile:" << item->scope->variableValues( "MAKEFILE", true, true, true ) << endl; + if ( item->scope->variableValues( "MAKEFILE", true, true, true ).isEmpty() ) + { + fi.setFile( dir + QString( QChar( QDir::separator() ) ) + "Makefile" ); + fi2.setFile( dir + QString( QChar( QDir::separator() ) ) + "makefile" ); + } + else + { + QString realmf = item->scope->resolveVariables( item->scope->variableValues( "MAKEFILE", true, true, true ).front() ); + fi.setFile( realmf ); + fi2.setFile( dir + QString( QChar( QDir::separator() ) ) + realmf ); + } + if ( !fi.exists() && !fi2.exists() ) + { + int r = KMessageBox::questionYesNo( this, i18n( "There is no Makefile in this directory. Run qmake first?" ), QString::null, i18n( "Run qmake" ), i18n( "Do Not Run" ) ); + if ( r == KMessageBox::No ) + return ; + m_part->startQMakeCommand( dir ); + } +} + +QMakeScopeItem* TrollProjectWidget::findSubprojectForPath( const QString& relPath ) +{ + if( !m_rootSubproject ) + return 0; + QStringList dirs = QStringList::split("/", relPath); + QMakeScopeItem* pitem = static_cast<QMakeScopeItem*>(m_rootSubproject); + for( QStringList::iterator it = dirs.begin(); it != dirs.end(); ++it) + { + QListViewItem* item = pitem->firstChild(); + while( item ) + { + QMakeScopeItem* sitem = static_cast<QMakeScopeItem*>(item); + if( QFileInfo( sitem->scope->projectDir() ).fileName() == *it ) + { + pitem = sitem; + break; + } + } + } + return pitem; +} + +QPtrList<QMakeScopeItem> TrollProjectWidget::findSubprojectForFile( QFileInfo fi ) +{ + QPtrList<QMakeScopeItem> list; + findSubprojectForFile( list, m_rootSubproject, fi.absFilePath() ); + return list; +} + +void TrollProjectWidget::findSubprojectForFile( QPtrList<QMakeScopeItem> &list, QMakeScopeItem * item, QString absFilePath ) +{ + if( !item ) + return; + + QDir d( item->scope->projectDir() ); + + QStringList vars = item->scope->variableValues( "SOURCES" ); + for ( QStringList::Iterator it = vars.begin(); it != vars.end(); ++it ) + { + QFileInfo fi2( d, item->scope->resolveVariables( *it ) ); + if ( absFilePath == fi2.absFilePath() ) + list.append( item ); + } + + vars = item->scope->variableValues( "HEADERS" ); + for ( QStringList::Iterator it = vars.begin(); it != vars.end(); ++it ) + { + QFileInfo fi2( d, item->scope->resolveVariables( *it ) ); + if ( absFilePath == fi2.absFilePath() ) + list.append( item ); + } + + QListViewItem * child = item->firstChild(); + while ( child ) + { + QMakeScopeItem * spitem = dynamic_cast<QMakeScopeItem*>( child ); + + if ( spitem ) + { + findSubprojectForFile( list, spitem, absFilePath ); + } + + child = child->nextSibling(); + } +} + +void TrollProjectWidget::slotRemoveScope( QMakeScopeItem * spitem ) +{ + if ( spitem == 0 && m_shownSubproject == 0 ) + return ; + else + { + m_filesCached = false; + m_allFilesCache.clear(); + + QMakeScopeItem* pitem = dynamic_cast<QMakeScopeItem *>( spitem->parent() ); + if ( pitem != 0 ) + { + switch ( spitem->scope->scopeType() ) + { + case Scope::FunctionScope: + if( !pitem->scope->deleteFunctionScope( spitem->scope->getNum() ) ) + { + KMessageBox::error(this, i18n("Could not delete Function Scope.\nThis is an internal error, please write a bug report to bugs.kde.org and include the output of kdevelop when run from a shell."),i18n("Function Scope Deletion failed")); + return; + } + // pitem->scopes.remove( spitem ); + break; + case Scope::IncludeScope: + if( !pitem->scope->deleteIncludeScope( spitem->scope->getNum() ) ) + { + KMessageBox::error(this, i18n("Could not delete Include Scope.\nThis is an internal error, please write a bug report to bugs.kde.org and include the output of kdevelop when run from a shell."),i18n("Include Scope Deletion failed")); + return; + } + // pitem->scopes.remove( spitem ); + delete spitem; + spitem = pitem; + pitem = dynamic_cast<QMakeScopeItem *>( pitem->parent() ); + // pitem->scopes.remove(spitem); + break; + case Scope::SimpleScope: + if( !pitem->scope->deleteSimpleScope( spitem->scope->getNum() ) ) + { + KMessageBox::error(this, i18n("Could not delete Scope.\nThis is an internal error, please write a bug report to bugs.kde.org and include the output of kdevelop when run from a shell."),i18n("Scope Deletion failed")); + return; + } + // pitem->scopes.remove( spitem ); + break; + default: + break; + } + pitem->scope->saveToFile(); + delete spitem; + m_shownSubproject = pitem; + overview->setCurrentItem ( m_shownSubproject ); + overview->setSelected( m_shownSubproject, true ); + slotOverviewSelectionChanged( m_shownSubproject ); + } + } +} + +QMakeScopeItem * TrollProjectWidget::findSubprojectForScope( QMakeScopeItem * scope ) +{ + if ( ( scope == 0 ) || ( scope->parent() == 0 ) ) + return 0; + if ( scope->scope->scopeType() == Scope::ProjectScope ) + return scope; + return findSubprojectForScope( dynamic_cast<QMakeScopeItem *>( scope->parent() ) ); +} + +void TrollProjectWidget::focusInEvent( QFocusEvent * /*e*/ ) +{ + switch ( m_lastFocusedView ) + { + case DetailsView: + details->setFocus(); + break; + case SubprojectView: + default: + overview->setFocus(); + } +} + +void TrollProjectWidget::setLastFocusedView( TrollProjectView view ) +{ + m_lastFocusedView = view; +} + +void TrollProjectWidget::runQMakeRecursive( QMakeScopeItem* proj ) +{ + if( m_part->isQt4Project() ) + { + m_part->startQMakeCommand( proj->scope->projectDir(), true ); + }else + { + if ( proj->scope->scopeType() == Scope::ProjectScope ) + { + m_part->startQMakeCommand( proj->scope->projectDir() ); + } + QMakeScopeItem* item = static_cast<QMakeScopeItem*>( proj->firstChild() ); + while ( item ) + { + runQMakeRecursive( item ); + item = static_cast<QMakeScopeItem*>( item->nextSibling() ); + } + } +} + +void TrollProjectWidget::slotBuildSelectedFile() +{ + QListViewItem * selectedItem = details->currentItem(); + if ( !selectedItem ) + return ; + qProjectItem *pvitem = static_cast<qProjectItem*>( selectedItem ); + // Check that it is a file (just in case) + if ( pvitem->type() != qProjectItem::File ) + return ; + FileItem *fitem = static_cast<FileItem*>( pvitem ); + buildFile( m_shownSubproject, fitem ); +} + +void TrollProjectWidget::buildFile( QMakeScopeItem* spitem, FileItem* fitem ) +{ + QFileInfo fi( spitem->scope->projectDir() + QChar( QDir::separator() ) + spitem->scope->resolveVariables( fitem->localFilePath ) ); + QString sourceDir = fi.dirPath(); + QString baseName = fi.baseName( true ); + kdDebug( 9024 ) << "Compiling " << spitem->scope->resolveVariables( fitem->text( 0 ) ) + << "in dir " << sourceDir + << " with baseName " << baseName << endl; + + QString buildDir = sourceDir; + QString target = baseName + ".o"; + if( !spitem->scope->variableValues("OBJECTS_DIR").isEmpty() ) + target = spitem->scope->resolveVariables( spitem->scope->variableValues("OBJECTS_DIR").first() )+ QString( QChar( QDir::separator() ) )+target; + kdDebug( 9024 ) << "builddir " << buildDir << ", target " << target << endl; + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + // m_part->startMakeCommand(buildDir, target); + + QString buildcmd = constructMakeCommandLine( spitem->scope ); + QString dircmd = "cd " + KProcess::quote( spitem->scope->projectDir() ) + " && " ; + kdDebug( 9024 ) << "builddir " << spitem->scope->projectDir() << ", cmd " << dircmd + buildcmd + " " + target << endl; + m_part->queueCmd( spitem->scope->projectDir(), dircmd + buildcmd + " " + target ); + + + // startMakeCommand(buildDir, target); + +} + +TrollProjectWidget::SaveType TrollProjectWidget::dialogSaveBehaviour() const +{ + switch ( DomUtil::readIntEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/savebehaviour", 2 ) ) + { + case 0: + return AlwaysSave; + break; + case 1: + return NeverSave; + break; + case 2: + default: + return Ask; + break; + } +} + +bool TrollProjectWidget::isTMakeProject() +{ + return m_part->isTMakeProject(); +} + +void TrollProjectWidget::slotDisableSubproject( QMakeScopeItem* spitem ) +{ + m_filesCached = false; + m_allFilesCache.clear(); + + if( spitem->scope->variableValues("TEMPLATE").findIndex("subdirs") != -1 ) + { + QStringList subdirs = spitem->scope->variableValues( "SUBDIRS" ); + DisableSubprojectDlg dlg( subdirs ); + if( dlg.exec() ) + { + QStringList values = dlg.selectedProjects(); + QListViewItem* item = spitem->firstChild(); + while( item ) + { + if( values.findIndex( item->text(0) ) != -1 ) + delete item; + item = item->nextSibling(); + } + spitem->disableSubprojects( values ); + spitem->scope->saveToFile(); + m_shownSubproject = spitem; + slotOverviewSelectionChanged( m_shownSubproject ); + } + }else + { + QMakeScopeItem* parent = static_cast<QMakeScopeItem*>(spitem->parent()); + parent->disableSubprojects( QStringList( spitem->scope->scopeName() ) ); + delete spitem; + parent->scope->saveToFile(); + m_shownSubproject = parent; + slotOverviewSelectionChanged( m_shownSubproject ); + } +} + +void TrollProjectWidget::slotProjectDirty(const QString& path) +{ + kdDebug(9024) << "File is dirty:" << path << " using method " << endl; + if( KMessageBox::warningYesNo(this, i18n("The project file \"%1\" has changed on disk\n(Or you have \"%2\" opened in the editor, which also triggers a reload when you change something in the QMake Manager).\n\nDo you want to reload it?").arg(path).arg(path), i18n("Project File Changed"), i18n("Reload"), i18n("Do Not Reload"), "trollproject_reload_project_file" ) != KMessageBox::No ) + { + m_part->dirWatch()->stopScan(); + QListViewItemIterator it(m_rootSubproject); + QValueList<QMakeScopeItem*> itemstoreload; + while( it.current() ) + { + QMakeScopeItem* projectitem = static_cast<QMakeScopeItem*>( it.current() ); + if( projectitem->scope->scopeType() == Scope::ProjectScope + || projectitem->scope->scopeType() == Scope::IncludeScope ) + { + QString projectfile = projectitem->scope->projectDir() + QString(QChar(QDir::separator())) + projectitem->scope->fileName(); + if( projectfile == path ) + { + itemstoreload.append(projectitem); + } + } + it++; + } + + QValueList<QMakeScopeItem*>::const_iterator reloadit = itemstoreload.begin(); + for( ; reloadit != itemstoreload.end() ; ++reloadit ) + { + (*reloadit)->reloadProject(); + if( m_shownSubproject == (*reloadit) ) + { + cleanDetailView(*reloadit); + setupContext(); + buildProjectDetailTree( *reloadit, details ); + } + if( m_configDlg->isShown() && m_configDlg->currentProjectItem() == (*reloadit) ) + { + m_configDlg->reject(); + m_configDlg->updateSubproject(m_shownSubproject); + m_configDlg->show(); + } + } + m_part->dirWatch()->startScan(); + } +} + + +QMakeScopeItem* TrollProjectWidget::currentSubproject() +{ + return m_shownSubproject; +} + +bool TrollProjectWidget::showFilenamesOnly() const +{ + return m_showFilenamesOnly; +} + +bool TrollProjectWidget::showVariablesInTree() const +{ + return m_showVariablesInTree; +} + + +QMap<QString,QString> TrollProjectWidget::qmakeEnvironment() const +{ + QMap<QString,QString> map; + DomUtil::PairList envvars = + DomUtil::readPairListEntry(*m_part->projectDom(), "/kdevtrollproject/make/envvars", "envvar", "name", "value"); + + QString environstr; + DomUtil::PairList::ConstIterator it; + bool hasQtDir = false; + for (it = envvars.begin(); it != envvars.end(); ++it) { + if( (*it).first == "QTDIR" ) + hasQtDir = true; + + map[(*it).first] = (*it).second; + } + + if( !hasQtDir && !m_part->isQt4Project() && !DomUtil::readEntry(*m_part->projectDom(), "/kdevcppsupport/qt/root", "").isEmpty() ) + { + map["QTDIR="] = DomUtil::readEntry(*m_part->projectDom(), "/kdevcppsupport/qt/root", ""); + map["PATH"] = map["PATH"].prepend( DomUtil::readEntry(*m_part->projectDom(), "/kdevcppsupport/qt/root", "") +"/bin" ); + } + return map; +} + +#include "trollprojectwidget.moc" + +//kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + diff --git a/buildtools/qmake/trollprojectwidget.h b/buildtools/qmake/trollprojectwidget.h new file mode 100644 index 00000000..19595f78 --- /dev/null +++ b/buildtools/qmake/trollprojectwidget.h @@ -0,0 +1,218 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* Copyright (C) 2002 by Jakob Simon-Gaarde * +* jakob@jsg.dk * +* Copyright (C) 2002-2003 by Alexander Dymo * +* cloudtemple@mksat.net * +* Copyright (C) 2003 by Thomas Hasart * +* thasart@gmx.de * +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 _TROLLPROJECTWIDGET_H_ +#define _TROLLPROJECTWIDGET_H_ + +#include <qdict.h> +#include <qlistview.h> +#include <qmap.h> +#include <qstrlist.h> +#include <qvbox.h> +#include <qtoolbutton.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kdeversion.h> +#include <qbutton.h> +#include <qfileinfo.h> +#include <qptrlist.h> +#include "choosesubprojectdlg.h" +#include "newwidgetdlg.h" +#include "domutil.h" +#include "qmakescopeitem.h" + +class TrollProjectPart; +class KListView; +class ProjectConfigurationDlg; + +class TrollProjectWidget : public QVBox +{ + Q_OBJECT + +public: + TrollProjectWidget( TrollProjectPart *part ); + ~TrollProjectWidget(); + + void openProject( const QString &dirName ); + void closeProject(); + + /** + * A list of the (relative) names of all subprojects (== subdirectories). + */ + //QStringList allSubprojects(); + /** + * A list of the (relative) names of all libraries. + */ + QStringList allLibraries(); + /** + * A list of all files that belong to the project. + **/ + QStringList allFiles(); + /** + * The top level directory of the project. + **/ + QString projectDirectory(); + /** + * The directory of the currently active subproject. + */ + QString subprojectDirectory(); + /** + * The directory of the currently active subproject. + */ + QString getCurrentTarget(); + + QString getCurrentDestDir(); + + QString getCurrentOutputFilename(); + + void addFileToCurrentSubProject( GroupItem *titem, const QString &filename ); + void addFileToCurrentSubProject( GroupItem::GroupType gtype, const QString &filename ); + void addFiles( QStringList &files, bool relativeToProjectRoot = true ); + void emitAddedFile( const QString &name ); + void emitRemovedFile( const QString &name ); + + QString getUiFileLink( const QString &path, const QString& filename ); + bool isTMakeProject(); + + enum TrollProjectView { SubprojectView, DetailsView }; + void setLastFocusedView( TrollProjectView view ); + enum SaveType { AlwaysSave, NeverSave, Ask }; + QMakeScopeItem* currentSubproject(); + + bool showFilenamesOnly() const; + bool showVariablesInTree() const; + +public slots: + void slotBuildTarget(); + void slotInstallTarget(); + void slotRebuildTarget(); + void slotCleanTarget(); + void slotDistCleanTarget(); + void slotExecuteTarget(); + + void slotBuildProject(); + void slotInstallProject(); + void slotRebuildProject(); + void slotCleanProject(); + void slotDistCleanProject(); + void slotExecuteProject(); + + void slotBuildOpenFile(); + void slotBuildSelectedFile(); + + void slotConfigureProject(); + void slotAddFiles(); + void slotNewFile(); + void slotRemoveFile(); + +protected: + virtual void focusInEvent( QFocusEvent *e ); + +private slots: + void slotOverviewSelectionChanged( QListViewItem *item ); + void slotOverviewContextMenu( KListView *, QListViewItem *item, const QPoint &p ); + void slotDetailsSelectionChanged( QListViewItem* ); + void slotDetailsExecuted( QListViewItem *item ); + void slotDetailsContextMenu( KListView *, QListViewItem *item, const QPoint &p ); + void slotExcludeFileFromScopeButton(); + void slotAddSubproject( QMakeScopeItem *spitem = 0 ); + void slotRemoveSubproject( QMakeScopeItem *spitem = 0 ); + void slotCreateScope( QMakeScopeItem *spitem = 0 ); + void slotRemoveScope( QMakeScopeItem *spitem = 0 ); + void slotDisableSubproject( QMakeScopeItem* spitem = 0 ); + void slotProjectDirty( const QString& ); + + void createQMakeScopeItems(); + +private: + void cleanDetailView( QMakeScopeItem *item ); + void runClean( QMakeScopeItem*, const QString& ); + void buildProjectDetailTree( QMakeScopeItem *item, KListView *listviewControl ); + void removeFile( QMakeScopeItem *spitem, FileItem *fitem ); + void addSubprojectToItem( QMakeScopeItem*, const QString& ); + void setupContext(); + // void parseScope(QMakeScopeItem *item,QString scopeString, Scope *scope); + GroupItem* getInstallRoot( QMakeScopeItem *item ); + GroupItem* getInstallObject( QMakeScopeItem *item, const QString& objectname ); + QString constructMakeCommandLine( Scope* s = 0 ); + + void createMakefileIfMissing( const QString &dir, QMakeScopeItem *item ); + + void runQMakeRecursive( QMakeScopeItem* proj); + void buildFile( QMakeScopeItem* spitem, FileItem* fitem); + + /*fileName: full base file name like QFileInfo::baseName ( true )*/ + QPtrList<QMakeScopeItem> findSubprojectForFile( QFileInfo fi ); + void findSubprojectForFile( QPtrList<QMakeScopeItem> &list, QMakeScopeItem * item, QString absFilePath ); + QMakeScopeItem* findSubprojectForPath( const QString& ); + // QString makeEnvironment(); + + TrollProjectWidget::SaveType dialogSaveBehaviour() const; + + QMakeScopeItem *findSubprojectForScope( QMakeScopeItem *scope ); + + void reloadProjectFromFile( QMakeScopeItem* item ); + QMap<QString,QString> qmakeEnvironment() const; + + QVBox *overviewContainer; + KListView *overview; + QHBox *projectTools; + QToolButton *addSubdirButton; + QToolButton *createScopeButton; + + QToolButton *buildProjectButton; + QToolButton *rebuildProjectButton; + QToolButton *executeProjectButton; + + QToolButton *buildTargetButton; + QToolButton *rebuildTargetButton; + QToolButton *executeTargetButton; + + QToolButton *buildFileButton; + QToolButton *projectconfButton; + + QVBox *detailContainer; + KListView *details; + QHBox *fileTools; + QToolButton *addfilesButton; + QToolButton *newfileButton; + QToolButton *removefileButton; + QToolButton *excludeFileFromScopeButton; + + DomUtil::PairList m_subclasslist; + QMakeScopeItem *m_shownSubproject; + QMakeScopeItem *m_rootSubproject; + Scope* m_rootScope; + TrollProjectPart *m_part; + ProjectConfigurationDlg* m_configDlg; + + TrollProjectView m_lastFocusedView; + + bool m_filesCached; + bool m_showFilenamesOnly; + bool m_showVariablesInTree; + QStringList m_allFilesCache; + + friend class ChooseSubprojectDlg; + friend class ProjectConfigurationDlg; +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/script/Makefile.am b/buildtools/script/Makefile.am new file mode 100644 index 00000000..73cee869 --- /dev/null +++ b/buildtools/script/Makefile.am @@ -0,0 +1,26 @@ +# Here resides the script project part. +# This is a generic part for various scripting languages that simply +# includes all files from the project directory without managing +# them. If a language needs more specific features, it deserves +# its own part (or the respective features should be added to the +# language support part) + +INCLUDES = -I$(top_srcdir)/buildtools/lib/base \ + -I$(top_srcdir)/buildtools/lib/widgets -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/interfaces/external -I$(top_srcdir)/lib/util \ + -I$(top_srcdir)/lib/external_interfaces $(all_includes) + +kde_module_LTLIBRARIES = libkdevscriptproject.la +libkdevscriptproject_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevscriptproject_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/buildtools/lib/widgets/libkdevbuildtoolswidgets.la $(top_builddir)/buildtools/lib/base/libkdevbuildbase.la + +libkdevscriptproject_la_SOURCES = scriptprojectpart.cpp scriptoptionswidget.cpp scriptoptionswidgetbase.ui scriptnewfiledlg.cpp + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevscriptproject.desktop + +rcdir = $(kde_datadir)/kdevscriptproject +rc_DATA = kdevscriptproject.rc diff --git a/buildtools/script/README.dox b/buildtools/script/README.dox new file mode 100644 index 00000000..a7a19983 --- /dev/null +++ b/buildtools/script/README.dox @@ -0,0 +1,48 @@ +/** \class ScriptProjectPart +This is the script build tool part +Put a more detailed description of your part in these lines. It can span +over several lines. You can even use some html commands in these lines like: +<code>This is code</code>, html links <a href="http://somelocation">link text</a>, +and images. + +\authors <a href="mailto:bernd AT kdevelop.org">Bernd Gehrmann</a> + +\unmaintained This part is currently un-maintained + +\deprecated This class is deprecated, use GenericProjectPart (buildtools/generic) instead. + +\feature Describe the first feature +\feature Describe the second feature +... +\feature Describe the last feature + +\bug Describe a the 1st bug that you know of, but probably hasn't been reported yet. +.. +\bug Describe a the nth bug that you know of, but probably hasn't been reported yet. + +\requirement Describe a the 1st requirement of your part. +\requirement Describe a the 2nd requirement of your part. +... +\requirement Describe a the nth requirement of your part. + +\todo Describe a the 1st TODO of your part. +\todo Describe a the 2nd TODO of your part. +... +\todo Describe a the nth TODO of your part. + +\faq <b>First frequenly asked question about your part ?</b> Answer. +\faq <b>Second frequenly asked question about your part ?</b> Answer. +... +\faq <b>Last frequenly asked question about your part ?</b> Answer. + +\note First note text. +\note Second note text. +... +\note Last note text. + +\warning First warning text. +\warning Second warning text. +... +\warning Last warning text. + +*/ diff --git a/buildtools/script/kdevscriptproject.desktop b/buildtools/script/kdevscriptproject.desktop new file mode 100644 index 00000000..1200f9ba --- /dev/null +++ b/buildtools/script/kdevscriptproject.desktop @@ -0,0 +1,87 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=Scripting Language Project +Comment[ca]=Projecte de llenguatge escrivint scripts +Comment[da]=Scriptsprog-projekt +Comment[de]=Skriptsprachen-Projekt für KDevelop +Comment[el]=Έργο γλώσσας γραφής σεναρίων +Comment[es]=Proyecto de lenguaje de guiones +Comment[et]=Skriptikeele projekt +Comment[eu]=Script lengoai proiektua +Comment[fa]=پروژۀ زبان دستنوشتهای +Comment[fr]=Projet avec les langages de scripts +Comment[ga]=Tionscadal i dTeanga Scriptithe +Comment[gl]=Proxecto de linguaxe de scripting +Comment[hi]=स्क्रिप्टिंग भाषा परियोजना +Comment[hu]=Szkript-projekt +Comment[is]=Skriftumálsverkefni +Comment[it]=Progetto con linguaggio di scripting +Comment[ja]=スクリプト言語プロジェクト +Comment[ms]=Projek Bahasa Penskrip +Comment[nds]=Skriptspraak-Projekt +Comment[ne]=स्क्रिप्टिङ भाषा परियोजना +Comment[nl]=Scripttaal-project +Comment[pl]=Projekt w języku skryptowym +Comment[pt]=Projecto de uma Linguagem de 'Scripting' +Comment[pt_BR]=Projeto de Linguagem de Script +Comment[ru]=Проект скриптового языка +Comment[sk]=Skriptovací jazyk projekt +Comment[sl]=Projekt skriptnega jezika +Comment[sr]=Пројекат скриптног језика +Comment[sr@Latn]=Projekat skriptnog jezika +Comment[sv]=Projekt för skriptspråk +Comment[ta]=ஸ்கிரிப்டிங் மொழி பிராஜக்ட் +Comment[tg]=Лоиҳа бо забони ғарчкунӣ +Comment[tr]=Betik Dili Projesi +Comment[zh_CN]=脚本语言工程 +Comment[zh_TW]=文稿語言專案 +Name=KDevScriptProject +Name[da]=KDevelop script-projekt +Name[de]=Skriptsprachen-Projekt (KDevelop) +Name[hi]=के-डेव-स्क्रिप्ट-परियोजना +Name[nds]=Skriptspraak-Projekt (KDevelop) +Name[ne]=केडीई विकास स्क्रिप्ट परियोजना +Name[pl]=KDevProjektSkrypt +Name[sk]=KDevSkriptProjekt +Name[sv]=KDevelop skriptprojekt +Name[ta]=கெடெவ் ஸ்கிரிப்ட் பிராஜக்ட் +Name[tg]=KDevЛоиҳаи скрипт +Name[zh_TW]=KDevelop 文稿專案 +GenericName=Scripting Language Project +GenericName[ca]=Projecte de llenguatge escrivint scripts +GenericName[da]=Scriptsprog-projekt +GenericName[de]=Skriptsprachen-Projekt +GenericName[el]=Έργο γλώσσας γραφής σεναρίων +GenericName[es]=Proyecto de lenguaje de guiones +GenericName[et]=Skriptikeele projekt +GenericName[eu]=Script lengoaia proiektua +GenericName[fa]=پروژۀ زبان دستنوشتهای +GenericName[fr]=Projet avec les langages de scripts +GenericName[ga]=Tionscadal i dTeanga Scriptithe +GenericName[gl]=Proxecto de linguaxe de scripting +GenericName[hi]=स्क्रिप्टिंग भाषा परियोजना +GenericName[hu]=Szkript-projekt +GenericName[it]=Progetto con linguaggio di scripting +GenericName[ja]=スクリプト言語プロジェクト +GenericName[nds]=Skriptspraak-Projekt +GenericName[ne]=स्क्रिप्टिङ भाषा परियोजना +GenericName[nl]=Scripttaal-project +GenericName[pl]=Projekt w języku skryptowym +GenericName[pt]=Projecto de uma Linguagem de 'Scripting' +GenericName[pt_BR]=Projeto de Linguagem de Script +GenericName[ru]=Проект скриптового языка +GenericName[sk]=Skriptovací jazyk projekt +GenericName[sl]=Projekt skriptnega jezika +GenericName[sr]=Пројекат скриптног језика +GenericName[sr@Latn]=Projekat skriptnog jezika +GenericName[sv]=Projekt för skriptspråk +GenericName[ta]=ஸ்கிரிப்டிங் மொழி பிராஜக்ட் +GenericName[tg]=Лоиҳа бо забони ғарчкунӣ +GenericName[tr]=Betik Dili Projesi +GenericName[zh_CN]=脚本语言工程 +GenericName[zh_TW]=文稿語言專案 +ServiceTypes=KDevelop/Project +Icon=kdevelop +X-KDE-Library=libkdevscriptproject +X-KDevelop-Version=5 diff --git a/buildtools/script/kdevscriptproject.rc b/buildtools/script/kdevscriptproject.rc new file mode 100644 index 00000000..651b10b4 --- /dev/null +++ b/buildtools/script/kdevscriptproject.rc @@ -0,0 +1,12 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KDevCustomProject" version="2"> +<MenuBar> + <Menu name="file" > + <Action name="file_newfile" /> + </Menu> + <Menu name="project" > + <Action name="rescan" /> + </Menu> +</MenuBar> +</kpartgui> + diff --git a/buildtools/script/scriptnewfiledlg.cpp b/buildtools/script/scriptnewfiledlg.cpp new file mode 100644 index 00000000..336187d3 --- /dev/null +++ b/buildtools/script/scriptnewfiledlg.cpp @@ -0,0 +1,119 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "scriptnewfiledlg.h" + +#include <qcheckbox.h> +#include <qfile.h> +#include <qfileinfo.h> +#include <qlabel.h> +#include <qlayout.h> +#include <klineedit.h> +#include <qpushbutton.h> +#include <kbuttonbox.h> +#include <kdebug.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kstdguiitem.h> +#include <kdeversion.h> + +#include "scriptprojectpart.h" +#include "filetemplate.h" + + +ScriptNewFileDialog::ScriptNewFileDialog(ScriptProjectPart *part, + QWidget *parent, const char *name) + : QDialog(parent, name, true) +{ + setCaption(i18n("New File")); + + QLabel *filename_label = new QLabel(i18n("&File name:"), this); + + filename_edit = new KLineEdit(this); + filename_edit->setFocus(); + filename_label->setBuddy(this); + QFontMetrics fm(filename_edit->fontMetrics()); + filename_edit->setMinimumWidth(fm.width('X')*35); + + usetemplate_box = new QCheckBox(i18n("&Use file template"), this); + usetemplate_box->setChecked(true); + + QFrame *frame = new QFrame(this); + frame->setFrameStyle(QFrame::HLine | QFrame::Sunken); + + KButtonBox *buttonbox = new KButtonBox(this); + buttonbox->addStretch(); + QPushButton *ok_button = buttonbox->addButton(KStdGuiItem::ok()); + QPushButton *cancel_button = buttonbox->addButton(KStdGuiItem::cancel()); + ok_button->setDefault(true); + connect( ok_button, SIGNAL(clicked()), this, SLOT(accept()) ); + connect( cancel_button, SIGNAL(clicked()), this, SLOT(reject()) ); + buttonbox->layout(); + + QVBoxLayout *layout = new QVBoxLayout(this, 10, 4); + layout->addWidget(filename_label); + layout->addWidget(filename_edit); + layout->addWidget(usetemplate_box); + layout->addWidget(frame, 0); + layout->addWidget(buttonbox, 0); + + m_part = part; +} + + +ScriptNewFileDialog::~ScriptNewFileDialog() +{} + + +void ScriptNewFileDialog::accept() +{ + QString fileName = filename_edit->text(); + if (fileName.find('/') != -1) { + KMessageBox::sorry(this, i18n("Please enter the file name without '/' and so on.")); + return; + } + + KDevProject *project = m_part->project(); + if (!project->activeDirectory().isEmpty()) + fileName.prepend(project->activeDirectory() + "/"); + QString destpath = project->projectDirectory() + "/" + fileName; + + if (QFileInfo(destpath).exists()) { + KMessageBox::sorry(this, i18n("A file with this name already exists.")); + return; + } + + bool success = false; + + if (usetemplate_box->isChecked()) { + QString extension = QFileInfo(destpath).extension(); + if (!FileTemplate::exists(m_part, extension)) { + KMessageBox::sorry(this, i18n("A file template for this extension does not exist.")); + return; + } + success = FileTemplate::copy(m_part, extension, destpath); + } else { + QFile f(destpath); + success = f.open(IO_WriteOnly); + if (success) + f.close(); + } + + if (!success) + KMessageBox::sorry(this, i18n("Could not create the new file.")); + + kdDebug(9015) << "AddFile1: " << fileName << endl; + m_part->addFile(fileName); + + QDialog::accept(); +} + +#include "scriptnewfiledlg.moc" diff --git a/buildtools/script/scriptnewfiledlg.h b/buildtools/script/scriptnewfiledlg.h new file mode 100644 index 00000000..b3c73713 --- /dev/null +++ b/buildtools/script/scriptnewfiledlg.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef _SCRIPTNEWFILEDLG_H_ +#define _SCRIPTNEWFILEDLG_H_ + +#include <qdialog.h> + +class QCheckBox; +class KLineEdit; +class ScriptProjectPart; + + +class ScriptNewFileDialog : public QDialog +{ + Q_OBJECT + +public: + ScriptNewFileDialog( ScriptProjectPart *part, QWidget *parent=0, const char *name=0 ); + ~ScriptNewFileDialog(); + +protected: + virtual void accept(); + +private: + QCheckBox *usetemplate_box; + KLineEdit *filename_edit; + ScriptProjectPart *m_part; +}; + +#endif diff --git a/buildtools/script/scriptoptionswidget.cpp b/buildtools/script/scriptoptionswidget.cpp new file mode 100644 index 00000000..c1660b00 --- /dev/null +++ b/buildtools/script/scriptoptionswidget.cpp @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "scriptoptionswidget.h" + +#include <qcheckbox.h> +#include <klineedit.h> +#include <qradiobutton.h> +#include <qtabwidget.h> +#include "domutil.h" +#include "kdevlanguagesupport.h" + + +ScriptOptionsWidget::ScriptOptionsWidget(KDevPlugin *part, + QWidget *parent, const char *name) + : ScriptOptionsWidgetBase(parent, name) +{ + m_part = part; + + QDomDocument &dom = *m_part->projectDom(); + + QString includepatterns + = DomUtil::readEntry(dom, "/kdevscriptproject/general/includepatterns"); + + if (includepatterns.isNull() && part->languageSupport()){ + QStringList includepatternList; + KMimeType::List list = part->languageSupport()->mimeTypes(); + KMimeType::List::Iterator it = list.begin(); + while( it != list.end() ){ + includepatternList += (*it)->patterns(); + ++it; + } + includepatterns = includepatternList.join( "," ); + } + + QString excludepatterns + = DomUtil::readEntry(dom, "/kdevscriptproject/general/excludepatterns"); + if (excludepatterns.isNull()) + excludepatterns = "*~"; + + includepatterns_edit->setText(includepatterns); + excludepatterns_edit->setText(excludepatterns); +} + + +ScriptOptionsWidget::~ScriptOptionsWidget() +{} + + +void ScriptOptionsWidget::accept() +{ + QDomDocument &dom = *m_part->projectDom(); + + QString includepatterns = includepatterns_edit->text(); + QString excludepatterns = excludepatterns_edit->text(); + + DomUtil::writeEntry(dom, "/kdevscriptproject/general/includepatterns", includepatterns); + DomUtil::writeEntry(dom, "/kdevscriptproject/general/excludepatterns", excludepatterns); +} + +#include "scriptoptionswidget.moc" diff --git a/buildtools/script/scriptoptionswidget.h b/buildtools/script/scriptoptionswidget.h new file mode 100644 index 00000000..c33d099d --- /dev/null +++ b/buildtools/script/scriptoptionswidget.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef _SCRIPTPROJECTOPTIONSWIDGET_H_ +#define _SCRIPTPROJECTOPTIONSWIDGET_H_ + +#include "scriptoptionswidgetbase.h" + +class KDevPlugin; + + +class ScriptOptionsWidget : public ScriptOptionsWidgetBase +{ + Q_OBJECT + +public: + ScriptOptionsWidget( KDevPlugin *part, QWidget *parent=0, const char *name=0 ); + ~ScriptOptionsWidget(); + +public slots: + void accept(); + +private: + KDevPlugin *m_part; +}; + +#endif diff --git a/buildtools/script/scriptoptionswidgetbase.ui b/buildtools/script/scriptoptionswidgetbase.ui new file mode 100644 index 00000000..3a8f7b99 --- /dev/null +++ b/buildtools/script/scriptoptionswidgetbase.ui @@ -0,0 +1,155 @@ +<!DOCTYPE UI><UI version="3.1" stdsetdef="1"> +<class>ScriptOptionsWidgetBase</class> +<widget class="QWidget"> + <property name="name"> + <cstring>script_project_options</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>600</width> + <height>482</height> + </rect> + </property> + <property name="caption"> + <string>Script Project Options</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>includepatterns_label</cstring> + </property> + <property name="text"> + <string>&Include files into the project with the following patterns:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>includepatterns_edit</cstring> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Minimum</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KLineEdit"> + <property name="name"> + <cstring>includepatterns_edit</cstring> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer7</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Minimum</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel"> + <property name="name"> + <cstring>excludepatterns_label</cstring> + </property> + <property name="text"> + <string>&Exclude the following patterns:</string> + </property> + <property name="buddy" stdset="0"> + <cstring>excludepatterns_edit</cstring> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>Layout2_2</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>Spacer4_2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Minimum</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="KLineEdit"> + <property name="name"> + <cstring>excludepatterns_edit</cstring> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>Spacer6</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </vbox> +</widget> +<includes> + <include location="global" impldecl="in implementation">kdialog.h</include> +</includes> +<layoutdefaults spacing="6" margin="11"/> +<layoutfunctions spacing="KDialog::spacingHint" margin="KDialog::marginHint"/> +</UI> diff --git a/buildtools/script/scriptprojectpart.cpp b/buildtools/script/scriptprojectpart.cpp new file mode 100644 index 00000000..ff560f23 --- /dev/null +++ b/buildtools/script/scriptprojectpart.cpp @@ -0,0 +1,446 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "scriptprojectpart.h" + +#include <qdir.h> +#include <qregexp.h> +#include <qstringlist.h> +#include <qvaluestack.h> +#include <qvbox.h> +#include <qwhatsthis.h> +#include <kaction.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kdevgenericfactory.h> +#include <kdevcreatefile.h> +#include <kdirwatch.h> + +#include "domutil.h" +#include "kdevcore.h" +#include "kdevmainwindow.h" +#include "kdevpartcontroller.h" +#include "kdevlanguagesupport.h" +#include "scriptoptionswidget.h" +#include "scriptnewfiledlg.h" +#include "kdevplugininfo.h" + +typedef KDevGenericFactory<ScriptProjectPart> ScriptProjectFactory; +static const KDevPluginInfo data("kdevscriptproject"); +K_EXPORT_COMPONENT_FACTORY( libkdevscriptproject, ScriptProjectFactory( data ) ) + +ScriptProjectPart::ScriptProjectPart(QObject *parent, const char *name, const QStringList &) + : KDevBuildTool(&data, parent, name ? name : "ScriptProjectPart") +{ + setInstance(ScriptProjectFactory::instance()); + + setXMLFile("kdevscriptproject.rc"); + + // only create new file action if file creation part not available + if (!extension<KDevCreateFile>("KDevelop/CreateFile")) { + KAction *action; + action = new KAction( i18n("New File..."), 0, + this, SLOT(slotNewFile()), + actionCollection(), "file_newfile" ); + action->setWhatsThis( i18n("<b>New file</b><p>Creates a new file.") ); + action->setToolTip( i18n("Create a new file") ); + } + new KAction( i18n("Rescan Project"), 0, CTRL+ALT+Key_R, + this, SLOT(rescan()), + actionCollection(), "rescan" ); + + connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), + this, SLOT(projectConfigWidget(KDialogBase*)) ); +} + + +ScriptProjectPart::~ScriptProjectPart() +{} + + +void ScriptProjectPart::projectConfigWidget(KDialogBase *dlg) +{ + QVBox *vbox; + vbox = dlg->addVBoxPage(i18n("Script Project Options"), i18n("Script Project Options"), BarIcon("kdevelop", KIcon::SizeMedium)); + ScriptOptionsWidget *w = new ScriptOptionsWidget(this, vbox); + connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); +} + + +/** + * @todo This should really be merged with FileTreeWidget::matchesHidePattern() + * and put in its own class. Currently this is repeated in scriptprojectpart.cpp, pascalproject_part.cpp, adaproject_part.cpp + */ +static bool matchesPattern(const QString &fileName, const QStringList &patternList) +{ + QStringList::ConstIterator it; + for (it = patternList.begin(); it != patternList.end(); ++it) { + QRegExp re(*it, true, true); + if (re.search(fileName) == 0 && re.matchedLength() == (int)fileName.length()) + return true; + } + + return false; +} + + +void ScriptProjectPart::openProject(const QString &dirName, const QString &projectName) +{ + if (!languageSupport()) + kdDebug(9015) << "ScriptProjectPart::openProject: no language support found!" << endl; + + m_projectDirectory = dirName; + m_projectName = projectName; + + QDomDocument &dom = *projectDom(); + + // Set the default directory radio to "executable" + if (DomUtil::readEntry(dom, "/kdevscriptproject/run/directoryradio") == "" ) { + DomUtil::writeEntry(dom, "/kdevscriptproject/run/directoryradio", "executable"); + } + + // Put all files from all subdirectories into file list + QValueStack<QString> s; + int prefixlen = m_projectDirectory.length()+1; + s.push(m_projectDirectory); + + QDir dir; + do { + dir.setPath(s.pop()); + kdDebug(9015) << "Examining: " << dir.path() << endl; + const QFileInfoList *dirEntries = dir.entryInfoList(); + if ( dirEntries ) + { + QPtrListIterator<QFileInfo> it(*dirEntries); + for (; it.current(); ++it) { + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == "..") + continue; + QString path = it.current()->absFilePath(); + if (it.current()->isDir()) { + //do not follow symlinks which point to the themselves + if (it.current()->isSymLink()) + { + QString symLink = it.current()->readLink(); + if ((symLink == path) || (symLink == "./")) + continue; + } else if (canAddDirectoryToProject(path)) { + kdDebug(9015) << "Pushing: " << path << endl; + s.push(path); + } + } + else { + if (canAddToProject(path)) + m_sourceFiles.append(path.mid(prefixlen)); + } + } + } + } while (!s.isEmpty()); + + KDevProject::openProject( dirName, projectName ); +} + + +void ScriptProjectPart::closeProject() +{ +} + + +QString ScriptProjectPart::projectDirectory() const +{ + return m_projectDirectory; +} + + +QString ScriptProjectPart::buildDirectory() const +{ + return m_projectDirectory; +} + +QString ScriptProjectPart::projectName() const +{ + return m_projectName; +} + + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList ScriptProjectPart::runEnvironmentVars() const +{ + return DomUtil::readPairListEntry(*projectDom(), "/kdevscriptproject/run/envvars", "envvar", "name", "value"); +} + + +/** Retuns the currently selected run directory + * The returned string can be: + * if run/directoryradio == executable + * The directory where the executable is + * if run/directoryradio == build + * The directory where the executable is relative to build directory + * if run/directoryradio == custom + * The custom directory absolute path + */ +QString ScriptProjectPart::runDirectory() const +{ + QString cwd = defaultRunDirectory("kdevscriptproject"); + if (cwd.isEmpty()) + cwd = buildDirectory(); + return cwd; +} + + +/** Retuns the currently selected main program + * The returned string can be: + * if run/directoryradio == executable + * The executable name + * if run/directoryradio == build + * The path to executable relative to build directory + * if run/directoryradio == custom or relative == false + * The absolute path to executable + */ +QString ScriptProjectPart::mainProgram() const +{ + QDomDocument * dom = projectDom(); + + if ( !dom ) return QString(); + + QString DomMainProgram = DomUtil::readEntry( *dom, "/kdevscriptproject/run/mainprogram"); + + if ( DomMainProgram.isEmpty() ) return QString(); + + if ( DomMainProgram.startsWith("/") ) // assume absolute path + { + return DomMainProgram; + } + else // assume project relative path + { + return projectDirectory() + "/" + DomMainProgram; + } + + return QString(); +} + +/** Retuns a QString with the debug command line arguments */ +QString ScriptProjectPart::debugArguments() const +{ + return DomUtil::readEntry(*projectDom(), "/kdevscriptproject/run/globaldebugarguments"); +} + + +/** Retuns a QString with the run command line arguments */ +QString ScriptProjectPart::runArguments() const +{ + return DomUtil::readEntry(*projectDom(), "/kdevscriptproject/run/programargs"); +} + + +QString ScriptProjectPart::activeDirectory() const +{ + QDomDocument &dom = *projectDom(); + + return DomUtil::readEntry(dom, "/kdevscriptproject/general/activedir"); +} + + +QStringList ScriptProjectPart::allFiles() const +{ +/* QStringList res; + + QStringList::ConstIterator it; + for (it = m_sourceFiles.begin(); it != m_sourceFiles.end(); ++it) + res += (m_projectDirectory + "/" + (*it)); + + return res;*/ + + // return all files relative to the project directory! + return m_sourceFiles; +} + +void ScriptProjectPart::addFile(const QString &fileName) +{ + kdDebug(9015) << "AddFile2" << fileName << endl; + + QStringList fileList; + fileList.append ( fileName ); + + this->addFiles ( fileList ); +} + +void ScriptProjectPart::addFiles ( const QStringList& fileList ) +{ + QStringList::ConstIterator it; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) + { + m_sourceFiles.append ( ( *it ) ); + } + + emit addedFilesToProject ( fileList ); +} + +void ScriptProjectPart::removeFile(const QString &fileName) +{ + QStringList fileList; + fileList.append ( fileName ); + + this->addFiles ( fileList ); +} + +void ScriptProjectPart::removeFiles ( const QStringList& fileList ) +{ + emit removedFilesFromProject ( fileList ); + + QStringList::ConstIterator it; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) + { + m_sourceFiles.remove ( ( *it ) ); + } +} + +void ScriptProjectPart::slotNewFile() +{ + ScriptNewFileDialog dlg(this); + dlg.exec(); +} + +/*! + \fn ScriptProjectPart::distFiles() const + */ +QStringList ScriptProjectPart::distFiles() const +{ + QStringList sourceList = allFiles(); + // Scan current source directory for any .pro files. + QString projectDir = projectDirectory(); + QDir dir(projectDir); + QStringList files = dir.entryList( "*README*"); + return sourceList + files; +} + +void ScriptProjectPart::rescan() +{ +// kdDebug() << "Directory " << path << " changed, scanning for new files in the project" << endl; + + // Put all files from all subdirectories into file list + QValueStack<QString> s; + int prefixlen = m_projectDirectory.length()+1; + s.push(m_projectDirectory); + + QDir dir; + do { + dir.setPath(s.pop()); + kdDebug(9015) << "Examining: " << dir.path() << endl; + const QFileInfoList *dirEntries = dir.entryInfoList(); + if ( dirEntries ) + { + QPtrListIterator<QFileInfo> it(*dirEntries); + for (; it.current(); ++it) { + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == "..") + continue; + QString path = it.current()->absFilePath(); + if (it.current()->isDir()) { + //do not follow symlinks which point to the themselves + if (it.current()->isSymLink()) + { + QString symLink = it.current()->readLink(); + if ((symLink == path) || (symLink == "./")) + continue; + } else if (canAddDirectoryToProject(path)) { + kdDebug(9015) << "Pushing: " << path << endl; + s.push(path); + } + } + else { + if (!isProjectFile(path) && canAddToProject(path)) + addFile(path.mid(prefixlen)); +// m_sourceFiles.append(path.mid(prefixlen)); + } + } + } + } while (!s.isEmpty()); + +/* const QFileInfoList *dirEntries = QDir(path).entryInfoList(); + if ( dirEntries ) + { + kdDebug() << "1" << endl; + QPtrListIterator<QFileInfo> it(*dirEntries); + for (; it.current(); ++it) { + kdDebug() << "2" << endl; + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == "..") + continue; + kdDebug() << "3" << endl; + QString filePath = it.current()->absFilePath(); + if (!it.current()->isDir() && canAddToProject(filePath) && !isProjectFile(filePath)) { + kdDebug() << "=== adding " << filePath << endl; + addFile(filePath); + } + } + }*/ +} + +bool ScriptProjectPart::canAddToProject(const QString & path) +{ + QDomDocument &dom = *projectDom(); + QString includepatterns + = DomUtil::readEntry(dom, "/kdevscriptproject/general/includepatterns"); + QStringList includepatternList; + if ( includepatterns.isNull() ) { + if ( languageSupport() ){ + KMimeType::List list = languageSupport()->mimeTypes(); + KMimeType::List::Iterator it = list.begin(); + while( it != list.end() ){ + includepatternList += (*it)->patterns(); + ++it; + } + } + } else { + includepatternList = QStringList::split(",", includepatterns); + } + + QString excludepatterns + = DomUtil::readEntry(dom, "/kdevscriptproject/general/excludepatterns"); + if (excludepatterns.isNull()) + excludepatterns = "*~"; + QStringList excludepatternList = QStringList::split(",", excludepatterns); + + if (matchesPattern(path, includepatternList) + && !matchesPattern(path, excludepatternList)) { + kdDebug(9015) << "Adding: " << path << endl; + return true; + } else { + kdDebug(9015) << "Ignoring: " << path << endl; + return false; + } +} + +bool ScriptProjectPart::canAddDirectoryToProject(const QString & path) +{ + QDomDocument &dom = *projectDom(); + QString excludepatterns + = DomUtil::readEntry(dom, "/kdevscriptproject/general/excludepatterns"); + if (excludepatterns.isNull()) { + return true; + } + QStringList excludepatternList = QStringList::split(",", excludepatterns); + + if (!matchesPattern(path, excludepatternList)) { + return true; + } else { + kdDebug(9015) << "Ignoring Directory: " << path << endl; + return false; + } +} + +#include "scriptprojectpart.moc" diff --git a/buildtools/script/scriptprojectpart.h b/buildtools/script/scriptprojectpart.h new file mode 100644 index 00000000..b16c4ffb --- /dev/null +++ b/buildtools/script/scriptprojectpart.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef _SCRIPTPROJECTPART_H_ +#define _SCRIPTPROJECTPART_H_ + +#include <qdict.h> +#include <qguardedptr.h> + +#include "kdevbuildtool.h" + +class QListViewItem; +class QStringList; +class KDialogBase; +class ScriptProjectWidget; + +class ScriptProjectPart : public KDevBuildTool +{ + Q_OBJECT + +public: + ScriptProjectPart( QObject *parent, const char *name, const QStringList &args ); + ~ScriptProjectPart(); + QStringList distFiles() const; + +protected: + virtual void openProject(const QString &dirName, const QString &projectName); + virtual void closeProject(); + + virtual QString projectDirectory() const; + virtual QString projectName() const; + virtual QString mainProgram() const; + virtual QString activeDirectory() const; + virtual QStringList allFiles() const; + virtual void addFile(const QString &fileName); + virtual void addFiles ( const QStringList& fileList ); + virtual void removeFile(const QString &fileName); + virtual void removeFiles ( const QStringList& fileList ); + virtual QString buildDirectory() const; + virtual QString runDirectory() const; + virtual QString debugArguments() const; + virtual QString runArguments() const; + virtual DomUtil::PairList runEnvironmentVars() const; + + bool canAddToProject(const QString &path); + bool canAddDirectoryToProject(const QString &path); + +private slots: + void projectConfigWidget(KDialogBase *dlg); + void slotNewFile(); + void rescan(); + +private: + QString m_projectDirectory; + QString m_projectName; + QStringList m_sourceFiles; + + friend class ScriptNewFileDialog; +}; + +#endif |