📄 propertyeditor.cpp
字号:
/************************************************************************ Copyright (C) 2000 Trolltech AS. All rights reserved.**** This file is part of Qt 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.**** 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.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include <qvariant.h> // HP-UX compiler needs this here#include "propertyeditor.h"#include "pixmapchooser.h"#include "formwindow.h"#include "command.h"#include "metadatabase.h"#include <widgetdatabase.h>#include "widgetfactory.h"#include "globaldefs.h"#include "defs.h"#include "asciivalidator.h"#include "paletteeditorimpl.h"#include "multilineeditorimpl.h"#include <limits.h>#include <qpainter.h>#include <qpalette.h>#include <qapplication.h>#include <qheader.h>#include <qlineedit.h>#include <qstrlist.h>#include <qmetaobject.h>#include <qcombobox.h>#include <qpushbutton.h>#include <qhbox.h>#include <qfontdialog.h>#include <qspinbox.h>#include <qevent.h>#include <qobjectlist.h>#include <qlistbox.h>#include <qfontdatabase.h>#include <qcolor.h>#include <qcolordialog.h>#include <qlabel.h>#include <qlayout.h>#include <qsizepolicy.h>#include <qbitmap.h>#include <qtooltip.h>#include <qwhatsthis.h>#include <qaccel.h>#include <qworkspace.h>#include "../pics/arrow.xbm"#include "../pics/uparrow.xbm"#include "../pics/cross.xbm"#include "../pics/wait.xbm"#include "../pics/ibeam.xbm"#include "../pics/sizeh.xbm"#include "../pics/sizev.xbm"#include "../pics/sizeb.xbm"#include "../pics/sizef.xbm"#include "../pics/sizeall.xbm"#include "../pics/vsplit.xbm"#include "../pics/hsplit.xbm"#include "../pics/hand.xbm"#include "../pics/no.xbm"static QFontDatabase *fontDataBase = 0;static void cleanupFontDatabase(){ delete fontDataBase; fontDataBase = 0;}static QStringList getFontList(){ if ( !fontDataBase ) { fontDataBase = new QFontDatabase; qAddPostRoutine( cleanupFontDatabase ); } return fontDataBase->families();}/*! \class PropertyItem propertyeditor.h \brief Base class for all property items This is the base class for each property item for the PropertyList. A simple property item has just a name and a value to provide an editor for a datatype. But more complex datatypes might provide an expandable item for editing single parts of the datatype. See hasSubItems(), initChildren() for that.*//*! If this item should be a child of another property item, specify \a prop as the parent item.*/PropertyItem::PropertyItem( PropertyList *l, PropertyItem *after, PropertyItem *prop, const QString &propName ) : QListViewItem( l, after ), listview( l ), property( prop ), propertyName( propName ){ setSelectable( FALSE ); open = FALSE; setText( 0, propertyName ); changed = FALSE; setText( 1, "" ); resetButton = 0;}PropertyItem::~PropertyItem(){ if ( resetButton ) delete resetButton->parentWidget(); resetButton = 0;}void PropertyItem::toggle(){}void PropertyItem::updateBackColor(){ if ( itemAbove() && this != listview->firstChild() ) { if ( ( ( PropertyItem*)itemAbove() )->backColor == backColor1 ) backColor = backColor2; else backColor = backColor1; } else { backColor = backColor1; } if ( listview->firstChild() == this ) backColor = backColor1;}QColor PropertyItem::backgroundColor(){ updateBackColor(); if ( (QListViewItem*)this == listview->currentItem() ) return selectedBack; return backColor;}/*! If a subclass is a expandable item, this is called when the childitems should be created.*/void PropertyItem::createChildren(){}/*! If a subclass is a expandable item, this is called when the childitems should be initialized.*/void PropertyItem::initChildren(){}void PropertyItem::paintCell( QPainter *p, const QColorGroup &cg, int column, int width, int align ){ QColorGroup g( cg ); g.setColor( QColorGroup::Base, backgroundColor() ); g.setColor( QColorGroup::Foreground, Qt::black ); g.setColor( QColorGroup::Text, Qt::black ); int indent = 0; if ( column == 0 ) { indent = 20 + ( property ? 20 : 0 ); p->fillRect( 0, 0, width, height(), backgroundColor() ); p->save(); p->translate( indent, 0 ); } if ( isChanged() && column == 0 ) { p->save(); QFont f = p->font(); f.setBold( TRUE ); p->setFont( f ); } if ( !hasCustomContents() || column != 1 ) { QListViewItem::paintCell( p, g, column, width - indent, align ); } else { p->fillRect( 0, 0, width, height(), backgroundColor() ); drawCustomContents( p, QRect( 0, 0, width, height() ) ); } if ( isChanged() && column == 0 ) p->restore(); if ( column == 0 ) p->restore(); if ( hasSubItems() && column == 0 ) { p->save(); p->setPen( cg.foreground() ); p->setBrush( cg.base() ); p->drawRect( 5, height() / 2 - 4, 9, 9 ); p->drawLine( 7, height() / 2, 11, height() / 2 ); if ( !isOpen() ) p->drawLine( 9, height() / 2 - 2, 9, height() / 2 + 2 ); p->restore(); } p->save(); p->setPen( QPen( cg.dark(), 1 ) ); p->drawLine( 0, height() - 1, width, height() - 1 ); p->drawLine( width - 1, 0, width - 1, height() ); p->restore(); if ( listview->currentItem() == this && column == 0 && !listview->hasFocus() && !listview->viewport()->hasFocus() ) paintFocus( p, cg, QRect( 0, 0, width, height() ) );}void PropertyItem::paintBranches( QPainter * p, const QColorGroup & cg, int w, int y, int h, GUIStyle s ){ QColorGroup g( cg ); g.setColor( QColorGroup::Base, backgroundColor() ); QListViewItem::paintBranches( p, g, w, y, h, s );} void PropertyItem::paintFocus( QPainter *p, const QColorGroup &cg, const QRect &r ){ p->save(); QApplication::style().drawPanel( p, r.x(), r.y(), r.width(), r.height(), cg, TRUE, 1 ); p->restore();}/*! Subclasses which are expandable items have to return TRUE here. Default is FALSE.*/bool PropertyItem::hasSubItems() const{ return FALSE;}/*! Returns the parent property item here if this is a child or 0 otherwise. */PropertyItem *PropertyItem::propertyParent() const{ return property;}bool PropertyItem::isOpen() const{ return open;}void PropertyItem::setOpen( bool b ){ if ( b == open ) return; open = b; if ( !open ) { children.setAutoDelete( TRUE ); children.clear(); children.setAutoDelete( FALSE ); qApp->processEvents(); listview->updateEditorSize(); return; } createChildren(); initChildren(); qApp->processEvents(); listview->updateEditorSize();}/*! Subclasses have to show the editor of the item here*/void PropertyItem::showEditor(){ createResetButton(); resetButton->parentWidget()->show();}/*! Subclasses have to hide the editor of the item here*/void PropertyItem::hideEditor(){ createResetButton(); resetButton->parentWidget()->hide();}/*! This is called to init the value of the item. Reimplement in subclasses to init the editor*/void PropertyItem::setValue( const QVariant &v ){ val = v;}QVariant PropertyItem::value() const{ return val;}bool PropertyItem::isChanged() const{ return changed;}void PropertyItem::setChanged( bool b, bool updateDb ){ if ( propertyParent() ) return; if ( changed == b ) return; changed = b; repaint(); if ( updateDb ) MetaDataBase::setPropertyChanged( listview->propertyEditor()->widget(), name(), changed ); updateResetButtonState();}QString PropertyItem::name() const{ return propertyName;}void PropertyItem::createResetButton(){ if ( resetButton ) { resetButton->parentWidget()->lower(); return; } QHBox *hbox = new QHBox( listview->viewport() ); hbox->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); hbox->setLineWidth( 1 ); resetButton = new QPushButton( hbox ); resetButton->setPixmap( PixmapChooser::loadPixmap( "resetproperty.xpm", PixmapChooser::Mini ) ); resetButton->setFixedWidth( resetButton->sizeHint().width() ); hbox->layout()->setAlignment( Qt::AlignRight ); listview->addChild( hbox ); hbox->hide(); QObject::connect( resetButton, SIGNAL( clicked() ), listview, SLOT( resetProperty() ) ); QToolTip::add( resetButton, PropertyEditor::tr( "Reset property to its default value" ) ); QWhatsThis::add( resetButton, PropertyEditor::tr( "Click this button to reset the property to its default value" ) ); updateResetButtonState();}void PropertyItem::updateResetButtonState(){ if ( !resetButton ) return; if ( propertyParent() || !WidgetFactory::canResetProperty( listview->propertyEditor()->widget(), name() ) ) resetButton->setEnabled( FALSE ); else resetButton->setEnabled( isChanged() );}/*! Call this to place/resize the item editor correctly (normally call it from showEditor())*/void PropertyItem::placeEditor( QWidget *w ){ createResetButton(); QRect r = listview->itemRect( this ); if ( r == QRect( 0, 0, -1, -1 ) ) listview->ensureItemVisible( this ); r = listview->itemRect( this ); r.setX( listview->header()->sectionPos( 1 ) ); r.setWidth( listview->header()->sectionSize( 1 ) - 1 ); r.setWidth( r.width() - resetButton->width() - 2 ); r = QRect( listview->viewportToContents( r.topLeft() ), r.size() ); w->resize( r.size() ); listview->moveChild( w, r.x(), r.y() ); resetButton->parentWidget()->resize( resetButton->sizeHint().width() + 10, r.height() ); listview->moveChild( resetButton->parentWidget(), r.x() + r.width() - 8, r.y() ); resetButton->setFixedHeight( r.height() - 3 );}/*! This should be called by subclasses if the use changed the value of the property and this value should be applied to the widget property*/void PropertyItem::notifyValueChange(){ if ( !propertyParent() ) { listview->valueChanged( this ); setChanged( TRUE ); if ( hasSubItems() ) initChildren(); } else { propertyParent()->childValueChanged( this ); setChanged( TRUE ); }}/*! If a subclass is a expandable item reimplement this as this is always called if a child item changed its value. So update the display of the item here then.*/void PropertyItem::childValueChanged( PropertyItem * ){}/*! When adding a child item, call this (normally from addChildren()*/void PropertyItem::addChild( PropertyItem *i ){ children.append( i );}int PropertyItem::childCount() const{ return children.count();}PropertyItem *PropertyItem::child( int i ) const{ // ARRRRRRRRG return ( (PropertyItem*)this )->children.at( i );}/*! If the contents of the item is not displayable with a text, but you want to draw it yourself (using drawCustomContents()), return TRUE here.*/bool PropertyItem::hasCustomContents() const{ return FALSE;}/*! \sa hasCustomContents()*/void PropertyItem::drawCustomContents( QPainter *, const QRect & ){}QString PropertyItem::currentItem() const{ return QString::null;}int PropertyItem::currentIntItem() const{ return -1;}void PropertyItem::setCurrentItem( const QString & ){}void PropertyItem::setCurrentItem( int ){}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -