~ubuntu-branches/ubuntu/trusty/kvirc/trusty

« back to all changes in this revision

Viewing changes to src/modules/classeditor/ClassEditorWindow.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Kai Wasserbäch, Kai Wasserbäch, Raúl Sánchez Siles
  • Date: 2011-02-12 10:40:21 UTC
  • mfrom: (14.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110212104021-5mh4f75jlku20mnt
The combined "Twisted Experiment" and "Nocturnal Raid" release.

[ Kai Wasserbäch ]
* Synced to upstream's SVN revision 5467.
* debian/rules:
  - Added .PHONY line.
  - Resurrect -DMANUAL_REVISION, got lost somewhere and we build SVN
    revisions again.
  - Replace "-DWITH_NO_EMBEDDED_CODE=YES" with "-DWANT_CRYPTOPP=YES".
  - Change the remaining -DWITH/-DWITHOUT to the new -DWANT syntax.
* debian/control:
  - Removed DMUA, I'm a DD now.
  - Changed my e-mail address.
  - Removed unneeded relationships (no upgrades over two releases are
    supported).
  - Fix Suggests for kvirc-dbg.
  - kvirc-data: Make the "Suggests: kvirc" a Recommends, doesn't make much
    sense to install the -data package without the program.
* debian/source/local-options: Added with "unapply-patches".
* debian/kvirc.lintian-overrides: Updated to work for 4.1.1.
* debian/patches/21_make_shared-mime-info_B-D_superfluous.patch: Updated.
* debian/kvirc-data.install: Added .notifyrc.

[ Raúl Sánchez Siles ]
* Stating the right version where kvirc-data break and replace should happen.
* Fixing link to license file.
* Added French and Portuguese man pages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//=============================================================================
 
2
//
 
3
//   File : ClassEditorWindow.cpp
 
4
//   Creation date : Mon Feb 15 2010 14:35:55 CEST by Carbone Alessandro
 
5
//
 
6
//   This file is part of the KVIrc irc client distribution
 
7
//   Copyright (C) 2010 Alessandro Carbone (elfonol at gmail dot com)
 
8
//
 
9
//   This program is FREE software. You can redistribute it and/or
 
10
//   modify it under the linkss of the GNU General Public License
 
11
//   as published by the Free Software Foundation; either version 2
 
12
//   of the License, or (at your opinion) any later version.
 
13
//
 
14
//   This program is distributed in the HOPE that it will be USEFUL,
 
15
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
17
//   See the GNU General Public License for more details.
 
18
//
 
19
//   You should have received a copy of the GNU General Public License
 
20
//   along with this program. If not, write to the Free Software Foundation,
 
21
//   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
22
//
 
23
//=============================================================================
 
24
 
 
25
 
 
26
#include "ClassEditorWindow.h"
 
27
 
 
28
#include "KviIconManager.h"
 
29
#include "KviOptions.h"
 
30
#include "KviLocale.h"
 
31
#include "KviImageDialog.h"
 
32
#include "KviConfigurationFile.h"
 
33
#include "KviFileDialog.h"
 
34
#include "KviFileUtils.h"
 
35
#include "KviScriptEditor.h"
 
36
#include "kvi_debug.h"
 
37
#include "KviApplication.h"
 
38
#include "KviMainWindow.h"
 
39
#include "KviQString.h"
 
40
#include "KviKvsKernel.h"
 
41
#include "KviKvsObjectClass.h"
 
42
#include "KviKvsObjectController.h"
 
43
#include "KviFileDialog.h"
 
44
#include "KviCommandFormatter.h"
 
45
#include "KviModule.h"
 
46
#include "KviTalVBox.h"
 
47
#include "kvi_fileextensions.h"
 
48
#include "KviModuleManager.h"
 
49
 
 
50
#include <QList>
 
51
#include <QSplitter>
 
52
#include <QLayout>
 
53
#include <QToolTip>
 
54
#include <QPushButton>
 
55
#include <QDir>
 
56
#include <QMessageBox>
 
57
#include <QInputDialog>
 
58
#include <QRegExp>
 
59
#include <QMouseEvent>
 
60
#include <QPainter>
 
61
#include <QBrush>
 
62
#include <QStringList>
 
63
#include <QLabel>
 
64
 
 
65
extern ClassEditorWindow * g_pClassEditorWindow;
 
66
extern KviModule * g_pClassEditorModule;
 
67
 
 
68
ClassEditorTreeWidget::ClassEditorTreeWidget(QWidget * pParent)
 
69
: QTreeWidget(pParent)
 
70
{
 
71
        setColumnCount (1);
 
72
        setHeaderLabel(__tr2qs_ctx("Class","editor"));
 
73
        setSelectionMode(QAbstractItemView::ExtendedSelection);
 
74
        setSortingEnabled(true);
 
75
        setRootIsDecorated(true);
 
76
        setAnimated(true);
 
77
}
 
78
 
 
79
ClassEditorTreeWidget::~ClassEditorTreeWidget()
 
80
{
 
81
        //remove and delete all items
 
82
        clear();
 
83
}
 
84
 
 
85
void ClassEditorTreeWidget::mousePressEvent(QMouseEvent * e)
 
86
{
 
87
        if(e->button() == Qt::RightButton)
 
88
        {
 
89
                QTreeWidgetItem * pItem = itemAt(e->pos());
 
90
                if(pItem)
 
91
                        emit rightButtonPressed(pItem,QCursor::pos());
 
92
        }
 
93
        QTreeWidget::mousePressEvent(e);
 
94
}
 
95
 
 
96
ClassEditorTreeWidgetItem::ClassEditorTreeWidgetItem(QTreeWidget * pTreeWidget, Type eType, const QString & szName)
 
97
: QTreeWidgetItem(pTreeWidget), KviHeapObject(), m_eType(eType)
 
98
{
 
99
        setName(szName);
 
100
        m_szInheritsClassName = "";
 
101
        m_iPos                = 0;
 
102
        m_bInternal           = false;
 
103
        m_bClassModified      = false;
 
104
        QPixmap * pIcon       = 0;
 
105
        
 
106
        if(eType == ClassEditorTreeWidgetItem::Namespace)
 
107
                pIcon = g_pIconManager->getSmallIcon(KviIconManager::NameSpace);
 
108
        else
 
109
                pIcon = g_pIconManager->getSmallIcon(KviIconManager::Class);
 
110
 
 
111
        setIcon(0,QIcon(*pIcon));
 
112
}
 
113
 
 
114
ClassEditorTreeWidgetItem::ClassEditorTreeWidgetItem(ClassEditorTreeWidgetItem * pParentItem, Type eType, const QString & szName)
 
115
: QTreeWidgetItem(pParentItem), m_eType(eType)
 
116
{
 
117
        setFlags(Qt::ItemIsEditable|Qt::ItemIsEnabled|Qt::ItemIsSelectable);
 
118
        setName(szName);
 
119
        m_szInheritsClassName = "";
 
120
        m_bInternal           = false;
 
121
        m_iPos                = 0;
 
122
        m_bClassModified      = false;
 
123
        QPixmap * pIcon       = 0;
 
124
        
 
125
        if(eType == ClassEditorTreeWidgetItem::Namespace)
 
126
                pIcon = g_pIconManager->getSmallIcon(KviIconManager::NameSpace);
 
127
        else if(eType == ClassEditorTreeWidgetItem::Class)
 
128
                pIcon = g_pIconManager->getSmallIcon(KviIconManager::Class);
 
129
        else
 
130
                pIcon = g_pIconManager->getSmallIcon(KviIconManager::Function);
 
131
        
 
132
        setIcon(0,QIcon(*pIcon));
 
133
}
 
134
 
 
135
void ClassEditorTreeWidgetItem::setClassNotBuilt(bool bModified)
 
136
{
 
137
        m_bClassModified = bModified;
 
138
        QPixmap * pIcon = 0;
 
139
        
 
140
        if(bModified)
 
141
                pIcon = g_pIconManager->getSmallIcon(KviIconManager::ClassNotBuilt);
 
142
        else
 
143
                pIcon = g_pIconManager->getSmallIcon(KviIconManager::Class);
 
144
        
 
145
        setIcon(0,QIcon(*pIcon));
 
146
}
 
147
 
 
148
void ClassEditorTreeWidgetItem::setName(const QString & szName)
 
149
{
 
150
        m_szName = szName;
 
151
        setText(0,m_szName);
 
152
}
 
153
 
 
154
void ClassEditorTreeWidgetItem::setType(Type eType)
 
155
{
 
156
        m_eType = eType;
 
157
        QPixmap * pIcon = 0;
 
158
        
 
159
        if(eType == ClassEditorTreeWidgetItem::Namespace)
 
160
                pIcon = g_pIconManager->getSmallIcon(KviIconManager::NameSpace);
 
161
        else if(eType == ClassEditorTreeWidgetItem::Class)
 
162
                pIcon = g_pIconManager->getSmallIcon(KviIconManager::Class);
 
163
        else
 
164
                pIcon = g_pIconManager->getSmallIcon(KviIconManager::Function);
 
165
        
 
166
        setIcon(0,QIcon(*pIcon));
 
167
}
 
168
 
 
169
ClassEditorWidget::ClassEditorWidget(QWidget * pParent)
 
170
: QWidget(pParent)
 
171
{
 
172
        m_pClasses = new KviPointerHashTable<QString,ClassEditorTreeWidgetItem>(100,false);
 
173
        m_pClasses->setAutoDelete(false);
 
174
        m_pLastEditedItem = 0;
 
175
        m_pLastClickedItem = 0;
 
176
        m_szDir = QDir::homePath();
 
177
 
 
178
        QGridLayout * pLayout = new QGridLayout(this);
 
179
 
 
180
        m_pSplitter = new QSplitter(Qt::Horizontal,this);
 
181
        m_pSplitter->setChildrenCollapsible(false);
 
182
        pLayout->addWidget(m_pSplitter,0,0);
 
183
 
 
184
        KviTalVBox * pVBox = new KviTalVBox(m_pSplitter);
 
185
        pVBox->setSpacing(0);
 
186
        pVBox->setMargin(0);
 
187
        m_pTreeWidget = new ClassEditorTreeWidget(pVBox);
 
188
 
 
189
        pVBox = new KviTalVBox(m_pSplitter);
 
190
 
 
191
        KviTalHBox * pHBox = new KviTalHBox(pVBox);
 
192
        pHBox->setSpacing(0);
 
193
        pHBox->setMargin(0);
 
194
        m_pClassNameLabel = new QLabel(__tr2qs_ctx("No item selected","editor"),pHBox);
 
195
        pHBox->setStretchFactor(m_pClassNameLabel,2);
 
196
        m_pClassNameLabel->setWordWrap(true);
 
197
        m_pClassNameRenameButton = new QPushButton(__tr2qs_ctx("Rename","editor"),pHBox);
 
198
        m_pClassNameRenameButton->setToolTip(__tr2qs_ctx("Edit the class or namespace name","editor"));
 
199
        m_pClassNameRenameButton->setEnabled(false);
 
200
        connect(m_pClassNameRenameButton,SIGNAL(clicked()),this,SLOT(renameItem()));
 
201
 
 
202
        pHBox = new KviTalHBox(pVBox);
 
203
        pHBox->setSpacing(0);
 
204
        pHBox->setMargin(0);
 
205
 
 
206
        pHBox = new KviTalHBox(pVBox);
 
207
        pHBox->setSpacing(0);
 
208
        pHBox->setMargin(0);
 
209
        m_pFunctionNameLabel = new QLabel(__tr2qs_ctx("No item selected","editor"),pHBox);
 
210
        pHBox->setStretchFactor(m_pFunctionNameLabel,2);
 
211
        m_pFunctionNameRenameButton = new QPushButton(__tr2qs_ctx("Rename","editor"),pHBox);
 
212
        m_pFunctionNameRenameButton->setToolTip(__tr2qs_ctx("Edit the function member name","editor"));
 
213
        m_pFunctionNameRenameButton->setEnabled(false);
 
214
        connect(m_pFunctionNameRenameButton,SIGNAL(clicked()),this,SLOT(renameFunction()));
 
215
 
 
216
        m_pReminderLabel = new QLabel(__tr2qs_ctx("No item selected","editor"),pVBox);
 
217
        m_pReminderLabel->hide();
 
218
        m_pReminderLabel->setWordWrap(true);
 
219
 
 
220
        m_pEditor = KviScriptEditor::createInstance(pVBox);
 
221
        m_pEditor->setFocus();
 
222
        connect(m_pEditor,SIGNAL(find(const QString &)),this,SLOT(slotFindWord(const QString &)));
 
223
        connect(m_pEditor,SIGNAL(replaceAll(const QString &,const QString &)),this,SLOT(slotReplaceAll(const QString &,const QString &)));
 
224
        m_pContextPopup = new KviTalPopupMenu(this);
 
225
 
 
226
        oneTimeSetup();
 
227
 
 
228
        currentItemChanged(0,0);
 
229
}
 
230
 
 
231
ClassEditorWidget::~ClassEditorWidget()
 
232
{
 
233
        m_pClasses->clear();
 
234
        delete m_pClasses;
 
235
}
 
236
 
 
237
void ClassEditorWidget::buildFullItemPath(ClassEditorTreeWidgetItem * pItem, QString & szBuffer)
 
238
{
 
239
        if(!pItem)
 
240
                return;
 
241
        szBuffer.prepend(pItem->name() + "::");
 
242
        pItem = (ClassEditorTreeWidgetItem *)pItem->parent();
 
243
        while(pItem)
 
244
        {
 
245
                QString szTmp = pItem->name();
 
246
                if(!szTmp.isEmpty())
 
247
                {
 
248
                        szBuffer.prepend("::");
 
249
                        szBuffer.prepend(szTmp);
 
250
                }
 
251
                pItem = (ClassEditorTreeWidgetItem *)pItem->parent();
 
252
        }
 
253
}
 
254
 
 
255
QString ClassEditorWidget::buildFullClassName(ClassEditorTreeWidgetItem * pItem)
 
256
{
 
257
        if(!pItem)
 
258
                return QString();
 
259
        QString szName = pItem->name();
 
260
        ClassEditorTreeWidgetItem * pNItem = (ClassEditorTreeWidgetItem *)pItem->parent();
 
261
        while(pNItem)
 
262
        {
 
263
                QString szTmp = pNItem->name();
 
264
                if(!szTmp.isEmpty())
 
265
                {
 
266
                        szName.prepend("::");
 
267
                        szName.prepend(szTmp);
 
268
                }
 
269
                pNItem = (ClassEditorTreeWidgetItem *)pNItem->parent();
 
270
        }
 
271
        return szName;
 
272
}
 
273
 
 
274
ClassEditorTreeWidgetItem * ClassEditorWidget::findTopLevelItem(const QString & szName)
 
275
{
 
276
        for(int i=0; i < m_pTreeWidget->topLevelItemCount(); i++)
 
277
        {
 
278
                if(KviQString::equalCI(m_pTreeWidget->topLevelItem(i)->text(0),szName))
 
279
                        return (ClassEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i);
 
280
        }
 
281
        return 0;
 
282
}
 
283
 
 
284
ClassEditorTreeWidgetItem * ClassEditorWidget::findItem(const QString & szFullName)
 
285
{
 
286
        bool bFound;
 
287
        QStringList lNamespaces = szFullName.split("::");
 
288
        if(lNamespaces.count() == 0)
 
289
                return 0;
 
290
        ClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0));
 
