WQtTextureSorter.cpp 8.79 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------

#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
30 31 32
#include <algorithm>

#include <boost/bind.hpp>
33 34 35 36

#include <QtCore/QList>
#include <QtGui/QScrollArea>
#include <QtGui/QVBoxLayout>
37
#include <QtGui/QListWidgetItem>
38

39
#include "../../../common/WLimits.h"
40
#include "../../../dataHandler/WDataSet.h"
41 42 43
#include "../../../dataHandler/WSubject.h"
#include "../../../dataHandler/WDataHandler.h"
#include "../../../dataHandler/exceptions/WDHNoSuchSubject.h"
44 45
#include "../../../kernel/WModuleFactory.h"

46
#include "WQtTextureSorter.h"
47 48 49


WQtTextureSorter::WQtTextureSorter( QWidget* parent )
50
    : QDockWidget( "Texture Sorter", parent )
51
{
52 53
    setObjectName( "Texture Sorter Dock" );

54
    m_textureListWidget = new QListWidget( this );
55 56 57
    m_textureListWidget->setToolTip( "List of available textures. Only the upper <b>"
                                     + QString().setNum( wlimits::MAX_NUMBER_OF_TEXTURES )
                                     + "</b> textures will be applied." );
58 59 60 61
    this->setAllowedAreas( Qt::AllDockWidgetAreas );
    this->setFeatures( QDockWidget::DockWidgetClosable |QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable );

    QWidget* panel = new QWidget( this );
62 63 64 65 66 67 68 69 70 71 72 73

    m_layout = new QVBoxLayout();

    QHBoxLayout* buttonLayout = new QHBoxLayout();
    m_downButton = new QPushButton();
    m_downButton->setText( QString( "down" ) );
    m_upButton = new QPushButton();
    m_upButton->setText( QString( "up" ) );

    buttonLayout->addWidget( m_downButton );
    buttonLayout->addWidget( m_upButton );

74 75 76
    connect( m_upButton, SIGNAL( pressed() ), this, SLOT( moveItemUp() ) );
    connect( m_downButton, SIGNAL( pressed() ), this, SLOT( moveItemDown() ) );

77 78 79
    m_layout->addWidget( m_textureListWidget );
    m_layout->addLayout( buttonLayout );

80 81
    connect( m_textureListWidget, SIGNAL( itemClicked( QListWidgetItem* ) ), this, SLOT( handleTextureClicked() ) );

82 83
    panel->setLayout( m_layout );
    setWidget( panel );
84 85 86 87 88 89
}

WQtTextureSorter::~WQtTextureSorter()
{
}

90 91 92 93
void WQtTextureSorter::handleTextureClicked()
{
    unsigned int index =  m_textureListWidget->currentIndex().row();

94
    DatasetSharedContainerType::ReadTicket r = m_textures.getReadTicket();
95 96 97

    QListWidgetItem* ci = m_textureListWidget->item( index );
    WAssert( ci, "Problem in source code." );
98
    boost::shared_ptr< WDataSet > dataSet = r->get()[index];
99 100 101 102

    emit textureSelectionChanged( dataSet );
}

103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
void WQtTextureSorter::update()
{
    boost::shared_ptr< WSubject > subject;
    try
    {
        subject =  WDataHandler::getDefaultSubject();
    }
    catch( WDHNoSuchSubject )
    {
        return;
    }

    if( !subject )
    {
        return;
    }


121 122
    DatasetSharedContainerType::WriteTicket writeTex =  m_textures.getWriteTicket();
    DatasetSharedContainerType::WriteTicket writeDataSet = subject->getDatasetsForWriting();
123

124
    if( writeTex->get().empty() )
125
    {
126
        for( DatasetContainerType::iterator it = writeDataSet->get().begin(); it != writeDataSet->get().end(); ++it )
127 128 129
        {
            if( ( *it )->isTexture() )
            {
130
                writeTex->get().insert( writeTex->get().begin(), *it );
131 132 133 134 135
            }
        }
    }
    else
    {
136
        // insert the new datasets into the texture sorter.
137
        for( DatasetContainerType::iterator it = writeDataSet->get().begin(); it != writeDataSet->get().end(); ++it )
138 139 140
        {
            if( ( *it )->isTexture() )
            {
141
                if( std::find( writeTex->get().begin(), writeTex->get().end(), *it ) == writeTex->get().end() )
142
                {
143
                    writeTex->get().insert( writeTex->get().begin(), *it );
144 145 146
                }
            }
        }
147 148

        // remove deregistered datasets from the texture sorter.
149
        for( DatasetContainerType::iterator it = writeTex->get().begin(); it != writeTex->get().end(); ++it )
150
        {
151 152
            DatasetContainerType::iterator fIt = std::find( writeDataSet->get().begin(), writeDataSet->get().end(), *it );
            if( fIt == writeDataSet->get().end() )
153
            {
154
                writeTex->get().erase( it );
155 156 157
                break;
            }
        }
158 159 160 161 162
    }

    int index =  m_textureListWidget->currentIndex().row();
    m_textureListWidget->clear();

163
    for( DatasetContainerType::iterator it = writeTex->get().begin(); it != writeTex->get().end(); ++it )
164
    {
165 166 167 168 169 170 171 172 173 174
        std::vector< std::string > names =  string_utils::tokenize( ( *it )->getFileName().c_str(), "/" );
        std::string name;
        if( names.size() )
        {
            name = names.back();
        }
        else
        {
            name = "No name given.";
        }
175 176 177 178
        m_textureListWidget->addItem( name.c_str() );
    }

    m_textureListWidget->setCurrentRow( index );
179 180 181

    writeTex.reset();
    writeDataSet.reset();
182
    sort();
183 184
}

