diff options
Diffstat (limited to 'tools/designer/plugins/cppeditor')
26 files changed, 4286 insertions, 0 deletions
diff --git a/tools/designer/plugins/cppeditor/common.cpp b/tools/designer/plugins/cppeditor/common.cpp new file mode 100644 index 0000000..07b52df --- /dev/null +++ b/tools/designer/plugins/cppeditor/common.cpp @@ -0,0 +1,111 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "editorinterfaceimpl.h" +#include "languageinterfaceimpl.h" +#include "preferenceinterfaceimpl.h" +#include "projectsettingsinterfaceimpl.h" +#include "sourcetemplateinterfaceimpl.h" + +class CommonInterface : public QComponentInformationInterface +{ +public: + CommonInterface(); + virtual ~CommonInterface(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + Q_REFCOUNT; + + QString name() const { return "C++"; } + QString description() const { return "C++ Integration"; } + QString version() const { return "0.1"; } + QString author() const { return "Trolltech AS"; } + +private: + LanguageInterfaceImpl *langIface; + PreferenceInterfaceImpl *prefIface; + ProjectSettingsInterfaceImpl *proIface; + SourceTemplateInterfaceImpl *srcIface; + +}; + +CommonInterface::CommonInterface() +{ + langIface = new LanguageInterfaceImpl( this ); + langIface->addRef(); + prefIface = new PreferenceInterfaceImpl( this ); + prefIface->addRef(); + proIface = new ProjectSettingsInterfaceImpl( this ); + proIface->addRef(); + srcIface = new SourceTemplateInterfaceImpl; + srcIface->addRef(); +} + +CommonInterface::~CommonInterface() +{ + langIface->release(); + prefIface->release(); + proIface->release(); + srcIface->release(); +} + +QRESULT CommonInterface::queryInterface( const QUuid &uuid, QUnknownInterface** iface ) +{ + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_QComponentInformation ) + *iface = (QComponentInformationInterface*)this; + else if ( uuid == IID_Editor ) + *iface = new EditorInterfaceImpl; + else if ( uuid == IID_Language ) + *iface = langIface; + else if ( uuid == IID_Preference ) + *iface = prefIface; + else if ( uuid == IID_ProjectSettings ) + *iface = proIface; + else if ( uuid == IID_SourceTemplate ) + *iface = srcIface; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + + +Q_EXPORT_COMPONENT() +{ + Q_CREATE_INSTANCE( CommonInterface ) +} diff --git a/tools/designer/plugins/cppeditor/cppbrowser.cpp b/tools/designer/plugins/cppeditor/cppbrowser.cpp new file mode 100644 index 0000000..3d004b5 --- /dev/null +++ b/tools/designer/plugins/cppeditor/cppbrowser.cpp @@ -0,0 +1,78 @@ +/********************************************************************** +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "cppbrowser.h" +#include <private/qrichtext_p.h> +#include <qprocess.h> +#include <qmainwindow.h> +#include <qstatusbar.h> +#include <editor.h> + +CppEditorBrowser::CppEditorBrowser( Editor *e ) + : EditorBrowser( e ) +{ +} + +void CppEditorBrowser::showHelp( const QString &w ) +{ + QString word( w ); + if ( word[ 0 ] == 'Q' ) { + if ( word[ (int)word.length() - 1 ] == '&' || + word[ (int)word.length() - 1 ] == '*' ) + word.remove( word.length() - 1, 1 ); + word = word.lower() + ".html"; + QStringList lst; + lst << "assistant" << "-file" << word; + QProcess proc( lst ); + proc.start(); + return; + } + + if ( word.find( '(' ) != -1 ) { + QString txt = "::" + word.left( word.find( '(' ) ); + QTextDocument *doc = curEditor->document(); + QTextParagraph *p = doc->firstParagraph(); + while ( p ) { + if ( p->string()->toString().find( txt ) != -1 ) { + curEditor->setCursorPosition( p->paragId(), 0 ); + return; + } + p = p->next(); + } + } + + QMainWindow *mw = ::qt_cast<QMainWindow*>(curEditor->topLevelWidget()); + if ( mw ) + mw->statusBar()->message( tr( "Nothing available for '%1'" ).arg( w ), 1500 ); +} diff --git a/tools/designer/plugins/cppeditor/cppbrowser.h b/tools/designer/plugins/cppeditor/cppbrowser.h new file mode 100644 index 0000000..92f07b9 --- /dev/null +++ b/tools/designer/plugins/cppeditor/cppbrowser.h @@ -0,0 +1,50 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef CPPBROWSER_H +#define CPPBROWSER_H + +#include <browser.h> + +class CppEditorBrowser : public EditorBrowser +{ + Q_OBJECT + +public: + CppEditorBrowser( Editor *e ); + void showHelp( const QString &word ); + +}; + +#endif diff --git a/tools/designer/plugins/cppeditor/cppcompletion.cpp b/tools/designer/plugins/cppeditor/cppcompletion.cpp new file mode 100644 index 0000000..464aedb --- /dev/null +++ b/tools/designer/plugins/cppeditor/cppcompletion.cpp @@ -0,0 +1,220 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "cppcompletion.h" +#include <qobject.h> +#include <qmetaobject.h> +#include <qobjectlist.h> +#include <qregexp.h> + +CppEditorCompletion::CppEditorCompletion( Editor *e ) + : EditorCompletion( e ) +{ +} + +bool CppEditorCompletion::doObjectCompletion( const QString &objName ) +{ + if ( !ths ) + return FALSE; + QString object( objName ); + int i = -1; + if ( ( i = object.findRev( "->" ) ) != -1 ) + object = object.mid( i + 2 ); + if ( ( i = object.findRev( "." ) ) != -1 ) + object = object.mid( i + 1 ); + object = object.simplifyWhiteSpace(); + QObject *obj = 0; + if ( ths->name() == object || object == "this" ) { + obj = ths; + } else { + obj = ths->child( object ); + } + + if ( !obj ) + return FALSE; + + QValueList<CompletionEntry> lst; + + if ( obj->children() ) { + for ( QObjectListIt cit( *obj->children() ); cit.current(); ++cit ) { + QString s( cit.current()->name() ); + if ( s.find( " " ) == -1 && s.find( "qt_" ) == -1 && s.find( "unnamed" ) == -1 ) { + CompletionEntry c; + c.type = "variable"; + c.text = s; + c.prefix = ""; + lst << c; + } + } + } + + QStrList props = obj->metaObject()->propertyNames( TRUE ); + for ( QPtrListIterator<char> pit( props ); pit.current(); ++pit ) { + QString f( pit.current() ); + QChar c = f[ 0 ]; + f.remove( (uint)0, 1 ); + f.prepend( c.upper() ); + f.prepend( "set" ); + + CompletionEntry ce; + ce.type = "property"; + ce.text = f; + ce.postfix = "()"; + + if ( lst.find( ce ) == lst.end() ) + lst << ce; + } + + QStrList slts = obj->metaObject()->slotNames( TRUE ); + for ( QPtrListIterator<char> sit( slts ); sit.current(); ++sit ) { + QString f( sit.current() ); + f = f.left( f.find( "(" ) ); + CompletionEntry c; + c.type = "slot"; + c.text = f; + c.postfix = "()"; + if ( lst.find( c ) == lst.end() ) + lst << c; + } + + if ( lst.isEmpty() ) + return FALSE; + + showCompletion( lst ); + return TRUE; +} + +QValueList<QStringList> CppEditorCompletion::functionParameters( const QString &expr, QChar &separator, + QString &prefix, QString &postfix ) +{ + Q_UNUSED( prefix ); + Q_UNUSED( postfix ); + separator = ','; + if ( !ths ) + return QValueList<QStringList>(); + QString func; + QString objName; + int i = -1; + + i = expr.findRev( "->" ); + if ( i == -1 ) + i = expr.findRev( "." ); + else + ++i; + if ( i == -1 ) { + i = expr.findRev( " " ); + + if ( i == -1 ) + i = expr.findRev( "\t" ); + else + objName = ths->name(); + + if ( i == -1 && expr[ 0 ] != ' ' && expr[ 0 ] != '\t' ) + objName = ths->name(); + } + + if ( !objName.isEmpty() ) { + func = expr.mid( i + 1 ); + func = func.simplifyWhiteSpace(); + } else { + func = expr.mid( i + 1 ); + func = func.simplifyWhiteSpace(); + QString ex( expr ); + ex.remove( i, 0xFFFFFF ); + if ( ex[ (int)ex.length() - 1 ] == '-' ) + ex.remove( ex.length() - 1, 1 ); + int j = -1; + j = ex.findRev( "->" ); + if ( j == -1 ) + j = ex.findRev( "." ); + else + ++j; + if ( j == -1 ) { + j = ex.findRev( " " ); + + if ( j == -1 ) + j = ex.findRev( "\t" ); + else + objName = ths->name(); + + if ( j == -1 ) + objName = ths->name(); + } + objName = ex.mid( j + 1 ); + objName = objName.simplifyWhiteSpace(); + } + + QObject *obj = 0; + if ( ths->name() == objName || objName == "this" ) { + obj = ths; + } else { + obj = ths->child( objName ); + } + + if ( !obj ) + return QValueList<QStringList>(); + + QStrList slts = obj->metaObject()->slotNames( TRUE ); + for ( QPtrListIterator<char> sit( slts ); sit.current(); ++sit ) { + QString f( sit.current() ); + f = f.left( f.find( "(" ) ); + if ( f == func ) { + f = QString( sit.current() ); + f.remove( (uint)0, f.find( "(" ) + 1 ); + f = f.left( f.find( ")" ) ); + QStringList lst = QStringList::split( ',', f ); + if ( !lst.isEmpty() ) { + QValueList<QStringList> l; + l << lst; + return l; + } + } + } + + const QMetaProperty *prop = + obj->metaObject()-> + property( obj->metaObject()->findProperty( func[ 3 ].lower() + func.mid( 4 ), TRUE ), TRUE ); + if ( prop ) { + QValueList<QStringList> l; + l << QStringList( prop->type() ); + return l; + } + + return QValueList<QStringList>(); +} + +void CppEditorCompletion::setContext( QObject *this_ ) +{ + ths = this_; +} diff --git a/tools/designer/plugins/cppeditor/cppcompletion.h b/tools/designer/plugins/cppeditor/cppcompletion.h new file mode 100644 index 0000000..170c850 --- /dev/null +++ b/tools/designer/plugins/cppeditor/cppcompletion.h @@ -0,0 +1,60 @@ +/********************************************************************** +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef CPPCOMPLETION_H +#define CPPCOMPLETION_H + +#include <completion.h> +#include <qguardedptr.h> + +class CppEditorCompletion : public EditorCompletion +{ + Q_OBJECT + +public: + CppEditorCompletion( Editor *e ); + +#if defined(Q_USING) + using EditorCompletion::doObjectCompletion; +#endif + bool doObjectCompletion( const QString &object ); + QValueList<QStringList> functionParameters( const QString &func, QChar &, QString &prefix, QString &postfix ); + void setContext( QObject *this_ ); + +private: + QGuardedPtr<QObject> ths; + +}; + +#endif diff --git a/tools/designer/plugins/cppeditor/cppeditor.cpp b/tools/designer/plugins/cppeditor/cppeditor.cpp new file mode 100644 index 0000000..37aa9cc --- /dev/null +++ b/tools/designer/plugins/cppeditor/cppeditor.cpp @@ -0,0 +1,168 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "cppeditor.h" +#include "syntaxhighliter_cpp.h" +#include <cindent.h> +#include "cppcompletion.h" +#include "cppbrowser.h" +#include <parenmatcher.h> +#include <qsettings.h> +#include <qpopupmenu.h> +#include <qinputdialog.h> +#include <designerinterface.h> + +CppEditor::CppEditor( const QString &fn, QWidget *parent, const char *name, DesignerInterface *i ) + : Editor( fn, parent, name ), dIface( i ) +{ + if ( dIface ) + dIface->addRef(); + document()->setPreProcessor( new SyntaxHighlighter_CPP ); + document()->setIndent( (indent = new CIndent) ); + completion = new CppEditorCompletion( this ); + browser = new CppEditorBrowser( this ); + int j = 0; + while ( SyntaxHighlighter_CPP::keywords[ j ] != QString::null ) + completion->addCompletionEntry( SyntaxHighlighter_CPP::keywords[ j++ ], 0, FALSE ); + configChanged(); +} + +CppEditor::~CppEditor() +{ + delete completion; + if ( dIface ) + dIface->release(); +} + +void CppEditor::configChanged() +{ + QString path = "/Trolltech/CppEditor/"; + QMap<QString, ConfigStyle> styles = Config::readStyles( path ); + config()->styles = styles; + ( (SyntaxHighlighter_CPP*)document()->preProcessor() )->updateStyles( config()->styles ); + + completion->setEnabled( Config::completion( path ) ); + parenMatcher->setEnabled( Config::parenMatching( path ) ); + if ( Config::wordWrap( path ) ) { + if ( hScrollBarMode() != AlwaysOff ) { + document()->setFormatter( new QTextFormatterBreakInWords ); + setHScrollBarMode( AlwaysOff ); + } + } else { + if ( hScrollBarMode() != AlwaysOn ) { + QTextFormatterBreakWords *f = new QTextFormatterBreakWords; + f->setWrapEnabled( FALSE ); + document()->setFormatter( f ); + setHScrollBarMode( AlwaysOn ); + } + } + + setFont( ( (SyntaxHighlighter_CPP*)document()->preProcessor() )->format( 0 )->font() ); + + indent->setTabSize( Config::indentTabSize( path ) ); + indent->setIndentSize( Config::indentIndentSize( path ) ); + indent->setKeepTabs( Config::indentKeepTabs( path ) ); + indent->setAutoIndent( Config::indentAutoIndent( path ) ); + if ( !Config::indentAutoIndent( path ) ) + document()->setIndent( 0 ); + else + document()->setIndent( indent ); + + document()->setTabStops( ( (SyntaxHighlighter_CPP*)document()->preProcessor() )->format( QTextPreProcessor::Standard )->width( 'x' ) * Config::indentTabSize( path ) ); + + Editor::configChanged(); +} + +QPopupMenu *CppEditor::createPopupMenu( const QPoint &p ) +{ + QPopupMenu *m = Editor::createPopupMenu( p ); + m->insertSeparator(); + int adddeclid = m->insertItem( tr( "Add Include File (in Declaration)..." ), this, SLOT( addInclDecl() ) ); + int addimplid = m->insertItem( tr( "Add Include File (in Implementation)..." ), this, SLOT( addInclImpl() ) ); + int addforid = m->insertItem( tr( "Add Forward Declaration..." ), this, SLOT( addForward() ) ); + if ( !dIface->currentForm() ) { + m->setItemEnabled( adddeclid, FALSE ); + m->setItemEnabled( addimplid, FALSE ); + m->setItemEnabled( addforid, FALSE ); + } + return m; +} + +void CppEditor::addInclDecl() +{ + if ( !dIface ) + return; + QString s = QInputDialog::getText( tr( "Add Include File (In Declaration)" ), + tr( "Input this using the format <b><include.h></b> or <b>\"include.h\"</b>" ) ); + if ( s.isEmpty() ) + return; + DesignerFormWindow *form = dIface->currentForm(); + QStringList lst = form->declarationIncludes(); + lst << s; + form->setDeclarationIncludes( lst ); +} + +void CppEditor::addInclImpl() +{ + if ( !dIface ) + return; + QString s = QInputDialog::getText( tr( "Add Include File (In Implementation)" ), + tr( "Input this using the format <b><include.h></b> or <b>\"include.h\"</b>" ) ); + if ( s.isEmpty() ) + return; + DesignerFormWindow *form = dIface->currentForm(); + QStringList lst = form->implementationIncludes(); + lst << s; + form->setImplementationIncludes( lst ); +} + +void CppEditor::addForward() +{ + if ( !dIface ) + return; + QString s = QInputDialog::getText( tr( "Add Forward Declaration" ), + tr( "Input this using the format <b>ClassName;</b>" ) ); + if ( s.isEmpty() ) + return; + DesignerFormWindow *form = dIface->currentForm(); + QStringList lst = form->forwardDeclarations(); + lst << s; + form->setForwardDeclarations( lst ); +} + +void CppEditor::paste() +{ + Editor::paste(); + emit intervalChanged(); +} diff --git a/tools/designer/plugins/cppeditor/cppeditor.h b/tools/designer/plugins/cppeditor/cppeditor.h new file mode 100644 index 0000000..05d7930 --- /dev/null +++ b/tools/designer/plugins/cppeditor/cppeditor.h @@ -0,0 +1,78 @@ +/********************************************************************** +** +** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef CPPEDITOR_H +#define CPPEDITOR_H + +#include <editor.h> + +class EditorCompletion; +class EditorBrowser; +struct DesignerInterface; +class CIndent; + +class CppEditor : public Editor +{ + Q_OBJECT + +public: + CppEditor( const QString &fn, QWidget *parent, const char *name, DesignerInterface *i ); + ~CppEditor(); + + virtual EditorCompletion *completionManager() { return completion; } + virtual EditorBrowser *browserManager() { return browser; } + void configChanged(); + + bool supportsBreakPoints() const { return FALSE; } +#if defined(Q_USING) + using QTextEdit::createPopupMenu; +#endif + QPopupMenu *createPopupMenu( const QPoint &p ); + + void paste(); + +private slots: + void addInclDecl(); + void addInclImpl(); + void addForward(); + +protected: + EditorCompletion *completion; + EditorBrowser *browser; + DesignerInterface *dIface; + CIndent *indent; + +}; + +#endif diff --git a/tools/designer/plugins/cppeditor/cppeditor.pro b/tools/designer/plugins/cppeditor/cppeditor.pro new file mode 100644 index 0000000..391c1d7 --- /dev/null +++ b/tools/designer/plugins/cppeditor/cppeditor.pro @@ -0,0 +1,21 @@ +TEMPLATE = lib +CONFIG += qt warn_on plugin + +SOURCES += cppeditor.cpp syntaxhighliter_cpp.cpp cppcompletion.cpp editorinterfaceimpl.cpp languageinterfaceimpl.cpp common.cpp preferenceinterfaceimpl.cpp yyreg.cpp cppbrowser.cpp projectsettingsinterfaceimpl.cpp sourcetemplateinterfaceimpl.cpp +HEADERS += cppeditor.h syntaxhighliter_cpp.h cppcompletion.h editorinterfaceimpl.h languageinterfaceimpl.h preferenceinterfaceimpl.h yyreg.h cppbrowser.h projectsettingsinterfaceimpl.h sourcetemplateinterfaceimpl.h +FORMS = projectsettings.ui mainfilesettings.ui + +TARGET = cppeditor +DESTDIR = ../../../../plugins/designer +VERSION = 1.0.0 + +INCLUDEPATH += ../../interfaces ../../editor $$QT_BUILD_TREE/tools/designer/editor + +hpux-* { + LIBS += $$QT_BUILD_TREE/lib/libeditor.a +} else { + LIBS += -L$$QT_BUILD_TREE/lib -leditor +} + +target.path += $$plugins.path/designer +INSTALLS += target diff --git a/tools/designer/plugins/cppeditor/editorinterfaceimpl.cpp b/tools/designer/plugins/cppeditor/editorinterfaceimpl.cpp new file mode 100644 index 0000000..d396720 --- /dev/null +++ b/tools/designer/plugins/cppeditor/editorinterfaceimpl.cpp @@ -0,0 +1,338 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "editorinterfaceimpl.h" +#include <viewmanager.h> +#include "cppeditor.h" +#include <private/qrichtext_p.h> +#include <qapplication.h> +#include "completion.h" +#include <designerinterface.h> +#include <qtimer.h> + +EditorInterfaceImpl::EditorInterfaceImpl() + : EditorInterface(), viewManager( 0 ), dIface( 0 ) +{ + updateTimer = new QTimer( this ); + connect( updateTimer, SIGNAL( timeout() ), + this, SLOT( update() ) ); +} + +EditorInterfaceImpl::~EditorInterfaceImpl() +{ + updateTimer->stop(); + delete (ViewManager*)viewManager; + if ( dIface ) + dIface->release(); +} + +QRESULT EditorInterfaceImpl::queryInterface( const QUuid &uuid, QUnknownInterface** iface ) +{ + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_Editor ) + *iface = (EditorInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +QWidget *EditorInterfaceImpl::editor( bool readonly, + QWidget *parent, QUnknownInterface *iface ) +{ + if ( !viewManager ) { + ( (EditorInterfaceImpl*)this )->viewManager = new ViewManager( parent, 0 ); + ( (EditorInterfaceImpl*)this )->viewManager->showMarkerWidget( FALSE ); + if ( iface ) + iface->queryInterface( IID_Designer, (QUnknownInterface**) &dIface ); + CppEditor *e = new CppEditor( QString::null, viewManager, "editor", dIface ); + e->setEditable( !readonly ); + e->installEventFilter( this ); + connect( e, SIGNAL( intervalChanged() ), this, SLOT( intervalChanged() ) ); + QApplication::sendPostedEvents( viewManager, QEvent::ChildInserted ); + } + return viewManager->currentView(); +} + +void EditorInterfaceImpl::setText( const QString &txt ) +{ + if ( !viewManager || !viewManager->currentView() ) + return; + CppEditor *e = (CppEditor*)viewManager->currentView(); + disconnect( e, SIGNAL( modificationChanged( bool ) ), this, SLOT( modificationChanged( bool ) ) ); + e->setText( txt ); + e->setModified( FALSE ); + connect( e, SIGNAL( modificationChanged( bool ) ), this, SLOT( modificationChanged( bool ) ) ); +} + +QString EditorInterfaceImpl::text() const +{ + if ( !viewManager || !viewManager->currentView() ) + return QString::null; + QString txt = ( (CppEditor*)viewManager->currentView() )->text(); + if ( !txt.isEmpty() && !txt.endsWith("\n") ) + txt += "\n"; + return txt; +} + +bool EditorInterfaceImpl::isUndoAvailable() const +{ + if ( !viewManager || !viewManager->currentView() ) + return FALSE; + return ( (CppEditor*)viewManager->currentView() )->isUndoAvailable(); +} + +bool EditorInterfaceImpl::isRedoAvailable() const +{ + if ( !viewManager || !viewManager->currentView() ) + return FALSE; + return ( (CppEditor*)viewManager->currentView() )->isRedoAvailable(); +} + +void EditorInterfaceImpl::undo() +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->undo(); +} + +void EditorInterfaceImpl::redo() +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->redo(); +} + +void EditorInterfaceImpl::cut() +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->cut(); +} + +void EditorInterfaceImpl::copy() +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->copy(); +} + +void EditorInterfaceImpl::paste() +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->paste(); +} + +void EditorInterfaceImpl::selectAll() +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->selectAll(); +} + +bool EditorInterfaceImpl::find( const QString &expr, bool cs, bool wo, bool forward, bool startAtCursor ) +{ + if ( !viewManager || !viewManager->currentView() ) + return FALSE; + CppEditor *e = (CppEditor*)viewManager->currentView(); + if ( startAtCursor ) + return e->find( expr, cs, wo, forward ); + int dummy = 0; + return e->find( expr, cs, wo, forward, &dummy, &dummy ); +} + +bool EditorInterfaceImpl::replace( const QString &find, const QString &replace, bool cs, bool wo, + bool forward, bool startAtCursor, bool replaceAll ) +{ + if ( !viewManager || !viewManager->currentView() ) + return FALSE; + CppEditor *e = (CppEditor*)viewManager->currentView(); + bool ok = FALSE; + if ( startAtCursor ) { + ok = e->find( find, cs, wo, forward ); + } else { + int dummy = 0; + ok = e->find( find, cs, wo, forward, &dummy, &dummy ); + } + + if ( ok ) { + e->removeSelectedText(); + e->insert( replace, FALSE, FALSE ); + } + + if ( !replaceAll || !ok ) { + if ( ok ) + e->setSelection( e->textCursor()->paragraph()->paragId(), + e->textCursor()->index() - replace.length(), + e->textCursor()->paragraph()->paragId(), + e->textCursor()->index() ); + return ok; + } + + bool ok2 = TRUE; + while ( ok2 ) { + ok2 = e->find( find, cs, wo, forward ); + if ( ok2 ) { + e->removeSelectedText(); + e->insert( replace, FALSE, FALSE ); + } + } + + return TRUE; +} + +void EditorInterfaceImpl::gotoLine( int line ) +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->setCursorPosition( line, 0 ); +} + +void EditorInterfaceImpl::indent() +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->QTextEdit::indent(); +} + +void EditorInterfaceImpl::splitView() +{ +#if 0 + if ( !viewManager || !viewManager->currentView() ) + return; + QTextDocument *doc = ( (CppEditor*)viewManager->currentView() )->document(); + CppEditor *editor = new CppEditor( QString::null, viewManager, "editor" ); + editor->setDocument( doc ); +#endif +} + +void EditorInterfaceImpl::scrollTo( const QString &txt, const QString & ) +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->sync(); + QTextDocument *doc = ( (CppEditor*)viewManager->currentView() )->document(); + QTextParagraph *p = doc->firstParagraph(); + while ( p ) { + if ( p->string()->toString().find( txt ) != -1 ) { + ( (CppEditor*)viewManager->currentView() )->setCursorPosition( p->paragId() + 2, 0 ); + break; + } + p = p->next(); + } + ( (CppEditor*)viewManager->currentView() )->setFocus(); +} + +void EditorInterfaceImpl::setContext( QObject *this_ ) +{ + if ( !viewManager || !viewManager->currentView() ) + return; + ( (CppEditor*)viewManager->currentView() )->completionManager()->setContext( this_ ); +} + +void EditorInterfaceImpl::setError( int line ) +{ + if ( !viewManager ) + return; + viewManager->setError( line ); +} + +void EditorInterfaceImpl::readSettings() +{ + if ( !viewManager ) + return; + ( (CppEditor*)viewManager->currentView() )->configChanged(); +} + +void EditorInterfaceImpl::modificationChanged( bool m ) +{ + if ( viewManager && dIface ) + dIface->setModified( m, viewManager->currentView() ); +} + +void EditorInterfaceImpl::setModified( bool m ) +{ + if ( !viewManager ) + return; + ( (CppEditor*)viewManager->currentView() )->setModified( m ); +} + +bool EditorInterfaceImpl::isModified() const +{ + if ( !viewManager ) + return FALSE; + return ( (CppEditor*)viewManager->currentView() )->isModified(); +} + +bool EditorInterfaceImpl::eventFilter( QObject *o, QEvent *e ) +{ + if ( e->type() == QEvent::KeyPress ) + updateTimer->stop(); + else if ( e->type() == QEvent::FocusOut ) + update(); + + return QObject::eventFilter( o, e ); +} + +int EditorInterfaceImpl::numLines() const +{ + if ( !viewManager || !viewManager->currentView() ) + return 0; + return ( (CppEditor*)viewManager->currentView() )->paragraphs(); +} + +void EditorInterfaceImpl::intervalChanged() +{ + if ( !dIface ) + return; + updateTimer->start( 2000, TRUE ); +} + +void EditorInterfaceImpl::update() +{ + if ( !dIface ) + return; + dIface->updateFunctionList(); +} + +void EditorInterfaceImpl::onBreakPointChange( QObject *receiver, const char *slot ) +{ + if ( !viewManager ) + return; + connect( viewManager, SIGNAL( markersChanged() ), receiver, slot ); +} diff --git a/tools/designer/plugins/cppeditor/editorinterfaceimpl.h b/tools/designer/plugins/cppeditor/editorinterfaceimpl.h new file mode 100644 index 0000000..06b3d2a --- /dev/null +++ b/tools/designer/plugins/cppeditor/editorinterfaceimpl.h @@ -0,0 +1,107 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef EDITORINTERFACEIMPL_H +#define EDITORINTERFACEIMPL_H + +#include <editorinterface.h> +#include <qobject.h> +#include <qguardedptr.h> + +class QTimer; +class ViewManager; +struct DesignerInterface; + +class EditorInterfaceImpl : public QObject, public EditorInterface +{ + Q_OBJECT + +public: + EditorInterfaceImpl(); + virtual ~EditorInterfaceImpl(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + Q_REFCOUNT; + + QWidget *editor( bool readonly, QWidget *parent, QUnknownInterface *designerIface ); + + void setText( const QString &txt ); + QString text() const; + bool isUndoAvailable() const; + bool isRedoAvailable() const; + void undo(); + void redo(); + void cut(); + void copy(); + void paste(); + void selectAll(); + bool find( const QString &expr, bool cs, bool wo, bool forward, bool startAtCursor ); + bool replace( const QString &find, const QString &replace, bool cs, bool wo, bool forward, bool startAtCursor, bool replaceAll ); + void gotoLine( int line ); + void indent(); + void scrollTo( const QString &txt, const QString &first ); + void splitView(); + void setContext( QObject *this_ ); + void readSettings(); + + void setError( int line ); + void setStep( int ) {} + void clearStep() {} + void setModified( bool m ); + bool isModified() const; + void setMode( Mode ) {} + + int numLines() const; + void breakPoints( QValueList<uint> & ) const {} + void setBreakPoints( const QValueList<uint> & ) {} + void onBreakPointChange( QObject *receiver, const char *slot ); + void clearStackFrame() {} + void setStackFrame( int ) {} + +protected: + bool eventFilter( QObject*, QEvent* ); + +private slots: + void modificationChanged( bool m ); + void intervalChanged(); + void update(); + +private: + QGuardedPtr<ViewManager> viewManager; + DesignerInterface *dIface; + QTimer *updateTimer; + +}; + +#endif diff --git a/tools/designer/plugins/cppeditor/languageinterfaceimpl.cpp b/tools/designer/plugins/cppeditor/languageinterfaceimpl.cpp new file mode 100644 index 0000000..124be70 --- /dev/null +++ b/tools/designer/plugins/cppeditor/languageinterfaceimpl.cpp @@ -0,0 +1,249 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "languageinterfaceimpl.h" +#include <qobject.h> +#include <designerinterface.h> +#include <qfile.h> +#include "yyreg.h" +#include <qmetaobject.h> + +LanguageInterfaceImpl::LanguageInterfaceImpl( QUnknownInterface *outer ) + : parent( outer ), ref( 0 ) +{ +} + +ulong LanguageInterfaceImpl::addRef() +{ + return parent ? parent->addRef() : ref++; +} + +ulong LanguageInterfaceImpl::release() +{ + if ( parent ) + return parent->release(); + if ( !--ref ) { + delete this; + return 0; + } + return ref; +} + +QRESULT LanguageInterfaceImpl::queryInterface( const QUuid &uuid, QUnknownInterface** iface ) +{ + if ( parent ) + return parent->queryInterface( uuid, iface ); + + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_Language ) + *iface = (LanguageInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + + +class NormalizeObject : public QObject +{ +public: + NormalizeObject() : QObject() {} + static QCString normalizeSignalSlot( const char *signalSlot ) { return QObject::normalizeSignalSlot( signalSlot ); } +}; + +void LanguageInterfaceImpl::functions( const QString &code, QValueList<Function> *functionMap ) const +{ + QValueList<CppFunction> l; + extractCppFunctions( code, &l ); + for ( QValueList<CppFunction>::Iterator it = l.begin(); it != l.end(); ++it ) { + Function func; + func.name = (*it).prototype(); + func.name.remove( 0, (*it).returnType().length() ); + if ( func.name.find( "::" ) == -1 ) + continue; + func.name.remove( (uint)0, func.name.find( "::" ) + 2 ); + func.body = (*it).body(); + func.returnType = (*it).returnType(); + func.start = (*it).functionStartLineNum(); + func.end = (*it).closingBraceLineNum(); + functionMap->append( func ); + } +} + +QString LanguageInterfaceImpl::createFunctionStart( const QString &className, const QString &func, + const QString &returnType, + const QString & ) +{ + return returnType + " " + className + "::" + func; +} + +QStringList LanguageInterfaceImpl::definitions() const +{ + QStringList lst; + lst << "Includes (in Implementation)" << "Includes (in Declaration)" << "Forward Declarations" << "Signals"; + return lst; +} + +QStringList LanguageInterfaceImpl::definitionEntries( const QString &definition, QUnknownInterface *designerIface ) const +{ + DesignerInterface *iface = 0; + designerIface->queryInterface( IID_Designer, (QUnknownInterface**) &iface ); + if ( !iface ) + return QStringList(); + DesignerFormWindow *fw = iface->currentForm(); + if ( !fw ) + return QStringList(); + QStringList lst; + if ( definition == "Includes (in Implementation)" ) { + lst = fw->implementationIncludes(); + } else if ( definition == "Includes (in Declaration)" ) { + lst = fw->declarationIncludes(); + } else if ( definition == "Forward Declarations" ) { + lst = fw->forwardDeclarations(); + } else if ( definition == "Signals" ) { + lst = fw->signalList(); + } + iface->release(); + return lst; +} + +void LanguageInterfaceImpl::setDefinitionEntries( const QString &definition, const QStringList &entries, QUnknownInterface *designerIface ) +{ + DesignerInterface *iface = 0; + designerIface->queryInterface( IID_Designer, (QUnknownInterface**) &iface ); + if ( !iface ) + return; + DesignerFormWindow *fw = iface->currentForm(); + if ( !fw ) + return; + if ( definition == "Includes (in Implementation)" ) { + fw->setImplementationIncludes( entries ); + } else if ( definition == "Includes (in Declaration)" ) { + fw->setDeclarationIncludes( entries ); + } else if ( definition == "Forward Declarations" ) { + fw->setForwardDeclarations( entries ); + } else if ( definition == "Signals" ) { + fw->setSignalList( entries ); + } + iface->release(); +} + +QString LanguageInterfaceImpl::createEmptyFunction() +{ + return "{\n\n}\n"; +} + +bool LanguageInterfaceImpl::supports( Support s ) const +{ + if ( s == ReturnType ) + return TRUE; + if ( s == ConnectionsToCustomSlots ) + return TRUE; + return FALSE; +} + +QStringList LanguageInterfaceImpl::fileFilterList() const +{ + QStringList f; + f << "C++ Files (*.cpp *.C *.cxx *.c++ *.c *.h *.H *.hpp *.hxx)"; + return f; + +} +QStringList LanguageInterfaceImpl::fileExtensionList() const +{ + QStringList f; + f << "cpp" << "C" << "cxx" << "c++" << "c" <<"h" << "H" << "hpp" << "hxx"; + return f; +} + +QString LanguageInterfaceImpl::projectKeyForExtension( const QString &extension ) const +{ + // also handle something like foo.ut.cpp + QString ext = extension; + int i = ext.findRev('.'); + if ( i > -1 && i < (int)(ext.length()-1) ) + ext = ext.mid( i + 1 ); + if ( ext[ 0 ] == 'c' || ext[ 0 ] == 'C' ) + return "SOURCES"; + return "HEADERS"; +} + +void LanguageInterfaceImpl::sourceProjectKeys( QStringList &keys ) const +{ + keys << "HEADERS" << "SOURCES"; +} + + class CheckObject : public QObject +{ +public: + CheckObject() {} + bool checkConnectArgs( const char *signal, const char *member ) { return QObject::checkConnectArgs( signal, 0, member ); } + +}; + +bool LanguageInterfaceImpl::canConnect( const QString &signal, const QString &slot ) +{ + CheckObject o; + return o.checkConnectArgs( signal.latin1(), slot.latin1() ); +} + +void LanguageInterfaceImpl::loadFormCode( const QString &, const QString &filename, + QValueList<Function> &functions, + QStringList &, + QValueList<Connection> & ) +{ + QFile f( filename ); + if ( !f.open( IO_ReadOnly ) ) + return; + QTextStream ts( &f ); + QString code( ts.read() ); + this->functions( code, &functions ); +} + +void LanguageInterfaceImpl::preferedExtensions( QMap<QString, QString> &extensionMap ) const +{ + extensionMap.insert( "cpp", "C++ Source File" ); + extensionMap.insert( "h", "C++ Header File" ); +} + +QStrList LanguageInterfaceImpl::signalNames( QObject *obj ) const +{ + QStrList sigs; + sigs = obj->metaObject()->signalNames( TRUE ); + sigs.remove( "destroyed()" ); + return sigs; +} diff --git a/tools/designer/plugins/cppeditor/languageinterfaceimpl.h b/tools/designer/plugins/cppeditor/languageinterfaceimpl.h new file mode 100644 index 0000000..55781e7 --- /dev/null +++ b/tools/designer/plugins/cppeditor/languageinterfaceimpl.h @@ -0,0 +1,90 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef LANGUAGEINTERFACEIMPL_H +#define LANGUAGEINTERFACEIMPL_H + +#include <languageinterface.h> + +class LanguageInterfaceImpl : public LanguageInterface +{ +public: + LanguageInterfaceImpl( QUnknownInterface *outer = 0 ); + + ulong addRef(); + ulong release(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + + void functions( const QString &code, QValueList<Function> *funcs ) const; + void connections( const QString &, QValueList<Connection> * ) const {}; + QString createFunctionStart( const QString &className, const QString &func, + const QString &returnType, const QString &access ); + QStringList definitions() const; + QStringList definitionEntries( const QString &definition, QUnknownInterface *designerIface ) const; + void setDefinitionEntries( const QString &definition, const QStringList &entries, QUnknownInterface *designerIface ); + QString createArguments( const QString & ) { return QString::null; } + QString createEmptyFunction(); + bool supports( Support s ) const; + QStringList fileFilterList() const; + QStringList fileExtensionList() const; + void preferedExtensions( QMap<QString, QString> &extensionMap ) const; + void sourceProjectKeys( QStringList &keys ) const; + QString projectKeyForExtension( const QString &extension ) const; + QString cleanSignature( const QString &sig ) { return sig; } // #### implement me + void loadFormCode( const QString &, const QString &, + QValueList<Function> &, + QStringList &, + QValueList<Connection> & ); + QString formCodeExtension() const { return ".h"; } + bool canConnect( const QString &signal, const QString &slot ); + void compressProject( const QString &, const QString &, bool ) {} + QString uncompressProject( const QString &, const QString & ) { return QString::null; } + QString aboutText() const { return ""; } + + void addConnection( const QString &, const QString &, + const QString &, const QString &, + QString * ) {} + void removeConnection( const QString &, const QString &, + const QString &, const QString &, + QString * ) {} + QStrList signalNames( QObject *obj ) const; + +private: + QUnknownInterface *parent; + ulong ref; + +}; + +#endif diff --git a/tools/designer/plugins/cppeditor/mainfilesettings.ui b/tools/designer/plugins/cppeditor/mainfilesettings.ui new file mode 100644 index 0000000..2816cda --- /dev/null +++ b/tools/designer/plugins/cppeditor/mainfilesettings.ui @@ -0,0 +1,211 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>CppMainFile</class> +<comment>********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +*********************************************************************</comment> +<widget class="QDialog"> + <property name="name"> + <cstring>CppMainFile</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>308</width> + <height>283</height> + </rect> + </property> + <property name="caption"> + <string>Configure Main-File</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>Filename:</string> + </property> + </widget> + <widget class="QLineEdit" row="0" column="1"> + <property name="name"> + <cstring>editFileName</cstring> + </property> + </widget> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>Main-Form:</string> + </property> + </widget> + <widget class="QListBox" row="2" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>listForms</cstring> + </property> + </widget> + <widget class="QLayoutWidget" row="3" column="0" rowspan="1" colspan="2"> + <property name="name"> + <cstring>Layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonHelp</cstring> + </property> + <property name="text"> + <string>Help</string> + </property> + <property name="accel"> + <number>4144</number> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="text"> + <string>OK</string> + </property> + <property name="accel"> + <number>0</number> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + <property name="default"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="text"> + <string>Cancel</string> + </property> + <property name="accel"> + <number>0</number> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </grid> +</widget> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>CppMainFile</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>CppMainFile</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>listForms</sender> + <signal>selectionChanged()</signal> + <receiver>CppMainFile</receiver> + <slot>updateOkButton()</slot> + </connection> + <connection> + <sender>listForms</sender> + <signal>currentChanged(QListBoxItem*)</signal> + <receiver>CppMainFile</receiver> + <slot>updateOkButton()</slot> + </connection> + <connection> + <sender>editFileName</sender> + <signal>textChanged(const QString&)</signal> + <receiver>CppMainFile</receiver> + <slot>updateOkButton()</slot> + </connection> +</connections> +<includes> + <include location="local" impldecl="in implementation">mainfilesettings.ui.h</include> +</includes> +<forwards> + <forward>struct QUnknownInterface;</forward> +</forwards> +<slots> + <slot>init()</slot> + <slot>setup( QUnknownInterface * appIface )</slot> + <slot>updateOkButton()</slot> +</slots> +<pixmapinproject/> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/tools/designer/plugins/cppeditor/mainfilesettings.ui.h b/tools/designer/plugins/cppeditor/mainfilesettings.ui.h new file mode 100644 index 0000000..ea79101 --- /dev/null +++ b/tools/designer/plugins/cppeditor/mainfilesettings.ui.h @@ -0,0 +1,36 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename slots use Qt Designer which will +** update this file, preserving your code. Create an init() slot in place of +** a constructor, and a destroy() slot in place of a destructor. +*****************************************************************************/ + +#include <designerinterface.h> + +void CppMainFile::init() +{ +} + +void CppMainFile::setup( QUnknownInterface *appIface ) +{ + DesignerInterface *dIface = 0; + appIface->queryInterface( IID_Designer, (QUnknownInterface**)&dIface ); + if ( !dIface ) + return; + QStringList l = dIface->currentProject()->formNames(); + editFileName->setText( "main.cpp" ); + listForms->clear(); + listForms->insertStringList( l ); + listForms->setCurrentItem( 0 ); + updateOkButton(); + editFileName->setFocus(); + editFileName->selectAll(); +} + +void CppMainFile::updateOkButton() +{ + buttonOk->setEnabled( editFileName->text().length() > 0 && listForms->currentItem() != -1 ); +} + + diff --git a/tools/designer/plugins/cppeditor/preferenceinterfaceimpl.cpp b/tools/designer/plugins/cppeditor/preferenceinterfaceimpl.cpp new file mode 100644 index 0000000..b6dd10c --- /dev/null +++ b/tools/designer/plugins/cppeditor/preferenceinterfaceimpl.cpp @@ -0,0 +1,102 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "preferenceinterfaceimpl.h" +#include <preferences.h> + +PreferenceInterfaceImpl::PreferenceInterfaceImpl( QUnknownInterface *outer ) + : parent( outer ), + ref( 0 ), + cppEditorSyntax( 0 ) +{ +} + +PreferenceInterfaceImpl::~PreferenceInterfaceImpl() +{ +} + +ulong PreferenceInterfaceImpl::addRef() +{ + return parent ? parent->addRef() : ref++; +} + +ulong PreferenceInterfaceImpl::release() +{ + if ( parent ) + return parent->release(); + if ( !--ref ) { + delete this; + return 0; + } + return ref; +} + +QRESULT PreferenceInterfaceImpl::queryInterface( const QUuid &uuid, QUnknownInterface** iface ) +{ + if ( parent ) + return parent->queryInterface( uuid, iface ); + + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_Preference ) + *iface = (PreferenceInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +PreferenceInterface::Preference *PreferenceInterfaceImpl::preference() +{ + if ( !cppEditorSyntax ) { + cppEditorSyntax = new PreferencesBase( 0, "cppeditor_syntax" ); + ( (PreferencesBase*)cppEditorSyntax )->setPath( "/Trolltech/CppEditor/" ); + cppEditorSyntax->hide(); + } + Preference *pf = 0; + pf = new Preference; + pf->tab = cppEditorSyntax; + pf->title = "C++ Editor"; + pf->receiver = pf->tab; + pf->init_slot = SLOT( reInit() ); + pf->accept_slot = SLOT( save() ); + return pf; +} + +void PreferenceInterfaceImpl::deletePreferenceObject( Preference *p ) +{ + delete p; +} diff --git a/tools/designer/plugins/cppeditor/preferenceinterfaceimpl.h b/tools/designer/plugins/cppeditor/preferenceinterfaceimpl.h new file mode 100644 index 0000000..e1225fc --- /dev/null +++ b/tools/designer/plugins/cppeditor/preferenceinterfaceimpl.h @@ -0,0 +1,64 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PREFERENCEINTERFACEIMPL_H +#define PREFERENCEINTERFACEIMPL_H + +#include <preferenceinterface.h> +class QWidget; + +class PreferenceInterfaceImpl : public PreferenceInterface +{ +public: + PreferenceInterfaceImpl( QUnknownInterface *outer = 0 ); + virtual ~PreferenceInterfaceImpl(); + + ulong addRef(); + ulong release(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + + Preference *preference(); + void connectTo( QUnknownInterface * ) {} + void deletePreferenceObject( Preference * ); + +private: + QUnknownInterface *parent; + int ref; + QWidget *cppEditorSyntax; + +}; + +#endif + diff --git a/tools/designer/plugins/cppeditor/projectsettings.ui b/tools/designer/plugins/cppeditor/projectsettings.ui new file mode 100644 index 0000000..d5d9d87 --- /dev/null +++ b/tools/designer/plugins/cppeditor/projectsettings.ui @@ -0,0 +1,347 @@ +<!DOCTYPE UI><UI version="3.0" stdsetdef="1"> +<class>CppProjectSettings</class> +<comment>********************************************************************* +** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +*********************************************************************</comment> +<include location="local" implDecl="in declaration">projectsettings.ui.h</include> +<forward>struct QUnknownInterface;</forward> +<variable>QMap<QString, QString> config, libs, defines, includes;</variable> +<pixmapinproject/> +<layoutdefaults spacing="6" margin="11"/> +<widget class="QWidget"> + <property name="name"> + <cstring>CppProjectSettings</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>373</width> + <height>191</height> + </rect> + </property> + <property name="caption"> + <string>Project Settings</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>11</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + <widget class="QLabel" row="1" column="0"> + <property name="name"> + <cstring>TextLabel1</cstring> + </property> + <property name="text"> + <string>Config:</string> + </property> + </widget> + <spacer row="5" column="2"> + <property name="name"> + <cstring>Spacer1</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="3" column="0"> + <property name="name"> + <cstring>TextLabel2_2</cstring> + </property> + <property name="text"> + <string>Defines:</string> + </property> + </widget> + <widget class="QLineEdit" row="3" column="2"> + <property name="name"> + <cstring>editDefines</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>TextLabel2</cstring> + </property> + <property name="text"> + <string>Libs:</string> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>TextLabel2_3</cstring> + </property> + <property name="text"> + <string>Includepath:</string> + </property> + </widget> + <widget class="QComboBox" row="3" column="1"> + <item> + <property name="text"> + <string>(all)</string> + </property> + </item> + <item> + <property name="text"> + <string>unix</string> + </property> + </item> + <item> + <property name="text"> + <string>win32</string> + </property> + </item> + <item> + <property name="text"> + <string>mac</string> + </property> + </item> + <property name="name"> + <cstring>comboDefines</cstring> + </property> + </widget> + <widget class="QComboBox" row="4" column="1"> + <item> + <property name="text"> + <string>(all)</string> + </property> + </item> + <item> + <property name="text"> + <string>unix</string> + </property> + </item> + <item> + <property name="text"> + <string>win32</string> + </property> + </item> + <item> + <property name="text"> + <string>mac</string> + </property> + </item> + <property name="name"> + <cstring>comboInclude</cstring> + </property> + </widget> + <widget class="QLineEdit" row="4" column="2"> + <property name="name"> + <cstring>editInclude</cstring> + </property> + </widget> + <widget class="QLineEdit" row="2" column="2"> + <property name="name"> + <cstring>editLibs</cstring> + </property> + </widget> + <widget class="QLineEdit" row="1" column="2"> + <property name="name"> + <cstring>editConfig</cstring> + </property> + </widget> + <widget class="QComboBox" row="2" column="1"> + <item> + <property name="text"> + <string>(all)</string> + </property> + </item> + <item> + <property name="text"> + <string>unix</string> + </property> + </item> + <item> + <property name="text"> + <string>win32</string> + </property> + </item> + <item> + <property name="text"> + <string>mac</string> + </property> + </item> + <property name="name"> + <cstring>comboLibs</cstring> + </property> + </widget> + <widget class="QComboBox" row="1" column="1"> + <item> + <property name="text"> + <string>(all)</string> + </property> + </item> + <item> + <property name="text"> + <string>unix</string> + </property> + </item> + <item> + <property name="text"> + <string>win32</string> + </property> + </item> + <item> + <property name="text"> + <string>mac</string> + </property> + </item> + <property name="name"> + <cstring>comboConfig</cstring> + </property> + </widget> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>TextLabel3</cstring> + </property> + <property name="text"> + <string>Template:</string> + </property> + </widget> + <spacer row="0" column="2"> + <property name="name"> + <cstring>Spacer2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QComboBox" row="0" column="1"> + <item> + <property name="text"> + <string>app</string> + </property> + </item> + <item> + <property name="text"> + <string>lib</string> + </property> + </item> + <property name="name"> + <cstring>comboTemplate</cstring> + </property> + </widget> + </grid> +</widget> +<connections> + <connection language="C++"> + <sender>comboConfig</sender> + <signal>activated(const QString&)</signal> + <receiver>CppProjectSettings</receiver> + <slot>configPlatformChanged(const QString&)</slot> + </connection> + <connection language="C++"> + <sender>comboLibs</sender> + <signal>activated(const QString&)</signal> + <receiver>CppProjectSettings</receiver> + <slot>libsPlatformChanged(const QString&)</slot> + </connection> + <connection language="C++"> + <sender>comboDefines</sender> + <signal>activated(const QString&)</signal> + <receiver>CppProjectSettings</receiver> + <slot>definesPlatformChanged(const QString&)</slot> + </connection> + <connection language="C++"> + <sender>editConfig</sender> + <signal>textChanged(const QString&)</signal> + <receiver>CppProjectSettings</receiver> + <slot>configChanged(const QString&)</slot> + </connection> + <connection language="C++"> + <sender>editLibs</sender> + <signal>textChanged(const QString&)</signal> + <receiver>CppProjectSettings</receiver> + <slot>libsChanged(const QString&)</slot> + </connection> + <connection language="C++"> + <sender>editDefines</sender> + <signal>textChanged(const QString&)</signal> + <receiver>CppProjectSettings</receiver> + <slot>definesChanged(const QString&)</slot> + </connection> + <connection language="C++"> + <sender>editInclude</sender> + <signal>textChanged(const QString&)</signal> + <receiver>CppProjectSettings</receiver> + <slot>includesChanged(const QString&)</slot> + </connection> + <connection language="C++"> + <sender>comboInclude</sender> + <signal>activated(const QString&)</signal> + <receiver>CppProjectSettings</receiver> + <slot>includesPlatformChanged(const QString&)</slot> + </connection> + <slot access="public" specifier="virtual" language="C++" returnType="void">reInit( QUnknownInterface * iface )</slot> + <slot access="public" specifier="virtual" language="C++" returnType="void">save( QUnknownInterface * iface )</slot> + <slot access="public" specifier="virtual" language="C++" returnType="void">configChanged( const QString & str )</slot> + <slot access="public" specifier="virtual" language="C++" returnType="void">libsChanged( const QString & str )</slot> + <slot access="public" specifier="virtual" language="C++" returnType="void">definesChanged( const QString & str )</slot> + <slot access="public" specifier="virtual" language="C++" returnType="void">includesChanged( const QString & str )</slot> + <slot access="public" specifier="virtual" language="C++" returnType="void">configPlatformChanged( const QString & plat )</slot> + <slot access="public" specifier="virtual" language="C++" returnType="void">libsPlatformChanged( const QString & plat )</slot> + <slot access="public" specifier="virtual" language="C++" returnType="void">definesPlatformChanged( const QString & plat )</slot> + <slot access="public" specifier="virtual" language="C++" returnType="void">includesPlatformChanged( const QString & plat )</slot> +</connections> +<tabstops> + <tabstop>comboTemplate</tabstop> + <tabstop>comboConfig</tabstop> + <tabstop>editConfig</tabstop> + <tabstop>comboLibs</tabstop> + <tabstop>editLibs</tabstop> + <tabstop>comboDefines</tabstop> + <tabstop>editDefines</tabstop> + <tabstop>comboInclude</tabstop> + <tabstop>editInclude</tabstop> +</tabstops> +</UI> diff --git a/tools/designer/plugins/cppeditor/projectsettings.ui.h b/tools/designer/plugins/cppeditor/projectsettings.ui.h new file mode 100644 index 0000000..f5de0b7 --- /dev/null +++ b/tools/designer/plugins/cppeditor/projectsettings.ui.h @@ -0,0 +1,106 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** Add custom slot implementations here. Use a slot init() for +** initialization code called during construction, and a slot destroy() +** for cleanup code called during destruction. +** +** This file gets modified by Qt Designer whenever you add, rename or +** remove custom slots. Implementation code does not get lost. +*****************************************************************************/ + +#include <designerinterface.h> + +void CppProjectSettings::reInit( QUnknownInterface *iface ) +{ + comboConfig->setCurrentItem( 0 ); + comboLibs->setCurrentItem( 0 ); + comboDefines->setCurrentItem( 0 ); + comboInclude->setCurrentItem( 0 ); + + DesignerInterface *dIface = 0; + iface->queryInterface( IID_Designer, (QUnknownInterface**)&dIface ); + if ( !dIface ) + return; + DesignerProject *project = dIface->currentProject(); + if ( project->templte() == "app" ) + comboTemplate->setCurrentItem( 0 ); + else + comboTemplate->setCurrentItem( 1 ); + + config.clear(); + defines.clear(); + libs.clear(); + defines.clear(); + includes.clear(); + + const QString platforms[] = { "(all)", "win32", "unix", "mac", QString::null }; + for ( int i = 0; platforms[ i ] != QString::null; ++i ) { + config.replace( platforms[ i ], project->config( platforms[ i ] ) ); + libs.replace( platforms[ i ], project->libs( platforms[ i ] ) ); + defines.replace( platforms[ i ], project->defines( platforms[ i ] ) ); + includes.replace( platforms[ i ], project->includePath( platforms[ i ] ) ); + } + editConfig->setText( config[ "(all)" ] ); + editLibs->setText( libs[ "(all)" ] ); + editDefines->setText( defines[ "(all)" ] ); + editInclude->setText( includes[ "(all)" ] ); +} + +void CppProjectSettings::save( QUnknownInterface *iface ) +{ + DesignerInterface *dIface = 0; + iface->queryInterface( IID_Designer, (QUnknownInterface**)&dIface ); + if ( !dIface ) + return; + DesignerProject *project = dIface->currentProject(); + + project->setTemplate( comboTemplate->currentText() ); + const QString platforms[] = { "(all)", "win32", "unix", "mac", QString::null }; + for ( int i = 0; platforms[ i ] != QString::null; ++i ) { + project->setConfig( platforms[ i ], config[ platforms[ i ] ] ); + project->setLibs( platforms[ i ], libs[ platforms[ i ] ] ); + project->setDefines( platforms[ i ], defines[ platforms[ i ] ] ); + project->setIncludePath( platforms[ i ], includes[ platforms[ i ] ] ); + } +} + +void CppProjectSettings::configChanged( const QString &str ) +{ + config.replace( comboConfig->currentText(), str ); +} + +void CppProjectSettings::libsChanged( const QString &str ) +{ + libs.replace( comboLibs->currentText(), str ); +} + +void CppProjectSettings::definesChanged( const QString &str ) +{ + defines.replace( comboDefines->currentText(), str ); +} + +void CppProjectSettings::includesChanged( const QString &str ) +{ + includes.replace( comboInclude->currentText(), str ); +} + +void CppProjectSettings::configPlatformChanged( const QString &plat ) +{ + editConfig->setText( config[ plat ] ); +} + +void CppProjectSettings::libsPlatformChanged( const QString &plat ) +{ + editLibs->setText( libs[ plat ] ); +} + +void CppProjectSettings::definesPlatformChanged( const QString &plat ) +{ + editDefines->setText( defines[ plat ] ); +} + +void CppProjectSettings::includesPlatformChanged( const QString &plat ) +{ + editInclude->setText( includes[ plat ] ); +} diff --git a/tools/designer/plugins/cppeditor/projectsettingsinterfaceimpl.cpp b/tools/designer/plugins/cppeditor/projectsettingsinterfaceimpl.cpp new file mode 100644 index 0000000..9bb5d51 --- /dev/null +++ b/tools/designer/plugins/cppeditor/projectsettingsinterfaceimpl.cpp @@ -0,0 +1,106 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "projectsettingsinterfaceimpl.h" +#include "projectsettings.h" + +ProjectSettingsInterfaceImpl::ProjectSettingsInterfaceImpl( QUnknownInterface *outer ) + : parent( outer ), + ref( 0 ), + settingsTab( 0 ) +{ +} + +ulong ProjectSettingsInterfaceImpl::addRef() +{ + return parent ? parent->addRef() : ref++; +} + +ulong ProjectSettingsInterfaceImpl::release() +{ + if ( parent ) + return parent->release(); + if ( !--ref ) { + delete this; + return 0; + } + return ref; +} + +ProjectSettingsInterface::ProjectSettings *ProjectSettingsInterfaceImpl::projectSetting() +{ + if ( !settingsTab ) { + settingsTab = new CppProjectSettings( 0 ); + settingsTab->hide(); + } + ProjectSettings *pf = 0; + pf = new ProjectSettings; + pf->tab = settingsTab; + pf->title = "C++"; + pf->receiver = pf->tab; + pf->init_slot = SLOT( reInit( QUnknownInterface * ) ); + pf->accept_slot = SLOT( save( QUnknownInterface * ) ); + return pf; +} + +QStringList ProjectSettingsInterfaceImpl::projectSettings() const +{ + return QStringList(); +} + +void ProjectSettingsInterfaceImpl::connectTo( QUnknownInterface * ) +{ +} + +void ProjectSettingsInterfaceImpl::deleteProjectSettingsObject( ProjectSettings *pf ) +{ + delete pf; +} + +QRESULT ProjectSettingsInterfaceImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) +{ + if ( parent ) + return parent->queryInterface( uuid, iface ); + + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_ProjectSettings ) + *iface = (ProjectSettingsInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} diff --git a/tools/designer/plugins/cppeditor/projectsettingsinterfaceimpl.h b/tools/designer/plugins/cppeditor/projectsettingsinterfaceimpl.h new file mode 100644 index 0000000..0cd0f45 --- /dev/null +++ b/tools/designer/plugins/cppeditor/projectsettingsinterfaceimpl.h @@ -0,0 +1,62 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef PROJECTSETTINGSINTERFACEIMPL_H +#define PROJECTSETTINGSINTERFACEIMPL_H + +#include <projectsettingsiface.h> + +class CppProjectSettings; + +class ProjectSettingsInterfaceImpl : public ProjectSettingsInterface +{ +public: + ProjectSettingsInterfaceImpl( QUnknownInterface *outer = 0 ); + + ulong addRef(); + ulong release(); + + ProjectSettings *projectSetting(); + QStringList projectSettings() const; + void connectTo( QUnknownInterface *appInterface ); + void deleteProjectSettingsObject( ProjectSettings * ); + QRESULT queryInterface( const QUuid &uuid, QUnknownInterface **iface ); + +private: + QUnknownInterface *parent; + int ref; + CppProjectSettings *settingsTab; +}; + +#endif diff --git a/tools/designer/plugins/cppeditor/sourcetemplateinterfaceimpl.cpp b/tools/designer/plugins/cppeditor/sourcetemplateinterfaceimpl.cpp new file mode 100644 index 0000000..a158e81 --- /dev/null +++ b/tools/designer/plugins/cppeditor/sourcetemplateinterfaceimpl.cpp @@ -0,0 +1,117 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "sourcetemplateinterfaceimpl.h" +#include <designerinterface.h> +#include "mainfilesettings.h" +#include <qlineedit.h> +#include <qlistbox.h> + +SourceTemplateInterfaceImpl::SourceTemplateInterfaceImpl() +{ +} + +QRESULT SourceTemplateInterfaceImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface ) +{ + *iface = 0; + if ( uuid == IID_QUnknown ) + *iface = (QUnknownInterface*)this; + else if ( uuid == IID_QFeatureList ) + *iface = (QFeatureListInterface*)this; + else if ( uuid == IID_SourceTemplate ) + *iface = (SourceTemplateInterface*)this; + else + return QE_NOINTERFACE; + + (*iface)->addRef(); + return QS_OK; +} + +QStringList SourceTemplateInterfaceImpl::featureList() const +{ + QStringList l; + l << "C++ Main-File (main.cpp)"; + return l; +} + +static QString generateMainCppCode( const QString &formname, const QString &include ) +{ + QString code; + code += "#include <qapplication.h>\n"; + code += "#include \"" + include + "\"\n"; + code += "\n"; + code += "int main( int argc, char ** argv )\n"; + code += "{\n"; + code += " QApplication a( argc, argv );\n"; + code += " " + formname + " w;\n"; + code += " w.show();\n"; + code += " a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );\n"; + code += " return a.exec();\n"; + code += "}\n"; + return code; +} + +SourceTemplateInterface::Source SourceTemplateInterfaceImpl::create( const QString &templ, + QUnknownInterface *appIface ) +{ + SourceTemplateInterface::Source src; + src.type = SourceTemplateInterface::Source::Invalid; + if ( templ == "C++ Main-File (main.cpp)" ) { + CppMainFile dia( 0, 0, TRUE ); + dia.setup( appIface ); + if ( dia.exec() == QDialog::Accepted ) { + DesignerInterface *dIface = 0; + appIface->queryInterface( IID_Designer, (QUnknownInterface**)&dIface ); + if ( dIface ) { + src.type = SourceTemplateInterface::Source::FileName; + src.filename = dia.editFileName->text(); + QString include = dIface->currentProject()-> + formFileName( dia.listForms->text( dia.listForms->currentItem() ) ); + include.remove( include.length() - 2, 2 ); + include += "h"; + int slashFind = include.findRev('/'); + if (slashFind != -1) + include = include.mid(slashFind+1); + src.code = generateMainCppCode( dia.listForms->text( dia.listForms->currentItem() ), + include ); + } + } + } + return src; +} + +QString SourceTemplateInterfaceImpl::language( const QString & ) const +{ + return "C++"; +} diff --git a/tools/designer/plugins/cppeditor/sourcetemplateinterfaceimpl.h b/tools/designer/plugins/cppeditor/sourcetemplateinterfaceimpl.h new file mode 100644 index 0000000..52ae2d6 --- /dev/null +++ b/tools/designer/plugins/cppeditor/sourcetemplateinterfaceimpl.h @@ -0,0 +1,54 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef SOURCETEMPLATEINTERFACEIMPL_H +#define SOURCETEMPLATEINTERFACEIMPL_H + +#include <sourcetemplateiface.h> + +class SourceTemplateInterfaceImpl : public SourceTemplateInterface +{ +public: + SourceTemplateInterfaceImpl(); + + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + QStringList featureList() const; + Source create( const QString &templ, QUnknownInterface *appIface ); + QString language( const QString &templ ) const; + + Q_REFCOUNT +}; + + +#endif diff --git a/tools/designer/plugins/cppeditor/syntaxhighliter_cpp.cpp b/tools/designer/plugins/cppeditor/syntaxhighliter_cpp.cpp new file mode 100644 index 0000000..1b0a617 --- /dev/null +++ b/tools/designer/plugins/cppeditor/syntaxhighliter_cpp.cpp @@ -0,0 +1,550 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include "syntaxhighliter_cpp.h" +#include "paragdata.h" +#include "qstring.h" +#include "qstringlist.h" +#include "qmap.h" +#include "qapplication.h" +#include "qregexp.h" + +const char * const SyntaxHighlighter_CPP::keywords[] = { + // C++ keywords + "and", + "and_eq", + "asm", + "auto", + "bitand", + "bitor", + "bool", + "break", + "case", + "catch", + "char", + "class", + "compl", + "const", + "const_cast", + "continue", + "default", + "delete", + "do", + "double", + "dynamic_cast", + "else", + "enum", + "explicit", + "export", + "extern", + "false", + "FALSE", + "float", + "for", + "friend", + "goto", + "if", + "inline", + "int", + "long", + "mutable", + "namespace", + "new", + "not", + "not_eq", + "operator", + "or", + "or_eq", + "private", + "protected", + "public", + "register", + "reinterpret_cast", + "return", + "short", + "signed", + "sizeof", + "static", + "static_cast", + "struct", + "switch", + "template", + "this", + "throw", + "true", + "TRUE", + "try", + "typedef", + "typeid", + "typename", + "union", + "unsigned", + "using", + "virtual", + "void", + "volatile", + "wchar_t", + "while", + "xor", + "xor_eq", + // additional "keywords" intoduced by Qt + "slots", + "signals", + "uint", + "ushort", + "ulong", + "emit", + // end of array + 0 +}; + +static QMap<int, QMap<QString, int > > *wordMap = 0; + +SyntaxHighlighter_CPP::SyntaxHighlighter_CPP() + : QTextPreProcessor(), lastFormat( 0 ), lastFormatId( -1 ) +{ + QFont f( qApp->font() ); + + addFormat( Standard, new QTextFormat( f, Qt::black ) ); + addFormat( Number, new QTextFormat( f, Qt::darkBlue ) ); + addFormat( String, new QTextFormat( f, Qt::darkGreen ) ); + addFormat( Type, new QTextFormat( f, Qt::darkMagenta ) ); + addFormat( Keyword, new QTextFormat( f, Qt::darkYellow ) ); + addFormat( PreProcessor, new QTextFormat( f, Qt::darkBlue ) ); + addFormat( Label, new QTextFormat( f, Qt::darkRed ) ); + f.setFamily( "times" ); + addFormat( Comment, new QTextFormat( f, Qt::red ) ); + + if ( wordMap ) + return; + + wordMap = new QMap<int, QMap<QString, int> >; + int len; + for ( int i = 0; keywords[ i ]; ++i ) { + len = (int)strlen( keywords[ i ] ); + if ( !wordMap->contains( len ) ) + wordMap->insert( len, QMap<QString, int >() ); + QMap<QString, int> &map = wordMap->operator[]( len ); + map[ keywords[ i ] ] = Keyword; + } +} + +SyntaxHighlighter_CPP::~SyntaxHighlighter_CPP() +{ +} + +static int string2Id( const QString &s ) +{ + if ( s == "Standard" ) + return SyntaxHighlighter_CPP::Standard; + if ( s == "Comment" ) + return SyntaxHighlighter_CPP::Comment; + if ( s == "Number" ) + return SyntaxHighlighter_CPP::Number; + if ( s == "String" ) + return SyntaxHighlighter_CPP::String; + if ( s == "Type" ) + return SyntaxHighlighter_CPP::Type; + if ( s == "Preprocessor" ) + return SyntaxHighlighter_CPP::PreProcessor; + if ( s == "Label" ) + return SyntaxHighlighter_CPP::Label; + if ( s == "Keyword" ) + return SyntaxHighlighter_CPP::Keyword; + return SyntaxHighlighter_CPP::Standard; +} + +void SyntaxHighlighter_CPP::updateStyles( const QMap<QString, ConfigStyle> &styles ) +{ + for ( QMap<QString, ConfigStyle>::ConstIterator it = styles.begin(); it != styles.end(); ++it ) { + int id = string2Id( it.key() ); + QTextFormat *f = format( id ); + if ( !f ) + continue; + f->setFont( (*it).font ); + f->setColor( (*it).color ); + } +} + +void SyntaxHighlighter_CPP::process( QTextDocument *doc, QTextParagraph *string, int, bool invalidate ) +{ + + QTextFormat *formatStandard = format( Standard ); + QTextFormat *formatComment = format( Comment ); + QTextFormat *formatNumber = format( Number ); + QTextFormat *formatString = format( String ); + QTextFormat *formatType = format( Type ); + QTextFormat *formatPreProcessor = format( PreProcessor ); + QTextFormat *formatLabel = format( Label ); + + // states + const int StateStandard = 0; + const int StateCommentStart1 = 1; + const int StateCCommentStart2 = 2; + const int StateCppCommentStart2 = 3; + const int StateCComment = 4; + const int StateCppComment = 5; + const int StateCCommentEnd1 = 6; + const int StateCCommentEnd2 = 7; + const int StateStringStart = 8; + const int StateString = 9; + const int StateStringEnd = 10; + const int StateString2Start = 11; + const int StateString2 = 12; + const int StateString2End = 13; + const int StateNumber = 14; + const int StatePreProcessor = 15; + + // tokens + const int InputAlpha = 0; + const int InputNumber = 1; + const int InputAsterix = 2; + const int InputSlash = 3; + const int InputParen = 4; + const int InputSpace = 5; + const int InputHash = 6; + const int InputQuotation = 7; + const int InputApostrophe = 8; + const int InputSep = 9; + + static uchar table[ 16 ][ 10 ] = { + { StateStandard, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateStandard + { StateStandard, StateNumber, StateCCommentStart2, StateCppCommentStart2, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateCommentStart1 + { StateCComment, StateCComment, StateCCommentEnd1, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCCommentStart2 + { StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment }, // CppCommentStart2 + { StateCComment, StateCComment, StateCCommentEnd1, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCComment + { StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment, StateCppComment }, // StateCppComment + { StateCComment, StateCComment, StateCCommentEnd1, StateCCommentEnd2, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment, StateCComment }, // StateCCommentEnd1 + { StateStandard, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateCCommentEnd2 + { StateString, StateString, StateString, StateString, StateString, StateString, StateString, StateStringEnd, StateString, StateString }, // StateStringStart + { StateString, StateString, StateString, StateString, StateString, StateString, StateString, StateStringEnd, StateString, StateString }, // StateString + { StateStandard, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateStringEnd + { StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2End, StateString2 }, // StateString2Start + { StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2, StateString2End, StateString2 }, // StateString2 + { StateStandard, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateString2End + { StateNumber, StateNumber, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard }, // StateNumber + { StatePreProcessor, StateStandard, StateStandard, StateCommentStart1, StateStandard, StateStandard, StatePreProcessor, StateStringStart, StateString2Start, StateStandard } // StatePreProcessor + }; + + QString buffer; + + int state = StateStandard; + if ( string->prev() ) { + if ( string->prev()->endState() == -1 ) + process( doc, string->prev(), 0, FALSE ); + state = string->prev()->endState(); + } + int input = -1; + int i = 0; + bool lastWasBackSlash = FALSE; + bool makeLastStandard = FALSE; + + ParagData *paragData = (ParagData*)string->extraData(); + if ( paragData ) + paragData->parenList.clear(); + else + paragData = new ParagData; + + QString alphabeth = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + QString mathChars = "xXeE"; + QString numbers = "0123456789"; + bool questionMark = FALSE; + QChar lastChar; + for (;;) { + QChar c = string->at( i )->c; + + if ( lastWasBackSlash ) { + input = InputSep; + } else { + switch ( c ) { + case '*': + input = InputAsterix; + break; + case '/': + input = InputSlash; + break; + case '(': case '[': case '{': + input = InputParen; + if ( state == StateStandard || + state == StateNumber || + state == StatePreProcessor || + state == StateCCommentEnd2 || + state == StateCCommentEnd1 || + state == StateString2End || + state == StateStringEnd ) + paragData->parenList << Paren( Paren::Open, c, i ); + break; + case ')': case ']': case '}': + input = InputParen; + if ( state == StateStandard || + state == StateNumber || + state == StatePreProcessor || + state == StateCCommentEnd2 || + state == StateCCommentEnd1 || + state == StateString2End || + state == StateStringEnd ) + paragData->parenList << Paren( Paren::Closed, c, i ); + break; + case '#': + input = InputHash; + break; + case '"': + input = InputQuotation; + break; + case '\'': + input = InputApostrophe; + break; + case ' ': + input = InputSpace; + break; + case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': case '0': + if ( alphabeth.find( lastChar ) != -1 && + ( mathChars.find( lastChar ) == -1 || numbers.find( string->at( i - 1 )->c ) == -1 ) ) { + input = InputAlpha; + } else { + if ( input == InputAlpha && numbers.find( lastChar ) != -1 ) + input = InputAlpha; + else + input = InputNumber; + } + break; + case ':': { + input = InputAlpha; + QChar nextChar = ' '; + if ( i < string->length() - 1 ) + nextChar = string->at( i + 1 )->c; + if ( state == StateStandard && !questionMark && lastChar != ':' && nextChar != ':' ) { + for ( int j = 0; j < i; ++j ) { + if ( string->at( j )->format() == formatStandard ) + string->setFormat( j, 1, formatLabel, FALSE ); + } + } + } break; + default: { + if ( !questionMark && c == '?' ) + questionMark = TRUE; + if ( c.isLetter() || c == '_' ) + input = InputAlpha; + else + input = InputSep; + } break; + } + } + + lastWasBackSlash = !lastWasBackSlash && c == '\\'; + + if ( input == InputAlpha ) + buffer += c; + + state = table[ state ][ input ]; + + switch ( state ) { + case StateStandard: { + int len = buffer.length(); + string->setFormat( i, 1, formatStandard, FALSE ); + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + if ( buffer.length() > 0 && input != InputAlpha ) { + if ( buffer[ 0 ] == 'Q' ) { + string->setFormat( i - buffer.length(), buffer.length(), formatType, FALSE ); + } else { + QMap<int, QMap<QString, int > >::Iterator it = wordMap->find( len ); + if ( it != wordMap->end() ) { + QMap<QString, int >::Iterator it2 = ( *it ).find( buffer ); + if ( it2 != ( *it ).end() ) + string->setFormat( i - buffer.length(), buffer.length(), format( ( *it2 ) ), FALSE ); + } + } + buffer = QString::null; + } + } break; + case StateCommentStart1: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = TRUE; + buffer = QString::null; + break; + case StateCCommentStart2: + string->setFormat( i - 1, 2, formatComment, FALSE ); + makeLastStandard = FALSE; + buffer = QString::null; + break; + case StateCppCommentStart2: + string->setFormat( i - 1, 2, formatComment, FALSE ); + makeLastStandard = FALSE; + buffer = QString::null; + break; + case StateCComment: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatComment, FALSE ); + buffer = QString::null; + break; + case StateCppComment: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatComment, FALSE ); + buffer = QString::null; + break; + case StateCCommentEnd1: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatComment, FALSE ); + buffer = QString::null; + break; + case StateCCommentEnd2: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatComment, FALSE ); + buffer = QString::null; + break; + case StateStringStart: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatStandard, FALSE ); + buffer = QString::null; + break; + case StateString: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatString, FALSE ); + buffer = QString::null; + break; + case StateStringEnd: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatStandard, FALSE ); + buffer = QString::null; + break; + case StateString2Start: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatStandard, FALSE ); + buffer = QString::null; + break; + case StateString2: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatString, FALSE ); + buffer = QString::null; + break; + case StateString2End: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatStandard, FALSE ); + buffer = QString::null; + break; + case StateNumber: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatNumber, FALSE ); + buffer = QString::null; + break; + case StatePreProcessor: + if ( makeLastStandard ) + string->setFormat( i - 1, 1, formatStandard, FALSE ); + makeLastStandard = FALSE; + string->setFormat( i, 1, formatPreProcessor, FALSE ); + buffer = QString::null; + break; + } + + lastChar = c; + i++; + if ( i >= string->length() ) + break; + } + + string->setExtraData( paragData ); + + int oldEndState = string->endState(); + if ( state == StateCComment || + state == StateCCommentEnd1 ) { + string->setEndState( StateCComment ); + } else if ( state == StateString ) { + string->setEndState( StateString ); + } else if ( state == StateString2 ) { + string->setEndState( StateString2 ); + } else { + string->setEndState( StateStandard ); + } + + string->setFirstPreProcess( FALSE ); + + QTextParagraph *p = string->next(); + if ( (!!oldEndState || !!string->endState()) && oldEndState != string->endState() && + invalidate && p && !p->firstPreProcess() && p->endState() != -1 ) { + while ( p ) { + if ( p->endState() == -1 ) + return; + p->setEndState( -1 ); + p = p->next(); + } + } +} + +QTextFormat *SyntaxHighlighter_CPP::format( int id ) +{ + if ( lastFormatId == id && lastFormat ) + return lastFormat; + + QTextFormat *f = formats[ id ]; + lastFormat = f ? f : formats[ 0 ]; + lastFormatId = id; + return lastFormat; +} + +void SyntaxHighlighter_CPP::addFormat( int id, QTextFormat *f ) +{ + formats.insert( id, f ); +} + +void SyntaxHighlighter_CPP::removeFormat( int id ) +{ + formats.remove( id ); +} + diff --git a/tools/designer/plugins/cppeditor/syntaxhighliter_cpp.h b/tools/designer/plugins/cppeditor/syntaxhighliter_cpp.h new file mode 100644 index 0000000..ea973d9 --- /dev/null +++ b/tools/designer/plugins/cppeditor/syntaxhighliter_cpp.h @@ -0,0 +1,73 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef QCPPSYNTAXHIGHLIGHTER_H +#define QCPPSYNTAXHIGHLIGHTER_H + +#include <private/qrichtext_p.h> +#include <conf.h> + +class SyntaxHighlighter_CPP : public QTextPreProcessor +{ +public: + enum CppIds { + Comment = 1, + Number, + String, + Type, + Keyword, + PreProcessor, + Label + }; + + SyntaxHighlighter_CPP(); + virtual ~SyntaxHighlighter_CPP(); + void process( QTextDocument *doc, QTextParagraph *string, int start, bool invalidate = TRUE ); + void updateStyles( const QMap<QString, ConfigStyle> &styles ); + + static const char * const keywords[]; + + QTextFormat *format( int id ); + +private: + void addFormat( int id, QTextFormat *f ); + void removeFormat( int id ); + + QTextFormat *lastFormat; + int lastFormatId; + QIntDict<QTextFormat> formats; + +}; + +#endif diff --git a/tools/designer/plugins/cppeditor/yyreg.cpp b/tools/designer/plugins/cppeditor/yyreg.cpp new file mode 100644 index 0000000..144c99f --- /dev/null +++ b/tools/designer/plugins/cppeditor/yyreg.cpp @@ -0,0 +1,800 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#include <qregexp.h> + +#include <ctype.h> +#include <stdio.h> + +#include "yyreg.h" + +/* + First comes the tokenizer. We don't need something that knows much + about C++. However, we need something that gives tokens from the + end of the file to the start, which is tricky. + + If you are not familiar with hand-written tokenizers and parsers, + you might want to read other simpler parsers written in the same + style: + + $(QTDIR)/src/tools/qregexp.cpp + $(QTDIR)/tools/inspector/cppparser.cpp + + You might also want to read Section 2 in the Dragon Book. +*/ + +/* + Those are the tokens we are interested in. Tok_Something represents + any C++ token that does not interest us, but it's dangerous to + ignore tokens completely. +*/ +enum { Tok_Boi, Tok_Ampersand, Tok_Aster, Tok_LeftParen, Tok_RightParen, + Tok_Equal, Tok_LeftBrace, Tok_RightBrace, Tok_Semicolon, Tok_Colon, + Tok_LeftAngle, Tok_RightAngle, Tok_Comma, Tok_Ellipsis, Tok_Gulbrandsen, + Tok_LeftBracket, Tok_RightBracket, Tok_Tilde, Tok_Something, Tok_Comment, + Tok_Ident, + + Tok_char, Tok_const, Tok_double, Tok_int, Tok_long, Tok_operator, + Tok_short, Tok_signed, Tok_unsigned }; + +/* + The following variables store the lexical analyzer state. The best way + to understand them is to implement a function myGetToken() that calls + getToken(), to add some qDebug() statements in there and then to + #define getToken() myGetToken(). +*/ +static QString *yyIn; // the input stream +static int yyPos; // the position of the current token in yyIn +static int yyCurPos; // the position of the next lookahead character +static char *yyLexBuf; // the lexeme buffer +static const int YYLexBufSize = 65536; // big enough for long comments +static char *yyLex; // the lexeme itself (a pointer into yyLexBuf) +static int yyCh; // the lookbehind character + +/* + Moves back to the previous character in the input stream and + updates the tokenizer state. This function is to be used only by + getToken(), which provides the right abstraction. +*/ +static inline void readChar() +{ + if ( yyCh == EOF ) + return; + + if ( yyLex > yyLexBuf ) + *--yyLex = (char) yyCh; + + if ( yyCurPos < 0 ) + yyCh = EOF; + else + yyCh = (*yyIn)[yyCurPos].unicode(); + yyCurPos--; +} + +/* + Sets up the tokenizer. +*/ +static void startTokenizer( const QString& in ) +{ + yyIn = new QString; + *yyIn = in; + yyPos = yyIn->length() - 1; + yyCurPos = yyPos; + yyLexBuf = new char[YYLexBufSize]; + yyLex = yyLexBuf + YYLexBufSize - 1; + *yyLex = '\0'; + yyCh = '\0'; + readChar(); +} + +/* + Frees resources allocated by the tokenizer. +*/ +static void stopTokenizer() +{ + delete yyIn; + delete[] yyLexBuf; + yyLexBuf = 0; +} + +/* + These two macros implement quick-and-dirty hashing for telling + apart keywords fast. +*/ +#define HASH( ch, len ) ( (ch) | ((len) << 8) ) +#define CHECK( target ) \ + if ( strcmp((target), yyLex) != 0 ) \ + break; + +/* + Returns the previous token in the abstract token stream. The parser + deals only with tokens, not with characters. +*/ +static int getToken() +{ + // why "+ 2"? try putting some qDebug()'s and see + yyPos = yyCurPos + 2; + + for ( ;; ) { + /* + See if the previous token is interesting. If it isn't, we + will loop anyway an go to the token before the previous + token, and so on. + */ + + yyLex = yyLexBuf + YYLexBufSize - 1; + *yyLex = '\0'; + + if ( yyCh == EOF ) { + break; + } else if ( isspace(yyCh) ) { + bool metNL = FALSE; + do { + metNL = ( metNL || yyCh == '\n' ); + readChar(); + } while ( isspace(yyCh) ); + + if ( metNL ) { + /* + C++ style comments are tricky. In left-to-right + thinking, C++ comments start with "//" and end with + '\n'. In right-to-left thinking, they start with a + '\n'; but of course not every '\n' starts a comment. + + When we meet the '\n', we look behind, on the same + line, for a "//", and if there is one we mess + around with the tokenizer state to effectively + ignore the comment. Beware of off-by-one and + off-by-two bugs when you modify this code by adding + qDebug()'s here and there. + */ + if ( yyCurPos >= 0 ) { + int lineStart = yyIn->findRev( QChar('\n'), yyCurPos ) + 1; + QString line = yyIn->mid( lineStart, + yyCurPos - lineStart + 2 ); + int commentStart = line.find( QString("//") ); + if ( commentStart != -1 ) { + yyCurPos = lineStart + commentStart - 1; + yyPos = yyCurPos + 2; + readChar(); + } + } + } + } else if ( isalnum(yyCh) || yyCh == '_' ) { + do { + readChar(); + } while ( isalnum(yyCh) || yyCh == '_' ); + + switch ( HASH(yyLex[0], strlen(yyLex)) ) { + case HASH( 'c', 4 ): + CHECK( "char" ); + return Tok_char; + case HASH( 'c', 5 ): + CHECK( "const" ); + return Tok_const; + case HASH( 'd', 6 ): + CHECK( "double" ); + return Tok_double; + case HASH( 'i', 3 ): + CHECK( "int" ); + return Tok_int; + case HASH( 'l', 4 ): + CHECK( "long" ); + return Tok_long; + case HASH( 'o', 8 ): + CHECK( "operator" ); + return Tok_operator; + case HASH( 's', 5 ): + CHECK( "short" ); + return Tok_short; + case HASH( 's', 6 ): + CHECK( "signed" ); + return Tok_signed; + case HASH( 'u', 8 ): + CHECK( "unsigned" ); + return Tok_unsigned; + } + if ( isdigit(*yyLex) ) + return Tok_Something; + else + return Tok_Ident; + } else { + int quote; + + switch ( yyCh ) { + case '!': + case '%': + case '^': + case '+': + case '-': + case '?': + case '|': + readChar(); + return Tok_Something; + case '"': + case '\'': + quote = yyCh; + readChar(); + + while ( yyCh != EOF && yyCh != '\n' ) { + if ( yyCh == quote ) { + readChar(); + if ( yyCh != '\\' ) + break; + } else { + readChar(); + } + } + return Tok_Something; + case '&': + readChar(); + if ( yyCh == '&' ) { + readChar(); + return Tok_Something; + } else { + return Tok_Ampersand; + } + case '(': + readChar(); + return Tok_LeftParen; + case ')': + readChar(); + return Tok_RightParen; + case '*': + readChar(); + return Tok_Aster; + case ',': + readChar(); + return Tok_Comma; + case '.': + readChar(); + if ( yyCh == '.' ) { + do { + readChar(); + } while ( yyCh == '.' ); + return Tok_Ellipsis; + } else { + return Tok_Something; + } + case '/': + /* + C-style comments are symmetric. C++-style comments + are handled elsewhere. + */ + readChar(); + if ( yyCh == '*' ) { + bool metAster = FALSE; + bool metAsterSlash = FALSE; + + readChar(); + + while ( !metAsterSlash ) { + if ( yyCh == EOF ) + break; + + if ( yyCh == '*' ) + metAster = TRUE; + else if ( metAster && yyCh == '/' ) + metAsterSlash = TRUE; + else + metAster = FALSE; + readChar(); + } + break; + // return Tok_Comment; + } else { + return Tok_Something; + } + case ':': + readChar(); + if ( yyCh == ':' ) { + readChar(); + return Tok_Gulbrandsen; + } else { + return Tok_Colon; + } + case ';': + readChar(); + return Tok_Semicolon; + case '<': + readChar(); + return Tok_LeftAngle; + case '=': + readChar(); + return Tok_Equal; + case '>': + readChar(); + return Tok_RightAngle; + case '[': + readChar(); + return Tok_LeftBracket; + case ']': + readChar(); + return Tok_RightBracket; + case '{': + readChar(); + return Tok_LeftBrace; + case '}': + readChar(); + return Tok_RightBrace; + case '~': + readChar(); + return Tok_Tilde; + default: + readChar(); + } + } + } + return Tok_Boi; +} + +/* + Follow the member function(s) of CppFunction. +*/ + +/* + Returns the prototype for the C++ function, without the semicolon. +*/ +QString CppFunction::prototype() const +{ + QString proto; + + if ( !returnType().isEmpty() ) + proto = returnType() + QChar( ' ' ); + proto += scopedName(); + proto += QChar( '(' ); + if ( !parameterList().isEmpty() ) { + QStringList::ConstIterator p = parameterList().begin(); + proto += *p; + ++p; + while ( p != parameterList().end() ) { + proto += QString( ", " ); + proto += *p; + ++p; + } + } + proto += QChar( ')' ); + if ( isConst() ) + proto += QString( " const" ); + return proto; +} + +/* + The parser follows. We are not really parsing C++, just trying to + find the start and end of function definitions. + + One important pitfall is that the parsed code needs not be valid. + Parsing from right to left helps cope with that, as explained in + comments below. + + In the examples, we will use the symbol @ to stand for the position + in the token stream. In "int @ x ;", the lookahead token (yyTok) is + 'int'. +*/ + +static int yyTok; // the current token + +/* + Returns TRUE if thingy is a constructor or a destructor; otherwise + returns FALSE. +*/ +static bool isCtorOrDtor( const QString& thingy ) +{ + // e.g., Alpha<a>::Beta<Bar<b, c> >::~Beta + QRegExp xtor( QString( + "(?:([A-Z_a-z][0-9A-Z_a-z]*)" // class name + "(?:<(?:[^>]|<[^>]*>)*>)*" // template arguments + "::)+" // many in a row + "~?" // ctor or dtor? + "\\1") ); // function has same name as class + return xtor.exactMatch( thingy ); +} + +/* + Skips over any template arguments with balanced angle brackets, and + returns the skipped material as a string. + + Before: QMap < QString , QValueList < QString > > @ m ; + After: QMap @ < QString , QValueList < QString > > m ; +*/ +static QString matchTemplateAngles() +{ + QString t; + + if ( yyTok == Tok_RightAngle ) { + int depth = 0; + do { + if ( yyTok == Tok_RightAngle ) + depth++; + else if ( yyTok == Tok_LeftAngle ) + depth--; + t.prepend( yyLex ); + yyTok = getToken(); + } while ( depth > 0 && yyTok != Tok_Boi && yyTok != Tok_LeftBrace ); + } + return t; +} + +/* + Similar to matchTemplateAngles(), but for array brackets in parameter + data types (as in "int *argv[]"). +*/ +static QString matchArrayBrackets() +{ + QString t; + + while ( yyTok == Tok_RightBracket ) { + t.prepend( yyLex ); + yyTok = getToken(); + if ( yyTok == Tok_Something ) { + t.prepend( yyLex ); + yyTok = getToken(); + } + if ( yyTok != Tok_LeftBracket ) + return QString::null; + t.prepend( yyLex ); + yyTok = getToken(); + } + return t; +} + +/* + Prepends prefix to *type. This operation is in theory trivial, but + for the spacing to look good, we have to do something. The original + spacing is lost as the input is tokenized. +*/ +static void prependToType( QString *type, const QString& prefix ) +{ + if ( !type->isEmpty() && !prefix.isEmpty() ) { + QChar left = prefix[(int) prefix.length() - 1]; + QChar right = (*type)[0]; + + if ( left.isLetter() && + (right.isLetter() || right == QChar('*') || right == QChar('&')) ) + type->prepend( QChar(' ') ); + } + type->prepend( prefix ); +} + +static bool isModifier( int tok ) +{ + return ( tok == Tok_signed || tok == Tok_unsigned || + tok == Tok_short || tok == Tok_long ); +} + +/* + Parses a data type (backwards as usual) and returns a textual + representation of it. +*/ +static QString matchDataType() +{ + QString type; + + while ( yyTok == Tok_Ampersand || yyTok == Tok_Aster || + yyTok == Tok_const ) { + prependToType( &type, yyLex ); + yyTok = getToken(); + } + + /* + This code is really hard to follow... sorry. The loop matches + Alpha::Beta::Gamma::...::Omega. + */ + for ( ;; ) { + bool modifierMet = FALSE; + + prependToType( &type, matchTemplateAngles() ); + + if ( yyTok != Tok_Ident ) { + /* + People may write 'const unsigned short' or + 'short unsigned const' or any other permutation. + */ + while ( yyTok == Tok_const || isModifier(yyTok) ) { + prependToType( &type, yyLex ); + yyTok = getToken(); + if ( yyTok != Tok_const ) + modifierMet = TRUE; + } + + if ( yyTok == Tok_Tilde ) { + prependToType( &type, yyLex ); + yyTok = getToken(); + } + } + + if ( !modifierMet ) { + if ( yyTok == Tok_Ellipsis || yyTok == Tok_Ident || + yyTok == Tok_char || yyTok == Tok_int || + yyTok == Tok_double ) { + prependToType( &type, yyLex ); + yyTok = getToken(); + } else { + return QString::null; + } + } else if ( yyTok == Tok_int || yyTok == Tok_char || + yyTok == Tok_double ) { + prependToType( &type, yyLex ); + yyTok = getToken(); + } + + while ( yyTok == Tok_const || isModifier(yyTok) ) { + prependToType( &type, yyLex ); + yyTok = getToken(); + } + + if ( yyTok == Tok_Gulbrandsen ) { + prependToType( &type, yyLex ); + yyTok = getToken(); + } else { + break; + } + } + return type; +} + +/* + Parses a function prototype (without the semicolon) and returns an + object that stores information about this function. +*/ +static CppFunction matchFunctionPrototype( bool stripParamNames ) +{ + CppFunction func; +#if 0 + QString documentation; +#endif + QString returnType; + QString scopedName; + QStringList params; + QString qualifier; + bool cnst = FALSE; + + if ( yyTok == Tok_const ) { + cnst = TRUE; + yyTok = getToken(); + } + + if ( yyTok != Tok_RightParen ) + return func; + yyTok = getToken(); + + if ( yyTok != Tok_LeftParen ) { + for ( ;; ) { + QString brackets = matchArrayBrackets(); + QString name; + if ( yyTok == Tok_Ident ) { + name = yyLex; + yyTok = getToken(); + } + QString type = matchDataType(); + + if ( type.isEmpty() ) { + if ( name.isEmpty() ) + return func; + type = name; + name = QString::null; + } + if ( stripParamNames ) + name = QString::null; + + QString param = type + QChar( ' ' ) + name + brackets; + params.prepend( param.stripWhiteSpace() ); + + if ( yyTok != Tok_Comma ) + break; + yyTok = getToken(); + } + if ( yyTok != Tok_LeftParen ) + return func; + } + yyTok = getToken(); + + for ( ;; ) { + scopedName.prepend( matchTemplateAngles() ); + + if ( yyTok != Tok_Ident ) { + // the operator keyword should be close + int i = 0; + while ( i < 4 && yyTok != Tok_operator ) { + scopedName.prepend( yyLex ); + i++; + } + if ( yyTok != Tok_operator ) + return func; + } + scopedName.prepend( yyLex ); + yyTok = getToken(); + + if ( yyTok != Tok_Gulbrandsen ) + break; + scopedName.prepend( yyLex ); + yyTok = getToken(); + } + + if ( !isCtorOrDtor(scopedName) ) { + returnType = matchDataType(); + if ( returnType.isEmpty() ) + return func; + } + + /* + The documentation feature is unused so far, since we cannot + really distinguist between a normal comment between two + functions and one that relates to the following function. One + good heuristic is to assume that a comment immediately followed + by a function with no blank line in between relates to the + function, but there's no easy way to find that out with a + tokenizer. + */ +#if 0 + if ( yyTok == Tok_Comment ) { + documentation = yyLex; + yyTok = getToken(); + } + + func.setDocumentation( documentation ); +#endif + func.setReturnType( returnType ); + func.setScopedName( scopedName ); + func.setParameterList( params ); + func.setConst( cnst ); + return func; +} + +/* + Try to set the body. It's not sufficient to call + func->setBody(somewhatBody), as the somewhatBody might be too large. + Case in point: + + void foo() + { + printf( "Hello" ); + } + + int n; + + void bar() + { + printf( " world!\n" ); + } + + The parser first finds bar(). Then it finds "void foo() {" and + naively expects the body to extend up to "void bar()". This + function's job is to count braces and make sure "int n;" is not + counted as part of the body. + + Cases where the closing brace of the body is missing require no + special processing. +*/ +static void setBody( CppFunction *func, const QString& somewhatBody ) +{ + QString body = somewhatBody; + + int braceDepth = 0; + int i = 0; + while ( i < (int) body.length() ) { + if ( body[i] == QChar('{') ) { + braceDepth++; + } else if ( body[i] == QChar('}') ) { + braceDepth--; + if ( braceDepth == 0 ) { + body.truncate( i + 1 ); + break; + } + } + i++; + } + + func->setBody( body ); +} + +/* + Parses a whole C++ file, looking for function definitions. Case in + point: + + void foo() + { + printf( "Hello" ); + + void bar() + { + printf( " world!\n" ); + } + + The parser looks for left braces and tries to parse a function + prototype backwards. First it finds "void bar() {". Then it works + up and finds "void foo() {". +*/ +static void matchTranslationUnit( QValueList<CppFunction> *flist ) +{ + int endBody = -1; + int startBody; + + for ( ;; ) { + if ( endBody == -1 ) + endBody = yyPos; + + while ( yyTok != Tok_Boi && yyTok != Tok_LeftBrace ) + yyTok = getToken(); + if ( yyTok == Tok_Boi ) + break; + + // found a left brace + yyTok = getToken(); + startBody = yyPos; + CppFunction func = matchFunctionPrototype( FALSE ); + if ( !func.scopedName().isEmpty() ) { + QString body = yyIn->mid( startBody, endBody - startBody ); + setBody( &func, body ); + body = func.body(); // setBody() can change the body + + /* + Compute important line numbers. + */ + int functionStartLineNo = 1 + QConstString( yyIn->unicode(), yyPos ) + .string().contains( QChar('\n') ); + int startLineNo = functionStartLineNo + + QConstString( yyIn->unicode() + yyPos, startBody - yyPos ) + .string().contains( QChar('\n') ); + int endLineNo = startLineNo + body.contains( QChar('\n') ); + + func.setLineNums( functionStartLineNo, startLineNo, endLineNo ); + flist->prepend( func ); + endBody = -1; + } + } +} + +/* + Extracts C++ function from source code and put them in a list. +*/ +void extractCppFunctions( const QString& code, QValueList<CppFunction> *flist ) +{ + startTokenizer( code ); + yyTok = getToken(); + matchTranslationUnit( flist ); + stopTokenizer(); +} + +/* + Returns the prototype with the parameter names removed. +*/ +QString canonicalCppProto( const QString& proto ) +{ + startTokenizer( proto ); + yyTok = getToken(); + CppFunction func = matchFunctionPrototype( TRUE ); + stopTokenizer(); + return func.prototype(); +} diff --git a/tools/designer/plugins/cppeditor/yyreg.h b/tools/designer/plugins/cppeditor/yyreg.h new file mode 100644 index 0000000..f75c948 --- /dev/null +++ b/tools/designer/plugins/cppeditor/yyreg.h @@ -0,0 +1,88 @@ +/********************************************************************** +** +** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** +** This file is part of Qt Designer. +** +** This file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free +** Software Foundation and appearing in the files LICENSE.GPL2 +** and LICENSE.GPL3 included in the packaging of this file. +** Alternatively you may (at your option) use any later version +** of the GNU General Public License if such license has been +** publicly approved by Trolltech ASA (or its successors, if any) +** and the KDE Free Qt Foundation. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. +** If you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with +** the Software. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted +** herein. +** +**********************************************************************/ + +#ifndef YYREG_H +#define YYREG_H + +#include <qstringlist.h> +#include <qvaluelist.h> + +class CppFunction +{ +public: + CppFunction() : cnst( FALSE ), lineno1( 0 ), lineno2( 0 ) { } + + void setReturnType( const QString& r ) { ret = r; } + void setScopedName( const QString& n ) { nam = n; } + void setParameterList( const QStringList& p ) { params = p; } + void setConst( bool c ) { cnst = c; } + void setBody( const QString& b ) { bod = b; } + void setDocumentation( const QString& d ) { doc = d; } + void setLineNums( int functionStart, int openingBrace, int closingBrace ) { + lineno0 = functionStart; + lineno1 = openingBrace; + lineno2 = closingBrace; + } + + const QString& returnType() const { return ret; } + const QString& scopedName() const { return nam; } + const QStringList& parameterList() const { return params; } + bool isConst() const { return cnst; } + QString prototype() const; + const QString& body() const { return bod; } + const QString& documentation() const { return doc; } + int functionStartLineNum() const { return lineno0; } + int openingBraceLineNum() const { return lineno1; } + int closingBraceLineNum() const { return lineno2; } + +#if defined(Q_FULL_TEMPLATE_INSTANTIATION) + bool operator==( const CppFunction& ) const { return FALSE; } +#endif + +private: + QString ret; + QString nam; + QStringList params; + bool cnst; + QString bod; + QString doc; + int lineno0; + int lineno1; + int lineno2; +}; + +void extractCppFunctions( const QString& code, QValueList<CppFunction> *flist ); +QString canonicalCppProto( const QString& proto ); + +#endif |