291
        if(!pItem)
 
292
                return 0;
 
293
        
 
294
        for(int i=1; i < lNamespaces.count(); i++)
 
295
        {
 
296
                bFound = false;
 
297
                for(int j=0; j < pItem->childCount(); j++)
 
298
                {
 
299
                        if (KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i)))
 
300
                        {
 
301
                                pItem=( ClassEditorTreeWidgetItem *)pItem->child(j);
 
302
                                bFound = true;
 
303
                                break;
 
304
                        }
 
305
                }
 
306
                if(!bFound)
 
307
                        return 0;
 
308
        }
 
309
        return (ClassEditorTreeWidgetItem *)pItem;
 
310
}
 
311
 
 
312
ClassEditorTreeWidgetItem * ClassEditorWidget::createFullItem(const QString & szFullName)
 
313
{
 
314
        bool bFound;
 
315
        int i;
 
316
        
 
317
        QStringList lNamespaces = szFullName.split("::");
 
318
        if(lNamespaces.count() == 0)
 
319
                return 0;
 
320
        if(lNamespaces.count() == 1)
 
321
        {
 
322
                ClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0));
 
323
                if(pItem)
 
324
                        return pItem;
 
325
                return new ClassEditorTreeWidgetItem(m_pTreeWidget,ClassEditorTreeWidgetItem::Class,lNamespaces.at(0));
 
326
        }
 
327
        ClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0));
 
328
        if(!pItem)
 
329
                pItem = new ClassEditorTreeWidgetItem(m_pTreeWidget,ClassEditorTreeWidgetItem::Namespace,lNamespaces.at(0));
 
330
 
 
331
        for(i=1; i < lNamespaces.count()-1; i++)
 
332
        {
 
333
                bFound = false;
 
334
                for(int j=0; j < pItem->childCount();j++)
 
335
                {
 
336
                        if(KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i)))
 
337
                        {
 
338
                                pItem = (ClassEditorTreeWidgetItem *)pItem->child(j);
 
339
                                bFound = true;
 
340
                                break;
 
341
                        }
 
342
                }
 
343
                if(!bFound)
 
344
                        pItem = new ClassEditorTreeWidgetItem(pItem,ClassEditorTreeWidgetItem::Namespace,lNamespaces.at(i));
 
345
        }
 
346
        return new ClassEditorTreeWidgetItem(pItem,ClassEditorTreeWidgetItem::Class,lNamespaces.at(i));
 
347
}
 
348
 
 
349
ClassEditorTreeWidgetItem * ClassEditorWidget::createFullNamespace(const QString & szFullName)
 
350
{
 
351
        bool bFound;
 
352
        int i;
 
353
        
 
354
        QStringList lNamespaces = szFullName.split("::");
 
355
        if(lNamespaces.count() == 0)
 
356
                return 0;
 
357
        ClassEditorTreeWidgetItem * pItem = findTopLevelItem(lNamespaces.at(0));
 
358
        if(!pItem)
 
359
                pItem = new ClassEditorTreeWidgetItem(m_pTreeWidget,ClassEditorTreeWidgetItem::Namespace,lNamespaces.at(0));
 
360
        if(lNamespaces.count() == 1)
 
361
                return pItem;
 
362
 
 
363
        for(i=1; i < lNamespaces.count(); i++)
 
364
        {
 
365
                bFound = false;
 
366
                for(int j=0;j<pItem->childCount();j++)
 
367
                {
 
368
                        if(KviQString::equalCI(pItem->child(j)->text(0),lNamespaces.at(i)) && (( ClassEditorTreeWidgetItem *)pItem->child(j))->isNamespace())
 
369
                        {
 
370
                                pItem = (ClassEditorTreeWidgetItem *)pItem->child(j);
 
371
                                bFound = true;
 
372
                                break;
 
373
                        }
 
374
                }
 
375
                if(!bFound)
 
376
                        pItem = new ClassEditorTreeWidgetItem(pItem,ClassEditorTreeWidgetItem::Namespace,lNamespaces.at(i));
 
377
        }
 
378
        return pItem;
 
379
}
 
380
 
 
381
void ClassEditorWidget::oneTimeSetup()
 
382
{
 
383
        QStringList sl;
 
384
        QString szClassName;
 
385
        QString szPath;
 
386
        g_pApp->getLocalKvircDirectory(szPath,KviApplication::Classes);
 
387
        QDir d(szPath);
 
388
        
 
389
        QString szExtension = QString("*%1").arg(KVI_FILEEXTENSION_SCRIPT); // *.kvs
 
390
        sl = d.entryList(QStringList(szExtension), QDir::Files | QDir::NoDotAndDotDot);
 
391
        
 
392
        g_pModuleManager->getModule("objects");
 
393
        KviPointerHashTableIterator<QString,KviKvsObjectClass> it(*KviKvsKernel::instance()->objectController()->classDict());
 
394
        
 
395
        KviKvsObjectClass * pClass = 0;
 
396
        ClassEditorTreeWidgetItem * pClassItem = 0;
 
397
        while(KviKvsObjectClass * pClass = it.current())
 
398
        {
 
399
                if(pClass->isBuiltin())
 
400
                        m_pClasses->insert(it.currentKey(),0);
 
401
                else
 
402
                {
 
403
                        QString szTmp;
 
404
                        szTmp = it.currentKey();
 
405
                        szTmp.replace("::","--");
 
406
                        szTmp.append(".kvs");
 
407
                        if(sl.indexOf(szTmp) == -1)
 
408
                        {
 
409
                                szClassName = it.currentKey();
 
410
                                pClassItem = createFullItem(szClassName);
 
411
                                createFullClass(it.current(),pClassItem,szClassName);
 
412
                        }
 
413
                }
 
414
                ++it;
 
415
        }
 
416
 
 
417
        for(int i=0; i < sl.count(); i++)
 
418
        {
 
419
                szClassName = sl.at(i);
 
420
                szClassName.replace("--","::");
 
421
                szClassName.chop(4);
 
422
                pClassItem = createFullItem(szClassName);
 
423
                pClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName);
 
424
                if(pClass)
 
425
                        createFullClass(pClass, pClassItem, szClassName);
 
426
        }
 
427
        loadNotBuiltClasses();
 
428
        connect(m_pTreeWidget,SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)));
 
429
        m_pTreeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
 
430
        connect(m_pTreeWidget,SIGNAL(customContextMenuRequested(const QPoint &)),this,SLOT(customContextMenuRequested(const QPoint &)));
 
431
}
 
432
 
 
433
void ClassEditorWidget::createFullClass(KviKvsObjectClass * pClass, ClassEditorTreeWidgetItem * pClassItem, const QString & szClassName)
 
434
{
 
435
        KviPointerHashTableIterator<QString,KviKvsObjectFunctionHandler>  it(* pClass->getHandlers());
 
436
        QStringList szFunctionsList;
 
437
        while(it.current())
 
438
        {
 
439
                szFunctionsList.append(it.currentKey());
 
440
                ++it;
 
441
        }
 
442
        szFunctionsList.sort();
 
443
        ClassEditorTreeWidgetItem *pFunctionItem;
 
444
        m_pClasses->insert(szClassName,pClassItem);
 
445
        KviKvsObjectClass * pParentClass = pClass->parentClass();
 
446
        pClassItem->setInheritsClass(pParentClass->name());
 
447
        for(int i=0;i<szFunctionsList.count();i++)
 
448
        {
 
449
                QString szCode;
 
450
                KviKvsObjectFunctionHandler *pHandler=pClass->lookupFunctionHandler(szFunctionsList.at(i));
 
451
                if (pClass->isScriptHandler(szFunctionsList.at(i)) && !pHandler->isClone())
 
452
                {
 
453
                        pFunctionItem=findFunction(szFunctionsList.at(i), pClassItem);
 
454
                        if(!pFunctionItem) pFunctionItem = new ClassEditorTreeWidgetItem(pClassItem,ClassEditorTreeWidgetItem::Method,szFunctionsList.at(i));
 
455
                        pClass->getFunctionCode(szCode,*pHandler);
 
456
                        pFunctionItem->setBuffer(szCode);
 
457
                        pFunctionItem->setReminder(pClass->reminder(pHandler));
 
458
                        if(pHandler->flags() & KviKvsObjectFunctionHandler::Internal)
 
459
                                pFunctionItem->setInternalFunction(true);
 
460
                }
 
461
                //++it;
 
462
        }
 
463
}
 
464
 
 
465
 
 
466
/*
 
467
void ClassEditorWidget::classRefresh(const QString & szName)
 
468
{
 
469
        if(m_bSaving)
 
470
                return;
 
471
        ClassEditorTreeWidgetItem * item;
 
472
        KviKvsScript * class = KviKvsClassManager::instance()->classDict()->find(szName);
 
473
        item = createFullItem(szName);
 
474
        if(item!=m_pLastEditedItem)
 
475
        {
 
476
                item->setBuffer(class->code());
 
477
                return;
 
478
        }
 
479
        if(
 
480
                QMessageBox::warning(0,__tr2qs_ctx("OverWrite Current Class","editor"),
 
481
                                __tr2qs_ctx("An external script has changed the class you are currently editing. Do you want to accept the external changes?","editor"),
 
482
                                QMessageBox::Yes,QMessageBox::No|QMessageBox::Default|QMessageBox::Escape) != QMessageBox::Yes
 
483
                )
 
484
                return;
 
485
        item->setBuffer(class->code());
 
486
        m_pEditor->setText(class->code());
 
487
}
 
488
*/
 
489
 
 
490
bool ClassEditorWidget::hasSelectedItems()
 
491
{
 
492
        return m_pTreeWidget->selectedItems().count() ? 1 : 0;
 
493
}
 
494
 
 
495
bool ClassEditorWidget::classExists(QString & szFullItemName)
 
496
{
 
497
        if(m_pClasses->find(szFullItemName))
 
498
                return true;
 
499
        else
 
500
                return false;
 
501
}
 
502
 
 
503
void ClassEditorWidget::renameFunction()
 
504
{
 
505
        if(!m_pLastEditedItem)
 
506
                return;
 
507
        ClassEditorTreeWidgetItem * pFunction = m_pLastEditedItem;
 
508
        QString szClassName = buildFullClassName((ClassEditorTreeWidgetItem *)pFunction->parent());
 
509
        QString szFunctionName = pFunction->name();
 
510
        QString szReminder = pFunction->reminder();
 
511
        QString szNewReminder = szReminder;
 
512
        ClassEditorTreeWidgetItem * pParentClass = (ClassEditorTreeWidgetItem *) pFunction->parent();
 
513
 
 
514
        QString szNewFunctionName = szFunctionName;
 
515
        bool bInternal = pFunction->isInternalFunction();
 
516
        if(!askForFunction(szNewFunctionName,szNewReminder,&bInternal,szClassName,true))
 
517
                return;
 
518
        if(KviQString::equalCS(szFunctionName,szNewFunctionName) && bInternal == pFunction->isInternalFunction())
 
519
        {
 
520
                if(!KviQString::equalCS(szNewReminder,szReminder))
 
521
                {
 
522
                        pFunction->setReminder(szNewReminder);
 
523
                        KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName);
 
524
                        if(pClass)
 
525
                        {
 
526
                                KviKvsObjectFunctionHandler * pHandler = pClass->lookupFunctionHandler(szFunctionName);
 
527
                                if(pHandler)
 
528
                                {
 
529
                                        pClass->setReminder(szNewReminder,pHandler);
 
530
                                        QString szPath;
 
531
                                        QString szFileName = szClassName.toLower();
 
532
                                        szFileName += ".kvs";
 
533
                                        szFileName.replace("::","--");
 
534
                                        g_pApp->getLocalKvircDirectory(szPath,KviApplication::Classes,szFileName);
 
535
                                        pClass->save(szPath);
 
536
                                }
 
537
                        }
 
538
                        currentItemChanged(pFunction,pFunction);
 
539
                } else {
 
540
                        g_pClassEditorModule->lock();
 
541
                        QMessageBox::information(this,
 
542
                        __tr2qs_ctx("Function already exists","editor"),
 
543
                        __tr2qs_ctx("This name is already in use. Please choose another one.","editor"),
 
544
                        __tr2qs_ctx("Ok, Let me try again...","editor"));
 
545
                        g_pClassEditorModule->unlock();
 
546
                        return;
 
547
                }
 
548
        }
 
549
        
 
550
        pFunction->setName(szNewFunctionName);
 
551
        pFunction->setReminder(szNewReminder);
 
552
        currentItemChanged(pFunction,pFunction);
 
553
        pFunction->setInternalFunction(bInternal);
 
554
        pParentClass->setClassNotBuilt(true);
 
555
        
 
556
        KviPointerList<ClassEditorTreeWidgetItem> lInheritedClasses;
 
557
        lInheritedClasses.setAutoDelete(false);
 
558
        searchInheritedClasses(szClassName,lInheritedClasses);
 
559
        for(unsigned int i=0; i < lInheritedClasses.count(); i++)
 
560
                lInheritedClasses.at(i)->setClassNotBuilt(true);
 
561
        activateItem(pFunction);
 
562
}
 
563
 
 
564
ClassEditorTreeWidgetItem * ClassEditorWidget::findFunction(const QString & szFunctionName, ClassEditorTreeWidgetItem * pClass)
 
565
{
 
566
        for(int i=0; i < pClass->childCount(); i++)
 
567
        {
 
568
                if(KviQString::equalCI(szFunctionName,((ClassEditorTreeWidgetItem *)pClass->child(i))->name()))
 
569
                        return (ClassEditorTreeWidgetItem *) pClass->child(i);
 
570
        }
 
571
        return 0;
 
572
}
 
573
 
 
574
void ClassEditorWidget::renameItem()
 
575
{
 
576
        if(!m_pLastEditedItem)
 
577
                return;
 
578
        if(m_pLastEditedItem->isClass())
 
579
                renameClass(m_pLastEditedItem);
 
580
        else if(m_pLastEditedItem->isNamespace())
 
581
                renameNamespace(m_pLastEditedItem);
 
582
        else {
 
583
                // is function
 
584
                ClassEditorTreeWidgetItem * pParent = (ClassEditorTreeWidgetItem *)m_pLastEditedItem->parent();
 
585
                if(pParent->isClass())
 
586
                        renameClass(pParent);
 
587
        }
 
588
}
 
589
 
 
590
void ClassEditorWidget::renameClass(ClassEditorTreeWidgetItem * pClassItem)
 
591
{
 
592
        QString szClassName = buildFullClassName(pClassItem);
 
593
        QString szNewClassName = szClassName;
 
594
 
 
595
        QString szInheritsClassName = pClassItem->inheritsClass();
 
596
        QString szNewInheritsClassName = szInheritsClassName;
 
597
        bool bOk = askForClassName(szNewClassName,szNewInheritsClassName,true);
 
598
        if(!bOk)
 
599
                return;
 
600
        if(classExists(szNewClassName) && KviQString::equalCS(szClassName,szNewClassName) && KviQString::equalCS(szInheritsClassName,szNewInheritsClassName))
 
601
        {
 
602
                g_pClassEditorModule->lock();
 
603
                QMessageBox::information(this,
 
604
                        __tr2qs_ctx("Class already exists","editor"),
 
605
                        __tr2qs_ctx("This name is already in use. Please choose another one.","editor"),
 
606
                        __tr2qs_ctx("Ok, Let me try again...","editor"));
 
607
                g_pClassEditorModule->unlock();
 
608
                return;
 
609
        }
 
610
        /*if(szNewClassName.tmp.indexOf("@@",Qt::CaseInsensitive) != -1)
 
611
        {
 
612
                g_pClassEditorModule->lock();
 
613
                QMessageBox::information(this,
 
614
                        __tr2qs_ctx("Bad Namespace Name","editor"),
 
615
                        __tr2qs_ctx("Found an empty namespace in namespace name","editor"),
 
616
                        __tr2qs_ctx("Ok, Let me try again...","editor"));
 
617
                g_pClassEditorModule->unlock();
 
618
                szNewName = "";
 
619
                continue;
 
620
        }*/
 
621
        ClassEditorTreeWidgetItem * pNewItem = 0;
 
622
        m_pClasses->removeRef(pClassItem);
 
623
        cutItem(pClassItem);
 
624
        if(szNewClassName.contains("::"))
 
625
        {
 
626
                pNewItem = createFullNamespace(szNewClassName.left(szNewClassName.lastIndexOf("::")));
 
627
                pClassItem->setName(szNewClassName.section("::",-1,-1));
 
628
                pNewItem->addChild(pClassItem);
 
629
        } else {
 
630
                pClassItem->setName(szNewClassName);
 
631
                m_pTreeWidget->addTopLevelItem(pClassItem);
 
632
        }
 
633
        m_pClasses->insert(szNewClassName,pClassItem);
 
634
        pClassItem->setInheritsClass(szNewInheritsClassName);
 
635
        pClassItem->setClassNotBuilt(true);
 
636
        
 
637
        KviPointerList<ClassEditorTreeWidgetItem> lInheritedClasses;
 
638
        lInheritedClasses.setAutoDelete(false);
 
639
        searchInheritedClasses(szClassName,lInheritedClasses);
 
640
        for(unsigned int i=0; i < lInheritedClasses.count(); i++)
 
641
        {
 
642
                lInheritedClasses.at(i)->setClassNotBuilt(true);
 
643
                lInheritedClasses.at(i)->setExpanded(true);
 
644
                lInheritedClasses.at(i)->setInheritsClass(szNewClassName);
 
645
        }
 
646
        
 
647
        if(pNewItem)
 
648
        {
 
649
                activateItem(pNewItem);
 
650
                pNewItem->setExpanded(true);
 
651
        } else {
 
652
                activateItem(pClassItem);
 
653
                pClassItem->setExpanded(true);
 
654
        }
 
655
        
 
656
        qDebug("delete class %s caused by rename",szClassName.toUtf8().data());
 
657
        KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName);
 
658
        if(pClass)
 
659
                KviKvsKernel::instance()->objectController()->deleteClass(pClass);
 
660
}
 
661
 
 
662
void ClassEditorWidget::cutItem(ClassEditorTreeWidgetItem * pItem)
 
663
{
 
664
        int iIdx = m_pTreeWidget->indexOfTopLevelItem(pItem);
 
665
        if(iIdx!=-1)
 
666
                m_pTreeWidget->takeTopLevelItem(iIdx);
 
667
        else {
 
668
                ClassEditorTreeWidgetItem * pParent = (ClassEditorTreeWidgetItem *)pItem->parent();
 
669
                pParent->removeChild(pItem);
 
670
        }
 
671
}
 
672
 
 
673
void ClassEditorWidget::renameNamespace(ClassEditorTreeWidgetItem * pOldNamespaceItem)
 
674
{
 
675
        QString szOldNameSpaceName = buildFullClassName(m_pLastEditedItem);
 
676
        QString szNewNameSpaceName;
 
677
        if(!askForNamespaceName(__tr2qs_ctx("Rename Namespace","editor"),__tr2qs_ctx("Please enter the new name for the namespace","editor"),szOldNameSpaceName,szNewNameSpaceName))
 
678
                return;
 
679
        if(KviQString::equalCI(szOldNameSpaceName,szNewNameSpaceName))
 
680
                return;
 
681
        ClassEditorTreeWidgetItem * pNewItem = findItem(szNewNameSpaceName);
 
682
        if(pNewItem)
 
683
        {
 
684
                g_pClassEditorModule->lock();
 
685
                if(pNewItem->isClass())
 
686
                {
 
687
                        QMessageBox::information(this,
 
688
                                __tr2qs_ctx("Name already exists as Class name","editor"),
 
689
                                __tr2qs_ctx("This name is already in use as Class name. Please choose another one.","editor"),
 
690
                                __tr2qs_ctx("Ok, Let me try again...","editor"));
 
691
                } else {
 
692
                        QMessageBox::information(this,
 
693
                        __tr2qs_ctx("Namespace already exists","editor"),
 
694
                        __tr2qs_ctx("This name is already in use. Please choose another one.","editor"),
 
695
                        __tr2qs_ctx("Ok, Let me try again...","editor"));
 
696
                }
 
697
                g_pClassEditorModule->unlock();
 
698
                return;
 
699
        }
 
700
        KviPointerList<ClassEditorTreeWidgetItem> pList;
 
701
        pList.setAutoDelete(false);
 
702
        appendAllClassItemsRecursive(&pList,pOldNamespaceItem);
 
703
        cutItem(pOldNamespaceItem);
 
704
        if(szNewNameSpaceName.contains("::"))
 
705
        {
 
706
                pNewItem=createFullNamespace(szNewNameSpaceName.left(szNewNameSpaceName.lastIndexOf("::")));
 
707
                pOldNamespaceItem->setName(szNewNameSpaceName.section("::",-1,-1));
 
708
                pNewItem->addChild(pOldNamespaceItem);
 
709
        } else {
 
710
                m_pTreeWidget->addTopLevelItem(pOldNamespaceItem);
 
711
                pOldNamespaceItem->setName(szNewNameSpaceName);
 
712
        }
 
713
        for(unsigned int u=0; u < pList.count(); u++)
 
714
        {
 
715
                KviPointerHashTableEntry<QString,ClassEditorTreeWidgetItem> * pEntry = m_pClasses->findRef(pList.at(u));
 
716
                if(pEntry)
 
717
                {
 
718
                        KviPointerList<ClassEditorTreeWidgetItem> lInheritedClasses;
 
719
                        lInheritedClasses.setAutoDelete(false);
 
720
 
 
721
                        QString szOldName = pEntry->key();
 
722
                        QString szNewName = buildFullClassName(pList.at(u));
 
723
                        searchInheritedClasses(szOldName,lInheritedClasses);
 
724
                        for(unsigned int v=0; v < lInheritedClasses.count(); v++)
 
725
                        {
 
726
                                lInheritedClasses.at(v)->setClassNotBuilt(true);
 
727
                                lInheritedClasses.at(v)->setExpanded(true);
 
728
                                lInheritedClasses.at(v)->setInheritsClass(szNewName);
 
729
                        }
 
730
                        m_pClasses->removeRef(pList.at(u));
 
731
                        m_pClasses->insert(szNewName,pList.at(u));
 
732
                        pList.at(u)->setClassNotBuilt(true);
 
733
 
 
734
                        KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szOldName);
 
735
                        if(pClass)
 
736
                                KviKvsKernel::instance()->objectController()->deleteClass(pClass);
 
737
                }
 
738
        }
 
739
 
 
740
        if(pNewItem)
 
741
        {
 
742
                activateItem(pNewItem);
 
743
                pNewItem->setExpanded(true);
 
744
        } else {
 
745
                activateItem(pOldNamespaceItem);
 
746
                pOldNamespaceItem->setExpanded(true);
 
747
        }
 
748
        //searchReplace(szOldNameSpaceName+"::",true,szNewNameSpaceName+"::");
 
749
}
 
750
 
 
751
void ClassEditorWidget::saveLastEditedItem()
 
752
{
 
753
        if(!m_pLastEditedItem)
 
754
                return;
 
755
        if(!m_pEditor->isModified() || m_pLastEditedItem->isNamespace() || m_pLastEditedItem->isClass())
 
756
                return;
 
757
        ((ClassEditorTreeWidgetItem *)m_pLastEditedItem)->setCursorPosition(m_pEditor->getCursor());
 
758
        QString newCode;
 
759
        m_pEditor->getText(newCode);
 
760
        ((ClassEditorTreeWidgetItem *)m_pLastEditedItem)->setBuffer(newCode);
 
761
        ((ClassEditorTreeWidgetItem *)m_pLastEditedItem->parent())->setClassNotBuilt(true);
 
762
}
 
763
 
 
764
void ClassEditorWidget::currentItemChanged(QTreeWidgetItem * pTree, QTreeWidgetItem *)
 
765
{
 
766
        saveLastEditedItem();
 
767
        m_pLastEditedItem = (ClassEditorTreeWidgetItem *)pTree;
 
768
        if(!m_pLastEditedItem)
 
769
        {
 
770
                m_pClassNameLabel->setText(__tr2qs_ctx("No item selected","editor"));
 
771
                m_pClassNameRenameButton->setEnabled(false);
 
772
                m_pEditor->setText("");
 
773
                m_pEditor->setEnabled(false);
 
774
                return;
 
775
        }
 
776
        
 
777
        ClassEditorTreeWidgetItem * pClassItem = 0;
 
778
        if(m_pLastEditedItem->isMethod())
 
779
                pClassItem = (ClassEditorTreeWidgetItem *)m_pLastEditedItem->parent();
 
780
        else
 
781
                pClassItem = m_pLastEditedItem;
 
782
        
 
783
        QString szClassName = buildFullClassName(pClassItem);
 
784
        
 
785
        if(m_pLastEditedItem->isNamespace())
 
786
        {
 
787
                QString szLabelText = __tr2qs_ctx("Namespace","editor");
 
788
                szLabelText += ": <b>";
 
789
                szLabelText += szClassName;
 
790
                szLabelText += "</b>";
 
791
                m_pClassNameLabel->setText(szLabelText);
 
792
                m_pClassNameRenameButton->setEnabled(true);
 
793
                m_pFunctionNameRenameButton->setEnabled(false);
 
794
                //m_pinheritsClassNameLabel->setText("");
 
795
                m_pFunctionNameLabel->setText("");
 
796
                m_pEditor->setText("");
 
797
                m_pEditor->setEnabled(false);
 
798
                m_pTreeWidget->setFocus();
 
799
                return;
 
800
        }
 
801
        
 
802
        QString szLabelText = __tr2qs_ctx("Class","editor");
 
803
        szLabelText += ": <b>";
 
804
        szLabelText += szClassName;
 
805
        szLabelText += "</b>, ";
 
806
        szLabelText += __tr2qs_ctx("inherits from class ","editor");
 
807
        szLabelText += ": <b>";
 
808
        szLabelText += pClassItem->inheritsClass();
 
809
        szLabelText += "</b>";
 
810
        m_pClassNameLabel->setText(szLabelText);
 
811
 
 
812
        szLabelText = __tr2qs_ctx("Member Function","editor");
 
813
        if(m_pLastEditedItem->isMethod())
 
814
        {
 
815
                szLabelText += ": <b>";
 
816
                szLabelText += m_pLastEditedItem->text(0);
 
817
                szLabelText += "</b>";
 
818
                m_pFunctionNameRenameButton->setEnabled(true);
 
819
                if(m_pLastEditedItem->reminder().isEmpty())
 
820
                        m_pReminderLabel->hide();
 
821
                else {
 
822
                        QString szReminderText =__tr2qs_ctx("Reminder text.","editor");
 
823
                        szReminderText += ": <b>";
 
824
                        szReminderText += m_pLastEditedItem->reminder();
 
825
                        szReminderText += "</b>";
 
826
                        m_pReminderLabel->setText(szReminderText);
 
827
                        m_pReminderLabel->show();
 
828
                }
 
829
                
 
830
                m_pFunctionNameLabel->setText(szLabelText);
 
831
                m_pFunctionNameLabel->show();
 
832
                m_pFunctionNameRenameButton->show();
 
833
        } else {
 
834
                m_pReminderLabel->hide();
 
835
                m_pFunctionNameLabel->hide();
 
836
                m_pClassNameRenameButton->setEnabled(true);
 
837
                m_pFunctionNameRenameButton->hide();
 
838
        }
 
839
        if(m_pLastEditedItem->isClass())
 
840
        {
 
841
                m_pFunctionNameRenameButton->setEnabled(false);
 
842
                m_pEditor->setText("");
 
843
                m_pEditor->setEnabled(true);
 
844
                m_pTreeWidget->setFocus();
 
845
                QString szBuffer;
 
846
                QStringList szFunctionsList;
 
847
                KviPointerHashTable<QString,ClassEditorTreeWidgetItem> lFunctions;
 
848
                lFunctions.setAutoDelete(false);
 
849
                
 
850
                ClassEditorTreeWidgetItem * pItem = 0;
 
851
                for(int i=0; i < pTree->childCount(); i++)
 
852
                {
 
853
                        pItem = ((ClassEditorTreeWidgetItem *)pTree->child(i));
 
854
                        szFunctionsList.append(pItem->name());
 
855
                        lFunctions.insert(pItem->name(),pItem);
 
856
                }
 
857
                szFunctionsList.sort();
 
858
                for(int i=0; i < szFunctionsList.count(); i++)
 
859
                {
 
860
                        szBuffer += "Member Function: <b>$" + szFunctionsList.at(i) + "</b><br>";
 
861
                        if(!lFunctions.find(szFunctionsList.at(i))->reminder().isEmpty())
 
862
                                szBuffer+="Parameters reminder: "+lFunctions.find(szFunctionsList.at(i))->reminder()+"<br>";
 
863
                        szBuffer+="<br>";
 
864
                }
 
865
                m_pEditor->setUnHighlightedText(szBuffer);
 
866
                m_pEditor->setReadOnly(true);
 
867
                return;
 
868
        }
 
869
        m_pEditor->setReadOnly(false);
 
870
        m_pEditor->setText(((ClassEditorTreeWidgetItem *)pTree)->buffer());
 
871
        m_pEditor->setFocus();
 
872
        m_pEditor->setCursorPosition(((ClassEditorTreeWidgetItem *)pTree)->cursorPosition());
 
873
        m_pEditor->setEnabled(true);
 
874
}
 
875
 
 
876
void ClassEditorWidget::customContextMenuRequested(QPoint pnt)
 
877
{
 
878
        m_pContextPopup->clear();
 
879
 
 
880
        m_pLastClickedItem = (ClassEditorTreeWidgetItem *)m_pTreeWidget->itemAt(pnt);
 
881
 
 
882
        int iId;
 
883
        iId = m_pContextPopup->insertItem(
 
884
                *(g_pIconManager->getSmallIcon(KviIconManager::NameSpace)),
 
885
                __tr2qs_ctx("Add Namespace","editor"),
 
886
                this,SLOT(newNamespace()));
 
887
        if(!m_pLastClickedItem)
 
888
                m_pContextPopup->setItemEnabled(iId,true);
 
889
        else
 
890
                m_pContextPopup->setItemEnabled(iId,m_pLastClickedItem->isNamespace());
 
891
 
 
892
        iId = m_pContextPopup->insertItem(
 
893
                *(g_pIconManager->getSmallIcon(KviIconManager::Class)),
 
894
                __tr2qs_ctx("Add Class","editor"),
 
895
                this,SLOT(newClass()));
 
896
        if(!m_pLastClickedItem)
 
897
                m_pContextPopup->setItemEnabled(iId,true);
 
898
        else
 
899
                m_pContextPopup->setItemEnabled(iId,m_pLastClickedItem->isNamespace());
 
900
 
 
901
        iId = m_pContextPopup->insertItem(
 
902
                *(g_pIconManager->getSmallIcon(KviIconManager::Function)),
 
903
                __tr2qs_ctx("Add Member Function","editor"),
 
904
                this,SLOT(newMemberFunction()));
 
905
        if(!m_pLastClickedItem)
 
906
                m_pContextPopup->setItemEnabled(iId,false);
 
907
        else
 
908
                m_pContextPopup->setItemEnabled(iId,m_pLastClickedItem->isClass()| m_pLastClickedItem->isMethod());
 
909
 
 
910
        bool bHasItems = m_pTreeWidget->topLevelItemCount();
 
911
        bool bHasSelected = hasSelectedItems();
 
912
 
 
913
        m_pContextPopup->insertSeparator();
 
914
 
 
915
        iId = m_pContextPopup->insertItem(
 
916
                *(g_pIconManager->getSmallIcon(KviIconManager::Quit)),
 
917
                __tr2qs_ctx("Remove Selected","editor"),
 
918
                this,SLOT(removeSelectedItems()));
 
919
        m_pContextPopup->setItemEnabled(iId,bHasSelected);
 
920
 
 
921
        m_pContextPopup->insertSeparator();
 
922
 
 
923
        m_pContextPopup->insertItem(
 
924
                *(g_pIconManager->getSmallIcon(KviIconManager::Folder)),
 
925
                __tr2qs_ctx("Export Selected...","editor"),
 
926
                this,SLOT(exportSelected()));
 
927
        m_pContextPopup->setItemEnabled(iId,bHasSelected);
 
928
 
 
929
        m_pContextPopup->insertItem(
 
930
                *(g_pIconManager->getSmallIcon(KviIconManager::Folder)),
 
931
                __tr2qs_ctx("Export Selected in singles files...","editor"),
 
932
                this,SLOT(exportSelectedSepFiles()));
 
933
 
 
934
        m_pContextPopup->setItemEnabled(iId,bHasSelected);
 
935
 
 
936
        m_pContextPopup->insertItem(
 
937
                        *(g_pIconManager->getSmallIcon(KviIconManager::Folder)),
 
938
                        __tr2qs_ctx("Export All...","editor"),
 
939
                        this,SLOT(exportAll()));
 
940
        m_pContextPopup->setItemEnabled(iId,bHasItems);
 
941
 
 
942
        m_pContextPopup->insertSeparator();
 
943
 
 
944
        m_pContextPopup->insertItem(
 
945
                        *(g_pIconManager->getSmallIcon(KviIconManager::Search)),
 
946
                        __tr2qs_ctx("Find In Classes...","editor"),
 
947
                        this,SLOT(slotFind()));
 
948
        m_pContextPopup->setItemEnabled(iId,bHasItems);
 
949
 
 
950
        m_pContextPopup->insertItem(
 
951
                        *(g_pIconManager->getSmallIcon(KviIconManager::NameSpace)),
 
952
                        __tr2qs_ctx("Collapse All Items","editor"),
 
953
                        this,SLOT(slotCollapseItems()));
 
954
 
 
955
        m_pContextPopup->setItemEnabled(iId,bHasItems);
 
956
        m_pContextPopup->popup(m_pTreeWidget->mapToGlobal(pnt));
 
957
}
 
958
 
 
959
void ClassEditorWidget::searchReplace(const QString & szSearch, bool bReplace, const QString & szReplace)
 
960
{
 
961
        KviPointerHashTableIterator<QString,ClassEditorTreeWidgetItem> it (*m_pClasses);
 
962
        while(it.current())
 
963
        {
 
964
                ClassEditorTreeWidgetItem * pItem = it.current();
 
965
                for(int j=0; j < pItem->childCount(); j++)
 
966
                {
 
967
                        bool bOpened = false;
 
968
                        if(((ClassEditorTreeWidgetItem *)pItem->child(j))->buffer().indexOf(szSearch,0,Qt::CaseInsensitive) != -1)
 
969
                        {
 
970
                                pItem->child(j)->setBackground(0, QColor(255,0,0,128));
 
971
                                if(bReplace)
 
972
                                {
 
973
                                        QString &buffer=(QString &)((ClassEditorTreeWidgetItem *)pItem->child(j))->buffer();
 
974
                                        pItem->setClassNotBuilt(true);
 
975
                                        buffer.replace(szSearch,szReplace,Qt::CaseInsensitive);
 
976
                                }
 
977
                                if(!bOpened)
 
978
                                {
 
979
                                        openParentItems(pItem->child(j));
 
980
                                        bOpened = true;
 
981
                                }
 
982
                        } else {
 
983
                                pItem->child(j)->setBackground(0, QColor(255,255,255));
 
984
                        }
 
985
                }
 
986
                ++it;
 
987
        }
 
988
}
 
989
 
 
990
void ClassEditorWidget::slotFind()
 
991
{
 
992
        g_pClassEditorModule->lock();
 
993
        bool bOk;
 
994
 
 
995
        QString szSearch = QInputDialog::getText(this,
 
996
                __tr2qs_ctx("Find In Classes","editor"),
 
997
                __tr2qs_ctx("Please enter the text to be searched for. The matching function will be highlighted.","editor"),
 
998
                QLineEdit::Normal,
 
999
                "",
 
1000
                &bOk);
 
1001
 
 
1002
        g_pClassEditorModule->unlock();
 
1003
        if(!bOk)
 
1004
                return;
 
1005
        if(szSearch.isEmpty())
 
1006
                return;
 
1007
        m_pEditor->setFindText(szSearch);
 
1008
        searchReplace(szSearch);
 
1009
}
 
1010
 
 
1011
void ClassEditorWidget::slotFindWord(const QString & szSearch)
 
1012
{
 
1013
        m_pEditor->setFindText(szSearch);
 
1014
}
 
1015
 
 
1016
void ClassEditorWidget::recursiveCollapseItems(ClassEditorTreeWidgetItem * pItem)
 
1017
{
 
1018
        if(!pItem)
 
1019
                return;
 
1020
        for(int i=0; i < pItem->childCount(); i++)
 
1021
        {
 
1022
                if(pItem->child(i)->childCount())
 
1023
                {
 
1024
                        pItem->child(i)->setExpanded(false);
 
1025
                        recursiveCollapseItems((ClassEditorTreeWidgetItem *)pItem->child(i));
 
1026
                }
 
1027
        }
 
1028
}
 
1029
 
 
1030
void ClassEditorWidget::slotCollapseItems()
 
1031
{
 
1032
        for(int i=0; i < m_pTreeWidget->topLevelItemCount(); i++)
 
1033
        {
 
1034
                if(m_pTreeWidget->topLevelItem(i)->childCount())
 
1035
                {
 
1036
                        m_pTreeWidget->topLevelItem(i)->setExpanded(false);
 
1037
                        recursiveCollapseItems((ClassEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i));
 
1038
                }
 
1039
        }
 
1040
}
 
1041
 
 
1042
void ClassEditorWidget::slotReplaceAll(const QString & szFind, const QString & szReplace)
 
1043
{
 
1044
        m_pEditor->setFindText(szReplace);
 
1045
        searchReplace(szFind,true,szReplace);
 
1046
        /*
 
1047
        for (int i=0;i<m_pTreeWidget->topLevelItemCount();i++)
 
1048
        {
 
1049
                recursiveSearchReplace(szFind,(ClassEditorTreeWidgetItem *)m_pTreeWidget->topLevelItem(i),true,szReplace);
 
1050
        }
 
1051
        */
 
1052
}
 
1053
 
 
1054
void ClassEditorWidget::exportClassBuffer(QString & szBuffer, ClassEditorTreeWidgetItem * pItem)
 
1055
{
 
1056
        QString szTmp = pItem->buffer();
 
1057
        KviCommandFormatter::blockFromBuffer(szTmp);
 
1058
        QString szName = buildFullClassName(pItem);
 
1059
 
 
1060
        szBuffer = "class(\"";
 
1061
        szBuffer += szName;
 
1062
        if(!pItem->inheritsClass().isEmpty())
 
1063
        {
 
1064
                szBuffer += "\",\"";
 
1065
                szBuffer += pItem->inheritsClass();
 
1066
        }
 
1067
        szBuffer += "\")\n{\n";
 
1068
        for(int i=0; i < pItem->childCount(); i++)
 
1069
        {
 
1070
                ClassEditorTreeWidgetItem * pFunction = (ClassEditorTreeWidgetItem *)pItem->child(i);
 
1071
                if(pFunction->isMethod())
 
1072
                {
 
1073
                        szBuffer += "\t";
 
1074
                        if(pFunction->isInternalFunction())
 
1075
                                szBuffer += "internal ";
 
1076
                        szBuffer += "function ";
 
1077
                        szBuffer += pFunction->name();
 
1078
                        szBuffer += "(" + pFunction->reminder() + ")";
 
1079
                        szBuffer += "\n\t{\n";
 
1080
                        szBuffer += pFunction->buffer();
 
1081
                        szBuffer += "\n\t}\n";
 
1082
                }
 
1083
        }
 
1084
        szBuffer += "}\n";
 
1085
}
 
1086
 
 
1087
void ClassEditorWidget::exportAll()
 
1088
{
 
1089
        exportClasses(false);
 
1090
}
 
1091
 
 
1092
void ClassEditorWidget::exportSelectedSepFiles()
 
1093
{
 
1094
        exportClasses(true,true);
 
1095
}
 
1096
 
 
1097
void ClassEditorWidget::exportSelected()
 
1098
{
 
1099
        exportClasses(true);
 
1100
}
 
1101
 
 
1102
void ClassEditorWidget::exportSelectionInSinglesFiles(KviPointerList<ClassEditorTreeWidgetItem> * pList)
 
1103
{
 
1104
        bool bReplaceAll = false;
 
1105
        
 
1106
        if(!m_szDir.endsWith(QString(KVI_PATH_SEPARATOR)))
 
1107
                m_szDir += KVI_PATH_SEPARATOR;
 
1108
        if(!pList->first())
 
1109
        {
 
1110
                g_pClassEditorModule->lock();
 
1111
                QMessageBox::warning(this,__tr2qs_ctx("Class Export","editor"),__tr2qs_ctx("There is no selection!","editor"),__tr2qs_ctx("OK","editor"));
 
1112
                g_pClassEditorModule->unlock();
 
1113
                return;
 
1114
        }
 
1115
        g_pClassEditorModule->lock();
 
1116
 
 
1117
        if(!KviFileDialog::askForDirectoryName(m_szDir,__tr2qs_ctx("Choose a Directory - KVIrc","editor"),m_szDir))
 
1118
        {
 
1119
                g_pClassEditorModule->unlock();
 
1120
                return;
 
1121
        }
 
1122
 
 
1123
        if(!m_szDir.endsWith(QString(KVI_PATH_SEPARATOR)))
 
1124
                m_szDir += KVI_PATH_SEPARATOR;
 
1125
 
 
1126
        for(ClassEditorTreeWidgetItem * pItem = pList->first(); pItem; pItem = pList->next())
 
1127
        {
 
1128
                QString szTmp;
 
1129
                exportClassBuffer(szTmp,pItem);
 
1130
                QString szFileName = buildFullClassName(pItem);
 
1131
                szFileName += ".kvs";
 
1132
                szFileName.replace("::","_");
 
1133
                QString szCompletePath = m_szDir+szFileName;
 
1134
                if(KviFileUtils::fileExists(szCompletePath) && !bReplaceAll)
 
1135
                {
 
1136
                        QString szMsg = __tr2qs_ctx("The file \"%1\" exists. Do you want to replace it?","editor").arg(szFileName);
 
1137
                        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"));
 
1138
                        if(iRet != 2)
 
1139
                        {
 
1140
                                KviFileUtils::writeFile(szCompletePath,szTmp);
 
1141
                                if(iRet == 1)
 
1142
                                        bReplaceAll = true;
 
1143
                        }
 
1144
                }
 
1145
                else
 
1146
                KviFileUtils::writeFile(szCompletePath,szTmp);
 
1147
        }
 
1148
        g_pClassEditorModule->unlock();
 
1149
}
 
1150
 
 
1151
void ClassEditorWidget::exportClasses(bool bSelectedOnly, bool bSingleFiles)
 
1152
{
 
1153
        QString szOut;
 
1154
        QString szNameFile;
 
1155
        QString szFile;
 
1156
        int iCount = 0;
 
1157
        
 
1158
        saveLastEditedItem();
 
1159
 
 
1160
        KviPointerList<ClassEditorTreeWidgetItem> list;
 
1161
        list.setAutoDelete(false);
 
1162
 
 
1163
        if(bSelectedOnly)
 
1164
                appendSelectedClassItems(&list);
 
1165
        else
 
1166
                appendAllClassItems(&list);
 
1167
        
 
1168
        if(bSingleFiles)
 
1169
        {
 
1170
                exportSelectionInSinglesFiles(&list);
 
1171
                return;
 
1172
        }
 
1173
        
 
1174
        ClassEditorTreeWidgetItem * pTempItem = 0;
 
1175
        for(ClassEditorTreeWidgetItem * pItem = list.first(); pItem; pItem = list.next())
 
1176
        {
 
1177
                pTempItem = pItem;
 
1178
                iCount++;
 
1179
                QString szTmp;
 
1180
                exportClassBuffer(szTmp,pItem);
 
1181
                szOut += szTmp;
 
1182
                szOut += "\n";
 
1183
        }
 
1184
        
 
1185
        if(szOut.isEmpty())
 
1186
        {
 
1187
                g_pClassEditorModule->lock();
 
1188
                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"));
 
1189
                g_pClassEditorModule->unlock();
 
1190
                return;
 
1191
        }
 
1192
 
 
1193
        QString szName = m_szDir;
 
1194
 
 
1195
        if(!szName.endsWith(QString(KVI_PATH_SEPARATOR)))
 
1196
                szName += KVI_PATH_SEPARATOR;
 
1197
        
 
1198
        g_pClassEditorModule->lock();
 
1199
 
 
1200
        if(iCount != 1)
 
1201
                szNameFile = "classes";
 
1202
        else {
 
1203
                QString szTmp = buildFullClassName(pTempItem);
 
1204
                szNameFile = szTmp.replace("::","_");
 
1205
        }
 
1206
        
 
1207
        szName += szNameFile;
 
1208
        szName += ".kvs";
 
1209
        if(!KviFileDialog::askForSaveFileName(szFile,__tr2qs_ctx("Choose a Filename - KVIrc","editor"),szName,KVI_FILTER_SCRIPT,false,true,true))
 
1210
        {
 
1211
                g_pClassEditorModule->unlock();
 
1212
                return;
 
1213
        }
 
1214
        m_szDir=QFileInfo(szFile).absolutePath();
 
1215
        g_pClassEditorModule->unlock();
 
1216
 
 
1217
        if(!KviFileUtils::writeFile(szFile,szOut))
 
1218
        {
 
1219
                g_pClassEditorModule->lock();
 
1220
                QMessageBox::warning(this,__tr2qs_ctx("Write Failed - KVIrc","editor"),__tr2qs_ctx("Unable to write to the class file.","editor"),__tr2qs_ctx("OK","editor"));
 
1221
                g_pClassEditorModule->unlock();
 
1222
        }
 
1223
}
 
1224
 
 
1225
void ClassEditorWidget::saveProperties(KviConfigurationFile * pCfg)
 
1226
{
 
1227
        pCfg->writeEntry("Sizes",m_pSplitter->sizes());
 
1228
        QString szName;
 
1229
        if(m_pLastEditedItem)
 
1230
                szName = buildFullClassName(m_pLastEditedItem);
 
1231
        pCfg->writeEntry("LastClass",szName);
 
1232
}
 
1233
 
 
1234
void ClassEditorWidget::loadProperties(KviConfigurationFile * pCfg)
 
1235
{
 
1236
        QList<int> def;
 
1237
        def.append(20);
 
1238
        def.append(80);
 
1239
        m_pSplitter->setSizes(pCfg->readIntListEntry("Sizes",def));
 
1240
        QString szTmp = pCfg->readEntry("LastClass",QString());
 
1241
 
 
1242
        ClassEditorTreeWidgetItem * pItem = findItem(szTmp);
 
1243
        activateItem(pItem);
 
1244
}
 
1245
 
 
1246
void ClassEditorWidget::appendSelectedClassItems(KviPointerList<ClassEditorTreeWidgetItem> * pList)
 
1247
{
 
1248
        QList<QTreeWidgetItem *> list = m_pTreeWidget->selectedItems();
 
1249
        for(int i=0; i < list.count(); i++)
 
1250
        {
 
1251
                if(((ClassEditorTreeWidgetItem *)list.at(i))->isClass())
 
1252
                        pList->append((ClassEditorTreeWidgetItem *)list.at(i));
 
1253
                else appendSelectedClassItemsRecursive(pList,list.at(i));
 
1254
        }
 
1255
}
 
1256
 
 
1257
void ClassEditorWidget::appendSelectedClassItemsRecursive(KviPointerList<ClassEditorTreeWidgetItem> * pList, QTreeWidgetItem * pStartFrom)
 
1258
{
 
1259
        for(int i=0; i < pStartFrom->childCount(); i++)
 
1260
        {
 
1261
                if(((ClassEditorTreeWidgetItem *)pStartFrom->child(i))->isClass())
 
1262
                        pList->append(((ClassEditorTreeWidgetItem *)pStartFrom->child(i)));
 
1263
                else
 
1264
                        appendSelectedClassItemsRecursive(pList,pStartFrom->child(i));
 
1265
        }
 
1266
}
 
1267
 
 
1268
void ClassEditorWidget::appendAllClassItems(KviPointerList<ClassEditorTreeWidgetItem> * pList)
 
1269
{
 
1270
        KviPointerHashTableIterator<QString,ClassEditorTreeWidgetItem> it (*m_pClasses);
 
1271
        while(it.current())
 
1272
        {
 
1273
                pList->append(it.current());
 
1274
                ++it;
 
1275
        }
 
1276
}
 
1277
 
 
1278
void ClassEditorWidget::appendAllClassItemsRecursive(KviPointerList<ClassEditorTreeWidgetItem> * pList, QTreeWidgetItem * pStartFrom)
 
1279
{
 
1280
        for(int i=0; i < pStartFrom->childCount(); i++)
 
1281
        {
 
1282
                if(((ClassEditorTreeWidgetItem *)pStartFrom->child(i))->isClass())
 
1283
                {
 
1284
                        pList->append((ClassEditorTreeWidgetItem *)pStartFrom->child(i));
 
1285
                } else {
 
1286
                        appendAllClassItemsRecursive(pList,pStartFrom->child(i));
 
1287
                }
 
1288
        }
 
1289
}
 
1290
 
 
1291
void ClassEditorWidget::removeItemChildren(ClassEditorTreeWidgetItem * pItem, KviPointerList <ClassEditorTreeWidgetItem> & lRemovedItems)
 
1292
{
 
1293
        if(pItem->isClass())
 
1294
        {
 
1295
                KviPointerList<ClassEditorTreeWidgetItem> lInheritedClasses;
 
1296
                lInheritedClasses.setAutoDelete(false);
 
1297
                searchInheritedClasses(buildFullClassName(pItem),lInheritedClasses);
 
1298
                for(unsigned int u=0; u < lInheritedClasses.count(); u++)
 
1299
                {
 
1300
                        lInheritedClasses.at(u)->setClassNotBuilt(true);
 
1301
                        lInheritedClasses.at(u)->setExpanded(true);
 
1302
                        lInheritedClasses.at(u)->setInheritsClass("object");
 
1303
                }
 
1304
        }
 
1305
        
 
1306
        while(pItem->childCount() > 0)
 
1307
        {
 
1308
                ClassEditorTreeWidgetItem * pChild = (ClassEditorTreeWidgetItem *)(pItem->child(0));
 
1309
                if(pChild->childCount())
 
1310
                        removeItemChildren(pChild,lRemovedItems);
 
1311
                if(pChild->isClass())
 
1312
                {
 
1313
                        m_pClasses->removeRef(pChild);
 
1314
                        KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(buildFullClassName(pChild));
 
1315
                        if(pClass)
 
1316
                                KviKvsKernel::instance()->objectController()->deleteClass(pClass);
 
1317
                        qDebug("removing class %s %p",buildFullClassName(pChild).toUtf8().data(), pClass);
 
1318
                }
 
1319
                pItem->removeChild(pChild);
 
1320
                lRemovedItems.append(pItem);
 
1321
                delete pChild;
 
1322
        }
 
1323
}
 
1324
 
 
1325
bool ClassEditorWidget::removeItem(ClassEditorTreeWidgetItem * pItem, KviPointerList <ClassEditorTreeWidgetItem> & lRemovedItems, bool * pbYesToAll)
 