185 186
void WQtTextureSorter::moveItemDown()
{
187 188
    unsigned int index =  m_textureListWidget->currentIndex().row();

189
    DatasetSharedContainerType::WriteTicket writeTex =  m_textures.getWriteTicket();
190

191
    if( index < writeTex->get().size() - 1 )
192 193 194 195 196 197 198 199 200
    {
        QListWidgetItem* ci = m_textureListWidget->takeItem( index );

        if( ci )
        {
            m_textureListWidget->insertItem( index + 1, ci );
            m_textureListWidget->clearSelection();
            m_textureListWidget->setCurrentItem( ci );
            ci->setSelected( true );
201 202 203
            boost::shared_ptr< WDataSet > tmp = writeTex->get()[index+1];
            writeTex->get()[index+1] = writeTex->get()[index];
            writeTex->get()[index] = tmp;
204 205 206 207 208
        }
    }
    else
    {
    }
209 210

    writeTex.reset();
211
    sort();
212 213 214 215
}

void WQtTextureSorter::moveItemUp()
{
216 217 218 219 220 221 222 223
    unsigned int index =  m_textureListWidget->currentIndex().row();

    if( index > 0 )
    {
        QListWidgetItem* ci = m_textureListWidget->takeItem( index );

        if( ci )
        {
224
            DatasetSharedContainerType::WriteTicket writeTex = m_textures.getWriteTicket();
225 226 227 228 229

            m_textureListWidget->insertItem( index - 1, ci );
            m_textureListWidget->clearSelection();
            m_textureListWidget->setCurrentItem( ci );
            ci->setSelected( true );
230 231 232
            boost::shared_ptr< WDataSet > tmp = writeTex->get()[index-1];
            writeTex->get()[index-1] = writeTex->get()[index];
            writeTex->get()[index] = tmp;
233 234 235 236 237
        }
    }
    sort();
}

238 239
void WQtTextureSorter::selectTexture( boost::shared_ptr< WDataSet > dataSet )
{
240 241
    DatasetSharedContainerType::ReadTicket readTex =  m_textures.getReadTicket();

242
    size_t i = 0;
243
    for( ; i < readTex->get().size(); ++i )
244
    {
245
        if( readTex->get()[i] == dataSet )
246 247 248 249
        {
            break;
        }
    }
250

251
    if( i < readTex->get().size() )
252 253 254 255 256 257 258 259 260 261
    {
        // select appropriate texture if the data set has a corresponding texture
        QListWidgetItem* ci = m_textureListWidget->item( i );
        m_textureListWidget->setCurrentItem( ci );
    }
    else
    {
        // unselect all if the dataset has no corresponding texture
        m_textureListWidget->clearSelection();
    }
262 263
}

264 265
bool WQtTextureSorter::isLess( boost::shared_ptr< WDataSet > lhs, boost::shared_ptr< WDataSet > rhs )
{
266
    DatasetSharedContainerType::ReadTicket readTex =  m_textures.getReadTicket();
267

268 269
    DatasetContainerType::const_iterator itLHS = std::find( readTex->get().begin(), readTex->get().end(), lhs );
    DatasetContainerType::const_iterator itRHS = std::find( readTex->get().begin(), readTex->get().end(), rhs );
270 271 272 273 274 275 276 277

    bool result = itLHS < itRHS;

    return result;
}

void WQtTextureSorter::sort()
{
278
    DatasetSharedContainerType::WriteTicket writeDataSet = WDataHandler::getDefaultSubject()->getDatasetsForWriting();
279

280
    std::sort( writeDataSet->get().begin(), writeDataSet->get().end(), boost::bind( boost::mem_fn( &WQtTextureSorter::isLess ), this, _1, _2 ) );
281 282

    WDataHandler::getDefaultSubject()->getChangeCondition()->notify();
283
}