Logo Search packages:      
Sourcecode: ktechlab version File versions  Download package

propertyeditor.cpp

/***************************************************************************
 *   Copyright (C) 2002 Lucijan Busch <lucijan@gmx.at>                     *
 *   Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr>            *
 *   Copyright (C) 2004 Jaroslaw Staniek <js@iidea.pl>                     *
 *   Copyright (C) 2006 David Saxton <david@bluehaze.org>                  *
 *                                                                         *
 *   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.                                   *
 ***************************************************************************/

#include "item.h"
#include "iteminterface.h"
#include "itemgroup.h"
#include "ktechlab.h"
#include "propertyeditor.h"
#include "propertyeditorcolor.h"
#include "propertyeditorfile.h"
#include "propertyeditorlist.h"
#include "propertyeditorinput.h"

#include <klocale.h>
#include <kdebug.h>
#include <kpushbutton.h>
#include <kiconloader.h>

#include <qheader.h>
#include <qevent.h>
#include <qfontmetrics.h>
#include <qtimer.h>
#include <qapplication.h>
#include <qeventloop.h>
#include <qtooltip.h>

00036 PropertyEditor::PropertyEditor( QWidget * parent, const char * name )
      : KListView( parent, name )
 , m_items(101, false)
 , justClickedItem(false)
{
      m_items.setAutoDelete(false);

      addColumn( i18n("Property") );
      addColumn( i18n("Value") );

      m_topItem = 0;
      m_editItem = 0;

      connect(this, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(slotClicked(QListViewItem *)));
      connect(this, SIGNAL(currentChanged(QListViewItem *)), this, SLOT(slotCurrentChanged(QListViewItem *)));
      connect(this, SIGNAL(expanded(QListViewItem *)), this, SLOT(slotExpanded(QListViewItem *)));
      connect(this, SIGNAL(collapsed(QListViewItem *)), this, SLOT(slotCollapsed(QListViewItem *)));
      connect(header(), SIGNAL(sizeChange( int, int, int )), this, SLOT(slotColumnSizeChanged( int, int, int )));
      connect(header(), SIGNAL(clicked( int )), this, SLOT(moveEditor()));
      connect(header(), SIGNAL(sectionHandleDoubleClicked ( int )), this, SLOT(slotColumnSizeChanged( int )));

      m_defaults = new KPushButton(viewport());
      m_defaults->setFocusPolicy(QWidget::NoFocus);
      setFocusPolicy(QWidget::ClickFocus);
      m_defaults->setPixmap(SmallIcon("undo"));
      QToolTip::add(m_defaults, i18n("Undo changes"));
      m_defaults->hide();
      connect(m_defaults, SIGNAL(clicked()), this, SLOT(resetItem()));

      setRootIsDecorated( false );
      setShowSortIndicator( false );
      setTooltipColumn(0);
      setSorting(0);
      setItemMargin(2);
      setResizeMode(QListView::LastColumn);
      header()->setMovingEnabled( false );
      setTreeStepSize(0);

      m_baseRowHeight = QFontMetrics(font()).height() + itemMargin()*2;
}


PropertyEditor::~PropertyEditor()
{
}


00083 void PropertyEditor::slotClicked(QListViewItem *item)
{
      if (!item)
            return;
      
      PropertyEditorItem *i = static_cast<PropertyEditorItem *>(item);
      createEditor(i);

      justClickedItem = true;
}


00095 void PropertyEditor::slotCurrentChanged(QListViewItem *item)
{
      if (item==firstChild())
      {
            QListViewItem *oldItem = item;
            while (item && (!item->isSelectable() || !item->isVisible()))
                  item = item->itemBelow();
            
            if (item && item!=oldItem)
            {
                  setSelected(item,true);
                  return;
            }
      }
}


void PropertyEditor::slotExpanded(QListViewItem *item)
{
      if (!item)
            return;
      moveEditor();
}


void PropertyEditor::slotCollapsed(QListViewItem *item)
{
      if (!item)
            return;
      moveEditor();
}


