Chris@58: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
Chris@0: 
Chris@0: /*
Chris@59:     Sonic Visualiser
Chris@59:     An audio file viewer and annotation editor.
Chris@59:     Centre for Digital Music, Queen Mary, University of London.
Chris@59:     This file copyright 2006 Chris Cannam.
Chris@0:     
Chris@59:     This program is free software; you can redistribute it and/or
Chris@59:     modify it under the terms of the GNU General Public License as
Chris@59:     published by the Free Software Foundation; either version 2 of the
Chris@59:     License, or (at your option) any later version.  See the file
Chris@59:     COPYING included with this distribution for more information.
Chris@0: */
Chris@0: 
Chris@0: #include "PropertyStack.h"
Chris@0: #include "PropertyBox.h"
Chris@0: #include "base/PropertyContainer.h"
Chris@0: #include "base/View.h"
Chris@47: #include "base/Layer.h"
Chris@0: 
Chris@0: #include <QIcon>
Chris@0: #include <QTabWidget>
Chris@0: 
Chris@0: #include <iostream>
Chris@0: 
Chris@36: //#define DEBUG_PROPERTY_STACK 1
Chris@0: 
Chris@0: PropertyStack::PropertyStack(QWidget *parent, View *client) :
Chris@0:     QTabWidget(parent),
Chris@0:     m_client(client)
Chris@0: {
Chris@0:     repopulate();
Chris@0: 
Chris@0:     connect(this, SIGNAL(currentChanged(int)),
Chris@0: 	    this, SLOT(selectedContainerChanged(int)));
Chris@0: 
Chris@0:     connect(m_client, SIGNAL(propertyContainerAdded(PropertyContainer *)),
Chris@0: 	    this, SLOT(propertyContainerAdded(PropertyContainer *)));
Chris@0: 
Chris@0:     connect(m_client, SIGNAL(propertyContainerRemoved(PropertyContainer *)),
Chris@0: 	    this, SLOT(propertyContainerRemoved(PropertyContainer *)));
Chris@0: 
Chris@0:     connect(m_client, SIGNAL(propertyContainerPropertyChanged(PropertyContainer *)),
Chris@0: 	    this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
Chris@0: 
Chris@0:     connect(m_client, SIGNAL(propertyContainerNameChanged(PropertyContainer *)),
Chris@0: 	    this, SLOT(propertyContainerNameChanged(PropertyContainer *)));
Chris@0: 
Chris@52:     connect(this, SIGNAL(propertyContainerSelected(View *, PropertyContainer *)),
Chris@52: 	    m_client, SLOT(propertyContainerSelected(View *, PropertyContainer *)));
Chris@0: }
Chris@0: 
Chris@0: void
Chris@0: PropertyStack::repopulate()
Chris@0: {
Chris@0:     blockSignals(true);
Chris@0: 
Chris@0: #ifdef DEBUG_PROPERTY_STACK
Chris@0:     std::cerr << "PropertyStack::repopulate" << std::endl;
Chris@0: #endif
Chris@0:     
Chris@0:     while (count() > 0) {
Chris@0: 	removeTab(0);
Chris@0:     }
Chris@0:     for (size_t i = 0; i < m_boxes.size(); ++i) {
Chris@0: 	delete m_boxes[i];
Chris@0:     }
Chris@0:     m_boxes.clear();
Chris@0:     
Chris@0:     for (size_t i = 0; i < m_client->getPropertyContainerCount(); ++i) {
Chris@0: 
Chris@0: 	PropertyContainer *container = m_client->getPropertyContainer(i);
Chris@0: 	QString name = container->getPropertyContainerName();
Chris@0: 	
Chris@0: 	QString iconName = container->getPropertyContainerIconName();
Chris@0: 
Chris@0: 	PropertyBox *box = new PropertyBox(container);
Chris@0: 
Chris@47: 	connect(box, SIGNAL(showLayer(bool)), this, SLOT(showLayer(bool)));
Chris@47: 
Chris@0: 	QIcon icon(QString(":/icons/%1.png").arg(iconName));
Chris@0: 	if (icon.isNull()) {
Chris@0: 	    addTab(box, name);
Chris@0: 	} else {
Chris@0: 	    addTab(box, icon, QString("&%1").arg(i + 1));
Chris@0: 	    setTabToolTip(count() - 1, name);
Chris@0: 	}
Chris@0: 
Chris@0: 	m_boxes.push_back(box);
Chris@0:     }    
Chris@0: 
Chris@0:     blockSignals(false);
Chris@0: }
Chris@0: 
Chris@0: bool
Chris@0: PropertyStack::containsContainer(PropertyContainer *pc) const
Chris@0: {
Chris@0:     for (size_t i = 0; i < m_client->getPropertyContainerCount(); ++i) {
Chris@0: 	PropertyContainer *container = m_client->getPropertyContainer(i);
Chris@0: 	if (pc == container) return true;
Chris@0:     }
Chris@0: 
Chris@0:     return false;
Chris@0: }
Chris@0: 
Chris@19: int
Chris@19: PropertyStack::getContainerIndex(PropertyContainer *pc) const
Chris@19: {
Chris@19:     for (size_t i = 0; i < m_client->getPropertyContainerCount(); ++i) {
Chris@19: 	PropertyContainer *container = m_client->getPropertyContainer(i);
Chris@19: 	if (pc == container) return i;
Chris@19:     }
Chris@19: 
Chris@19:     return false;
Chris@19: }
Chris@19: 
Chris@0: void
Chris@0: PropertyStack::propertyContainerAdded(PropertyContainer *)
Chris@0: {
Chris@0:     if (sender() != m_client) return;
Chris@0:     repopulate();
Chris@0: }
Chris@0: 
Chris@0: void
Chris@0: PropertyStack::propertyContainerRemoved(PropertyContainer *)
Chris@0: {
Chris@0:     if (sender() != m_client) return;
Chris@0:     repopulate();
Chris@0: }
Chris@0: 
Chris@0: void
Chris@0: PropertyStack::propertyContainerPropertyChanged(PropertyContainer *pc)
Chris@0: {
Chris@0:     for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@0: 	if (pc == m_boxes[i]->getContainer()) {
Chris@0: 	    m_boxes[i]->propertyContainerPropertyChanged(pc);
Chris@0: 	}
Chris@0:     }
Chris@0: }
Chris@0: 
Chris@0: void
Chris@0: PropertyStack::propertyContainerNameChanged(PropertyContainer *pc)
Chris@0: {
Chris@0:     if (sender() != m_client) return;
Chris@0:     repopulate();
Chris@0: }
Chris@0: 
Chris@0: void
Chris@47: PropertyStack::showLayer(bool show)
Chris@47: {
Chris@47:     QObject *obj = sender();
Chris@47:     
Chris@47:     for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@47: 	if (obj == m_boxes[i]) {
Chris@47: 	    Layer *layer = dynamic_cast<Layer *>(m_boxes[i]->getContainer());
Chris@47: 	    if (layer) {
Chris@47: 		layer->showLayer(m_client, show);
Chris@47: 		return;
Chris@47: 	    }
Chris@47: 	}
Chris@47:     }
Chris@47: }
Chris@47: 
Chris@47: void
Chris@0: PropertyStack::selectedContainerChanged(int n)
Chris@0: {
Chris@0:     if (n >= int(m_boxes.size())) return;
Chris@52:     emit propertyContainerSelected(m_client, m_boxes[n]->getContainer());
Chris@0: }
Chris@0: 
Chris@0: #ifdef INCLUDE_MOCFILES
Chris@0: #include "PropertyStack.moc.cpp"
Chris@0: #endif
Chris@0: