You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdemultimedia/arts/builder/propertypanel.cpp

405 lines
10 KiB

/*
Copyright (C) 2001 Hans Meine <hans_meine@gmx.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "propertypanel.h"
#include "propertypanel.moc"
#include "module.h"
#include <kapplication.h>
#include <klocale.h>
#include <kdebug.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqpushbutton.h>
#include <tqbuttongroup.h>
#include <tqradiobutton.h>
#include <tqcombobox.h>
#include <tqlistbox.h>
#include <tqlineedit.h>
#include <arts/debug.h>
PropertyPanel::PropertyPanel( TQWidget* parent, const char* name, WFlags fl )
: PropertyPanelBase( parent, name, fl ),
component(0L),
port(0L)
{
setTitleFont();
setTitleColors();
connect( kapp, TQT_SIGNAL( kdisplayFontChanged() ),
this, TQT_SLOT( setTitleFont() ));
connect( kapp, TQT_SIGNAL( kdisplayPaletteChanged() ),
this, TQT_SLOT( setTitleColors() ));
connect( portValueGroup, TQT_SIGNAL( clicked(int) ),
this, TQT_SLOT( pvModeChanged(int) ));
connect( constantValueEdit, TQT_SIGNAL( returnPressed() ),
this, TQT_SLOT( writePortProperties() ));
connect( constantValueComboBox, TQT_SIGNAL( activated(int) ),
this, TQT_SLOT( writePortProperties() ));
connect( portCombo, TQT_SIGNAL( activated(int) ),
this, TQT_SLOT( comboPortSelected(int) ));
connect( connectButton, TQT_SIGNAL( clicked() ),
this, TQT_SLOT( connectButtonClicked() ));
constantValueComboBox->hide();
setEnabled( false );
tipLabel->hide();
}
void PropertyPanel::setTitleFont()
{
TQFont titleFont = font();
titleFont.setPointSizeFloat( titleFont.pointSizeFloat()*1.5f );
moduleNameLabel->setFont( titleFont );
titleFont = font();
titleFont.setPointSizeFloat( titleFont.pointSizeFloat()*1.15f );
selectedLabel->setFont( titleFont );
}
TQColorGroup PropertyPanel::highlightColorGroup( TQColorGroup cg )
{
cg.setColor( TQColorGroup::Foreground, cg.highlightedText() );
cg.setColor( TQColorGroup::Background, cg.highlight() );
return cg;
}
void PropertyPanel::setTitleColors()
{
TQPalette palette = titleFrame->palette();
palette.setActive( highlightColorGroup( palette.active() ) );
palette.setInactive( highlightColorGroup( palette.inactive() ) );
palette.setDisabled( highlightColorGroup( palette.disabled() ) );
titleFrame->setPalette( palette );
}
void PropertyPanel::resizeEvent ( TQResizeEvent * )
{
if(width()*3 < height()*4)
mainBoxLayout->setDirection( TQBoxLayout::TopToBottom );
else
mainBoxLayout->setDirection( TQBoxLayout::LeftToRight );
}
/*************************************************************/
void PropertyPanel::setSelectedComponent( StructureComponent *component )
{
//kdDebug() << TQString("PropertyPanel::setSelectedComponent ") << component << endl;
if( this->component == component ) return;
this->component = component;
portCombo->clear();
modulePorts.clear();
if(!component)
setEnabled(false);
else
{
moduleNameLabel->setText( component->name() );
if(component->pixmap())
{
moduleIconLabel->setPixmap( *component->pixmap() );
moduleIconLabel->setMinimumSize( moduleIconLabel->sizeHint() );
moduleIconLabel->show();
}
else
moduleIconLabel->hide();
component->dumpPorts(modulePorts);
// fill combobox
for(std::list<ModulePort *>::iterator it = modulePorts.begin();
it != modulePorts.end(); it++)
{
TQString portTitle = (*it)->description
+ TQString(" (%1)").arg( (*it)->PortDesc.type().direction == Arts::output ?
i18n("OUTPUT") : i18n("INPUT") );
portCombo->insertItem( portTitle );
}
//portCombo->setMinimumSize( portCombo->sizeHint() );
setEnabled(true);
}
}
void PropertyPanel::setSelectedPort( ModulePort *port )
{
if( this->port == port ) return;
// if( this->port ) writePortProperties( false ); // rereading not necessary here
this->port = port;
if(port)
{
setSelectedComponent( port->owner );
rereadPortProperties();
portValueGroup->setEnabled( true );
TQString tipText = i18n("Tip: Just typing numbers or alphabetic characters starts entering constant values.");
tipLabel->setText( tipText );
tipLabel->show();
// select port in combobox - bah, should be easier ;-)
portCombo->setCurrentItem(
portCombo->listBox()->index(
portCombo->listBox()->findItem( port->description + " (" ) ) );
}
else
{
portValueGroup->setEnabled( false );
tipLabel->hide();
}
}
void PropertyPanel::pvModeChanged( int newMode )
{
if(!port) return; // sanity check
switch( newMode )
{
case 0:
case 1:
writePortProperties();
break;
case 2:
; // connection should already be established
}
}
void PropertyPanel::comboPortSelected( int number )
{
if(!component) return;
std::list<ModulePort *>::iterator it;
for( it = modulePorts.begin();
(it != modulePorts.end()) && number > 0; it++, number--)
;
setSelectedPort( *it );
emit portSelected( *it );
}
void PropertyPanel::connectButtonClicked()
{
if(!port) return; // sanity check
pvConnectionButton->setChecked( true );
emit startConnection( port );
}
// this is a slot connected to changed() of the editing stuff
void PropertyPanel::writePortProperties()
{
writePortProperties( true );
}
void PropertyPanel::writePortProperties( bool reread )
{
//kdDebug() << TQString("PropertyPanel::writePortProperties") << endl;
if(!port) return; // sanity check
bool dirty = false;
if(!pvConnectionButton->isChecked())
{
if(port->PortDesc.isConnected())
{
port->PortDesc.disconnectAll();
dirty = true;
}
}
if(pvNotSetButton->isChecked() &&
(port->PortDesc.isConnected() || port->PortDesc.hasValue()))
{
port->PortDesc.hasValue(false);
dirty = true;
}
if(pvConstantButton->isChecked())
{
std::string type = port->PortDesc.type().dataType;
TQString newvalue = constantValueEdit->text();
Arts::Any a;
a.type = type;
Arts::Buffer b;
if(type == "float")
b.writeFloat(newvalue.toFloat());
else if(type == "long")
b.writeLong(newvalue.toLong());
else if(type == "string")
b.writeString(newvalue.local8Bit().data());
else if(type == "boolean")
{
b.writeBool(newvalue.upper() == "TRUE" || newvalue.upper() == "T"
|| newvalue == "1");
}
else if(isEnum(type))
{
b.writeLong(selectedEnumValue(type));
}
if(b.size() > 0)
{
b.read(a.value, b.size());
port->PortDesc.value(a);
dirty = true;
}
}
if( dirty )
emit portPropertiesChanged( port );
if( reread )
rereadPortProperties();
}
void PropertyPanel::rereadPortProperties()
{
//kdDebug() << TQString("PropertyPanel::rereadPortProperties") << endl;
if(!port) return; // sanity check
std::string dataType = port->PortDesc.type().dataType;
if(isEnum(dataType))
{
constantValueEdit->hide();
constantValueComboBox->show();
fillEnumChoices(dataType);
}
else
{
constantValueEdit->show();
constantValueComboBox->hide();
}
if( port->PortDesc.hasValue() )
{
pvConstantButton->setChecked( true );
TQString constValue;
Arts::Any value = port->PortDesc.value();
Arts::Buffer b;
b.write(value.value);
if(isEnum(value.type))
{
long v = b.readLong();
constantValueComboBox->setCurrentItem(findEnumIndex(value.type,v));
}
else
{
if(value.type == "float")
constValue.sprintf("%2.4f", b.readFloat());
else if(value.type == "long")
constValue.sprintf("%ld", b.readLong());
else if(value.type == "string")
{
std::string s;
b.readString(s);
constValue = s.c_str();
}
else if(value.type == "boolean")
{
if(b.readBool())
constValue = "true";
else
constValue = "false";
}
else constValue = ("*unknown type* " + value.type).c_str();
constantValueEdit->setText( constValue );
}
}
else if( port->PortDesc.isConnected() )
pvConnectionButton->setChecked( true );
else
{
pvNotSetButton->setChecked( true );
constantValueEdit->clear();
}
pvConnectionButton->setEnabled( port->PortDesc.isConnected() );
}
bool PropertyPanel::eventFilter( TQObject *o, TQEvent *e )
{
if( port && !constantValueEdit->hasFocus() && (e->type() == TQEvent::KeyPress) ) {
// kdDebug() << TQString(" ..is KeyPress") << endl;
TQString entered = static_cast<TQKeyEvent *>(e)->text();
bool goodString = entered.length() > 0;
// kdDebug() << TQString("pressed '%1'").arg(entered) << endl;
for( unsigned int i = 0; i < entered.length(); i++)
goodString = goodString && entered[i].isLetterOrNumber();
if( goodString )
{
pvConstantButton->setChecked( true );
constantValueEdit->setText( entered );
constantValueEdit->setFocus();
// kdDebug() << "keyPress used in propPanel" << endl;
return TRUE; // eat event
}
}
// else
// kdDebug() << "event type = " << e->type() << " != " << TQEvent::KeyPress << endl;
return FALSE; // PropertyPanelBase::eventFilter( o, e );
}
bool PropertyPanel::isEnum(const std::string& type)
{
Arts::InterfaceRepoV2 interfaceRepo = Arts::DynamicCast(Arts::Dispatcher::the()->interfaceRepo());
return (interfaceRepo.identifyType(type) == Arts::tiEnum);
}
void PropertyPanel::fillEnumChoices(const std::string& type)
{
Arts::EnumDef edef =
Arts::Dispatcher::the()->interfaceRepo().queryEnum(type);
constantValueComboBox->clear();
std::vector<Arts::EnumComponent>::const_iterator eci;
for(eci = edef.contents.begin(); eci != edef.contents.end(); ++eci)
constantValueComboBox->insertItem(TQString::fromUtf8(eci->name.c_str()));
}
long PropertyPanel::selectedEnumValue(const std::string& type)
{
unsigned int i = (unsigned int)constantValueComboBox->currentItem();
Arts::EnumDef edef =
Arts::Dispatcher::the()->interfaceRepo().queryEnum(type);
if(i >= edef.contents.size()) i = 0;
if(edef.contents.size() == 0) return 0;
return edef.contents[i].value;
}
int PropertyPanel::findEnumIndex(const std::string& type, long value)
{
Arts::EnumDef edef =
Arts::Dispatcher::the()->interfaceRepo().queryEnum(type);
for(unsigned int i = 0; i < edef.contents.size(); i++)
if(edef.contents[i].value == value)
return i;
return 0;
}