Logo Search packages:      
Sourcecode: packagesearch version File versions

tagselectionlistview.cpp

//
// C++ Implementation: tagselectionlistview.cpp
//
// Description: 
//
//
// Author: Benjamin Mesing <bensmail@gmx.net>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//
// The first version of this file was generated by umbrello 
// on Tue May 18 2004 at 20:13:27


#include <vector>
#include <algorithm>
#include <functional>
#include <assert.h>

#include <qpopupmenu.h>

#include <Tag.h>
#include <TagSet.h>

#include <Vocabulary.h>

#include "tagselectionlistview.h"
#include "taglistviewitem.h"
#include "exception.h"


namespace NWidgets
{

00036 TagSelectionListView::TagSelectionListView(QWidget *parent, const char *name)
 : QListView(parent, name)
{
      _pColl = 0;
      
      addColumn("Tags");
      addColumn("Description");
      setColumnWidthMode(0, QListView::Manual);
      setColumnWidthMode(1, QListView::Manual);
      setResizeMode(QListView::LastColumn);
      setSelectionMode(QListView::Multi);
      
      connect( 
            this, SIGNAL(contextMenuRequested(QListViewItem*, const QPoint&, int)),
            SLOT(onContextMenuRequested(QListViewItem*, const QPoint&, int))
      );
      connect( this, SIGNAL(selectionChanged()), SLOT(onSelectionChanged()));

      setColumnWidth(0,100);
}


00058 void TagSelectionListView::deselectTag(const string& fullTagname)
{
      /// @todo had to change to the this... version because of the covariance not supported thing
      TagListViewItem* p = thisGetTagItem(fullTagname);
      setSelected(p, false);
}

00065 void TagSelectionListView::deselectAll()
{
      clearSelection(); // this triggers selectionChanged signal(s)
}

00070 void TagSelectionListView::expandAll()
{
      for (iterator it = begin(); it != end(); ++it)
            it->setOpen(true);
}

00076 void TagSelectionListView::collapseAll()
{
      for (iterator it = begin(); it != end(); ++it)
            it->setOpen(false);
}


00083 void TagSelectionListView::clear()
{
      // clear the list
      QListView::clear();     // this should emit the selection changed signal
}

00089 TagItem* TagSelectionListView::getTagItem(const string& fullName)
{
      iterator it = std::find_if(
            begin(), end(), 
            // unfortunatelly bind2nd(mem_fun(&TagItem::equals_to),fullName)
            // with equals_to(const string&) 
            // does not work, as the algorithm tries to create "const const string& &" for
            // the constructor :-(
            TagSelectionView::equal_to_tagname(fullName)
            
//          bind1st( equal_to<string>(mem_fun(&TagItem::fullTagname)),fullName )
      );
      return (it == end()) ?  0 : (*it);
}


00105 void TagSelectionListView::loadVocabulary(const Tagcoll::FacetSet& vocabulary)
{
      set<string> selectedTags;
      // collect the items currently selected
      transform (
            _selected.begin(), _selected.end(), 
            inserter(selectedTags, selectedTags.begin()),   // inserter to insert in the set
            mem_fun(&TagItem::fullTagname)
      );
      // This will be filled with the new tagItems that where selected in the old version.
      vector<TagListViewItem*> newSelected;
      clear();
      TagListViewItem* pRoot = new TagListViewItem(this, "/");    // insert as subitem of the root
      pRoot->setSelectable(false);
      pRoot->setOpen(true);
      // iterate over all facets
      int count = 0;
      // iterate over the facetset, a vocabulary entry is a pair of <tag, Record>
      // the whole algorithm does only work, because the Vocabulary class' content is arranged in
      // a map, which assures: it->first < (it+1)->first (and this way app comes before app::myApp)
      for ( Tagcoll::FacetSet::const_iterator it = vocabulary.begin(); it != vocabulary.end(); ++it )
      {
            ++count;
            // add the facet to the view
            /// @todo add the long description as tooltip
            const Tagcoll::Facet& facet = *it;
            if (facet.name().empty())     // it seems that there is the global facet, which contains the facets..
                  continue;
            TagListViewItem* pFacetItem = new TagListViewItem(pRoot, facet.name(), facet.sdesc());
            assert(pFacetItem);
            for ( Tagcoll::TagSet::iterator jt = facet.tags().begin(); jt != facet.tags().end(); ++jt)
            {
                  const Tagcoll::Tag& tag = *jt;
                  ///@todo here loading fails under really strange circumstences - I assume a qt 
                  /// or debtags bug here
                  /// though I am not sure about it. The plugin crashes if this is called some more often
                  /// and I don't know why. Using pRoot as parent works completely and so does it with
                  /// loading only the 5 first factes (see above)
                  /// it even happens if I use QListViewItems instead of TagListViewItems so it
                  /// strongly speaks for a QT or debtags bug
                  TagListViewItem* pItem = new TagListViewItem(
                        pFacetItem, facet.name() + "::" + tag.name(), tag.sdesc());
/*                TagListViewItem* pItem = new TagListViewItem(
                        pRoot, facet.name() + "::" + tag.name(), tag.sdesc());*/

                  if ( selectedTags.find(tag.name()) != selectedTags.end() )  // if the tag was selected before
                        newSelected.push_back(pItem); // add it to the new selected items
            }
            if ( selectedTags.find(facet.name()) != selectedTags.end() )      // if the tag was selected before
                  newSelected.push_back(pFacetItem);  // add it to the new selected items
      }
      for( vector<TagListViewItem*>::iterator it = newSelected.begin(); it != newSelected.end(); ++it)
            setSelected(*it,true);
}

00160 void TagSelectionListView::filter()
{
      // this is necessary as QListViewItem setVisible() also makes all beneath the parents visible,
      // this behavoir is kinda odd because it does only occur if we go from a less detailed listview
      // to a more detailed one
      QListViewItem* pCurrent = currentItem();
      if (pCurrent && !pCurrent->isVisible())   // if the item is not visible do not ensure it later
            pCurrent = 0;
      makeAllVisible();
      filterByName();
      filterByTagSet();
      if (pCurrent)
            ensureItemVisible(pCurrent);
}

00175 void TagSelectionListView::filterByName() 
{
      if (_filterByNamePattern.empty()) return;
      // there should be exactly one or no root item
      TagListViewItem* pRoot = static_cast<TagListViewItem*>(firstChild());
      if (pRoot == 0)   // if we do not have a root
            return;
      pRoot->filterByName(_filterByNamePattern);
}

00185 void TagSelectionListView::filterByTagSet()
{
      if (_pColl==0 || _selected.empty() ) return;
      TagListViewItem* pRoot = static_cast<TagListViewItem*>(firstChild());
      if (pRoot == 0)   // if we do not have a root
            return;
      Tagcoll::OpSet<string> selectedTags;
      // insert all items names in the new set
      transform(
            _selected.begin(), _selected.end(), 
            inserter(selectedTags, selectedTags.begin()),   // inserter to insert in the set
            mem_fun(&TagItem::fullTagname)
      );
      Tagcoll::OpSet<string> companionTags = _pColl->getCompanionTags(selectedTags);
      companionTags += selectedTags;
      pRoot->filterByTagset(companionTags);

/*    for ( iterator it = begin(QListViewItemIterator::Visible); it != end(); ++it)
      {
            // assumes that a child implies its parent, else the parent could be hidden and the 
            // child shown
            if ( companionTags.find(it->fullTagname()) == companionTags.end() )
                  it->setVisible(false);
      }*/
      
}

00212 void TagSelectionListView::makeAllVisible()
{
      for ( iterator it = begin(QListViewItemIterator::Invisible); it != end(); ++it)
            it->setVisible(true);
}

00218 void TagSelectionListView::onSelectionChanged()
{
      _selected.clear();
      _selected = getSelected();
      //for ( iterator it = begin(QListViewItemIterator::Selected); it != end(); ++it)
      //    _selected.insert( static_cast<TagListViewItem*>( *it ));
      filter();
      emit tagItemsSelected(_selected);
}

void TagSelectionListView::onContextMenuRequested(QListViewItem* item, const QPoint& pos, int col)
{
      QPopupMenu menu(this);
      menu.insertItem("Expand all", 1);
      menu.insertItem("Collapse all", 2);
      menu.insertItem("Deselect all", 3);
      switch (menu.exec(pos))
      {
            case 1:
                  expandAll();
                  break;
            case 2:
                  collapseAll();
                  break;
            case 3:
                  deselectAll();
                  break;
            default:
                  break;
      }
}


00251 void TagSelectionListView::contentsMousePressEvent(QMouseEvent* pE)
{
      QListViewItem* pItem = itemAt( QPoint(0, pE->pos().y()) );
      if (pE->button() == QMouseEvent::RightButton )
            emit contextMenuRequested(pItem, pE->globalPos(), -1 );
      else
            QListView::contentsMousePressEvent(pE);
      return;
}


}     // namespace NWidgets


Generated by  Doxygen 1.6.0   Back to index