00128 void PropertyEditor::createEditor( PropertyEditorItem * i )
{
      int y = viewportToContents(QPoint(0, itemRect(i).y())).y();
      QRect geometry(columnWidth(0), y, columnWidth(1), i->height());

      delete m_currentEditor;

      m_editItem = i;

      PropertySubEditor *editor=0;
      switch ( i->type() )
      {
            case Variant::Type::String:
                  editor = new PropertyEditorInput( viewport(), i->property() );
                  break;

            case Variant::Type::Port:
            case Variant::Type::Pin:
            case Variant::Type::Combo:
            case Variant::Type::VarName:
            case Variant::Type::Select:
            case Variant::Type::PenStyle:
            case Variant::Type::PenCapStyle:
            case Variant::Type::SevenSegment:
            case Variant::Type::KeyPad:
                  editor = new PropertyEditorList( viewport(), i->property() );
                  break;
                  
            case Variant::Type::FileName:
                  editor = new PropertyEditorFile( viewport(), i->property() );
                  break;
                  
            case Variant::Type::Int:
                  editor = new PropertyEditorSpin( viewport(), i->property() );
                  break;
                  
            case Variant::Type::Double:
                  editor = new PropertyEditorDblSpin( viewport(), i->property() );
                  break;
                  
            case Variant::Type::Color:
                  editor = new PropertyEditorColor( viewport(), i->property() );
                  break;
                  
            case Variant::Type::Bool:
                  editor = new PropertyEditorBool( viewport(), i->property() );
                  break;

            case Variant::Type::Raw:
            case Variant::Type::Multiline:
            case Variant::Type::RichText:
            case Variant::Type::None:
                  break;
      }

      if (editor)
      {
            addChild(editor);
            moveChild(editor, geometry.x(), geometry.y());
            editor->show();

            editor->setFocus();
      }
      
      m_currentEditor = editor;
      showDefaultsButton( i->property()->changed() );
}


void PropertyEditor::showDefaultsButton( bool show )
{
      int y = viewportToContents(QPoint(0, itemRect(m_editItem).y())).y();
      QRect geometry(columnWidth(0), y, columnWidth(1), m_editItem->height());
      m_defaults->resize(m_baseRowHeight, m_baseRowHeight);

      if (!show) {
            if (m_currentEditor) {
                  if (m_currentEditor->leavesTheSpaceForRevertButton()) {
                        geometry.setWidth(geometry.width()-m_defaults->width());
                  }
                  m_currentEditor->resize(geometry.width(), geometry.height());
            }
            m_defaults->hide();
            return;
      }

      QPoint p = contentsToViewport(QPoint(0, geometry.y()));
      m_defaults->move(geometry.x() + geometry.width() - m_defaults->width(), p.y());
      if (m_currentEditor) {
            m_currentEditor->move(m_currentEditor->x(), p.y());
            m_currentEditor->resize(geometry.width()-m_defaults->width(), geometry.height());
      }
      m_defaults->show();
}


00224 void PropertyEditor::updateDefaultsButton()
{
      if (!m_editItem)
            return;
      showDefaultsButton( m_editItem->property()->changed() );
      m_editItem->repaint();
}


00233 void PropertyEditor::slotColumnSizeChanged( int section, int, int newS)
{
      if ( m_currentEditor )
      {
            if(section == 0)
            {
                  m_currentEditor->move(newS, m_currentEditor->y());
            }
            else
            {
                  if(m_defaults->isVisible())
                        m_currentEditor->resize(newS - m_defaults->width(), m_currentEditor->height());
                  else
                        m_currentEditor->resize(
                              newS-(m_currentEditor->leavesTheSpaceForRevertButton()?m_defaults->width():0),
                              m_currentEditor->height());
            }
      }
}


void PropertyEditor::slotColumnSizeChanged( int section)
{
      setColumnWidth(1, viewport()->width() - columnWidth(0));
      slotColumnSizeChanged(section, 0, header()->sectionSize(section));
      if(m_currentEditor)
      {
            if(m_defaults->isVisible())
                  m_currentEditor->resize(columnWidth(1) - m_defaults->width(), m_currentEditor->height());
            else
                  m_currentEditor->resize(
                        columnWidth(1)-(m_currentEditor->leavesTheSpaceForRevertButton()?m_defaults->width():0),
                        m_currentEditor->height());
      }
}


00270 void PropertyEditor::reset()
{
      if ( m_currentEditor )
            m_currentEditor->deleteLater();
      m_currentEditor = 0;
      
      if ( m_defaults->isVisible() )
            m_defaults->hide();

      clear();
      m_editItem = 0;
      m_topItem = 0;
}


QSize PropertyEditor::sizeHint() const
{
      return QSize( QFontMetrics(font()).width(columnText(0)+columnText(1)+"   "),
            KListView::sizeHint().height());
}


00292 void PropertyEditor::create( ItemGroup * b )
{
      m_pItemGroup = b;
      
      QCString selectedPropertyName1, selectedPropertyName2;
      
      fill();
      
      //select prev. selecteed item
      PropertyEditorItem * item = 0;
      if (!selectedPropertyName2.isEmpty()) //try other one for old buffer
            item = m_items[selectedPropertyName2];
      if (!item && !selectedPropertyName1.isEmpty()) //try old one for current buffer
            item = m_items[selectedPropertyName1];
      if (item)
      {
            setSelected(item, true);
            ensureItemVisible(item);
      }
}


00314 void PropertyEditor::fill()
{
      reset();
      
      if ( !m_pItemGroup || !m_pItemGroup->activeItem() )
            return;

      if(!m_topItem)
      {
            m_topItem = new PropertyEditorItem(this,"Top Item");
      }

      m_items.clear();

      VariantDataMap *vmap = m_pItemGroup->activeItem()->variantMap();
      // Build the list
      for( VariantDataMap::iterator vait = vmap->begin(); vait != vmap->end(); ++vait )
      {
            Variant * v = *vait;
            if ( v->isHidden() )
                  continue;
            
            switch ( v->type() )
            {
                  case Variant::Type::String:
                  case Variant::Type::Port:
                  case Variant::Type::Pin:
                  case Variant::Type::Combo:
                  case Variant::Type::VarName:
                  case Variant::Type::Select:
                  case Variant::Type::PenStyle:
                  case Variant::Type::PenCapStyle:
                  case Variant::Type::SevenSegment:
                  case Variant::Type::KeyPad:
                  case Variant::Type::FileName:
                  case Variant::Type::Int:
                  case Variant::Type::Double:
                  case Variant::Type::Color:
                  case Variant::Type::Bool:
                        // These are all handled by the ItemEditor
                        break;

                  case Variant::Type::Raw:
                  case Variant::Type::Multiline:
                  case Variant::Type::None:
                  case Variant::Type::RichText:
                        // These are not handled by the ItemEditor
                        continue;
            }
            
            PropertyEditorItem  *item = new PropertyEditorItem( m_topItem, v );
            m_items.insert( v->id(), item );
            
      }
}


00371 void PropertyEditor::setFocus()
{
      PropertyEditorItem *item = static_cast<PropertyEditorItem *>(selectedItem());
      if (item) {
            if (!justClickedItem)
                  ensureItemVisible(item);
            justClickedItem = false;
      }
      else
      {
            //select an item before focusing
            item = static_cast<PropertyEditorItem *>(itemAt(QPoint(10,1)));
            if (item)
            {
                  ensureItemVisible(item);
                  setSelected(item, true);
            }
      }
      if (m_currentEditor)
            m_currentEditor->setFocus();
      
      else
            KListView::setFocus();
}


00397 void PropertyEditor::resetItem()
{
      if ( m_editItem  )
      {
            ItemInterface::self()->slotSetData( m_editItem->property()->id(), m_editItem->property()->defaultValue() );
      }
}


00406 void PropertyEditor::moveEditor()
{
      if ( !m_currentEditor )
            return;
      
      QPoint p = contentsToViewport(QPoint(0, itemPos(m_editItem)));
      m_currentEditor->move(m_currentEditor->x(), p.y());
      if( m_defaults->isVisible() )
            m_defaults->move(m_defaults->x(), p.y());
}


00418 void PropertyEditor::resizeEvent(QResizeEvent *ev)
{
      KListView::resizeEvent(ev);
      if(m_defaults->isVisible())
      {
            QRect r = itemRect(m_editItem);
            if(r.y()) // r.y() == 0 if the item is not visible on the screen
                  m_defaults->move(r.x() + r.width() - m_defaults->width(), r.y());
      }

      if ( m_currentEditor )
      {
            m_currentEditor->resize(
                  columnWidth(1)-((m_currentEditor->leavesTheSpaceForRevertButton()||m_defaults->isVisible()) ? m_defaults->width() : 0),
                  m_currentEditor->height());
      }
}


00437 bool PropertyEditor::handleKeyPress( QKeyEvent* ev )
{
      const int k = ev->key();
      const Qt::ButtonState s = ev->state();

      //selection moving
      QListViewItem *item = 0;

      if ((s==NoButton && k==Key_Up) || k==Key_BackTab) {
            //find prev visible
            item = selectedItem() ? selectedItem()->itemAbove() : 0;
            while (item && (!item->isSelectable() || !item->isVisible()))
                  item = item->itemAbove();
            if (!item)
                  return true;
      }
      else if (s==NoButton && (k==Key_Down || k==Key_Tab)) {
            //find next visible
            item = selectedItem() ? selectedItem()->itemBelow() : 0;
            while (item && (!item->isSelectable() || !item->isVisible()))
                  item = item->itemBelow();
            if (!item)
                  return true;
      }
      else if(s==NoButton && k==Key_Home) {
            if (m_currentEditor && m_currentEditor->hasFocus())
                  return false;
            //find 1st visible
            item = firstChild();
            while (item && (!item->isSelectable() || !item->isVisible()))
                  item = item->itemBelow();
      }
      else if(s==NoButton && k==Key_End) {
            if (m_currentEditor && m_currentEditor->hasFocus())
                  return false;
            //find last visible
            item = selectedItem();
            QListViewItem *lastVisible = item;
            while (item) { // && (!item->isSelectable() || !item->isVisible()))
                  item = item->itemBelow();
                  if (item && item->isSelectable() && item->isVisible())
                        lastVisible = item;
            }
            item = lastVisible;
      }
      if(item) {
            ev->accept();
            ensureItemVisible(item);
            setSelected(item, true);
            return true;
      }
      return false;
}

#include "propertyeditor.moc"

Generated by  Doxygen 1.6.0   Back to index