1326
{
 
1327
        if(!pItem)
 
1328
                return true;
 
1329
        QString szMsg;
 
1330
        QString szName = pItem->name();
 
1331
 
 
1332
        if(!*pbYesToAll)
 
1333
        {
 
1334
                saveLastEditedItem();
 
1335
                if(pItem->isClass())
 
1336
                {
 
1337
                        szMsg = QString(__tr2qs_ctx("Do you really want to remove the class \"%1\"?","editor")).arg(szName);
 
1338
                } else if(pItem->isNamespace())
 
1339
                {
 
1340
                        szMsg = QString(__tr2qs_ctx("Do you really want to remove the namespace \"%1\"?","editor")).arg(szName);
 
1341
                        szMsg += "<br>";
 
1342
                        szMsg += __tr2qs_ctx("Please note that all the children classes/functions will be deleted too.","editor");
 
1343
                } else if(pItem->isMethod())
 
1344
                {
 
1345
                        szMsg = QString(__tr2qs_ctx("Do you really want to remove the function \"%1\"?","editor")).arg(szName);
 
1346
                }
 
1347
                
 
1348
                g_pClassEditorModule->lock();
 
1349
                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"));
 
1350
                g_pClassEditorModule->unlock();
 
1351
                switch(iRet)
 
1352
                {
 
1353
                        case 0:
 
1354
                                // nothing
 
1355
                        break;
 
1356
                        case 1:
 
1357
                                *pbYesToAll = true;
 
1358
                        break;
 
1359
                        default:
 
1360
                                return false;
 
1361
                        break;
 
1362
                }
 
1363
        }
 
1364
 
 
1365
        if(pItem == m_pLastEditedItem)
 
1366
                m_pLastEditedItem = 0;
 
1367
        if(pItem == m_pLastClickedItem)
 
1368
                m_pLastClickedItem = 0;
 
1369
        if(pItem->childCount())
 
1370
                removeItemChildren(pItem,lRemovedItems);
 
1371
        if(pItem->isClass())
 
1372
        {
 
1373
                m_pClasses->removeRef(pItem);
 
1374
                KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(buildFullClassName(pItem));
 
1375
                qDebug("removing class %s %p",buildFullClassName(pItem).toUtf8().data(), pClass);
 
1376
                if(pClass)
 
1377
                        KviKvsKernel::instance()->objectController()->deleteClass(pClass);
 
1378
                else
 
1379
                {
 
1380
                        QString szFileName = buildFullClassName(pItem);
 
1381
                        szFileName.replace("::","--");
 
1382
                        szFileName.append(KVI_FILEEXTENSION_SCRIPT);
 
1383
                        QString szPath;
 
1384
                        g_pApp->getLocalKvircDirectory(szPath,KviApplication::Classes);
 
1385
                        QDir d(szPath);
 
1386
                        if(d.exists(szFileName))
 
1387
                        {
 
1388
                                qDebug("rimuovo dal disco il file %s",szFileName.toUtf8().data());
 
1389
                                d.remove(szFileName);
 
1390
                        }
 
1391
                }
 
1392
        }
 
1393
        if(pItem->isMethod())
 
1394
        {
 
1395
                updateClassHierarchy((ClassEditorTreeWidgetItem *)pItem->parent());
 
1396
        }
 
1397
        lRemovedItems.append(pItem);
 
1398
        delete pItem;
 
1399
        return true;
 
1400
}
 
1401
 
 
1402
void ClassEditorWidget::updateClassHierarchy(ClassEditorTreeWidgetItem * pClass)
 
1403
{
 
1404
        pClass->setClassNotBuilt(true);
 
1405
        KviPointerList<ClassEditorTreeWidgetItem> lInheritedClasses;
 
1406
        lInheritedClasses.setAutoDelete(false);
 
1407
        searchInheritedClasses(pClass->name(),lInheritedClasses);
 
1408
        for(unsigned int u=0; u < lInheritedClasses.count(); u++)
 
1409
        {
 
1410
                lInheritedClasses.at(u)->setClassNotBuilt(true);
 
1411
                lInheritedClasses.at(u)->setInheritsClass(pClass->name());
 
1412
                lInheritedClasses.at(u)->setExpanded(true);
 
1413
        }
 
1414
}
 
1415
 
 
1416
void ClassEditorWidget::removeSelectedItems()
 
1417
{
 
1418
        KviPointerList<ClassEditorTreeWidgetItem> lRemovedItems;
 
1419
        lRemovedItems.setAutoDelete(false);
 
1420
        QList<QTreeWidgetItem *> list = m_pTreeWidget->selectedItems();
 
1421
        bool bYesToAll = false;
 
1422
        for(int i=0; i < list.count(); i++)
 
1423
        {
 
1424
                if(lRemovedItems.findRef((ClassEditorTreeWidgetItem *) list.at(i)) != -1)
 
1425
                        continue;
 
1426
                if(!removeItem((ClassEditorTreeWidgetItem *) list.at(i),lRemovedItems,&bYesToAll))
 
1427
                        return;
 
1428
        }
 
1429
}
 
1430
 
 
1431
bool ClassEditorWidget::askForClassName(QString & szClassName, QString & szInheritsClassName, bool bEdit)
 
1432
{
 
1433
        KviClassEditorDialog * pDialog = new KviClassEditorDialog(this,"classdialog",m_pClasses,szClassName,szInheritsClassName,bEdit);
 
1434
        szClassName = "";
 
1435
        g_pClassEditorModule->lock();
 
1436
        bool bOk = pDialog->exec();
 
1437
        g_pClassEditorModule->unlock();
 
1438
        if(bOk)
 
1439
        {
 
1440
                szClassName = pDialog->className();
 
1441
                szInheritsClassName = pDialog->inheritsClassName();
 
1442
                delete pDialog;
 
1443
                return true;
 
1444
        }
 
1445
        delete pDialog;
 
1446
        return false;
 
1447
}
 
1448
 
 
1449
bool ClassEditorWidget::askForFunction(QString & szFunctionName, QString & szReminder, bool * bInternal, const QString & szClassName, bool bRenameMode)
 
1450
{
 
1451
        KviClassEditorFunctionDialog * pDialog = new KviClassEditorFunctionDialog(this,"function",szClassName,szFunctionName,szReminder,*bInternal, bRenameMode);
 
1452
        szFunctionName = "";
 
1453
        g_pClassEditorModule->lock();
 
1454
        bool bOk = pDialog->exec();
 
1455
        g_pClassEditorModule->unlock();
 
1456
        if(bOk)
 
1457
        {
 
1458
                szFunctionName = pDialog->functionName();
 
1459
                szReminder = pDialog->reminder();
 
1460
                *bInternal = pDialog->isInternalFunction();
 
1461
                delete pDialog;
 
1462
                return true;
 
1463
        }
 
1464
        delete pDialog;
 
1465
        return false;
 
1466
}
 
1467
 
 
1468
bool ClassEditorWidget::askForNamespaceName(const QString & szAction, const QString & szText, const QString & szInitialText, QString & szNewName)
 
1469
{
 
1470
        bool bOk = false;
 
1471
        while(szNewName.isEmpty())
 
1472
        {
 
1473
                g_pClassEditorModule->lock();
 
1474
                szNewName = QInputDialog::getText(this,
 
1475
                        szAction,
 
1476
                        szText,
 
1477
                        QLineEdit::Normal,
 
1478
                        szInitialText,
 
1479
                        &bOk);
 
1480
                g_pClassEditorModule->unlock();
 
1481
                if(!bOk)
 
1482
                        return false;
 
1483
                if(szNewName.isEmpty())
 
1484
                {
 
1485
                        g_pClassEditorModule->lock();
 
1486
                        QMessageBox::warning(this,
 
1487
                                __tr2qs_ctx("Missing Namespace Name","editor"),
 
1488
                                __tr2qs_ctx("You must specify a valid name for the namespace","editor"),
 
1489
                                __tr2qs_ctx("Ok, Let me try again...","editor"));
 
1490
                        g_pClassEditorModule->unlock();
 
1491
                        continue;
 
1492
                }
 
1493
 
 
1494
                // we allow only [\w:]+
 
1495
                QRegExp re("[\\w:]+");
 
1496
                if(!re.exactMatch(szNewName))
 
1497
                {
 
1498
                        g_pClassEditorModule->lock();
 
1499
                        QMessageBox::information(this,
 
1500
                                __tr2qs_ctx("Bad Namespace Name","editor"),
 
1501
                                __tr2qs_ctx("Namespace names can contain only letters, digits, underscores and '::' namespace separators","editor"),
 
1502
                                __tr2qs_ctx("Ok, Let me try again...","editor"));
 
1503
                        g_pClassEditorModule->unlock();
 
1504
                        szNewName = "";
 
1505
                        continue;
 
1506
                }
 
1507
                // make sure that we have only doubled "::" and not ":" or ":::..."
 
1508
                QString szTmp = szNewName;
 
1509
                szTmp.replace("::","@"); // @ is not allowed by the rule above
 
1510
                if(szTmp.indexOf(":",Qt::CaseInsensitive) != -1)
 
1511
                {
 
1512
                        g_pClassEditorModule->lock();
 
1513
                        QMessageBox::information(this,
 
1514
                                __tr2qs_ctx("Bad Namespace Name","editor"),
 
1515
                                __tr2qs_ctx("Stray ':' character in namespace name: did you mean ...<namespace>::<name> ?","editor"),
 
1516
                                __tr2qs_ctx("Ok, Let me try again...","editor"));
 
1517
                        g_pClassEditorModule->unlock();
 
1518
                        szNewName = "";
 
1519
                        continue;
 
1520
                }
 
1521
                if(szTmp.indexOf("@@",Qt::CaseInsensitive) != -1)
 
1522
                {
 
1523
                        g_pClassEditorModule->lock();
 
1524
                        QMessageBox::information(this,
 
1525
                                __tr2qs_ctx("Bad Namespace Name","editor"),
 
1526
                                __tr2qs_ctx("Found an empty namespace in namespace name","editor"),
 
1527
                                __tr2qs_ctx("Ok, Let me try again...","editor"));
 
1528
                        g_pClassEditorModule->unlock();
 
1529
                        szNewName = "";
 
1530
                        continue;
 
1531
                }
 
1532
        }
 
1533
        return true;
 
1534
}
 
1535
 
 
1536
void ClassEditorWidget::openParentItems(QTreeWidgetItem * pItem)
 
1537
{
 
1538
        if(pItem->parent())
 
1539
        {
 
1540
                pItem->parent()->setExpanded(true);
 
1541
                openParentItems(pItem->parent());
 
1542
        }
 
1543
}
 
1544
 
 
1545
void ClassEditorWidget::activateItem(QTreeWidgetItem * pItem)
 
1546
{
 
1547
        if(!pItem)
 
1548
                return;
 
1549
        openParentItems(pItem);
 
1550
        m_pTreeWidget->setCurrentItem(pItem);
 
1551
}
 
1552
 
 
1553
void ClassEditorWidget::newClass()
 
1554
{
 
1555
        QString szClassName;
 
1556
        QString szinheritsClassName;
 
1557
        askForClassName(szClassName,szinheritsClassName,false);
 
1558
        if(szClassName.isEmpty())
 
1559
                return;
 
1560
        ClassEditorTreeWidgetItem * pItem = newItem(szClassName,ClassEditorTreeWidgetItem::Class);
 
1561
        
 
1562
        KviQString::escapeKvs(&szClassName, KviQString::EscapeSpace);
 
1563
        KviQString::escapeKvs(&szinheritsClassName, KviQString::EscapeSpace);
 
1564
 
 
1565
        QString szClass = "class(";
 
1566
        szClass += szClassName + "," + szinheritsClassName;
 
1567
        szClass += "){}\n";
 
1568
        pItem->setInheritsClass(szinheritsClassName);
 
1569
        activateItem(pItem);
 
1570
        m_pClasses->insert(szClassName,pItem);
 
1571
        KviKvsScript::run(szClass,g_pActiveWindow);
 
1572
}
 
1573
 
 
1574
void ClassEditorWidget::newNamespace()
 
1575
{
 
1576
        QString szName;
 
1577
        if(!askForNamespaceName(__tr2qs_ctx("Add Namespace","editor"),__tr2qs_ctx("Please enter the name for the new namespace","editor"),"mynamespace",szName))
 
1578
                return;
 
1579
        if(szName.isEmpty())
 
1580
                return;
 
1581
        ClassEditorTreeWidgetItem * pItem = newItem(szName,ClassEditorTreeWidgetItem::Namespace);
 
1582
        activateItem(pItem);
 
1583
}
 
1584
 
 
1585
void ClassEditorWidget::newMemberFunction()
 
1586
{
 
1587
        QString szFunctionName;
 
1588
        QString szClassName;
 
1589
        QString szReminder;
 
1590
        
 
1591
        if(m_pLastClickedItem->isMethod())
 
1592
                m_pLastClickedItem = (ClassEditorTreeWidgetItem*)m_pLastClickedItem->parent();
 
1593
        szClassName = buildFullClassName(m_pLastClickedItem);
 
1594
        bool bInternal = false;
 
1595
        if(!askForFunction(szFunctionName, szReminder,&bInternal,szClassName,false))
 
1596
                return;
 
1597
        if(szFunctionName.isEmpty())
 
1598
                return;
 
1599
        
 
1600
        ClassEditorTreeWidgetItem * pItem = newItem(szFunctionName,ClassEditorTreeWidgetItem::Method);
 
1601
        pItem->setInternalFunction(bInternal);
 
1602
        if(!szReminder.isEmpty())
 
1603
                pItem->setReminder(szReminder);
 
1604
        activateItem(pItem);
 
1605
        ((ClassEditorTreeWidgetItem*)pItem->parent())->setClassNotBuilt(true);
 
1606
}
 
