diff options
Diffstat (limited to 'tdevdesigner/designer/workspace.cpp')
-rw-r--r-- | tdevdesigner/designer/workspace.cpp | 711 |
1 files changed, 711 insertions, 0 deletions
diff --git a/tdevdesigner/designer/workspace.cpp b/tdevdesigner/designer/workspace.cpp new file mode 100644 index 00000000..7eb7f86f --- /dev/null +++ b/tdevdesigner/designer/workspace.cpp @@ -0,0 +1,711 @@ +/********************************************************************** +** Copyright (C) 2000-2002 Trolltech AS. All rights reserved. +** +** This file is part of TQt Designer. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition +** licenses may use this file in accordance with the TQt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about TQt Commercial License Agreements. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include <tqvariant.h> // HP-UX compiler needs this here +#include "workspace.h" +#include "formwindow.h" +#include "mainwindow.h" +#include "globaldefs.h" +#include "command.h" +#include "project.h" +#include "pixmapcollection.h" +#include "sourcefile.h" +#include "sourceeditor.h" +#include "propertyeditor.h" + +#include <kiconloader.h> +#include "tdevdesigner_part.h" + +#include <tqheader.h> +#include <tqdragobject.h> +#include <tqfileinfo.h> +#include <tqapplication.h> +#include <tqpainter.h> +#include <tqpen.h> +#include <tqobjectlist.h> +#include <tqworkspace.h> +#include <tqpopupmenu.h> +#include <tqtextstream.h> +#include "qcompletionedit.h" + +#include <tdelocale.h> + +WorkspaceItem::WorkspaceItem( TQListView *parent, Project* p ) + : TQListViewItem( parent ) +{ + init(); + project = p; + t = ProjectType; + setPixmap( 0, SmallIcon( "designer_folder.png" , TDevDesignerPartFactory::instance()) ); + setExpandable( FALSE ); +} + +WorkspaceItem::WorkspaceItem( TQListViewItem *parent, SourceFile* sf ) + : TQListViewItem( parent ) +{ + init(); + sourceFile = sf; + t = SourceFileType; + setPixmap( 0, SmallIcon( "designer_filenew.png" , TDevDesignerPartFactory::instance()) ); +} + +WorkspaceItem::WorkspaceItem( TQListViewItem *parent, TQObject *o, Project *p ) + : TQListViewItem( parent ) +{ + init(); + object = o; + project = p; + t = ObjectType; + setPixmap( 0, SmallIcon( "designer_object.png" , TDevDesignerPartFactory::instance()) ); + TQObject::connect( p->fakeFormFileFor( o ), TQT_SIGNAL( somethingChanged(FormFile*) ), + listView(), TQT_SLOT( update() ) ); +} + +WorkspaceItem::WorkspaceItem( TQListViewItem *parent, FormFile* ff, Type type ) + : TQListViewItem( parent ) +{ + init(); + formFile = ff; + t = type; + if ( type == FormFileType ) { + setPixmap( 0, SmallIcon( "designer_form.png" , TDevDesignerPartFactory::instance()) ); + TQObject::connect( ff, TQT_SIGNAL( somethingChanged(FormFile*) ), listView(), TQT_SLOT( update(FormFile*) ) ); + if ( formFile->supportsCodeFile() ) { + (void) new WorkspaceItem( this, formFile, FormSourceType ); + } + } else if ( type == FormSourceType ) { + setPixmap( 0, SmallIcon( "designer_filenew.png" , TDevDesignerPartFactory::instance()) ); + } +} + + +void WorkspaceItem::init() +{ + autoOpen = FALSE; + useOddColor = FALSE; + project = 0; + sourceFile = 0; + formFile = 0; +} + +void WorkspaceItem::paintCell( TQPainter *p, const TQColorGroup &cg, int column, int width, int align ) +{ + TQColorGroup g( cg ); + g.setColor( TQColorGroup::Base, backgroundColor() ); + g.setColor( TQColorGroup::Foreground, TQt::black ); + + if ( type() == FormSourceType && + ( !formFile->hasFormCode() || ( formFile->codeFileState() == FormFile::Deleted && formFile->formWindow() ) ) && + parent() && parent()->parent() && ( (WorkspaceItem*)parent()->parent() )->project && + ( (WorkspaceItem*)parent()->parent() )->project->isCpp() ) { + g.setColor( TQColorGroup::Text, listView()->palette().disabled().color( TQColorGroup::Text) ); + g.setColor( TQColorGroup::HighlightedText, listView()->palette().disabled().color( TQColorGroup::Text) ); + } else { + g.setColor( TQColorGroup::Text, TQt::black ); + } + p->save(); + + if ( isModified() ) { + TQFont f = p->font(); + f.setBold( TRUE ); + p->setFont( f ); + } + + TQListViewItem::paintCell( p, g, column, width, align ); + p->setPen( TQPen( cg.dark(), 1 ) ); + if ( column == 0 ) + p->drawLine( 0, 0, 0, height() - 1 ); + if ( listView()->firstChild() != this ) { + if ( nextSibling() != itemBelow() && itemBelow()->depth() < depth() ) { + int d = depth() - itemBelow()->depth(); + p->drawLine( -listView()->treeStepSize() * d, height() - 1, 0, height() - 1 ); + } + } + p->drawLine( 0, height() - 1, width, height() - 1 ); + p->drawLine( width - 1, 0, width - 1, height() ); + p->restore(); +} + +TQString WorkspaceItem::text( int column ) const +{ + if ( column != 0 ) + return TQListViewItem::text( column ); + switch( t ) { + case ProjectType: + if ( project->isDummy() ) { + return i18n("<No Project>" ); + } else if ( MainWindow::self->singleProjectMode() ) { + return TQFileInfo( project->fileName() ).baseName(); + } + return project->makeRelative( project->fileName() ); + case FormFileType: + if ( !MainWindow::self->singleProjectMode() ) + return formFile->formName() + ": " + formFile->fileName(); + return formFile->formName(); + case FormSourceType: + if ( !MainWindow::self->singleProjectMode() ) + return formFile->codeFile(); + return formFile->formName() + " [Source]"; + case SourceFileType: + return sourceFile->fileName(); + case ObjectType: + if ( !project->hasParentObject( object ) ) + return object->name(); + return project->qualifiedName( object ); + } + + return TQString(); // shut up compiler +} + +void WorkspaceItem::fillCompletionList( TQStringList& completion ) +{ + switch( t ) { + case ProjectType: + break; + case FormFileType: + completion += formFile->formName(); + completion += formFile->fileName(); + break; + case FormSourceType: + completion += formFile->codeFile(); + break; + case SourceFileType: + completion += sourceFile->fileName(); + break; + case ObjectType: + completion += object->name(); + } +} + +bool WorkspaceItem::checkCompletion( const TQString& completion ) +{ + switch( t ) { + case ProjectType: + break; + case FormFileType: + return completion == formFile->formName() + || completion == formFile->fileName(); + case FormSourceType: + return completion == formFile->codeFile(); + case SourceFileType: + return completion == sourceFile->fileName(); + case ObjectType: + return completion == object->name(); + } + return FALSE; +} + + +bool WorkspaceItem::isModified() const +{ + switch( t ) { + case ProjectType: + return project->isModified(); + case FormFileType: + return formFile->isModified( FormFile::WFormWindow ); + case FormSourceType: + return formFile->isModified( FormFile::WFormCode ); + case SourceFileType: + return sourceFile->isModified(); + case ObjectType: + return project->fakeFormFileFor( object )->isModified(); + break; + } + return FALSE; // shut up compiler +} + +TQString WorkspaceItem::key( int column, bool ) const +{ + TQString key = text( column ); + if ( t == FormFileType ) + key.prepend( "0" ); + else if ( t == ObjectType ) + key.prepend( "a" ); + else + key.prepend( "A" ); + return key; +} + +TQColor WorkspaceItem::backgroundColor() +{ + bool b = useOddColor; + if ( t == FormSourceType && parent() ) + b = ( ( WorkspaceItem*)parent() )->useOddColor; + return b ? *backColor2 : *backColor1; +} + + +void WorkspaceItem::setOpen( bool b ) +{ + TQListViewItem::setOpen( b ); + autoOpen = FALSE; +} + +void WorkspaceItem::setAutoOpen( bool b ) +{ + TQListViewItem::setOpen( b ); + autoOpen = b; +} + +Workspace::Workspace( TQWidget *parent, MainWindow *mw ) + : TQListView( parent, 0, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | + WStyle_Tool | WStyle_MinMax | WStyle_SysMenu ), mainWindow( mw ), + project( 0 ), completionDirty( FALSE ) +{ + init_colors(); + + setDefaultRenameAction( Accept ); + blockNewForms = FALSE; + bufferEdit = 0; + header()->setStretchEnabled( TRUE ); + header()->hide(); + setSorting( 0 ); + setResizePolicy( TQScrollView::Manual ); +#ifndef TQ_WS_MAC + TQPalette p( palette() ); + p.setColor( TQColorGroup::Base, TQColor( *backColor2 ) ); + (void)*selectedBack; // hack + setPalette( p ); +#endif + addColumn( i18n( "Files" ) ); + setAllColumnsShowFocus( TRUE ); + connect( this, TQT_SIGNAL( mouseButtonClicked( int, TQListViewItem *, const TQPoint &, int ) ), + this, TQT_SLOT( itemClicked( int, TQListViewItem *, const TQPoint& ) ) ), + connect( this, TQT_SIGNAL( doubleClicked( TQListViewItem * ) ), + this, TQT_SLOT( itemDoubleClicked( TQListViewItem * ) ) ), + connect( this, TQT_SIGNAL( contextMenuRequested( TQListViewItem *, const TQPoint &, int ) ), + this, TQT_SLOT( rmbClicked( TQListViewItem *, const TQPoint& ) ) ), + setHScrollBarMode( AlwaysOff ); + setVScrollBarMode( AlwaysOn ); + viewport()->setAcceptDrops( TRUE ); + setAcceptDrops( TRUE ); + setColumnWidthMode( 1, Manual ); +} + + +void Workspace::projectDestroyed( TQObject* o ) +{ + if ( o == project ) { + project = 0; + clear(); + } +} + +void Workspace::setCurrentProject( Project *pro ) +{ + if ( project == pro ) + return; + if ( project ) { + disconnect( project, TQT_SIGNAL( sourceFileAdded(SourceFile*) ), this, TQT_SLOT( sourceFileAdded(SourceFile*) ) ); + disconnect( project, TQT_SIGNAL( sourceFileRemoved(SourceFile*) ), this, TQT_SLOT( sourceFileRemoved(SourceFile*) ) ); + disconnect( project, TQT_SIGNAL( formFileAdded(FormFile*) ), this, TQT_SLOT( formFileAdded(FormFile*) ) ); + disconnect( project, TQT_SIGNAL( formFileRemoved(FormFile*) ), this, TQT_SLOT( formFileRemoved(FormFile*) ) ); + disconnect( project, TQT_SIGNAL( objectAdded(TQObject*) ), this, TQT_SLOT( objectAdded(TQObject*) ) ); + disconnect( project, TQT_SIGNAL( objectRemoved(TQObject*) ), this, TQT_SLOT( objectRemoved(TQObject*) ) ); + disconnect( project, TQT_SIGNAL( projectModified() ), this, TQT_SLOT( update() ) ); + } + project = pro; + connect( project, TQT_SIGNAL( sourceFileAdded(SourceFile*) ), this, TQT_SLOT( sourceFileAdded(SourceFile*) ) ); + connect( project, TQT_SIGNAL( sourceFileRemoved(SourceFile*) ), this, TQT_SLOT( sourceFileRemoved(SourceFile*) ) ); + connect( project, TQT_SIGNAL( formFileAdded(FormFile*) ), this, TQT_SLOT( formFileAdded(FormFile*) ) ); + connect( project, TQT_SIGNAL( formFileRemoved(FormFile*) ), this, TQT_SLOT( formFileRemoved(FormFile*) ) ); + connect( project, TQT_SIGNAL( destroyed(TQObject*) ), this, TQT_SLOT( projectDestroyed(TQObject*) ) ); + connect( project, TQT_SIGNAL( objectAdded(TQObject*) ), this, TQT_SLOT( objectAdded(TQObject*) ) ); + connect( project, TQT_SIGNAL( objectRemoved(TQObject*) ), this, TQT_SLOT( objectRemoved(TQObject*) ) ); + connect( project, TQT_SIGNAL( projectModified() ), this, TQT_SLOT( update() ) ); + clear(); + + if ( bufferEdit ) + bufferEdit->clear(); + + projectItem = new WorkspaceItem( this, project ); + + projectItem->setOpen( TRUE ); + + for ( TQPtrListIterator<SourceFile> sources = project->sourceFiles(); + sources.current(); ++sources ) { + SourceFile* f = sources.current(); + (void) new WorkspaceItem( projectItem, f ); + } + + for ( TQPtrListIterator<FormFile> forms = project->formFiles(); + forms.current(); ++forms ) { + FormFile* f = forms.current(); + if ( f->isFake() ) + continue; + + (void) new WorkspaceItem( projectItem, f ); + } + + TQObjectList l = project->objects(); + TQObjectListIt objs( l ); + for ( ;objs.current(); ++objs ) { + TQObject* o = objs.current(); + (void) new WorkspaceItem( projectItem, o, project ); + } + + updateColors(); + completionDirty = TRUE; +} + +void Workspace::sourceFileAdded( SourceFile* sf ) +{ + (void) new WorkspaceItem( projectItem, sf ); + updateColors(); +} + +void Workspace::sourceFileRemoved( SourceFile* sf ) +{ + delete findItem( sf ); + updateColors(); +} + +void Workspace::formFileAdded( FormFile* ff ) +{ + if ( ff->isFake() ) + return; + (void) new WorkspaceItem( projectItem, ff ); + updateColors(); +} + +void Workspace::formFileRemoved( FormFile* ff ) +{ + delete findItem( ff ); + updateColors(); +} + +void Workspace::objectAdded( TQObject *o ) +{ + (void) new WorkspaceItem( projectItem, o, project ); + updateColors(); +} + +void Workspace::objectRemoved( TQObject *o ) +{ + delete findItem( o ); + updateColors(); +} + +void Workspace::update() +{ + completionDirty = TRUE; + triggerUpdate(); +} + +void Workspace::update( FormFile* ff ) +{ + TQListViewItem* i = findItem( ff ); + if ( i ) { + i->repaint(); + if ( (i = i->firstChild()) ) + i->repaint(); + } +} + + +void Workspace::activeFormChanged( FormWindow *fw ) +{ + WorkspaceItem *i = findItem( fw->formFile() ); + if ( i ) { + setCurrentItem( i ); + setSelected( i, TRUE ); + if ( !i->isOpen() ) + i->setAutoOpen( TRUE ); + } + + closeAutoOpenItems(); + +} + +void Workspace::activeEditorChanged( SourceEditor *se ) +{ + if ( !se->object() ) + return; + + if ( se->formWindow() ) { + WorkspaceItem *i = findItem( se->formWindow()->formFile() ); + if ( i && i->firstChild() ) { + if ( !i->isOpen() ) + i->setAutoOpen( TRUE ); + setCurrentItem( i->firstChild() ); + setSelected( i->firstChild(), TRUE ); + } + } else { + WorkspaceItem *i = findItem( se->sourceFile() ); + if ( i ) { + setCurrentItem( i ); + setSelected( i, TRUE ); + } + } + + closeAutoOpenItems(); +} + +WorkspaceItem *Workspace::findItem( FormFile* ff) +{ + TQListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + if ( ( (WorkspaceItem*)it.current() )->formFile == ff ) + return (WorkspaceItem*)it.current(); + } + return 0; +} + +WorkspaceItem *Workspace::findItem( SourceFile *sf ) +{ + TQListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + if ( ( (WorkspaceItem*)it.current() )->sourceFile == sf ) + return (WorkspaceItem*)it.current(); + } + return 0; +} + +WorkspaceItem *Workspace::findItem( TQObject *o ) +{ + TQListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + if ( ( (WorkspaceItem*)it.current() )->object == o ) + return (WorkspaceItem*)it.current(); + } + return 0; +} + +void Workspace::closeAutoOpenItems() +{ + TQListViewItemIterator it( this ); + for ( ; it.current(); ++it ) { + WorkspaceItem* i = (WorkspaceItem*) it.current(); + WorkspaceItem* ip = (WorkspaceItem*) i->parent(); + if ( i->type() == WorkspaceItem::FormSourceType ) { + if ( !i->isSelected() && !ip->isSelected() + && ip->isAutoOpen() ) { + ip->setAutoOpen( FALSE ); + } + } + } +} + + +void Workspace::closeEvent( TQCloseEvent *e ) +{ + e->accept(); +} + +void Workspace::itemDoubleClicked( TQListViewItem *i ) +{ + if ( ( (WorkspaceItem*)i)->type()== WorkspaceItem::ProjectType ) + i->setOpen( TRUE ); +} + +void Workspace::itemClicked( int button, TQListViewItem *i, const TQPoint& ) +{ + if ( !i || button != Qt::LeftButton ) + return; + + closeAutoOpenItems(); + + WorkspaceItem* wi = (WorkspaceItem*)i; + switch( wi->type() ) { + case WorkspaceItem::ProjectType: + break; // ### TODO + case WorkspaceItem::FormFileType: + wi->formFile->showFormWindow(); + break; + case WorkspaceItem::FormSourceType: + wi->formFile->showEditor( FALSE ); + break; + case WorkspaceItem::SourceFileType: + mainWindow->editSource( wi->sourceFile ); + break; + case WorkspaceItem::ObjectType: + project->fakeFormFileFor( wi->object )->formWindow()->setFocus(); + mainWindow->propertyeditor()->setWidget( wi->object, + project->fakeFormFileFor( wi->object )->formWindow() ); + mainWindow->objectHierarchy()-> + setFormWindow( project->fakeFormFileFor( wi->object )->formWindow(), wi->object ); + project->fakeFormFileFor( wi->object )->showEditor(); + break; + } +} + +void Workspace::contentsDropEvent( TQDropEvent *e ) +{ + if ( !TQUriDrag::canDecode( e ) ) { + e->ignore(); + } else { + TQStringList files; + TQUriDrag::decodeLocalFiles( e, files ); + if ( !files.isEmpty() ) { + for ( TQStringList::Iterator it = files.begin(); it != files.end(); ++it ) { + TQString fn = *it; + mainWindow->fileOpen( "", "", fn ); + } + } + } +} + +void Workspace::contentsDragEnterEvent( TQDragEnterEvent *e ) +{ + if ( !TQUriDrag::canDecode( e ) ) + e->ignore(); + else + e->accept(); +} + +void Workspace::contentsDragMoveEvent( TQDragMoveEvent *e ) +{ + if ( !TQUriDrag::canDecode( e ) ) + e->ignore(); + else + e->accept(); +} + +void Workspace::rmbClicked( TQListViewItem *i, const TQPoint& pos ) +{ + if ( !i ) + return; + WorkspaceItem* wi = (WorkspaceItem*)i; + enum { OPEN_SOURCE, REMOVE_SOURCE, OPEN_FORM, REMOVE_FORM, + OPEN_FORM_SOURCE, REMOVE_FORM_SOURCE, OPEN_OBJECT_SOURCE }; + TQPopupMenu menu( this ); + menu.setCheckable( TRUE ); + switch ( wi->type() ) { + case WorkspaceItem::SourceFileType: + menu.insertItem( i18n( "&Open Source File" ), OPEN_SOURCE ); + menu.insertSeparator(); + menu.insertItem( SmallIcon( "designer_editcut.png" , TDevDesignerPartFactory::instance()), + i18n( "&Remove Source File From Project" ), REMOVE_SOURCE ); + break; + case WorkspaceItem::FormFileType: + menu.insertItem( i18n( "&Open Form" ), OPEN_FORM ); + menu.insertSeparator(); + menu.insertItem( SmallIcon( "designer_editcut.png" , TDevDesignerPartFactory::instance()), + i18n( "&Remove Form From Project" ), REMOVE_FORM ); + break; + case WorkspaceItem::FormSourceType: + menu.insertItem( i18n( "&Open Form Source" ), OPEN_FORM_SOURCE ); + menu.insertSeparator(); + if ( project->isCpp() ) + menu.insertItem( SmallIcon( "designer_editcut.png" , TDevDesignerPartFactory::instance()), + i18n( "&Remove Source File From Form" ), REMOVE_FORM_SOURCE ); + else + menu.insertItem( SmallIcon( "designer_editcut.png" , TDevDesignerPartFactory::instance()), + i18n( "&Remove Form From Project" ), REMOVE_FORM ); + break; + case WorkspaceItem::ProjectType: + MainWindow::self->popupProjectMenu( pos ); + return; + case WorkspaceItem::ObjectType: + menu.insertItem( i18n( "&Open Source" ), OPEN_OBJECT_SOURCE ); + break; + } + + switch ( menu.exec( pos ) ) { + case REMOVE_SOURCE: + project->removeSourceFile( wi->sourceFile ); + break; + case REMOVE_FORM: + project->removeFormFile( wi->formFile ); + break; + case REMOVE_FORM_SOURCE: + ( (WorkspaceItem*)i )->formFile->setModified( TRUE ); + ( (WorkspaceItem*)i )->formFile->setCodeFileState( FormFile::Deleted ); + delete ( (WorkspaceItem*)i )->formFile->editor(); + break; + case OPEN_OBJECT_SOURCE: + case OPEN_SOURCE: + case OPEN_FORM: + case OPEN_FORM_SOURCE: + itemClicked( Qt::LeftButton, i, pos ); + break; + } +} + +bool Workspace::eventFilter( TQObject *o, TQEvent * e ) +{ + // Reggie, on what type of events do we have to execute updateBufferEdit() + if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(bufferEdit) && e->type() != TQEvent::ChildRemoved ) + updateBufferEdit(); + return TQListView::eventFilter( o, e ); +} + +void Workspace::setBufferEdit( QCompletionEdit *edit ) +{ + bufferEdit = edit; + connect( bufferEdit, TQT_SIGNAL( chosen( const TQString & ) ), + this, TQT_SLOT( bufferChosen( const TQString & ) ) ); + bufferEdit->installEventFilter( this ); +} + +void Workspace::updateBufferEdit() +{ + if ( !bufferEdit || !completionDirty || !MainWindow::self) + return; + completionDirty = FALSE; + TQStringList completion = MainWindow::self->projectFileNames(); + TQListViewItemIterator it( this ); + while ( it.current() ) { + ( (WorkspaceItem*)it.current())->fillCompletionList( completion ); + ++it; + } + completion.sort(); + bufferEdit->setCompletionList( completion ); +} + +void Workspace::bufferChosen( const TQString &buffer ) +{ + if ( bufferEdit ) + bufferEdit->setText( "" ); + + if ( MainWindow::self->projectFileNames().contains( buffer ) ) { + MainWindow::self->setCurrentProjectByFilename( buffer ); + return; + } + + TQListViewItemIterator it( this ); + while ( it.current() ) { + if ( ( (WorkspaceItem*)it.current())->checkCompletion( buffer ) ) { + itemClicked( Qt::LeftButton, it.current(), TQPoint() ); + break; + } + ++it; + } +} + +void Workspace::updateColors() +{ + TQListViewItem* i = firstChild(); + if ( i ) + i = i->firstChild(); + bool b = TRUE; + while ( i ) { + WorkspaceItem* wi = ( WorkspaceItem*) i; + i = i->nextSibling(); + wi->useOddColor = b; + b = !b; + } +} |