aboutsummaryrefslogtreecommitdiffstats
path: root/src/modules/classeditor/ClassEditorWindow.cpp
diff options
context:
space:
mode:
authorGravatar Szymon Tomasz Stefanek2011-01-01 20:19:56 +0000
committerGravatar Szymon Tomasz Stefanek2011-01-01 20:19:56 +0000
commitc601b5a27f74b16158adafe429faefbe573e64a2 (patch)
treea3cde3206a45628f8ac86e8dfbdab70b20c3a831 /src/modules/classeditor/ClassEditorWindow.cpp
parentprobable compilation fix for rijndaled/crypto++ (diff)
downloadKVIrc-c601b5a27f74b16158adafe429faefbe573e64a2.tar.gz
KVIrc-c601b5a27f74b16158adafe429faefbe573e64a2.tar.bz2
KVIrc-c601b5a27f74b16158adafe429faefbe573e64a2.zip
The big rename for modules. Still some details remaining.
git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@5284 17fca916-40b9-46aa-a4ea-0a15b648b75c
Diffstat (limited to 'src/modules/classeditor/ClassEditorWindow.cpp')
-rw-r--r--src/modules/classeditor/ClassEditorWindow.cpp2101
1 files changed, 2101 insertions, 0 deletions
diff --git a/src/modules/classeditor/ClassEditorWindow.cpp b/src/modules/classeditor/ClassEditorWindow.cpp
new file mode 100644
index 000000000..95ae67111
--- /dev/null
+++ b/src/modules/classeditor/ClassEditorWindow.cpp
@@ -0,0 +1,2101 @@
+//=============================================================================
+//
+// File : ClassEditorWindow.cpp
+// Creation date : Mon Feb 15 2010 14:35:55 CEST by Carbone Alessandro
+//
+// This file is part of the KVIrc irc client distribution
+// Copyright (C) 2010 Alessandro Carbone (elfonol at gmail dot com)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under the linkss of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your opinion) 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.
+//
+//=============================================================================
+
+
+#include "ClassEditorWindow.h"
+
+#include "KviIconManager.h"
+#include "KviOptions.h"
+#include "KviLocale.h"
+#include "KviImageDialog.h"
+#include "KviConfigurationFile.h"
+#include "KviFileDialog.h"
+#include "KviFileUtils.h"
+#include "KviScriptEditor.h"
+#include "kvi_debug.h"
+#include "KviApplication.h"
+#include "KviMainWindow.h"
+#include "KviQString.h"
+#include "KviKvsKernel.h"
+#include "KviKvsObjectClass.h"
+#include "KviKvsObjectController.h"
+#include "KviFileDialog.h"
+#include "KviCommandFormatter.h"
+#include "KviModule.h"
+#include "KviTalVBox.h"
+#include "kvi_fileextensions.h"
+#include "KviModuleManager.h"
+
+#include <QList>
+#include <QSplitter>
+#include <QLayout>
+#include <QToolTip>
+#include <QPushButton>
+#include <QDir>
+#include <QMessageBox>
+#include <QInputDialog>
+#include <QRegExp>
+#include <QMouseEvent>
+#include <QPainter>
+#include <QBrush>
+#include <QStringList>
+#include <QLabel>
+
+extern ClassEditorWindow * g_pClassEditorWindow;
+extern KviModule * g_pClassEditorModule;
+
+ClassEditorTreeWidget::ClassEditorTreeWidget(QWidget * pParent)
+: QTreeWidget(pParent)
+{
+ setColumnCount (1);
+ setHeaderLabel(__tr2qs_ctx("Class","editor"));
+ setSelectionMode(QAbstractItemView::ExtendedSelection);
+ setSortingEnabled(true);
+ setRootIsDecorated(true);
+ setAnimated(true);
+}
+
+ClassEditorTreeWidget::~ClassEditorTreeWidget()
+{
+ //remove and delete all items
+ clear();
+}
+
+void ClassEditorTreeWidget::mousePressEvent(QMouseEvent * e)
+{
+ if(e->button() == Qt::RightButton)
+ {
+ QTreeWidgetItem * pItem = itemAt(e->pos());
+ if(pItem)
+ emit rightButtonPressed(pItem,QCursor::pos());
+ }
+ QTreeWidget::mousePressEvent(e);
+}
+
+ClassEditorTreeWidgetItem::ClassEditorTreeWidgetItem(QTreeWidget * pTreeWidget, Type eType, const QString & szName)
+: QTreeWidgetItem(pTreeWidget), KviHeapObject(), m_eType(eType)
+{
+ setName(szName);
+ m_szInheritsClassName = "";
+ m_iPos = 0;
+ m_bInternal = false;
+ m_bClassModified = false;
+ QPixmap * pIcon = 0;
+
+ if(eType == ClassEditorTreeWidgetItem::Namespace)
+ pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE);
+ else
+ pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS);
+
+ setIcon(0,QIcon(*pIcon));
+}
+
+ClassEditorTreeWidgetItem::ClassEditorTreeWidgetItem(ClassEditorTreeWidgetItem * pParentItem, Type eType, const QString & szName)
+: QTreeWidgetItem(pParentItem), m_eType(eType)
+{
+ setFlags(Qt::ItemIsEditable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
+ setName(szName);
+ m_szInheritsClassName = "";
+ m_bInternal = false;
+ m_iPos = 0;
+ m_bClassModified = false;
+ QPixmap * pIcon = 0;
+
+ if(eType == ClassEditorTreeWidgetItem::Namespace)
+ pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE);
+ else if(eType == ClassEditorTreeWidgetItem::Class)
+ pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS);
+ else
+ pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_FUNCTION);
+
+ setIcon(0,QIcon(*pIcon));
+}
+
+void ClassEditorTreeWidgetItem::setClassNotBuilt(bool bModified)
+{
+ m_bClassModified = bModified;
+ QPixmap * pIcon = 0;
+
+ if(bModified)
+ pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASSNOTBUILT);
+ else
+ pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS);
+
+ setIcon(0,QIcon(*pIcon));
+}
+
+void ClassEditorTreeWidgetItem::setName(const QString & szName)
+{
+ m_szName = szName;
+ setText(0,m_szName);
+}
+
+void ClassEditorTreeWidgetItem::setType(Type eType)
+{
+ m_eType = eType;
+ QPixmap * pIcon = 0;
+
+ if(eType == ClassEditorTreeWidgetItem::Namespace)
+ pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE);
+ else if(eType == ClassEditorTreeWidgetItem::Class)
+ pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS);
+ else
+ pIcon = g_pIconManager->getSmallIcon(KVI_SMALLICON_FUNCTION);
+
+ setIcon(0,QIcon(*pIcon));
+}
+
+ClassEditorWidget::ClassEditorWidget(QWidget * pParent)
+: QWidget(pParent)
+{
+ m_pClasses = new KviPointerHashTable<QString,ClassEditorTreeWidgetItem>(100,false);
+ m_pClasses->setAutoDelete(false);
+ m_pLastEditedItem = 0;
+ m_pLastClickedItem = 0;
+ m_szDir = QDir::homePath();
+
+ QGridLayout * pLayout = new QGridLayout(this);
+
+ m_pSplitter = new QSplitter(Qt::Horizontal,this);
+ m_pSplitter->setChildrenCollapsible(false);
+ pLayout->addWidget(m_pSplitter,0,0);
+
+ KviTalVBox * pVBox = new KviTalVBox(m_pSplitter);
+ pVBox->setSpacing(0);
+ pVBox->setMargin(0);
+ m_pTreeWidget = new ClassEditorTreeWidget(pVBox);
+
+ pVBox = new KviTalVBox(m_pSplitter);
+
+ KviTalHBox * pHBox = new KviTalHBox(pVBox);
+ pHBox->setSpacing(0);
+ pHBox->setMargin(0);
+ m_pClassNameLabel = new QLabel(__tr2qs_ctx("No item selected","editor"),pHBox);
+ pHBox->setStretchFactor(m_pClassNameLabel,2);
+ m_pClassNameLabel->setWordWrap(true);
+ m_pClassNameRenameButton = new QPushButton(__tr2qs_ctx("Rename","editor"),pHBox);
+ m_pClassNameRenameButton->setToolTip(__tr2qs_ctx("Edit the class or namespace name","editor"));
+ m_pClassNameRenameButton->setEnabled(false);
+ connect(m_pClassNameRenameButton,SIGNAL(clicked()),this,SLOT(renameItem()));
+
+ pHBox = new KviTalHBox(pVBox);
+ pHBox->setSpacing(0);
+ pHBox->setMargin(0);
+
+ pHBox = new KviTalHBox(pVBox);
+ pHBox->setSpacing(0);
+ pHBox->setMargin(0);
+ m_pFunctionNameLabel = new QLabel(__tr2qs_ctx("No item selected","editor"),pHBox);
+ pHBox->setStretchFactor(m_pFunctionNameLabel,2);
+ m_pFunctionNameRenameButton = new QPushButton(__tr2qs_ctx("Rename","editor"),pHBox);
+ m_pFunctionNameRenameButton->setToolTip(__tr2qs_ctx("Edit the function member name","editor"));
+ m_pFunctionNameRenameButton->setEnabled(false);
+ connect(m_pFunctionNameRenameButton,SIGNAL(clicked()),this,SLOT(renameFunction()));
+
+ m_pReminderLabel = new QLabel(__tr2qs_ctx("No item selected","editor"),pVBox);
+ m_pReminderLabel->hide();
+ m_pReminderLabel->setWordWrap(true);
+
+ m_pEditor = KviScriptEditor::createInstance(pVBox);
+ m_pEditor->setFocus();
+ connect(m_pEditor,SIGNAL(find(const QString &)),this,SLOT(slotFindWord(const QString &)));
+ connect(m_pEditor,SIGNAL(replaceAll(const QString &,const QString &)),this,SLOT(slotReplaceAll(const QString &,const QString &)));
+ m_pContextPopup = new KviTalPopupMenu(this);
+
+ oneTimeSetup();
+
+ currentItemChanged(0,0);
+}
+
+ClassEditorWidget::~ClassEditorWidget()
+{
+ m_pClasses->clear();
+ delete m_pClasses;
+}
+
+void ClassEditorWidget::buildFullItemPath(ClassEditorTreeWidgetItem * pItem, QString & szBuffer)
+{
+ if(!pItem)
+ return;
+ szBuffer.prepend(pItem->name() + "::");
+ pItem = (ClassEditorTreeWidgetItem *)pItem->parent();
+ while(pItem)
+ {
+ QString szTmp = pItem->name();
+ if(!szTmp.isEmpty())
+ {
+ szBuffer.prepend("::");
+ szBuffer.prepend(szTmp);
+ }
+ pItem = (ClassEditorTreeWidgetItem *)pItem->parent();
+ }
+}
+
+QString ClassEditorWidget::buildFullClassName(ClassEditorTreeWidgetItem * pItem)
+{
+ if(!pItem)
+ return QString();
+ QString szName = pItem->name();
+ ClassEditorTreeWidgetItem * pNItem = (ClassEditorTreeWidgetItem *)pItem->parent();
+ while(pNItem)
+ {
+ QString szTmp = pNItem->name();
+ if(!szTmp.isEmpty())
+ {
+ szName.prepend("::");
+ szName.prepend(szTmp);
+ }
+ pNItem = (ClassEditorTreeWidgetItem *)pNItem->parent();
+ }
+ return szName;
+}
+
+ClassEditorTreeWidgetItem * ClassEditorWidget::findTopLevelItem(const QString & szName)
+{
+ for(int i=0; i < m_pTreeWidget->topLevelItemCount(); i++)
+ {
+ if(KviQString::equalCI(m_pTreeWidget->topLevelItem(i)->text(0),szName))
+ return (ClassEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i);
+ }
+ return 0;
+}
+
+ClassEditorTreeWidgetItem * ClassEditorWidget::findItem(const QString & szFullName)
+{
+ bool bFound;
+ QStringList lNamespaces = szFullName.split("::");
+ if(lNamespaces.count() == 0)
+ return 0;
+ ClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0));
+ if(!pItem)
+ return 0;
+
+ for(int i=1; i < lNamespaces.count(); i++)
+ {
+ bFound = false;
+ for(int j=0; j < pItem->childCount(); j++)
+ {
+ if (KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i)))
+ {
+ pItem=( ClassEditorTreeWidgetItem *)pItem->child(j);
+ bFound = true;
+ break;
+ }
+ }
+ if(!bFound)
+ return 0;
+ }
+ return (ClassEditorTreeWidgetItem *)pItem;
+}
+
+ClassEditorTreeWidgetItem * ClassEditorWidget::createFullItem(const QString & szFullName)
+{
+ bool bFound;
+ int i;
+
+ QStringList lNamespaces = szFullName.split("::");
+ if(lNamespaces.count() == 0)
+ return 0;
+ if(lNamespaces.count() == 1)
+ {
+ ClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0));
+ if(pItem)
+ return pItem;
+ return new ClassEditorTreeWidgetItem(m_pTreeWidget,ClassEditorTreeWidgetItem::Class,lNamespaces.at(0));
+ }
+ ClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0));
+ if(!pItem)
+ pItem = new ClassEditorTreeWidgetItem(m_pTreeWidget,ClassEditorTreeWidgetItem::Namespace,lNamespaces.at(0));
+
+ for(i=1; i < lNamespaces.count()-1; i++)
+ {
+ bFound = false;
+ for(int j=0; j < pItem->childCount();j++)
+ {
+ if(KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i)))
+ {
+ pItem = (ClassEditorTreeWidgetItem *)pItem->child(j);
+ bFound = true;
+ break;
+ }
+ }
+ if(!bFound)
+ pItem = new ClassEditorTreeWidgetItem(pItem,ClassEditorTreeWidgetItem::Namespace,lNamespaces.at(i));
+ }
+ return new ClassEditorTreeWidgetItem(pItem,ClassEditorTreeWidgetItem::Class,lNamespaces.at(i));
+}
+
+ClassEditorTreeWidgetItem * ClassEditorWidget::createFullNamespace(const QString & szFullName)
+{
+ bool bFound;
+ int i;
+
+ QStringList lNamespaces = szFullName.split("::");
+ if(lNamespaces.count() == 0)
+ return 0;
+ ClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0));
+ if(!pItem)
+ pItem = new ClassEditorTreeWidgetItem(m_pTreeWidget,ClassEditorTreeWidgetItem::Namespace,lNamespaces.at(0));
+ if(lNamespaces.count() == 1)
+ return pItem;
+
+ for(i=1; i < lNamespaces.count(); i++)
+ {
+ bFound = false;
+ for(int j=0;j<pItem->childCount();j++)
+ {
+ if(KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i)) && (( ClassEditorTreeWidgetItem *)pItem->child(j))->isNamespace())
+ {
+ pItem = (ClassEditorTreeWidgetItem *)pItem->child(j);
+ bFound = true;
+ break;
+ }
+ }
+ if(!bFound)
+ pItem = new ClassEditorTreeWidgetItem(pItem,ClassEditorTreeWidgetItem::Namespace,lNamespaces.at(i));
+ }
+ return pItem;
+}
+
+void ClassEditorWidget::oneTimeSetup()
+{
+ QStringList sl;
+ QString szClassName;
+ QString szPath;
+ g_pApp->getLocalKvircDirectory(szPath,KviApplication::Classes);
+ QDir d(szPath);
+
+ QString szExtension = QString("*%1").arg(KVI_FILEEXTENSION_SCRIPT); // *.kvs
+ sl = d.entryList(QStringList(szExtension), QDir::Files | QDir::NoDotAndDotDot);
+
+ g_pModuleManager->getModule("objects");
+ KviPointerHashTableIterator<QString,KviKvsObjectClass> it(*KviKvsKernel::instance()->objectController()->classDict());
+
+ KviKvsObjectClass * pClass = 0;
+ ClassEditorTreeWidgetItem * pClassItem = 0;
+ while(KviKvsObjectClass * pClass = it.current())
+ {
+ if(pClass->isBuiltin())
+ m_pClasses->insert(it.currentKey(),0);
+ else
+ {
+ QString szTmp;
+ szTmp = it.currentKey();
+ szTmp.replace("::","--");
+ szTmp.append(".kvs");
+ if(sl.indexOf(szTmp) == -1)
+ {
+ szClassName = it.currentKey();
+ pClassItem = createFullItem(szClassName);
+ createFullClass(it.current(),pClassItem,szClassName);
+ }
+ }
+ ++it;
+ }
+
+ for(int i=0; i < sl.count(); i++)
+ {
+ szClassName = sl.at(i);
+ szClassName.replace("--","::");
+ szClassName.chop(4);
+ pClassItem = createFullItem(szClassName);
+ pClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName);
+ if(pClass)
+ createFullClass(pClass, pClassItem, szClassName);
+ }
+ loadNotBuiltClasses();
+ connect(m_pTreeWidget,SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)));
+ m_pTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(m_pTreeWidget,SIGNAL(customContextMenuRequested(const QPoint &)),this,SLOT(customContextMenuRequested(const QPoint &)));
+}
+
+void ClassEditorWidget::createFullClass(KviKvsObjectClass * pClass, ClassEditorTreeWidgetItem * pClassItem, const QString & szClassName)
+{
+ KviPointerHashTableIterator<QString,KviKvsObjectFunctionHandler> it(* pClass->getHandlers());
+ QStringList szFunctionsList;
+ while(it.current())
+ {
+ szFunctionsList.append(it.currentKey());
+ ++it;
+ }
+ szFunctionsList.sort();
+ ClassEditorTreeWidgetItem *pFunctionItem;
+ m_pClasses->insert(szClassName,pClassItem);
+ KviKvsObjectClass * pParentClass = pClass->parentClass();
+ pClassItem->setInheritsClass(pParentClass->name());
+ for(int i=0;i<szFunctionsList.count();i++)
+ {
+ QString szCode;
+ KviKvsObjectFunctionHandler *pHandler=pClass->lookupFunctionHandler(szFunctionsList.at(i));
+ if (pClass->isScriptHandler(szFunctionsList.at(i)) && !pHandler->isClone())
+ {
+ pFunctionItem=findFunction(szFunctionsList.at(i), pClassItem);
+ if(!pFunctionItem) pFunctionItem = new ClassEditorTreeWidgetItem(pClassItem,ClassEditorTreeWidgetItem::Method,szFunctionsList.at(i));
+ pClass->getFunctionCode(szCode,*pHandler);
+ pFunctionItem->setBuffer(szCode);
+ pFunctionItem->setReminder(pClass->reminder(pHandler));
+ if(pHandler->flags() & KviKvsObjectFunctionHandler::Internal)
+ pFunctionItem->setInternalFunction(true);
+ }
+ //++it;
+ }
+}
+
+
+/*
+void ClassEditorWidget::classRefresh(const QString & szName)
+{
+ if(m_bSaving)
+ return;
+ ClassEditorTreeWidgetItem * item;
+ KviKvsScript * class = KviKvsClassManager::instance()->classDict()->find(szName);
+ item = createFullItem(szName);
+ if(item!=m_pLastEditedItem)
+ {
+ item->setBuffer(class->code());
+ return;
+ }
+ if(
+ QMessageBox::warning(0,__tr2qs_ctx("OverWrite Current Class","editor"),
+ __tr2qs_ctx("An external script has changed the class you are currently editing. Do you want to accept the external changes?","editor"),
+ QMessageBox::Yes,QMessageBox::No|QMessageBox::Default|QMessageBox::Escape) != QMessageBox::Yes
+ )
+ return;
+ item->setBuffer(class->code());
+ m_pEditor->setText(class->code());
+}
+*/
+
+bool ClassEditorWidget::hasSelectedItems()
+{
+ return m_pTreeWidget->selectedItems().count() ? 1 : 0;
+}
+
+bool ClassEditorWidget::classExists(QString & szFullItemName)
+{
+ if(m_pClasses->find(szFullItemName))
+ return true;
+ else
+ return false;
+}
+
+void ClassEditorWidget::renameFunction()
+{
+ if(!m_pLastEditedItem)
+ return;
+ ClassEditorTreeWidgetItem * pFunction = m_pLastEditedItem;
+ QString szClassName = buildFullClassName((ClassEditorTreeWidgetItem *)pFunction->parent());
+ QString szFunctionName = pFunction->name();
+ QString szReminder = pFunction->reminder();
+ QString szNewReminder = szReminder;
+ ClassEditorTreeWidgetItem * pParentClass = (ClassEditorTreeWidgetItem *) pFunction->parent();
+
+ QString szNewFunctionName = szFunctionName;
+ bool bInternal = pFunction->isInternalFunction();
+ if(!askForFunction(szNewFunctionName,szNewReminder,&bInternal,szClassName,true))
+ return;
+ if(KviQString::equalCS(szFunctionName,szNewFunctionName) && bInternal == pFunction->isInternalFunction())
+ {
+ if(!KviQString::equalCS(szNewReminder,szReminder))
+ {
+ pFunction->setReminder(szNewReminder);
+ KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName);
+ if(pClass)
+ {
+ KviKvsObjectFunctionHandler * pHandler = pClass->lookupFunctionHandler(szFunctionName);
+ if(pHandler)
+ {
+ pClass->setReminder(szNewReminder,pHandler);
+ QString szPath;
+ QString szFileName = szClassName.toLower();
+ szFileName += ".kvs";
+ szFileName.replace("::","--");
+ g_pApp->getLocalKvircDirectory(szPath,KviApplication::Classes,szFileName);
+ pClass->save(szPath);
+ }
+ }
+ currentItemChanged(pFunction,pFunction);
+ } else {
+ g_pClassEditorModule->lock();
+ QMessageBox::information(this,
+ __tr2qs_ctx("Function already exists","editor"),
+ __tr2qs_ctx("This name is already in use. Please choose another one.","editor"),
+ __tr2qs_ctx("Ok, Let me try again...","editor"));
+ g_pClassEditorModule->unlock();
+ return;
+ }
+ }
+
+ pFunction->setName(szNewFunctionName);
+ pFunction->setReminder(szNewReminder);
+ currentItemChanged(pFunction,pFunction);
+ pFunction->setInternalFunction(bInternal);
+ pParentClass->setClassNotBuilt(true);
+
+ KviPointerList<ClassEditorTreeWidgetItem> lInheritedClasses;
+ lInheritedClasses.setAutoDelete(false);
+ searchInheritedClasses(szClassName,lInheritedClasses);
+ for(unsigned int i=0; i < lInheritedClasses.count(); i++)
+ lInheritedClasses.at(i)->setClassNotBuilt(true);
+ activateItem(pFunction);
+}
+
+ClassEditorTreeWidgetItem * ClassEditorWidget::findFunction(const QString & szFunctionName, ClassEditorTreeWidgetItem * pClass)
+{
+ for(int i=0; i < pClass->childCount(); i++)
+ {
+ if(KviQString::equalCI(szFunctionName,((ClassEditorTreeWidgetItem *)pClass->child(i))->name()))
+ return (ClassEditorTreeWidgetItem *) pClass->child(i);
+ }
+ return 0;
+}
+
+void ClassEditorWidget::renameItem()
+{
+ if(!m_pLastEditedItem)
+ return;
+ if(m_pLastEditedItem->isClass())
+ renameClass(m_pLastEditedItem);
+ else if(m_pLastEditedItem->isNamespace())
+ renameNamespace(m_pLastEditedItem);
+ else {
+ // is function
+ ClassEditorTreeWidgetItem * pParent = (ClassEditorTreeWidgetItem *)m_pLastEditedItem->parent();
+ if(pParent->isClass())
+ renameClass(pParent);
+ }
+}
+
+void ClassEditorWidget::renameClass(ClassEditorTreeWidgetItem * pClassItem)
+{
+ QString szClassName = buildFullClassName(pClassItem);
+ QString szNewClassName = szClassName;
+
+ QString szInheritsClassName = pClassItem->inheritsClass();
+ QString szNewInheritsClassName = szInheritsClassName;
+ bool bOk = askForClassName(szNewClassName,szNewInheritsClassName,true);
+ if(!bOk)
+ return;
+ if(classExists(szNewClassName) && KviQString::equalCS(szClassName,szNewClassName) && KviQString::equalCS(szInheritsClassName,szNewInheritsClassName))
+ {
+ g_pClassEditorModule->lock();
+ QMessageBox::information(this,
+ __tr2qs_ctx("Class already exists","editor"),
+ __tr2qs_ctx("This name is already in use. Please choose another one.","editor"),
+ __tr2qs_ctx("Ok, Let me try again...","editor"));
+ g_pClassEditorModule->unlock();
+ return;
+ }
+ /*if(szNewClassName.tmp.indexOf("@@",Qt::CaseInsensitive) != -1)
+ {
+ g_pClassEditorModule->lock();
+ QMessageBox::information(this,
+ __tr2qs_ctx("Bad Namespace Name","editor"),
+ __tr2qs_ctx("Found an empty namespace in namespace name","editor"),
+ __tr2qs_ctx("Ok, Let me try again...","editor"));
+ g_pClassEditorModule->unlock();
+ szNewName = "";
+ continue;
+ }*/
+ ClassEditorTreeWidgetItem * pNewItem = 0;
+ m_pClasses->removeRef(pClassItem);
+ cutItem(pClassItem);
+ if(szNewClassName.contains("::"))
+ {
+ pNewItem = createFullNamespace(szNewClassName.left(szNewClassName.lastIndexOf("::")));
+ pClassItem->setName(szNewClassName.section("::",-1,-1));
+ pNewItem->addChild(pClassItem);
+ } else {
+ pClassItem->setName(szNewClassName);
+ m_pTreeWidget->addTopLevelItem(pClassItem);
+ }
+ m_pClasses->insert(szNewClassName,pClassItem);
+ pClassItem->setInheritsClass(szNewInheritsClassName);
+ pClassItem->setClassNotBuilt(true);
+
+ KviPointerList<ClassEditorTreeWidgetItem> lInheritedClasses;
+ lInheritedClasses.setAutoDelete(false);
+ searchInheritedClasses(szClassName,lInheritedClasses);
+ for(unsigned int i=0; i < lInheritedClasses.count(); i++)
+ {
+ lInheritedClasses.at(i)->setClassNotBuilt(true);
+ lInheritedClasses.at(i)->setExpanded(true);
+ lInheritedClasses.at(i)->setInheritsClass(szNewClassName);
+ }
+
+ if(pNewItem)
+ {
+ activateItem(pNewItem);
+ pNewItem->setExpanded(true);
+ } else {
+ activateItem(pClassItem);
+ pClassItem->setExpanded(true);
+ }
+
+ qDebug("delete class %s caused by rename",szClassName.toUtf8().data());
+ KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName);
+ if(pClass)
+ KviKvsKernel::instance()->objectController()->deleteClass(pClass);
+}
+
+void ClassEditorWidget::cutItem(ClassEditorTreeWidgetItem * pItem)
+{
+ int iIdx = m_pTreeWidget->indexOfTopLevelItem(pItem);
+ if(iIdx!=-1)
+ m_pTreeWidget->takeTopLevelItem(iIdx);
+ else {
+ ClassEditorTreeWidgetItem * pParent = (ClassEditorTreeWidgetItem *)pItem->parent();
+ pParent->removeChild(pItem);
+ }
+}
+
+void ClassEditorWidget::renameNamespace(ClassEditorTreeWidgetItem * pOldNamespaceItem)
+{
+ QString szOldNameSpaceName = buildFullClassName(m_pLastEditedItem);
+ QString szNewNameSpaceName;
+ if(!askForNamespaceName(__tr2qs_ctx("Rename Namespace","editor"),__tr2qs_ctx("Please enter the new name for the namespace","editor"),szOldNameSpaceName,szNewNameSpaceName))
+ return;
+ if(KviQString::equalCI(szOldNameSpaceName,szNewNameSpaceName))
+ return;
+ ClassEditorTreeWidgetItem * pNewItem = findItem(szNewNameSpaceName);
+ if(pNewItem)
+ {
+ g_pClassEditorModule->lock();
+ if(pNewItem->isClass())
+ {
+ QMessageBox::information(this,
+ __tr2qs_ctx("Name already exists as Class name","editor"),
+ __tr2qs_ctx("This name is already in use as Class name. Please choose another one.","editor"),
+ __tr2qs_ctx("Ok, Let me try again...","editor"));
+ } else {
+ QMessageBox::information(this,
+ __tr2qs_ctx("Namespace already exists","editor"),
+ __tr2qs_ctx("This name is already in use. Please choose another one.","editor"),
+ __tr2qs_ctx("Ok, Let me try again...","editor"));
+ }
+ g_pClassEditorModule->unlock();
+ return;
+ }
+ KviPointerList<ClassEditorTreeWidgetItem> pList;
+ pList.setAutoDelete(false);
+ appendAllClassItemsRecursive(&pList,pOldNamespaceItem);
+ cutItem(pOldNamespaceItem);
+ if(szNewNameSpaceName.contains("::"))
+ {
+ pNewItem=createFullNamespace(szNewNameSpaceName.left(szNewNameSpaceName.lastIndexOf("::")));
+ pOldNamespaceItem->setName(szNewNameSpaceName.section("::",-1,-1));
+ pNewItem->addChild(pOldNamespaceItem);
+ } else {
+ m_pTreeWidget->addTopLevelItem(pOldNamespaceItem);
+ pOldNamespaceItem->setName(szNewNameSpaceName);
+ }
+ for(unsigned int u=0; u < pList.count(); u++)
+ {
+ KviPointerHashTableEntry<QString,ClassEditorTreeWidgetItem> * pEntry = m_pClasses->findRef(pList.at(u));
+ if(pEntry)
+ {
+ KviPointerList<ClassEditorTreeWidgetItem> lInheritedClasses;
+ lInheritedClasses.setAutoDelete(false);
+
+ QString szOldName = pEntry->key();
+ QString szNewName = buildFullClassName(pList.at(u));
+ searchInheritedClasses(szOldName,lInheritedClasses);
+ for(unsigned int v=0; v < lInheritedClasses.count(); v++)
+ {
+ lInheritedClasses.at(v)->setClassNotBuilt(true);
+ lInheritedClasses.at(v)->setExpanded(true);
+ lInheritedClasses.at(v)->setInheritsClass(szNewName);
+ }
+ m_pClasses->removeRef(pList.at(u));
+ m_pClasses->insert(szNewName,pList.at(u));
+ pList.at(u)->setClassNotBuilt(true);
+
+ KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szOldName);
+ if(pClass)
+ KviKvsKernel::instance()->objectController()->deleteClass(pClass);
+ }
+ }
+
+ if(pNewItem)
+ {
+ activateItem(pNewItem);
+ pNewItem->setExpanded(true);
+ } else {
+ activateItem(pOldNamespaceItem);
+ pOldNamespaceItem->setExpanded(true);
+ }
+ //searchReplace(szOldNameSpaceName+"::",true,szNewNameSpaceName+"::");
+}
+
+void ClassEditorWidget::saveLastEditedItem()
+{
+ if(!m_pLastEditedItem)
+ return;
+ if(!m_pEditor->isModified() || m_pLastEditedItem->isNamespace() || m_pLastEditedItem->isClass())
+ return;
+ ((ClassEditorTreeWidgetItem *)m_pLastEditedItem)->setCursorPosition(m_pEditor->getCursor());
+ QString newCode;
+ m_pEditor->getText(newCode);
+ ((ClassEditorTreeWidgetItem *)m_pLastEditedItem)->setBuffer(newCode);
+ ((ClassEditorTreeWidgetItem *)m_pLastEditedItem->parent())->setClassNotBuilt(true);
+}
+
+void ClassEditorWidget::currentItemChanged(QTreeWidgetItem * pTree, QTreeWidgetItem *)
+{
+ saveLastEditedItem();
+ m_pLastEditedItem = (ClassEditorTreeWidgetItem *)pTree;
+ if(!m_pLastEditedItem)
+ {
+ m_pClassNameLabel->setText(__tr2qs_ctx("No item selected","editor"));
+ m_pClassNameRenameButton->setEnabled(false);
+ m_pEditor->setText("");
+ m_pEditor->setEnabled(false);
+ return;
+ }
+
+ ClassEditorTreeWidgetItem * pClassItem = 0;
+ if(m_pLastEditedItem->isMethod())
+ pClassItem = (ClassEditorTreeWidgetItem *)m_pLastEditedItem->parent();
+ else
+ pClassItem = m_pLastEditedItem;
+
+ QString szClassName = buildFullClassName(pClassItem);
+
+ if(m_pLastEditedItem->isNamespace())
+ {
+ QString szLabelText = __tr2qs_ctx("Namespace","editor");
+ szLabelText += ": <b>";
+ szLabelText += szClassName;
+ szLabelText += "</b>";
+ m_pClassNameLabel->setText(szLabelText);
+ m_pClassNameRenameButton->setEnabled(true);
+ m_pFunctionNameRenameButton->setEnabled(false);
+ //m_pinheritsClassNameLabel->setText("");
+ m_pFunctionNameLabel->setText("");
+ m_pEditor->setText("");
+ m_pEditor->setEnabled(false);
+ m_pTreeWidget->setFocus();
+ return;
+ }
+
+ QString szLabelText = __tr2qs_ctx("Class","editor");
+ szLabelText += ": <b>";
+ szLabelText += szClassName;
+ szLabelText += "</b>, ";
+ szLabelText += __tr2qs_ctx("inherits from class ","editor");
+ szLabelText += ": <b>";
+ szLabelText += pClassItem->inheritsClass();
+ szLabelText += "</b>";
+ m_pClassNameLabel->setText(szLabelText);
+
+ szLabelText = __tr2qs_ctx("Member Function","editor");
+ if(m_pLastEditedItem->isMethod())
+ {
+ szLabelText += ": <b>";
+ szLabelText += m_pLastEditedItem->text(0);
+ szLabelText += "</b>";
+ m_pFunctionNameRenameButton->setEnabled(true);
+ if(m_pLastEditedItem->reminder().isEmpty())
+ m_pReminderLabel->hide();
+ else {
+ QString szReminderText =__tr2qs_ctx("Reminder text.","editor");
+ szReminderText += ": <b>";
+ szReminderText += m_pLastEditedItem->reminder();
+ szReminderText += "</b>";
+ m_pReminderLabel->setText(szReminderText);
+ m_pReminderLabel->show();
+ }
+
+ m_pFunctionNameLabel->setText(szLabelText);
+ m_pFunctionNameLabel->show();
+ m_pFunctionNameRenameButton->show();
+ } else {
+ m_pReminderLabel->hide();
+ m_pFunctionNameLabel->hide();
+ m_pClassNameRenameButton->setEnabled(true);
+ m_pFunctionNameRenameButton->hide();
+ }
+ if(m_pLastEditedItem->isClass())
+ {
+ m_pFunctionNameRenameButton->setEnabled(false);
+ m_pEditor->setText("");
+ m_pEditor->setEnabled(true);
+ m_pTreeWidget->setFocus();
+ QString szBuffer;
+ QStringList szFunctionsList;
+ KviPointerHashTable<QString,ClassEditorTreeWidgetItem> lFunctions;
+ lFunctions.setAutoDelete(false);
+
+ ClassEditorTreeWidgetItem * pItem = 0;
+ for(int i=0; i < pTree->childCount(); i++)
+ {
+ pItem = ((ClassEditorTreeWidgetItem *)pTree->child(i));
+ szFunctionsList.append(pItem->name());
+ lFunctions.insert(pItem->name(),pItem);
+ }
+ szFunctionsList.sort();
+ for(int i=0; i < szFunctionsList.count(); i++)
+ {
+ szBuffer += "Member Function: <b>$" + szFunctionsList.at(i) + "</b><br>";
+ if(!lFunctions.find(szFunctionsList.at(i))->reminder().isEmpty())
+ szBuffer+="Parameters reminder: "+lFunctions.find(szFunctionsList.at(i))->reminder()+"<br>";
+ szBuffer+="<br>";
+ }
+ m_pEditor->setUnHighlightedText(szBuffer);
+ m_pEditor->setReadOnly(true);
+ return;
+ }
+ m_pEditor->setReadOnly(false);
+ m_pEditor->setText(((ClassEditorTreeWidgetItem *)pTree)->buffer());
+ m_pEditor->setFocus();
+ m_pEditor->setCursorPosition(((ClassEditorTreeWidgetItem *)pTree)->cursorPosition());
+ m_pEditor->setEnabled(true);
+}
+
+void ClassEditorWidget::customContextMenuRequested(QPoint pnt)
+{
+ m_pContextPopup->clear();
+
+ m_pLastClickedItem = (ClassEditorTreeWidgetItem *)m_pTreeWidget->itemAt(pnt);
+
+ int iId;
+ iId = m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)),
+ __tr2qs_ctx("Add Namespace","editor"),
+ this,SLOT(newNamespace()));
+ if(!m_pLastClickedItem)
+ m_pContextPopup->setItemEnabled(iId,true);
+ else
+ m_pContextPopup->setItemEnabled(iId,m_pLastClickedItem->isNamespace());
+
+ iId = m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASS)),
+ __tr2qs_ctx("Add Class","editor"),
+ this,SLOT(newClass()));
+ if(!m_pLastClickedItem)
+ m_pContextPopup->setItemEnabled(iId,true);
+ else
+ m_pContextPopup->setItemEnabled(iId,m_pLastClickedItem->isNamespace());
+
+ iId = m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FUNCTION)),
+ __tr2qs_ctx("Add Member Function","editor"),
+ this,SLOT(newMemberFunction()));
+ if(!m_pLastClickedItem)
+ m_pContextPopup->setItemEnabled(iId,false);
+ else
+ m_pContextPopup->setItemEnabled(iId,m_pLastClickedItem->isClass()| m_pLastClickedItem->isMethod());
+
+ bool bHasItems = m_pTreeWidget->topLevelItemCount();
+ bool bHasSelected = hasSelectedItems();
+
+ m_pContextPopup->insertSeparator();
+
+ iId = m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),
+ __tr2qs_ctx("Remove Selected","editor"),
+ this,SLOT(removeSelectedItems()));
+ m_pContextPopup->setItemEnabled(iId,bHasSelected);
+
+ m_pContextPopup->insertSeparator();
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)),
+ __tr2qs_ctx("Export Selected...","editor"),
+ this,SLOT(exportSelected()));
+ m_pContextPopup->setItemEnabled(iId,bHasSelected);
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)),
+ __tr2qs_ctx("Export Selected in singles files...","editor"),
+ this,SLOT(exportSelectedSepFiles()));
+
+ m_pContextPopup->setItemEnabled(iId,bHasSelected);
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_FOLDER)),
+ __tr2qs_ctx("Export All...","editor"),
+ this,SLOT(exportAll()));
+ m_pContextPopup->setItemEnabled(iId,bHasItems);
+
+ m_pContextPopup->insertSeparator();
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_SEARCH)),
+ __tr2qs_ctx("Find In Classes...","editor"),
+ this,SLOT(slotFind()));
+ m_pContextPopup->setItemEnabled(iId,bHasItems);
+
+ m_pContextPopup->insertItem(
+ *(g_pIconManager->getSmallIcon(KVI_SMALLICON_NAMESPACE)),
+ __tr2qs_ctx("Collapse All Items","editor"),
+ this,SLOT(slotCollapseItems()));
+
+ m_pContextPopup->setItemEnabled(iId,bHasItems);
+ m_pContextPopup->popup(m_pTreeWidget->mapToGlobal(pnt));
+}
+
+void ClassEditorWidget::searchReplace(const QString & szSearch, bool bReplace, const QString & szReplace)
+{
+ KviPointerHashTableIterator<QString,ClassEditorTreeWidgetItem> it (*m_pClasses);
+ while(it.current())
+ {
+ ClassEditorTreeWidgetItem * pItem = it.current();
+ for(int j=0; j < pItem->childCount(); j++)
+ {
+ bool bOpened = false;
+ if(((ClassEditorTreeWidgetItem *)pItem->child(j))->buffer().indexOf(szSearch,0,Qt::CaseInsensitive) != -1)
+ {
+ pItem->child(j)->setBackground(0, QColor(255,0,0,128));
+ if(bReplace)
+ {
+ QString &buffer=(QString &)((ClassEditorTreeWidgetItem *)pItem->child(j))->buffer();
+ pItem->setClassNotBuilt(true);
+ buffer.replace(szSearch,szReplace,Qt::CaseInsensitive);
+ }
+ if(!bOpened)
+ {
+ openParentItems(pItem->child(j));
+ bOpened = true;
+ }
+ } else {
+ pItem->child(j)->setBackground(0, QColor(255,255,255));
+ }
+ }
+ ++it;
+ }
+}
+
+void ClassEditorWidget::slotFind()
+{
+ g_pClassEditorModule->lock();
+ bool bOk;
+
+ QString szSearch = QInputDialog::getText(this,
+ __tr2qs_ctx("Find In Classes","editor"),
+ __tr2qs_ctx("Please enter the text to be searched for. The matching function will be highlighted.","editor"),
+ QLineEdit::Normal,
+ "",
+ &bOk);
+
+ g_pClassEditorModule->unlock();
+ if(!bOk)
+ return;
+ if(szSearch.isEmpty())
+ return;
+ m_pEditor->setFindText(szSearch);
+ searchReplace(szSearch);
+}
+
+void ClassEditorWidget::slotFindWord(const QString & szSearch)
+{
+ m_pEditor->setFindText(szSearch);
+}
+
+void ClassEditorWidget::recursiveCollapseItems(ClassEditorTreeWidgetItem * pItem)
+{
+ if(!pItem)
+ return;
+ for(int i=0; i < pItem->childCount(); i++)
+ {
+ if(pItem->child(i)->childCount())
+ {
+ pItem->child(i)->setExpanded(false);
+ recursiveCollapseItems((ClassEditorTreeWidgetItem *)pItem->child(i));
+ }
+ }
+}
+
+void ClassEditorWidget::slotCollapseItems()
+{
+ for(int i=0; i < m_pTreeWidget->topLevelItemCount(); i++)
+ {
+ if(m_pTreeWidget->topLevelItem(i)->childCount())
+ {
+ m_pTreeWidget->topLevelItem(i)->setExpanded(false);
+ recursiveCollapseItems((ClassEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i));
+ }
+ }
+}
+
+void ClassEditorWidget::slotReplaceAll(const QString & szFind, const QString & szReplace)
+{
+ m_pEditor->setFindText(szReplace);
+ searchReplace(szFind,true,szReplace);
+ /*
+ for (int i=0;i<m_pTreeWidget->topLevelItemCount();i++)
+ {
+ recursiveSearchReplace(szFind,(ClassEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i),true,szReplace);
+ }
+ */
+}
+
+void ClassEditorWidget::exportClassBuffer(QString & szBuffer, ClassEditorTreeWidgetItem * pItem)
+{
+ QString szTmp = pItem->buffer();
+ KviCommandFormatter::blockFromBuffer(szTmp);
+ QString szName = buildFullClassName(pItem);
+
+ szBuffer = "class(\"";
+ szBuffer += szName;
+ if(!pItem->inheritsClass().isEmpty())
+ {
+ szBuffer += "\",\"";
+ szBuffer += pItem->inheritsClass();
+ }
+ szBuffer += "\")\n{\n";
+ for(int i=0; i < pItem->childCount(); i++)
+ {
+ ClassEditorTreeWidgetItem * pFunction = (ClassEditorTreeWidgetItem *)pItem->child(i);
+ if(pFunction->isMethod())
+ {
+ szBuffer += "\t";
+ if(pFunction->isInternalFunction())
+ szBuffer += "internal ";
+ szBuffer += "function ";
+ szBuffer += pFunction->name();
+ szBuffer += "(" + pFunction->reminder() + ")";
+ szBuffer += "\n\t{\n";
+ szBuffer += pFunction->buffer();
+ szBuffer += "\n\t}\n";
+ }
+ }
+ szBuffer += "}\n";
+}
+
+void ClassEditorWidget::exportAll()
+{
+ exportClasses(false);
+}
+
+void ClassEditorWidget::exportSelectedSepFiles()
+{
+ exportClasses(true,true);
+}
+
+void ClassEditorWidget::exportSelected()
+{
+ exportClasses(true);
+}
+
+void ClassEditorWidget::exportSelectionInSinglesFiles(KviPointerList<ClassEditorTreeWidgetItem> * pList)
+{
+ bool bReplaceAll = false;
+
+ if(!m_szDir.endsWith(QString(KVI_PATH_SEPARATOR)))
+ m_szDir += KVI_PATH_SEPARATOR;
+ if(!pList->first())
+ {
+ g_pClassEditorModule->lock();
+ QMessageBox::warning(this,__tr2qs_ctx("Class Export","editor"),__tr2qs_ctx("There is no selection!","editor"),__tr2qs_ctx("OK","editor"));
+ g_pClassEditorModule->unlock();
+ return;
+ }
+ g_pClassEditorModule->lock();
+
+ if(!KviFileDialog::askForDirectoryName(m_szDir,__tr2qs_ctx("Choose a Directory - KVIrc","editor"),m_szDir))
+ {
+ g_pClassEditorModule->unlock();
+ return;
+ }
+
+ if(!m_szDir.endsWith(QString(KVI_PATH_SEPARATOR)))
+ m_szDir += KVI_PATH_SEPARATOR;
+
+ for(ClassEditorTreeWidgetItem * pItem = pList->first(); pItem; pItem = pList->next())
+ {
+ QString szTmp;
+ exportClassBuffer(szTmp,pItem);
+ QString szFileName = buildFullClassName(pItem);
+ szFileName += ".kvs";
+ szFileName.replace("::","_");
+ QString szCompletePath = m_szDir+szFileName;
+ if(KviFileUtils::fileExists(szCompletePath) && !bReplaceAll)
+ {
+ QString szMsg = __tr2qs_ctx("The file \"%1\" exists. Do you want to replace it?","editor").arg(szFileName);
+ int iRet = QMessageBox::question(this,__tr2qs_ctx("Replace file","editor"),szMsg,__tr2qs_ctx("Yes","editor"),__tr2qs_ctx("Yes to All","editor"),__tr2qs_ctx("No","editor"));
+ if(iRet != 2)
+ {
+ KviFileUtils::writeFile(szCompletePath,szTmp);
+ if(iRet == 1)
+ bReplaceAll = true;
+ }
+ }
+ else
+ KviFileUtils::writeFile(szCompletePath,szTmp);
+ }
+ g_pClassEditorModule->unlock();
+}
+
+void ClassEditorWidget::exportClasses(bool bSelectedOnly, bool bSingleFiles)
+{
+ QString szOut;
+ QString szNameFile;
+ QString szFile;
+ int iCount = 0;
+
+ saveLastEditedItem();
+
+ KviPointerList<ClassEditorTreeWidgetItem> list;
+ list.setAutoDelete(false);
+
+ if(bSelectedOnly)
+ appendSelectedClassItems(&list);
+ else
+ appendAllClassItems(&list);
+
+ if(bSingleFiles)
+ {
+ exportSelectionInSinglesFiles(&list);
+ return;
+ }
+
+ ClassEditorTreeWidgetItem * pTempItem = 0;
+ for(ClassEditorTreeWidgetItem * pItem = list.first(); pItem; pItem = list.next())
+ {
+ pTempItem = pItem;
+ iCount++;
+ QString szTmp;
+ exportClassBuffer(szTmp,pItem);
+ szOut += szTmp;
+ szOut += "\n";
+ }
+
+ if(szOut.isEmpty())
+ {
+ g_pClassEditorModule->lock();
+ QMessageBox::warning(this,__tr2qs_ctx("Class Export","editor"),__tr2qs_ctx("The exported file would be empty: cowardly refusing to write it","editor"),__tr2qs_ctx("OK","editor"));
+ g_pClassEditorModule->unlock();
+ return;
+ }
+
+ QString szName = m_szDir;
+
+ if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))
+ szName += KVI_PATH_SEPARATOR;
+
+ g_pClassEditorModule->lock();
+
+ if(iCount != 1)
+ szNameFile = "classes";
+ else {
+ QString szTmp = buildFullClassName(pTempItem);
+ szNameFile = szTmp.replace("::","_");
+ }
+
+ szName += szNameFile;
+ szName += ".kvs";
+ if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs_ctx("Choose a Filename - KVIrc","editor"),szName,KVI_FILTER_SCRIPT,false,true,true))
+ {
+ g_pClassEditorModule->unlock();
+ return;
+ }
+ m_szDir=QFileInfo(szFile).absolutePath();
+ g_pClassEditorModule->unlock();
+
+ if(!KviFileUtils::writeFile(szFile,szOut))
+ {
+ g_pClassEditorModule->lock();
+ QMessageBox::warning(this,__tr2qs_ctx("Write Failed - KVIrc","editor"),__tr2qs_ctx("Unable to write to the class file.","editor"),__tr2qs_ctx("OK","editor"));
+ g_pClassEditorModule->unlock();
+ }
+}
+
+void ClassEditorWidget::saveProperties(KviConfigurationFile * pCfg)
+{
+ pCfg->writeEntry("Sizes",m_pSplitter->sizes());
+ QString szName;
+ if(m_pLastEditedItem)
+ szName = buildFullClassName(m_pLastEditedItem);
+ pCfg->writeEntry("LastClass",szName);
+}
+
+void ClassEditorWidget::loadProperties(KviConfigurationFile * pCfg)
+{
+ QList<int> def;
+ def.append(20);
+ def.append(80);
+ m_pSplitter->setSizes(pCfg->readIntListEntry("Sizes",def));
+ QString szTmp = pCfg->readEntry("LastClass",QString());
+
+ ClassEditorTreeWidgetItem * pItem = findItem(szTmp);
+ activateItem(pItem);
+}
+
+void ClassEditorWidget::appendSelectedClassItems(KviPointerList<ClassEditorTreeWidgetItem> * pList)
+{
+ QList<QTreeWidgetItem *> list = m_pTreeWidget->selectedItems();
+ for(int i=0; i < list.count(); i++)
+ {
+ if(((ClassEditorTreeWidgetItem *)list.at(i))->isClass())
+ pList->append((ClassEditorTreeWidgetItem *)list.at(i));
+ else appendSelectedClassItemsRecursive(pList,list.at(i));
+ }
+}
+
+void ClassEditorWidget::appendSelectedClassItemsRecursive(KviPointerList<ClassEditorTreeWidgetItem> * pList, QTreeWidgetItem * pStartFrom)
+{
+ for(int i=0; i < pStartFrom->childCount(); i++)
+ {
+ if(((ClassEditorTreeWidgetItem *)pStartFrom->child(i))->isClass())
+ pList->append(((ClassEditorTreeWidgetItem *)pStartFrom->child(i)));
+ else
+ appendSelectedClassItemsRecursive(pList,pStartFrom->child(i));
+ }
+}
+
+void ClassEditorWidget::appendAllClassItems(KviPointerList<ClassEditorTreeWidgetItem> * pList)
+{
+ KviPointerHashTableIterator<QString,ClassEditorTreeWidgetItem> it (*m_pClasses);
+ while(it.current())
+ {
+ pList->append(it.current());
+ ++it;
+ }
+}
+
+void ClassEditorWidget::appendAllClassItemsRecursive(KviPointerList<ClassEditorTreeWidgetItem> * pList, QTreeWidgetItem * pStartFrom)
+{
+ for(int i=0; i < pStartFrom->childCount(); i++)
+ {
+ if(((ClassEditorTreeWidgetItem *)pStartFrom->child(i))->isClass())
+ {
+ pList->append((ClassEditorTreeWidgetItem *)pStartFrom->child(i));
+ } else {
+ appendAllClassItemsRecursive(pList,pStartFrom->child(i));
+ }
+ }
+}
+
+void ClassEditorWidget::removeItemChildren(ClassEditorTreeWidgetItem * pItem, KviPointerList <ClassEditorTreeWidgetItem> & lRemovedItems)
+{
+ if(pItem->isClass())
+ {
+ KviPointerList<ClassEditorTreeWidgetItem> lInheritedClasses;
+ lInheritedClasses.setAutoDelete(false);
+ searchInheritedClasses(buildFullClassName(pItem),lInheritedClasses);
+ for(unsigned int u=0; u < lInheritedClasses.count(); u++)
+ {
+ lInheritedClasses.at(u)->setClassNotBuilt(true);
+ lInheritedClasses.at(u)->setExpanded(true);
+ lInheritedClasses.at(u)->setInheritsClass("object");
+ }
+ }
+
+ while(pItem->childCount() > 0)
+ {
+ ClassEditorTreeWidgetItem * pChild = (ClassEditorTreeWidgetItem *)(pItem->child(0));
+ if(pChild->childCount())
+ removeItemChildren(pChild,lRemovedItems);
+ if(pChild->isClass())
+ {
+ m_pClasses->removeRef(pChild);
+ KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(buildFullClassName(pChild));
+ if(pClass)
+ KviKvsKernel::instance()->objectController()->deleteClass(pClass);
+ qDebug("removing class %s %p",buildFullClassName(pChild).toUtf8().data(), pClass);
+ }
+ pItem->removeChild(pChild);
+ lRemovedItems.append(pItem);
+ delete pChild;
+ }
+}
+
+bool ClassEditorWidget::removeItem(ClassEditorTreeWidgetItem * pItem, KviPointerList <ClassEditorTreeWidgetItem> & lRemovedItems, bool * pbYesToAll)
+{
+ if(!pItem)
+ return true;
+ QString szMsg;
+ QString szName = pItem->name();
+
+ if(!*pbYesToAll)
+ {
+ saveLastEditedItem();
+ if(pItem->isClass())
+ {
+ KviQString::sprintf(szMsg,__tr2qs_ctx("Do you really want to remove the class \"%Q\" ?","editor"),&szName);
+ } else if(pItem->isNamespace())
+ {
+ KviQString::sprintf(szMsg,__tr2qs_ctx("Do you really want to remove the namespace \"%Q\" ?","editor"),&szName);
+ szMsg += "<br>";
+ szMsg += __tr2qs_ctx("Please note that all the children classes/functions will be deleted too.","editor");
+ } else if(pItem->isMethod())
+ {
+ KviQString::sprintf(szMsg,__tr2qs_ctx("Do you really want to remove the function \"%Q\" ?","editor"),&szName);
+ }
+
+ g_pClassEditorModule->lock();
+ int iRet = QMessageBox::question(this,__tr2qs_ctx("Remove item","editor"),szMsg,__tr2qs_ctx("Yes","editor"),__tr2qs_ctx("Yes to All","editor"),__tr2qs_ctx("No","editor"));
+ g_pClassEditorModule->unlock();
+ switch(iRet)
+ {
+ case 0:
+ // nothing
+ break;
+ case 1:
+ *pbYesToAll = true;
+ break;
+ default:
+ return false;
+ break;
+ }
+ }
+
+ if(pItem == m_pLastEditedItem)
+ m_pLastEditedItem = 0;
+ if(pItem == m_pLastClickedItem)
+ m_pLastClickedItem = 0;
+ if(pItem->childCount())
+ removeItemChildren(pItem,lRemovedItems);
+ if(pItem->isClass())
+ {
+ m_pClasses->removeRef(pItem);
+ KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(buildFullClassName(pItem));
+ qDebug("rimuovo class %s %p",buildFullClassName(pItem).toUtf8().data(), pClass);
+ if(pClass)
+ KviKvsKernel::instance()->objectController()->deleteClass(pClass);
+ else
+ {
+ QString szFileName = buildFullClassName(pItem);
+ szFileName.replace("::","--");
+ szFileName.append(KVI_FILEEXTENSION_SCRIPT);
+ QString szPath;
+ g_pApp->getLocalKvircDirectory(szPath,KviApplication::Classes);
+ QDir d(szPath);
+ if(d.exists(szFileName))
+ {
+ qDebug("rimuovo dal disco il file %s",szFileName.toUtf8().data());
+ d.remove(szFileName);
+ }
+ }
+ }
+ if(pItem->isMethod())
+ {
+ updateClassHierarchy((ClassEditorTreeWidgetItem *)pItem->parent());
+ }
+ lRemovedItems.append(pItem);
+ delete pItem;
+ return true;
+}
+
+void ClassEditorWidget::updateClassHierarchy(ClassEditorTreeWidgetItem * pClass)
+{
+ pClass->setClassNotBuilt(true);
+ KviPointerList<ClassEditorTreeWidgetItem> lInheritedClasses;
+ lInheritedClasses.setAutoDelete(false);
+ searchInheritedClasses(pClass->name(),lInheritedClasses);
+ for(unsigned int u=0; u < lInheritedClasses.count(); u++)
+ {
+ lInheritedClasses.at(u)->setClassNotBuilt(true);
+ lInheritedClasses.at(u)->setInheritsClass(pClass->name());
+ lInheritedClasses.at(u)->setExpanded(true);
+ }
+}
+
+void ClassEditorWidget::removeSelectedItems()
+{
+ KviPointerList<ClassEditorTreeWidgetItem> lRemovedItems;
+ lRemovedItems.setAutoDelete(false);
+ QList<QTreeWidgetItem *> list = m_pTreeWidget->selectedItems();
+ bool bYesToAll = false;
+ for(int i=0; i < list.count(); i++)
+ {
+ if(lRemovedItems.findRef((ClassEditorTreeWidgetItem *) list.at(i)) != -1)
+ continue;
+ if(!removeItem((ClassEditorTreeWidgetItem *) list.at(i),lRemovedItems,&bYesToAll))
+ return;
+ }
+}
+
+bool ClassEditorWidget::askForClassName(QString & szClassName, QString & szInheritsClassName, bool bEdit)
+{
+ KviClassEditorDialog * pDialog = new KviClassEditorDialog(this,"classdialog",m_pClasses,szClassName,szInheritsClassName,bEdit);
+ szClassName = "";
+ g_pClassEditorModule->lock();
+ bool bOk = pDialog->exec();
+ g_pClassEditorModule->unlock();
+ if(bOk)
+ {
+ szClassName = pDialog->className();
+ szInheritsClassName = pDialog->inheritsClassName();
+ delete pDialog;
+ return true;
+ }
+ delete pDialog;
+ return false;
+}
+
+bool ClassEditorWidget::askForFunction(QString & szFunctionName, QString & szReminder, bool * bInternal, const QString & szClassName, bool bRenameMode)
+{
+ KviClassEditorFunctionDialog * pDialog = new KviClassEditorFunctionDialog(this,"function",szClassName,szFunctionName,szReminder,*bInternal, bRenameMode);
+ szFunctionName = "";
+ g_pClassEditorModule->lock();
+ bool bOk = pDialog->exec();
+ g_pClassEditorModule->unlock();
+ if(bOk)
+ {
+ szFunctionName = pDialog->functionName();
+ szReminder = pDialog->reminder();
+ *bInternal = pDialog->isInternalFunction();
+ delete pDialog;
+ return true;
+ }
+ delete pDialog;
+ return false;
+}
+
+bool ClassEditorWidget::askForNamespaceName(const QString & szAction, const QString & szText, const QString & szInitialText, QString & szNewName)
+{
+ bool bOk = false;
+ while(szNewName.isEmpty())
+ {
+ g_pClassEditorModule->lock();
+ szNewName = QInputDialog::getText(this,
+ szAction,
+ szText,
+ QLineEdit::Normal,
+ szInitialText,
+ &bOk);
+ g_pClassEditorModule->unlock();
+ if(!bOk)
+ return false;
+ if(szNewName.isEmpty())
+ {
+ g_pClassEditorModule->lock();
+ QMessageBox::warning(this,
+ __tr2qs_ctx("Missing Namespace Name","editor"),
+ __tr2qs_ctx("You must specify a valid name for the namespace","editor"),
+ __tr2qs_ctx("Ok, Let me try again...","editor"));
+ g_pClassEditorModule->unlock();
+ continue;
+ }
+
+ // we allow only [\w:]+
+ QRegExp re("[\\w:]+");
+ if(!re.exactMatch(szNewName))
+ {
+ g_pClassEditorModule->lock();
+ QMessageBox::information(this,
+ __tr2qs_ctx("Bad Namespace Name","editor"),
+ __tr2qs_ctx("Namespace names can contain only letters, digits, underscores and '::' namespace separators","editor"),
+ __tr2qs_ctx("Ok, Let me try again...","editor"));
+ g_pClassEditorModule->unlock();
+ szNewName = "";
+ continue;
+ }
+ // make sure that we have only doubled "::" and not ":" or ":::..."
+ QString szTmp = szNewName;
+ szTmp.replace("::","@"); // @ is not allowed by the rule above
+ if(szTmp.indexOf(":",Qt::CaseInsensitive) != -1)
+ {
+ g_pClassEditorModule->lock();
+ QMessageBox::information(this,
+ __tr2qs_ctx("Bad Namespace Name","editor"),
+ __tr2qs_ctx("Stray ':' character in namespace name: did you mean ...<namespace>::<name> ?","editor"),
+ __tr2qs_ctx("Ok, Let me try again...","editor"));
+ g_pClassEditorModule->unlock();
+ szNewName = "";
+ continue;
+ }
+ if(szTmp.indexOf("@@",Qt::CaseInsensitive) != -1)
+ {
+ g_pClassEditorModule->lock();
+ QMessageBox::information(this,
+ __tr2qs_ctx("Bad Namespace Name","editor"),
+ __tr2qs_ctx("Found an empty namespace in namespace name","editor"),
+ __tr2qs_ctx("Ok, Let me try again...","editor"));
+ g_pClassEditorModule->unlock();
+ szNewName = "";
+ continue;
+ }
+ }
+ return true;
+}
+
+void ClassEditorWidget::openParentItems(QTreeWidgetItem * pItem)
+{
+ if(pItem->parent())
+ {
+ pItem->parent()->setExpanded(true);
+ openParentItems(pItem->parent());
+ }
+}
+
+void ClassEditorWidget::activateItem(QTreeWidgetItem * pItem)
+{
+ if(!pItem)
+ return;
+ openParentItems(pItem);
+ m_pTreeWidget->setCurrentItem(pItem);
+}
+
+void ClassEditorWidget::newClass()
+{
+ QString szClassName;
+ QString szinheritsClassName;
+ askForClassName(szClassName,szinheritsClassName,false);
+ if(szClassName.isEmpty())
+ return;
+ ClassEditorTreeWidgetItem * pItem = newItem(szClassName,ClassEditorTreeWidgetItem::Class);
+
+ KviQString::escapeKvs(&szClassName, KviQString::EscapeSpace);
+ KviQString::escapeKvs(&szinheritsClassName, KviQString::EscapeSpace);
+
+ QString szClass = "class(";
+ szClass += szClassName + "," + szinheritsClassName;
+ szClass += "){}\n";
+ pItem->setInheritsClass(szinheritsClassName);
+ activateItem(pItem);
+ m_pClasses->insert(szClassName,pItem);
+ KviKvsScript::run(szClass,g_pActiveWindow);
+}
+
+void ClassEditorWidget::newNamespace()
+{
+ QString szName;
+ if(!askForNamespaceName(__tr2qs_ctx("Add Namespace","editor"),__tr2qs_ctx("Please enter the name for the new namespace","editor"),"mynamespace",szName))
+ return;
+ if(szName.isEmpty())
+ return;
+ ClassEditorTreeWidgetItem * pItem = newItem(szName,ClassEditorTreeWidgetItem::Namespace);
+ activateItem(pItem);
+}
+
+void ClassEditorWidget::newMemberFunction()
+{
+ QString szFunctionName;
+ QString szClassName;
+ QString szReminder;
+
+ if(m_pLastClickedItem->isMethod())
+ m_pLastClickedItem = (ClassEditorTreeWidgetItem*)m_pLastClickedItem->parent();
+ szClassName = buildFullClassName(m_pLastClickedItem);
+ bool bInternal = false;
+ if(!askForFunction(szFunctionName, szReminder,&bInternal,szClassName,false))
+ return;
+ if(szFunctionName.isEmpty())
+ return;
+
+ ClassEditorTreeWidgetItem * pItem = newItem(szFunctionName,ClassEditorTreeWidgetItem::Method);
+ pItem->setInternalFunction(bInternal);
+ if(!szReminder.isEmpty())
+ pItem->setReminder(szReminder);
+ activateItem(pItem);
+ ((ClassEditorTreeWidgetItem*)pItem->parent())->setClassNotBuilt(true);
+}
+
+ClassEditorTreeWidgetItem * ClassEditorWidget::newItem(QString & szName, ClassEditorTreeWidgetItem::Type eType)
+{
+ if(m_pLastClickedItem)
+ buildFullItemPath(m_pLastClickedItem,szName);
+
+ QString szTmp;
+ if(findItem(szName))
+ szName.append("1");
+
+ int iIdx = 2;
+ while(findItem(szName))
+ {
+ szTmp.setNum(iIdx);
+ szName.chop(szTmp.length());
+ szName.append(szTmp);
+ iIdx++;
+ }
+ ClassEditorTreeWidgetItem * pItem;
+ pItem = createFullItem(szName);
+ pItem->setType(eType);
+ return pItem;
+}
+
+void ClassEditorWidget::build()
+{
+ saveLastEditedItem();
+ KviPointerHashTableIterator<QString,ClassEditorTreeWidgetItem> it (*m_pClasses);
+ KviPointerList<ClassEditorTreeWidgetItem> linkedClasses;
+ linkedClasses.setAutoDelete(false);
+ KviPointerList<ClassEditorTreeWidgetItem> skipClasses;
+ skipClasses.setAutoDelete(false);
+ bool bErrorWhilecompiling = false;
+ while(it.current())
+ {
+ ClassEditorTreeWidgetItem * pClass = it.current();
+ if(skipClasses.findRef(it.current()) != -1)
+ {
+ ++it;
+ continue;
+ }
+ if(pClass->classNotBuilt())
+ {
+ //qDebug("compiling %s",pClass->name().toUtf8().data());
+ ClassEditorTreeWidgetItem * pParentClass = m_pClasses->find(pClass->inheritsClass());
+
+ linkedClasses.append(pClass);
+ //if (!pParentClass) qDebug("no parent class");
+ while(pParentClass)
+ {
+ if(pParentClass->classNotBuilt())
+ linkedClasses.append(pParentClass);
+ pParentClass = m_pClasses->find(pParentClass->inheritsClass());
+ }
+ for(int i = linkedClasses.count()-1; i >= 0; i--)
+ {
+ QString szFullClassName = buildFullClassName(linkedClasses.at(i));
+ KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szFullClassName);
+ if(pClass)
+ KviKvsKernel::instance()->objectController()->deleteClass(pClass);
+ QString szClass;
+ exportClassBuffer(szClass, linkedClasses.at(i));
+ KviKvsScript::run(szClass,g_pActiveWindow);
+ pClass = KviKvsKernel::instance()->objectController()->lookupClass(szFullClassName);
+ if(!pClass)
+ {
+ bErrorWhilecompiling = true;
+ QString szError = __tr2qs_ctx("Unable to compile class: ","editor");
+ szError += szFullClassName + "\n";
+ KviPointerList<ClassEditorTreeWidgetItem> lInheritedClasses;
+ lInheritedClasses.setAutoDelete(false);
+ searchInheritedClasses(szFullClassName,lInheritedClasses);
+ if(lInheritedClasses.count())
+ {
+ szError += __tr2qs_ctx("These inherited classes will be not compiled too:","editor");
+ szError += "\n";
+ for(unsigned int u=0; u < lInheritedClasses.count(); u++)
+ {
+ szError += buildFullClassName(lInheritedClasses.at(u)) + "\n";
+ lInheritedClasses.at(u)->setClassNotBuilt(true);
+ skipClasses.append(lInheritedClasses.at(u));
+ }
+ }
+ QMessageBox::critical(this,__tr2qs_ctx("Compilation error - KVIrc","editor"),szError,
+ QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
+ break;
+ }
+ //else qDebug("class compiled %s :\n",szClass.toUtf8().data());
+ linkedClasses.at(i)->setClassNotBuilt(false);
+ m_pEditor->setModified(false);
+ }
+ }
+ ++it;
+ }
+ if(bErrorWhilecompiling)
+ saveNotBuiltClasses();
+ else {
+ QString szFileName = "libkviclasseditortmp.kvc";
+ QString szBuffer;
+ g_pApp->getLocalKvircDirectory(szBuffer,KviApplication::ConfigPlugins,szFileName);
+ KviConfigurationFile cfg(szBuffer,KviConfigurationFile::Write);
+ cfg.clear();
+ cfg.sync();
+ }
+ KviKvsKernel::instance()->objectController()->flushUserClasses();
+}
+
+void ClassEditorWidget::loadNotBuiltClasses()
+{
+ QString szFileName = "libkviclasseditortmp.kvc";
+ QString szBuffer;
+ g_pApp->getLocalKvircDirectory(szBuffer,KviApplication::ConfigPlugins,szFileName);
+ KviConfigurationFile cfg(szBuffer,KviConfigurationFile::Read);
+ KviConfigurationFileIterator it(*(cfg.dict()));
+
+ KviPointerList<QString> l;
+ l.setAutoDelete(true);
+
+ while(it.current())
+ {
+ l.append(new QString(it.currentKey()));
+ ++it;
+ }
+
+ for(QString * pszTmp = l.first(); pszTmp; pszTmp = l.next())
+ {
+ cfg.setGroup(*pszTmp);
+ ClassEditorTreeWidgetItem * pClassItem = createFullItem(*pszTmp);
+ m_pClasses->insert(*pszTmp,pClassItem);
+ pClassItem->setClassNotBuilt(true);
+ KviConfigurationFileGroup * pDict = cfg.dict()->find(*pszTmp);
+ if(pDict)
+ {
+ KviConfigurationFileGroupIterator it(*pDict);
+ KviPointerList<QString> names;
+ names.setAutoDelete(true);
+ while(it.current())
+ {
+ names.append(new QString(it.currentKey()));
+ ++it;
+ }
+ for(QString * pszTmp = names.first(); pszTmp; pszTmp = names.next())
+ {
+
+ if(KviQString::equalCI(*pszTmp,"@Inherits"))
+ {
+ pClassItem->setInheritsClass(cfg.readEntry(*pszTmp,""));
+ continue;
+ }
+ if((*pszTmp).left(9) == "@Reminder")
+ continue;
+ QString szCode = cfg.readEntry(*pszTmp,"");
+ ClassEditorTreeWidgetItem * pFunctionItem = findFunction(*pszTmp, pClassItem);
+ if(!pFunctionItem)
+ pFunctionItem = new ClassEditorTreeWidgetItem(pClassItem,ClassEditorTreeWidgetItem::Method,*pszTmp);
+ pFunctionItem->setBuffer(szCode);
+ QString szEntry = "@Reminder|" + (*pszTmp);
+ QString szReminder = cfg.readEntry(szEntry,"");
+ pFunctionItem->setReminder(szReminder);
+ }
+ }
+ }
+}
+
+void ClassEditorWidget::saveNotBuiltClasses()
+{
+ saveLastEditedItem();
+ KviPointerHashTableIterator<QString,ClassEditorTreeWidgetItem> it (*m_pClasses);
+ QString szFileName = "libkviclasseditortmp.kvc";
+ QString szBuffer;
+ g_pApp->getLocalKvircDirectory(szBuffer,KviApplication::ConfigPlugins,szFileName);
+ KviConfigurationFile cfg(szBuffer,KviConfigurationFile::Write);
+ cfg.clear();
+
+ while(it.current())
+ {
+ if(it.current()->classNotBuilt())
+ {
+ KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(it.currentKey());
+ if(pClass)
+ KviKvsKernel::instance()->objectController()->deleteClass(pClass);
+
+ cfg.setGroup(it.currentKey());
+ cfg.writeEntry("@Inherits",it.current()->inheritsClass());
+ QString szReminderEntry;
+ for(int i=0; i < it.current()->childCount(); i++)
+ {
+ if(!((ClassEditorTreeWidgetItem *)it.current()->child(i))->reminder().isEmpty())
+ {
+ szReminderEntry="@Reminder|"+((ClassEditorTreeWidgetItem *)it.current()->child(i))->name();
+ cfg.writeEntry(szReminderEntry,((ClassEditorTreeWidgetItem *)it.current()->child(i))->reminder());
+ }
+ cfg.writeEntry(((ClassEditorTreeWidgetItem *)it.current()->child(i))->name(),((ClassEditorTreeWidgetItem *)it.current()->child(i))->buffer());
+ }
+ }
+ ++it;
+ }
+ cfg.sync();
+}
+
+void ClassEditorWidget::searchInheritedClasses(const QString szClass, KviPointerList<ClassEditorTreeWidgetItem> & lInheritedClasses)
+{
+ KviPointerHashTableIterator<QString,ClassEditorTreeWidgetItem> it (*m_pClasses);
+ while(it.current())
+ {
+ if(KviQString::equalCI(szClass,it.current()->inheritsClass()))
+ lInheritedClasses.append(it.current());
+ ++it;
+ }
+}
+
+ClassEditorWindow::ClassEditorWindow(KviMainWindow * pFrm)
+: KviWindow(KVI_WINDOW_TYPE_SCRIPTEDITOR,pFrm,"classeditor",0)
+{
+ g_pClassEditorWindow = this;
+
+ setFixedCaption(__tr2qs_ctx("Class Editor","editor"));
+
+ QGridLayout * pLayout = new QGridLayout();
+
+ m_pEditor = new ClassEditorWidget(this);
+ pLayout->addWidget(m_pEditor,0,0,1,4);
+
+ QPushButton * pBtn = new QPushButton(__tr2qs_ctx("&Build","editor"),this);
+ pBtn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ pLayout->addWidget(pBtn,1,1);
+ connect(pBtn,SIGNAL(clicked()),this,SLOT(buildClicked()));
+
+ pBtn = new QPushButton(__tr2qs_ctx("&Save","editor"),this);
+ pBtn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_ACCEPT)));
+ pLayout->addWidget(pBtn,1,2);
+ connect(pBtn,SIGNAL(clicked()),this,SLOT(saveClicked()));
+
+ pBtn = new QPushButton(__tr2qs_ctx("Close","editor"),this);
+ pBtn->setIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_DISCARD)));
+ pLayout->addWidget(pBtn,1,3);
+ connect(pBtn,SIGNAL(clicked()),this,SLOT(cancelClicked()));
+
+ pLayout->setRowStretch(0,1);
+ pLayout->setColumnStretch(0,1);
+ setLayout(pLayout);
+}
+
+ClassEditorWindow::~ClassEditorWindow()
+{
+ g_pClassEditorWindow = 0;
+}
+
+void ClassEditorWindow::buildClicked()
+{
+ m_pEditor->build();
+}
+
+void ClassEditorWindow::saveClicked()
+{
+ m_pEditor->saveNotBuiltClasses();
+}
+
+void ClassEditorWindow::cancelClicked()
+{
+ close();
+}
+
+QPixmap * ClassEditorWindow::myIconPtr()
+{
+ return g_pIconManager->getSmallIcon(KVI_SMALLICON_CLASSEDITOR);
+}
+
+void ClassEditorWindow::configGroupName(QString &szName)
+{
+ szName = "classeditor";
+}
+
+void ClassEditorWindow::saveProperties(KviConfigurationFile * pCfg)
+{
+ m_pEditor->saveProperties(pCfg);
+}
+
+void ClassEditorWindow::loadProperties(KviConfigurationFile * pCfg)
+{
+ m_pEditor->loadProperties(pCfg);
+}
+
+KviClassEditorDialog::KviClassEditorDialog(QWidget * pParent, const QString & szName, KviPointerHashTable<QString,ClassEditorTreeWidgetItem> * pClasses, const QString & szClassName, const QString & szInheritsClassName, bool bRenameMode)
+: QDialog(pParent)
+{
+ setObjectName(szName);
+
+ QGridLayout * pLayout = new QGridLayout(this);
+
+ KviTalHBox * pHBox = new KviTalHBox(this);
+ pHBox->setSpacing(0);
+ pHBox->setMargin(0);
+ pLayout->addWidget(pHBox,0,0);
+
+ QLabel * pLabel = new QLabel(pHBox);
+ pLabel->setObjectName("classnamelabel");
+ pLabel->setText(__tr2qs_ctx("Please enter the name for the class:","editor"));
+
+ m_pClassNameLineEdit = new QLineEdit(pHBox);
+ m_pClassNameLineEdit->setObjectName("classnameineedit");
+ m_pClassNameLineEdit->setText(szClassName);
+ pLabel->setBuddy(m_pClassNameLineEdit);
+ QRegExp re;
+ if(!bRenameMode)
+ {
+ // we allow only [\w:]+ class name
+ re.setPattern("[\\w]+");
+ m_pClassNameLineEdit->setToolTip(__tr2qs_ctx("Class names can contain only letters, digits and underscores","editor"));
+ } else {
+ // in editor mode we allow [\w:]+ and namespace separator
+ re.setPattern("[\\w]+(::[\\w]+)+");
+ m_pClassNameLineEdit->setToolTip(__tr2qs_ctx("In rename mode class names can contain only letters, digits and underscores and namespaces :: separator","editor"));
+ }
+ QRegExpValidator * pValidator = new QRegExpValidator(re,this);
+ m_pClassNameLineEdit->setValidator(pValidator);
+ m_pClassNameLineEdit->setObjectName("functionameineedit");
+
+ pHBox = new KviTalHBox(this);
+ pHBox->setSpacing(0);
+ pHBox->setMargin(0);
+ pLayout->addWidget(pHBox,1,0);
+
+ pLabel = new QLabel(pHBox);
+ pLabel->setObjectName("Inheritsclasslabel");
+ pLabel->setText(__tr2qs_ctx("Inherits Class:","editor"));
+
+ m_pInheritsClassComboBox = new QComboBox(pHBox);
+ pLabel->setBuddy(m_pInheritsClassComboBox);
+
+ KviPointerHashTableIterator<QString,ClassEditorTreeWidgetItem> pClassesIt(*pClasses);
+
+ QStringList szClasses;
+ while(pClassesIt.current())
+ {
+ if(!KviQString::equalCI(pClassesIt.currentKey(),szClassName))
+ szClasses.append(pClassesIt.currentKey());
+ ++pClassesIt;
+ }
+ KviPointerHashTableIterator<QString,KviKvsObjectClass> pBuiltinClasses(*KviKvsKernel::instance()->objectController()->classDict());
+ while(pBuiltinClasses.current())
+ {
+ if(pBuiltinClasses.current()->isBuiltin())
+ szClasses.append(pBuiltinClasses.currentKey());
+ ++pBuiltinClasses;
+ }
+
+ int iCurrentIdx;
+ szClasses.sort();
+ for(int i=0; i < szClasses.count(); i++)
+ m_pInheritsClassComboBox->addItem(szClasses.at(i));
+ if(szInheritsClassName.isEmpty())
+ iCurrentIdx = m_pInheritsClassComboBox->findText("object");
+ else {
+ iCurrentIdx = m_pInheritsClassComboBox->findText(szInheritsClassName);
+ if(iCurrentIdx == -1)
+ iCurrentIdx = m_pInheritsClassComboBox->findText("object");
+ }
+ m_pInheritsClassComboBox->setCurrentIndex(iCurrentIdx);
+ m_pClassNameLineEdit->setFocus();
+ connect(m_pClassNameLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &)));
+
+ pHBox = new KviTalHBox(this);
+ pHBox->setSpacing(0);
+ pHBox->setMargin(0);
+ pLayout->addWidget(pHBox,2,0);
+
+ m_pNewClassButton = new QPushButton(pHBox);
+ m_pNewClassButton->setObjectName("newclassbutton");
+ if(bRenameMode)
+ m_pNewClassButton->setText(__tr2qs_ctx("&Rename Class","editor"));
+ else {
+ m_pNewClassButton->setText(__tr2qs_ctx("&Create Class","editor"));
+ m_pNewClassButton->setEnabled(false);
+ }
+ connect(m_pNewClassButton, SIGNAL(clicked()), this, SLOT(accept()));
+
+ QPushButton * pCancelButton = new QPushButton(pHBox);
+ pCancelButton->setObjectName("cancelButton");
+ pCancelButton->setText(__tr2qs_ctx("&Cancel","editor"));
+ connect(pCancelButton, SIGNAL(clicked()), this, SLOT(reject()));
+
+ setLayout(pLayout);
+}
+
+KviClassEditorDialog::~KviClassEditorDialog()
+{
+}
+
+void KviClassEditorDialog::textChanged(const QString & szText)
+{
+ m_pNewClassButton->setEnabled(!szText.isEmpty());
+}
+
+KviClassEditorFunctionDialog::KviClassEditorFunctionDialog(QWidget * pParent, const QString & szName, const QString & szClassName, const QString & szFunctionName, const QString & szReminder, bool bIsInternal, bool bRenameMode)
+: QDialog(pParent)
+{
+ setObjectName(szName);
+
+ QGridLayout * pLayout = new QGridLayout(this);
+
+ KviTalHBox * pHBox = new KviTalHBox(this);
+ pHBox->setSpacing(0);
+ pHBox->setMargin(0);
+ pLayout->addWidget(pHBox,0,0);
+
+ QLabel * pLabel = new QLabel(pHBox);
+ pLabel->setObjectName("classnamelabel");
+ pLabel->setText("Class: <b>"+szClassName+"</b>");
+
+ pHBox = new KviTalHBox(this);
+ pHBox->setSpacing(0);
+ pHBox->setMargin(0);
+ pLayout->addWidget(pHBox,1,0);
+
+ pLabel = new QLabel(pHBox);
+ pLabel->setObjectName("functionnamelabel");
+ pLabel->setText(__tr2qs_ctx("Please enter the name for the member function:","editor"));
+
+ m_pFunctionNameLineEdit = new QLineEdit(pHBox);
+
+ // we allow only [\w:]+ function name
+ QRegExp re("[\\w]+");
+ QRegExpValidator * pValidator = new QRegExpValidator(re,this);
+ m_pFunctionNameLineEdit->setValidator(pValidator);
+ m_pFunctionNameLineEdit->setObjectName("functionameineedit");
+ m_pFunctionNameLineEdit->setToolTip(__tr2qs_ctx("Function names can contain only letters, digits and underscores","editor"));
+ m_pFunctionNameLineEdit->setText(szFunctionName);
+ pLabel->setBuddy(m_pFunctionNameLineEdit);
+
+ pHBox = new KviTalHBox(this);
+ pHBox->setSpacing(0);
+ pHBox->setMargin(0);
+ pLayout->addWidget(pHBox,2,0);
+
+ pLabel = new QLabel(pHBox);
+ pLabel->setObjectName("reminderlabel");
+ pLabel->setWordWrap(1);
+ pLabel->setText(__tr2qs_ctx("Please enter the optional reminder string for the member function:","editor"));
+
+ m_pReminderLineEdit = new QLineEdit(pHBox);
+ m_pReminderLineEdit->setText(szReminder);
+ pLabel->setBuddy(m_pReminderLineEdit);
+
+ pHBox = new KviTalHBox(this);
+ pHBox->setSpacing(0);
+ pHBox->setMargin(0);
+ pLayout->addWidget(pHBox,3,0);
+
+ pLabel = new QLabel(pHBox);
+ pLabel->setObjectName("functionnamelabel");
+ pLabel->setText(__tr2qs_ctx("Set as <b>Internal</b> Function: ","editor"));
+
+ m_pInternalCheckBox = new QCheckBox(pHBox);
+ m_pInternalCheckBox->setChecked(bIsInternal);
+ m_pFunctionNameLineEdit->setFocus();
+ pLabel->setBuddy(m_pInternalCheckBox);
+ connect(m_pFunctionNameLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &)));
+
+ pHBox->setAlignment(m_pInternalCheckBox,Qt::AlignLeft);
+ pHBox->setStretchFactor(m_pInternalCheckBox,70);
+ pHBox->setStretchFactor(pLabel,30);
+
+ pHBox = new KviTalHBox(this);
+ pHBox->setSpacing(0);
+ pHBox->setMargin(0);
+ pLayout->addWidget(pHBox,4,0);
+
+ m_pNewFunctionButton = new QPushButton(pHBox);
+ m_pNewFunctionButton->setObjectName("newfunctionbutton");
+ if(!bRenameMode)
+ m_pNewFunctionButton->setText(__tr2qs_ctx("&Add","editor"));
+ else
+ m_pNewFunctionButton->setText(__tr2qs_ctx("&Rename","editor"));
+
+ if(szFunctionName.isEmpty())
+ m_pNewFunctionButton->setEnabled(false);
+ connect(m_pNewFunctionButton, SIGNAL(clicked()), this, SLOT(accept()));
+
+ QPushButton * pCancelButton = new QPushButton(pHBox);
+ pCancelButton->setObjectName("cancelButton");
+ pCancelButton->setText(__tr2qs_ctx("&Cancel","editor"));
+ connect(pCancelButton, SIGNAL(clicked()), this, SLOT(reject()));
+
+ setLayout(pLayout);
+}
+
+KviClassEditorFunctionDialog::~KviClassEditorFunctionDialog()
+{
+}
+
+void KviClassEditorFunctionDialog::textChanged(const QString & szText)
+{
+ m_pNewFunctionButton->setEnabled(!szText.isEmpty());
+}