1607
 
 
1608
ClassEditorTreeWidgetItem * ClassEditorWidget::newItem(QString & szName, ClassEditorTreeWidgetItem::Type eType)
 
1609
{
 
1610
        if(m_pLastClickedItem)
 
1611
                buildFullItemPath(m_pLastClickedItem,szName);
 
1612
        
 
1613
        QString szTmp;
 
1614
        if(findItem(szName))
 
1615
                szName.append("1");
 
1616
        
 
1617
        int iIdx = 2;
 
1618
        while(findItem(szName))
 
1619
        {
 
1620
                szTmp.setNum(iIdx);
 
1621
                szName.chop(szTmp.length());
 
1622
                szName.append(szTmp);
 
1623
                iIdx++;
 
1624
        }
 
1625
        ClassEditorTreeWidgetItem * pItem;
 
1626
        pItem = createFullItem(szName);
 
1627
        pItem->setType(eType);
 
1628
        return pItem;
 
1629
}
 
1630
 
 
1631
void ClassEditorWidget::build()
 
1632
{
 
1633
        saveLastEditedItem();
 
1634
        KviPointerHashTableIterator<QString,ClassEditorTreeWidgetItem> it (*m_pClasses);
 
1635
        KviPointerList<ClassEditorTreeWidgetItem> linkedClasses;
 
1636
        linkedClasses.setAutoDelete(false);
 
1637
        KviPointerList<ClassEditorTreeWidgetItem> skipClasses;
 
1638
        skipClasses.setAutoDelete(false);
 
1639
        bool bErrorWhilecompiling = false;
 
1640
        while(it.current())
 
1641
        {
 
1642
                ClassEditorTreeWidgetItem * pClass = it.current();
 
1643
                if(skipClasses.findRef(it.current()) != -1)
 
1644
                {
 
1645
                        ++it;
 
1646
                        continue;
 
1647
                }
 
1648
                if(pClass->classNotBuilt())
 
1649
                {
 
1650
                        //qDebug("compiling %s",pClass->name().toUtf8().data());
 
1651
                        ClassEditorTreeWidgetItem * pParentClass = m_pClasses->find(pClass->inheritsClass());
 
1652
 
 
1653
                        linkedClasses.append(pClass);
 
1654
                        //if (!pParentClass) qDebug("no parent class");
 
1655
                        while(pParentClass)
 
1656
                        {
 
1657
                                if(pParentClass->classNotBuilt())
 
1658
                                        linkedClasses.append(pParentClass);
 
1659
                                pParentClass = m_pClasses->find(pParentClass->inheritsClass());
 
1660
                        }
 
1661
                        for(int i = linkedClasses.count()-1; i >= 0; i--)
 
1662
                        {
 
1663
                                QString szFullClassName = buildFullClassName(linkedClasses.at(i));
 
1664
                                KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(szFullClassName);
 
1665
                                if(pClass)
 
1666
                                        KviKvsKernel::instance()->objectController()->deleteClass(pClass);
 
1667
                                QString szClass;
 
1668
                                exportClassBuffer(szClass, linkedClasses.at(i));
 
1669
                                KviKvsScript::run(szClass,g_pActiveWindow);
 
1670
                                pClass = KviKvsKernel::instance()->objectController()->lookupClass(szFullClassName);
 
1671
                                if(!pClass)
 
1672
                                {
 
1673
                                        bErrorWhilecompiling = true;
 
1674
                                        QString szError = __tr2qs_ctx("Unable to compile class: ","editor");
 
1675
                                        szError += szFullClassName + "\n";
 
1676
                                        KviPointerList<ClassEditorTreeWidgetItem> lInheritedClasses;
 
1677
                                        lInheritedClasses.setAutoDelete(false);
 
1678
                                        searchInheritedClasses(szFullClassName,lInheritedClasses);
 
1679
                                        if(lInheritedClasses.count())
 
1680
                                        {
 
1681
                                                szError += __tr2qs_ctx("These inherited classes will be not compiled too:","editor");
 
1682
                                                szError += "\n";
 
1683
                                                for(unsigned int u=0; u < lInheritedClasses.count(); u++)
 
1684
                                                {
 
1685
                                                        szError += buildFullClassName(lInheritedClasses.at(u)) + "\n";
 
1686
                                                        lInheritedClasses.at(u)->setClassNotBuilt(true);
 
1687
                                                        skipClasses.append(lInheritedClasses.at(u));
 
1688
                                                }
 
1689
                                        }
 
1690
                                        QMessageBox::critical(this,__tr2qs_ctx("Compilation error - KVIrc","editor"),szError,
 
1691
                                        QMessageBox::Ok,QMessageBox::NoButton,QMessageBox::NoButton);
 
1692
                                        break;
 
1693
                                }
 
1694
                                //else qDebug("class compiled %s :\n",szClass.toUtf8().data());
 
1695
                                linkedClasses.at(i)->setClassNotBuilt(false);
 
1696
                                m_pEditor->setModified(false);
 
1697
                        }
 
1698
                }
 
1699
                ++it;
 
1700
        }
 
1701
        if(bErrorWhilecompiling)
 
1702
                saveNotBuiltClasses();
 
1703
        else {
 
1704
                QString szFileName = "libkviclasseditortmp.kvc";
 
1705
                QString szBuffer;
 
1706
                g_pApp->getLocalKvircDirectory(szBuffer,KviApplication::ConfigPlugins,szFileName);
 
1707
                KviConfigurationFile cfg(szBuffer,KviConfigurationFile::Write);
 
1708
                cfg.clear();
 
1709
                cfg.sync();
 
1710
        }
 
1711
        KviKvsKernel::instance()->objectController()->flushUserClasses();
 
1712
}
 
1713
 
 
1714
void ClassEditorWidget::loadNotBuiltClasses()
 
1715
{
 
1716
        QString szFileName = "libkviclasseditortmp.kvc";
 
1717
        QString szBuffer;
 
1718
        g_pApp->getLocalKvircDirectory(szBuffer,KviApplication::ConfigPlugins,szFileName);
 
1719
        KviConfigurationFile cfg(szBuffer,KviConfigurationFile::Read);
 
1720
        KviConfigurationFileIterator it(*(cfg.dict()));
 
1721
 
 
1722
        KviPointerList<QString> l;
 
1723
        l.setAutoDelete(true);
 
1724
 
 
1725
        while(it.current())
 
1726
        {
 
1727
                l.append(new QString(it.currentKey()));
 
1728
                ++it;
 
1729
        }
 
1730
 
 
1731
        for(QString * pszTmp = l.first(); pszTmp; pszTmp = l.next())
 
1732
        {
 
1733
                cfg.setGroup(*pszTmp);
 
1734
                ClassEditorTreeWidgetItem * pClassItem = createFullItem(*pszTmp);
 
1735
                m_pClasses->insert(*pszTmp,pClassItem);
 
1736
                pClassItem->setClassNotBuilt(true);
 
1737
                KviConfigurationFileGroup * pDict = cfg.dict()->find(*pszTmp);
 
1738
                if(pDict)
 
1739
                {
 
1740
                        KviConfigurationFileGroupIterator it(*pDict);
 
1741
                        KviPointerList<QString> names;
 
1742
                        names.setAutoDelete(true);
 
1743
                        while(it.current())
 
1744
                        {
 
1745
                                names.append(new QString(it.currentKey()));
 
1746
                                ++it;
 
1747
                        }
 
1748
                        for(QString * pszTmp = names.first(); pszTmp; pszTmp = names.next())
 
1749
                        {
 
1750
 
 
1751
                                if(KviQString::equalCI(*pszTmp,"@Inherits"))
 
1752
                                {
 
1753
                                        pClassItem->setInheritsClass(cfg.readEntry(*pszTmp,""));
 
1754
                                        continue;
 
1755
                                }
 
1756
                                if((*pszTmp).left(9) == "@Reminder")
 
1757
                                        continue;
 
1758
                                QString szCode = cfg.readEntry(*pszTmp,"");
 
1759
                                ClassEditorTreeWidgetItem * pFunctionItem = findFunction(*pszTmp, pClassItem);
 
1760
                                if(!pFunctionItem)
 
1761
                                        pFunctionItem = new ClassEditorTreeWidgetItem(pClassItem,ClassEditorTreeWidgetItem::Method,*pszTmp);
 
1762
                                pFunctionItem->setBuffer(szCode);
 
1763
                                QString szEntry = "@Reminder|" + (*pszTmp);
 
1764
                                QString szReminder = cfg.readEntry(szEntry,"");
 
1765
                                pFunctionItem->setReminder(szReminder);
 
1766
                        }
 
1767
                }
 
1768
        }
 
1769
}
 
1770
 
 
1771
void ClassEditorWidget::saveNotBuiltClasses()
 
1772
{
 
1773
        saveLastEditedItem();
 
1774
        KviPointerHashTableIterator<QString,ClassEditorTreeWidgetItem> it (*m_pClasses);
 
1775
        QString szFileName = "libkviclasseditortmp.kvc";
 
1776
        QString szBuffer;
 
1777
        g_pApp->getLocalKvircDirectory(szBuffer,KviApplication::ConfigPlugins,szFileName);
 
1778
        KviConfigurationFile cfg(szBuffer,KviConfigurationFile::Write);
 
1779
        cfg.clear();
 
1780
 
 
1781
        while(it.current())
 
1782
        {
 
1783
                if(it.current()->classNotBuilt())
 
1784
                {
 
1785
                        KviKvsObjectClass * pClass = KviKvsKernel::instance()->objectController()->lookupClass(it.currentKey());
 
1786
                        if(pClass)
 
1787
                                KviKvsKernel::instance()->objectController()->deleteClass(pClass);
 
1788
 
 
1789
                        cfg.setGroup(it.currentKey());
 
1790
                        cfg.writeEntry("@Inherits",it.current()->inheritsClass());
 
1791
                        QString szReminderEntry;
 
1792
                        for(int i=0; i < it.current()->childCount(); i++)
 
1793
                        {
 
1794
                                if(!((ClassEditorTreeWidgetItem *)it.current()->child(i))->reminder().isEmpty())
 
1795
                                {
 
1796
                                        szReminderEntry="@Reminder|"+((ClassEditorTreeWidgetItem *)it.current()->child(i))->name();
 
1797
                                        cfg.writeEntry(szReminderEntry,((ClassEditorTreeWidgetItem *)it.current()->child(i))->reminder());
 
1798
                                }
 
1799
                                cfg.writeEntry(((ClassEditorTreeWidgetItem *)it.current()->child(i))->name(),((ClassEditorTreeWidgetItem *)it.current()->child(i))->buffer());
 
1800
                        }
 
1801
                }
 
1802
                ++it;
 
1803
        }
 
1804
        cfg.sync();
 
1805
}
 
1806
 
 
1807
void ClassEditorWidget::searchInheritedClasses(const QString szClass, KviPointerList<ClassEditorTreeWidgetItem> & lInheritedClasses)
 
1808
{
 
1809
        KviPointerHashTableIterator<QString,ClassEditorTreeWidgetItem> it (*m_pClasses);
 
1810
        while(it.current())
 
1811
        {
 
1812
                if(KviQString::equalCI(szClass,it.current()->inheritsClass()))
 
1813
                        lInheritedClasses.append(it.current());
 
1814
                ++it;
 
1815
        }
 
1816
}
 
1817
 
 
1818
ClassEditorWindow::ClassEditorWindow(KviMainWindow * pFrm)
 
1819
: KviWindow(KviWindow::ScriptEditor,pFrm,"classeditor",0)
 
1820
{
 
1821
        g_pClassEditorWindow = this;
 
1822
 
 
1823
        setFixedCaption(__tr2qs_ctx("Class Editor","editor"));
 
1824
 
 
1825
        QGridLayout * pLayout = new QGridLayout();
 
1826
 
 
1827
        m_pEditor = new ClassEditorWidget(this);
 
1828
        pLayout->addWidget(m_pEditor,0,0,1,4);
 
1829
 
 
1830
        QPushButton * pBtn = new QPushButton(__tr2qs_ctx("&Build","editor"),this);
 
1831
        pBtn->setIcon(*(g_pIconManager->getSmallIcon(KviIconManager::Accept)));
 
1832
        pLayout->addWidget(pBtn,1,1);
 
1833
        connect(pBtn,SIGNAL(clicked()),this,SLOT(buildClicked()));
 
1834
 
 
1835
        pBtn = new QPushButton(__tr2qs_ctx("&Save","editor"),this);
 
1836
        pBtn->setIcon(*(g_pIconManager->getSmallIcon(KviIconManager::Accept)));
 
1837
        pLayout->addWidget(pBtn,1,2);
 
1838
        connect(pBtn,SIGNAL(clicked()),this,SLOT(saveClicked()));
 
1839
 
 
1840
        pBtn = new QPushButton(__tr2qs_ctx("Close","editor"),this);
 
1841
        pBtn->setIcon(*(g_pIconManager->getSmallIcon(KviIconManager::Discard)));
 
1842
        pLayout->addWidget(pBtn,1,3);
 
1843
        connect(pBtn,SIGNAL(clicked()),this,SLOT(cancelClicked()));
 
1844
 
 
1845
        pLayout->setRowStretch(0,1);
 
1846
        pLayout->setColumnStretch(0,1);
 
1847
        setLayout(pLayout);
 
1848
}
 
