You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdewebdev/kommander/editor/functionsimpl.cpp

393 lines
14 KiB

/***************************************************************************
functionsimpl.cpp - Function browser implementation
-------------------
copyright : (C) 2004 Michal Rudolf <mrudolf@kdewebdev.org>
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or mody *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/* QT INCLUDES */
#include <tqcheckbox.h>
#include <tqlabel.h>
#include <tqmetaobject.h>
#include <tqstringlist.h>
#include <tqregexp.h>
/* KDE INCLUDES */
#include <kcombobox.h>
#include <tdeglobal.h>
#include <kiconloader.h>
#include <tdelistbox.h>
#include <klineedit.h>
#include <tdelocale.h>
#include <kpushbutton.h>
#include <ktextedit.h>
#include <ktextbrowser.h>
#include <kdebug.h>
/* OTHER INCLUDES */
#include "functionsimpl.h"
#include "kommanderwidget.h"
#include "invokeclass.h"
#include "widgetdatabase.h"
const int MaxFunctionArgs = 6;
FunctionsDialog::FunctionsDialog(TQWidget* a_parent, const TQDict<TQWidget>& a_widgetList, bool useInternalParser, char* a_name,
bool a_modal)
: FunctionsDialogBase(a_parent, a_name, a_modal), m_widgetList(a_widgetList), m_useInternalParser(useInternalParser)
{
clearButton->setPixmap(TDEGlobal::iconLoader()->loadIcon("locationbar_erase", TDEIcon::Toolbar));
copyButton->setPixmap(TDEGlobal::iconLoader()->loadIcon("1downarrow", TDEIcon::Toolbar));
groupComboBox->insertStringList(SpecialInformation::groups());
connect(groupComboBox, TQT_SIGNAL(activated(int)), TQT_SLOT(groupChanged(int)));
connect(widgetComboBox, TQT_SIGNAL(activated(int)), TQT_SLOT(groupChanged(int)));
connect(functionListBox, TQT_SIGNAL(highlighted(int)), TQT_SLOT(functionChanged(int)));
connect(copyButton, TQT_SIGNAL(clicked()), TQT_SLOT(copyText()));
connect(clearButton, TQT_SIGNAL(clicked()), insertedText, TQT_SLOT(clear()));
// build widget name list
for (TQDictIterator<TQWidget> It(m_widgetList); It.current(); ++It)
m_widgetNames.append(It.currentKey());
m_widgetNames.sort();
widgetComboBox->insertStringList(m_widgetNames);
for (int j = 0; j < WidgetDatabase::count(); j++)
{
TQString group = WidgetDatabase::group(j);
if (group == "Kommander" || group == "Custom")
m_widgetTypes << WidgetDatabase::className(j);
}
m_widgetTypes.sort();
//TODO: Insert either the generic widget types or parse for on the fly created widget
//names. The problem is that the rest of the code depends on the fact that the widget
//from the widgetComboBox exists
// widgetComboBox->insertStringList(m_widgetTypes);
m_acceptedSlots = InvokeClass::acceptedSlots();
m_DCOP = -1; // Select DCOP functions by default
m_Slots = -1;
for (int i=0; i<groupComboBox->count(); i++)
{
if (groupComboBox->text(i) == i18n("Slots"))
{
m_Slots = i;
break;
}
}
if (!useInternalParser)
{
groupComboBox->removeItem(m_Slots);
m_Slots = -1;
}
for (int i=0; i<groupComboBox->count(); i++)
{
if (groupComboBox->text(i) == "DCOP")
{
m_DCOP = i;
break;
}
}
groupComboBox->changeItem(i18n("Functions"), m_DCOP); //this is a quick way to rename this group in the UI
groupComboBox->setCurrentItem(m_DCOP);
groupChanged(groupComboBox->currentItem());
}
FunctionsDialog::~FunctionsDialog()
{
}
TQString FunctionsDialog::functionText() const
{
return insertedText->text();
}
TQString FunctionsDialog::currentFunctionText()
{
TQString prefix, function;
int index = groupComboBox->currentItem();
TQString s = (index != m_DCOP ) ? groupComboBox->text(index) : "DCOP";
if (m_useInternalParser)
{
function = SpecialInformation::parserGroupName(s);
if (!function.isEmpty())
function += "_";
}
else
{
prefix = "@";
function = s + ".";
}
if (groupComboBox->currentText() == "Kommander")
return TQString("%1%2%3").arg(prefix).arg(functionListBox->currentText()).arg(params());
else if (groupComboBox->currentItem() == m_DCOP || groupComboBox->currentItem() == m_Slots)
return TQString("%1%2.%3%4").arg(prefix).arg(widgetComboBox->currentText().section(' ', 0, 0))
.arg(functionListBox->currentText().left(functionListBox->currentText().find('('))).arg(params());
else
return TQString("%1%2%3%4").arg(prefix).arg(function)
.arg(functionListBox->currentText()).arg(params());
}
void FunctionsDialog::groupChanged(int index)
{
index = groupComboBox->currentItem();
functionListBox->clear();
m_slotList.clear();
if (index == m_Slots)
{
KommanderWidget* a_atw = dynamic_cast<KommanderWidget *>(m_widgetList[widgetComboBox->currentText()]);
TQStringList pFunctions = TQStringList::fromStrList(a_atw->object()->metaObject()->slotNames(true));
for (uint i=0; i<pFunctions.count(); i++)
{
TQString slot = pFunctions[i];
TQString slotArgStr = slot.section(TQRegExp("\\(|\\)"), 1);
if (slotArgStr.isEmpty() || m_acceptedSlots.contains(slotArgStr))
{
TQString name = slot.remove("()");
if (!m_slotList.contains(name))
{
m_slotList[name] = slot;
functionListBox->insertItem(name);
}
}
}
} else
{
TQString s = (index != m_DCOP ) ? groupComboBox->text(index) : "DCOP";
TQStringList pFunctions = SpecialInformation::functions(s);
KommanderWidget* a_atw = 0;
if (index == m_DCOP)
a_atw = dynamic_cast<KommanderWidget *>(m_widgetList[widgetComboBox->currentText()]);
int pGroup = SpecialInformation::group(s);
SpecialFunction::ParserType pType = m_useInternalParser
? SpecialFunction::InternalParser : SpecialFunction::MacroParser;
for (uint i=0; i<pFunctions.count(); i++)
{
int pFunction = SpecialInformation::function(pGroup, pFunctions[i]);
if (!SpecialInformation::isValid(pGroup, pFunction, pType))
continue;
if (a_atw && !a_atw->isFunctionSupported(pFunction) && !a_atw->isCommonFunction(pFunction))
continue;
functionListBox->insertItem(pFunctions[i]);
}
}
functionListBox->sort();
functionListBox->setCurrentItem(0);
functionChanged(functionListBox->currentItem());
}
void FunctionsDialog::functionChanged(int)
{
if (groupComboBox->currentItem() == m_Slots)
{
KommanderWidget* w = dynamic_cast<KommanderWidget *>(m_widgetList[widgetComboBox->currentText()]);
TQObject *o = w->object();
TQString slotHelp = i18n("To learn more about the slot, look at the documentation of the base TQt/TDE class, most probably <i>%1</i>.").arg(o->metaObject()->superClassName() ? TQString(o->metaObject()->superClassName()) : TQString(o->className()) );
TQString slotName = functionListBox->currentText();
TQString slot = m_slotList[slotName];
descriptionText->clear();
descriptionText->setText(i18n("<qt><h3>%1</h3>"
"<p><b>Description:</b> %2\n<p><b>Syntax:</b> <i>%3</i>%4</qt>")
.arg(slotName).arg(slotHelp).arg(slot).arg(""));
} else
{
int index = groupComboBox->currentItem();
TQString s = (index != m_DCOP ) ? groupComboBox->text(index) : "DCOP";
m_function = SpecialInformation::functionObject(s,
functionListBox->currentText());
TQString defArgs;
if (m_function.minArg() < m_function.argumentCount())
if (!m_function.minArg())
defArgs = i18n("<p>Parameters are not obligatory.");
else
defArgs = i18n("<p>Only first argument is obligatory.",
"<p>Only first %n arguments are obligatory.",
m_function.minArg());
uint pflags = SpecialFunction::ShowArgumentNames;
if (m_function.maxArg() && m_function.argumentName(0) == "widget")
pflags = pflags | SpecialFunction::SkipFirstArgument;
descriptionText->clear();
descriptionText->setText(i18n("<qt><h3>%1</h3>"
"<p><b>Description:</b> %2\n<p><b>Syntax:</b> <i>%3</i>%4</qt>")
.arg(functionListBox->currentText()).arg(m_function.description())
.arg(m_function.prototype(pflags)).arg(defArgs));
}
showParameters();
}
void FunctionsDialog::copyText()
{
TQString text = currentFunctionText();
int para, i;
insertedText->getCursorPosition(&para, &i);
// int cursorPos = insertedText->cursorPosition();
insertedText->insert(text);
insertedText->setCursorPosition(para, i + text.find('(') + 1);
}
void FunctionsDialog::showParameters()
{
KLineEdit* edits[MaxFunctionArgs] = {arg1Edit, arg2Edit, arg3Edit, arg4Edit, arg5Edit, arg6Edit};
TQLabel* labels[MaxFunctionArgs] = {argLabel1, argLabel2, argLabel3, argLabel4, argLabel5, argLabel6};
KComboBox* combos[MaxFunctionArgs] = {combo1, combo2, combo3, combo4, combo5, combo6};
TQCheckBox* quotes[MaxFunctionArgs] = {quote1, quote2, quote3, quote4, quote5, quote6};
if (groupComboBox->currentItem() == m_Slots)
{
widgetComboBox->setShown(true);
widgetLabel->setShown(true);
TQString slot = m_slotList[functionListBox->currentText()];
TQStringList slotArgs = TQStringList::split(',', slot.section(TQRegExp("\\(|\\)"), 1), false);
int argsCount = slotArgs.count();
for (int i = 0; i < MaxFunctionArgs; i++)
{
labels[i]->setShown(i < argsCount);
TQString type;
if (i < argsCount)
{
type = slotArgs[i].remove(TQRegExp("\\*|\\&|const\\s"));
labels[i]->setText(TQString("%1:").arg(type));
}
quotes[i]->setChecked(true);
quotes[i]->setShown(false);
if (type == "bool")
{
edits[i]->setShown(false);
combos[i]->setShown(i < argsCount);
combos[i]->clear();
combos[i]->setEditable(false);
combos[i]->insertItem("true");
combos[i]->insertItem("false");
} else
{
combos[i]->setShown(false);
edits[i]->setShown(i < argsCount);
edits[i]->clear();
if (type == "TQString")
{
quotes[i]->setShown(i < argsCount);
}
}
}
} else
{
int start = (m_function.argumentCount() && m_function.argumentName(0) == "widget");
widgetComboBox->setShown(start);
widgetLabel->setShown(start);
if (start)
{
arg1Edit->setShown(false);
argLabel1->setShown(false);
combo1->setShown(false);
quote1->setShown(false);
}
int argsCount = m_function.argumentCount();
for (int i=start; i<MaxFunctionArgs; i++)
{
labels[i]->setShown(i < argsCount);
if (i < argsCount)
labels[i]->setText(TQString("%1:").arg(m_function.argumentName(i)));
quotes[i]->setChecked(true);
quotes[i]->setShown(false);
if (m_function.argumentType(i) == "bool")
{
edits[i]->setShown(false);
combos[i]->setShown(i < argsCount);
combos[i]->setEditable(false);
combos[i]->clear();
combos[i]->insertItem("true");
combos[i]->insertItem("false");
} else
{
//FIXME: big hack to show a combo for createWidgets. Good solution: extra flag for arguments telling if it is a file/widget/etc.
if (m_function.name() == "createWidget" && ( i == 1 || i == 2))
{
combos[i]->clear();
combos[i]->setEditable(true);
if ( i == 1)
{
combos[i]->insertStringList(m_widgetTypes);
} else
{
combos[i]->insertItem("");
combos[i]->insertStringList(m_widgetNames);
}
edits[i]->setShown(false);
combos[i]->setShown(true);
} else
{
combos[i]->setShown(false);
edits[i]->setShown(i < argsCount);
edits[i]->clear();
if (m_function.argumentType(i) == "TQString")
{
quotes[i]->setShown(i < argsCount);
}
}
}
}
}
}
TQString FunctionsDialog::params()
{
TQLabel* labels[MaxFunctionArgs] = {argLabel1, argLabel2, argLabel3, argLabel4, argLabel5, argLabel6};
KLineEdit* edits[MaxFunctionArgs] = {arg1Edit, arg2Edit, arg3Edit, arg4Edit, arg5Edit, arg6Edit};
KComboBox* combos[MaxFunctionArgs] = {combo1, combo2, combo3, combo4, combo5, combo6};
TQStringList pars;
TQCheckBox* quotes[MaxFunctionArgs] = {quote1, quote2, quote3, quote4, quote5, quote6};
bool params = false;
bool slotsShown = (groupComboBox->currentItem() == m_Slots);
for (int i=0; i<MaxFunctionArgs; i++)
{
if (edits[i]->isShown())
{
TQString s = edits[i]->text();
if (!s.isEmpty() || i < m_function.minArg())
{
if (quotes[i]->isChecked() && ( (!slotsShown && m_function.argumentType(i) == "TQString")
|| (slotsShown && labels[i]->text().startsWith("TQString")) ) )
s = '"' + s + '"';
pars.append(s);
}
params = true;
} else
if (combos[i]->isShown())
{
TQString s = combos[i]->currentText();
if (!s.isEmpty() || i < m_function.minArg())
{
if (s != "true" && s !="false")
s = '"' + s + '"';
pars.append(s);
}
params = true;
}
}
TQString a_param = pars.join(", ");
if (params)
return TQString("(%1)").arg(a_param);
else
return a_param;
}
#include "functionsimpl.moc"