1849
 
 
1850
ClassEditorWindow::~ClassEditorWindow()
 
1851
{
 
1852
        g_pClassEditorWindow = 0;
 
1853
}
 
1854
 
 
1855
void ClassEditorWindow::buildClicked()
 
1856
{
 
1857
        m_pEditor->build();
 
1858
}
 
1859
 
 
1860
void ClassEditorWindow::saveClicked()
 
1861
{
 
1862
        m_pEditor->saveNotBuiltClasses();
 
1863
}
 
1864
 
 
1865
void ClassEditorWindow::cancelClicked()
 
1866
{
 
1867
        close();
 
1868
}
 
1869
 
 
1870
QPixmap * ClassEditorWindow::myIconPtr()
 
1871
{
 
1872
        return g_pIconManager->getSmallIcon(KviIconManager::ClassEditor);
 
1873
}
 
1874
 
 
1875
void ClassEditorWindow::configGroupName(QString &szName)
 
1876
{
 
1877
        szName = "classeditor";
 
1878
}
 
1879
 
 
1880
void ClassEditorWindow::saveProperties(KviConfigurationFile * pCfg)
 
1881
{
 
1882
        m_pEditor->saveProperties(pCfg);
 
1883
}
 
1884
 
 
1885
void ClassEditorWindow::loadProperties(KviConfigurationFile * pCfg)
 
1886
{
 
1887
        m_pEditor->loadProperties(pCfg);
 
1888
}
 
1889
 
 
1890
KviClassEditorDialog::KviClassEditorDialog(QWidget * pParent, const QString & szName, KviPointerHashTable<QString,ClassEditorTreeWidgetItem> * pClasses, const QString & szClassName, const QString & szInheritsClassName, bool bRenameMode)
 
1891
: QDialog(pParent)
 
1892
{
 
1893
        setObjectName(szName);
 
1894
 
 
1895
        QGridLayout * pLayout = new QGridLayout(this);
 
1896
 
 
1897
        KviTalHBox * pHBox = new KviTalHBox(this);
 
1898
        pHBox->setSpacing(0);
 
1899
        pHBox->setMargin(0);
 
1900
        pLayout->addWidget(pHBox,0,0);
 
1901
 
 
1902
        QLabel * pLabel = new QLabel(pHBox);
 
1903
        pLabel->setObjectName("classnamelabel");
 
1904
        pLabel->setText(__tr2qs_ctx("Please enter the name for the class:","editor"));
 
1905
 
 
1906
        m_pClassNameLineEdit = new QLineEdit(pHBox);
 
1907
        m_pClassNameLineEdit->setObjectName("classnameineedit");
 
1908
        m_pClassNameLineEdit->setText(szClassName);
 
1909
        pLabel->setBuddy(m_pClassNameLineEdit);
 
1910
        QRegExp re;
 
1911
        if(!bRenameMode)
 
1912
        {
 
1913
                // we allow only [\w:]+ class name
 
1914
                re.setPattern("[\\w]+");
 
1915
                m_pClassNameLineEdit->setToolTip(__tr2qs_ctx("Class names can contain only letters, digits and underscores","editor"));
 
1916
        } else {
 
1917
                // in editor mode we allow [\w:]+ and namespace separator
 
1918
                re.setPattern("[\\w]+(::[\\w]+)+");
 
1919
                m_pClassNameLineEdit->setToolTip(__tr2qs_ctx("In rename mode class names can contain only letters, digits and underscores and namespaces :: separator","editor"));
 
1920
        }
 
1921
        QRegExpValidator * pValidator = new QRegExpValidator(re,this);
 
1922
        m_pClassNameLineEdit->setValidator(pValidator);
 
1923
        m_pClassNameLineEdit->setObjectName("functionameineedit");
 
1924
        
 
1925
        pHBox = new KviTalHBox(this);
 
1926
        pHBox->setSpacing(0);
 
1927
        pHBox->setMargin(0);
 
1928
        pLayout->addWidget(pHBox,1,0);
 
1929
 
 
1930
        pLabel = new QLabel(pHBox);
 
1931
        pLabel->setObjectName("Inheritsclasslabel");
 
1932
        pLabel->setText(__tr2qs_ctx("Inherits Class:","editor"));
 
1933
 
 
1934
        m_pInheritsClassComboBox = new QComboBox(pHBox);
 
1935
        pLabel->setBuddy(m_pInheritsClassComboBox);
 
1936
 
 
1937
        KviPointerHashTableIterator<QString,ClassEditorTreeWidgetItem> pClassesIt(*pClasses);
 
1938
 
 
1939
        QStringList szClasses;
 
1940
        while(pClassesIt.current())
 
1941
        {
 
1942
                if(!KviQString::equalCI(pClassesIt.currentKey(),szClassName))
 
1943
                        szClasses.append(pClassesIt.currentKey());
 
1944
                ++pClassesIt;
 
1945
        }
 
1946
        KviPointerHashTableIterator<QString,KviKvsObjectClass> pBuiltinClasses(*KviKvsKernel::instance()->objectController()->classDict());
 
1947
        while(pBuiltinClasses.current())
 
1948
        {
 
1949
                if(pBuiltinClasses.current()->isBuiltin())
 
1950
                        szClasses.append(pBuiltinClasses.currentKey());
 
1951
                ++pBuiltinClasses;
 
1952
        }
 
1953
        
 
1954
        int iCurrentIdx;
 
1955
        szClasses.sort();
 
1956
        for(int i=0; i < szClasses.count(); i++)
 
1957
                m_pInheritsClassComboBox->addItem(szClasses.at(i));
 
1958
        if(szInheritsClassName.isEmpty())
 
1959
                iCurrentIdx = m_pInheritsClassComboBox->findText("object");
 
1960
        else {
 
1961
                iCurrentIdx = m_pInheritsClassComboBox->findText(szInheritsClassName);
 
1962
                if(iCurrentIdx == -1)
 
1963
                        iCurrentIdx = m_pInheritsClassComboBox->findText("object");
 
1964
        }
 
1965
        m_pInheritsClassComboBox->setCurrentIndex(iCurrentIdx);
 
1966
        m_pClassNameLineEdit->setFocus();
 
1967
        connect(m_pClassNameLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &)));
 
1968
 
 
1969
        pHBox = new KviTalHBox(this);
 
1970
        pHBox->setSpacing(0);
 
1971
        pHBox->setMargin(0);
 
1972
        pLayout->addWidget(pHBox,2,0);
 
1973
 
 
1974
        m_pNewClassButton = new QPushButton(pHBox);
 
1975
        m_pNewClassButton->setObjectName("newclassbutton");
 
1976
        if(bRenameMode)
 
1977
                m_pNewClassButton->setText(__tr2qs_ctx("&Rename Class","editor"));
 
1978
        else {
 
1979
                m_pNewClassButton->setText(__tr2qs_ctx("&Create Class","editor"));
 
1980
                m_pNewClassButton->setEnabled(false);
 
1981
        }
 
1982
        connect(m_pNewClassButton, SIGNAL(clicked()), this, SLOT(accept()));
 
1983
 
 
1984
        QPushButton * pCancelButton = new QPushButton(pHBox);
 
1985
        pCancelButton->setObjectName("cancelButton");
 
1986
        pCancelButton->setText(__tr2qs_ctx("&Cancel","editor"));
 
1987
        connect(pCancelButton, SIGNAL(clicked()), this, SLOT(reject()));
 
1988
        
 
1989
        setLayout(pLayout);
 
1990
}
 
1991
 
 
1992
KviClassEditorDialog::~KviClassEditorDialog()
 
1993
{
 
1994
}
 
1995
 
 
1996
void KviClassEditorDialog::textChanged(const QString & szText)
 
1997
{
 
1998
        m_pNewClassButton->setEnabled(!szText.isEmpty());
 
1999
}
 
2000
 
 
2001
KviClassEditorFunctionDialog::KviClassEditorFunctionDialog(QWidget * pParent, const QString & szName, const QString & szClassName, const QString & szFunctionName, const QString & szReminder, bool bIsInternal, bool bRenameMode)
 
2002
: QDialog(pParent)
 
2003
{
 
2004
        setObjectName(szName);
 
2005
 
 
2006
        QGridLayout * pLayout = new QGridLayout(this);
 
2007
 
 
2008
        KviTalHBox * pHBox = new KviTalHBox(this);
 
2009
        pHBox->setSpacing(0);
 
2010
        pHBox->setMargin(0);
 
2011
        pLayout->addWidget(pHBox,0,0);
 
2012
 
 
2013
        QLabel * pLabel = new QLabel(pHBox);
 
2014
        pLabel->setObjectName("classnamelabel");
 
2015
        pLabel->setText("Class: <b>"+szClassName+"</b>");
 
2016
 
 
2017
        pHBox = new KviTalHBox(this);
 
2018
        pHBox->setSpacing(0);
 
2019
        pHBox->setMargin(0);
 
2020
        pLayout->addWidget(pHBox,1,0);
 
2021
 
 
2022
        pLabel = new QLabel(pHBox);
 
2023
        pLabel->setObjectName("functionnamelabel");
 
2024
        pLabel->setText(__tr2qs_ctx("Please enter the name for the member function:","editor"));
 
2025
 
 
2026
        m_pFunctionNameLineEdit = new QLineEdit(pHBox);
 
2027
 
 
2028
        // we allow only [\w:]+ function name
 
2029
        QRegExp re("[\\w]+");
 
2030
        QRegExpValidator * pValidator = new QRegExpValidator(re,this);
 
2031
        m_pFunctionNameLineEdit->setValidator(pValidator);
 
2032
        m_pFunctionNameLineEdit->setObjectName("functionameineedit");
 
2033
        m_pFunctionNameLineEdit->setToolTip(__tr2qs_ctx("Function names can contain only letters, digits and underscores","editor"));
 
2034
        m_pFunctionNameLineEdit->setText(szFunctionName);
 
2035
        pLabel->setBuddy(m_pFunctionNameLineEdit);
 
2036
 
 
2037
        pHBox = new KviTalHBox(this);
 
2038
        pHBox->setSpacing(0);
 
2039
        pHBox->setMargin(0);
 
2040
        pLayout->addWidget(pHBox,2,0);
 
2041
 
 
2042
        pLabel = new QLabel(pHBox);
 
2043
        pLabel->setObjectName("reminderlabel");
 
2044
        pLabel->setWordWrap(1);
 
2045
        pLabel->setText(__tr2qs_ctx("Please enter the optional reminder string for the member function:","editor"));
 
2046
 
 
2047
        m_pReminderLineEdit = new QLineEdit(pHBox);
 
2048
        m_pReminderLineEdit->setText(szReminder);
 
2049
        pLabel->setBuddy(m_pReminderLineEdit);
 
2050
 
 
2051
        pHBox = new KviTalHBox(this);
 
2052
        pHBox->setSpacing(0);
 
2053
        pHBox->setMargin(0);
 
2054
        pLayout->addWidget(pHBox,3,0);
 
2055
 
 
2056
        pLabel = new QLabel(pHBox);
 
2057
        pLabel->setObjectName("functionnamelabel");
 
2058
        pLabel->setText(__tr2qs_ctx("Set as <b>Internal</b> Function: ","editor"));
 
2059
 
 
2060
        m_pInternalCheckBox = new QCheckBox(pHBox);
 
2061
        m_pInternalCheckBox->setChecked(bIsInternal);
 
2062
        m_pFunctionNameLineEdit->setFocus();
 
2063
        pLabel->setBuddy(m_pInternalCheckBox);
 
2064
        connect(m_pFunctionNameLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &)));
 
2065
        
 
2066
        pHBox->setAlignment(m_pInternalCheckBox,Qt::AlignLeft);
 
2067
        pHBox->setStretchFactor(m_pInternalCheckBox,70);
 
2068
        pHBox->setStretchFactor(pLabel,30);
 
2069
 
 
2070
        pHBox = new KviTalHBox(this);
 
2071
        pHBox->setSpacing(0);
 
2072
        pHBox->setMargin(0);
 
2073
        pLayout->addWidget(pHBox,4,0);
 
2074
 
 
2075
        m_pNewFunctionButton = new QPushButton(pHBox);
 
2076
        m_pNewFunctionButton->setObjectName("newfunctionbutton");
 
2077
        if(!bRenameMode)
 
2078
                m_pNewFunctionButton->setText(__tr2qs_ctx("&Add","editor"));
 
2079
        else
 
2080
                m_pNewFunctionButton->setText(__tr2qs_ctx("&Rename","editor"));
 
2081
        
 
2082
        if(szFunctionName.isEmpty())
 
2083
                m_pNewFunctionButton->setEnabled(false);
 
2084
        connect(m_pNewFunctionButton, SIGNAL(clicked()), this, SLOT(accept()));
 
2085
 
 
2086
        QPushButton * pCancelButton = new QPushButton(pHBox);
 
2087
        pCancelButton->setObjectName("cancelButton");
 
2088
        pCancelButton->setText(__tr2qs_ctx("&Cancel","editor"));
 
2089
        connect(pCancelButton, SIGNAL(clicked()), this, SLOT(reject()));
 
2090
 
 
2091
        setLayout(pLayout);
 
2092
}
 
2093
 
 
2094
KviClassEditorFunctionDialog::~KviClassEditorFunctionDialog()
 
2095
{
 
2096
}
 
2097
 
 
2098
void KviClassEditorFunctionDialog::textChanged(const QString & szText)
 
2099
{
 
2100
        m_pNewFunctionButton->setEnabled(!szText.isEmpty());
 
2101
}