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.
krecipes/krecipes/src/widgets/categorylistview.h

289 lines
7.6 KiB

/***************************************************************************
* Copyright (C) 2004 by *
* Jason Kivlighn (jkivlighn@gmail.com) *
* Unai Garro (ugarro@users.sourceforge.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. *
***************************************************************************/
#ifndef CATEGORYLISTVIEW_H
#define CATEGORYLISTVIEW_H
#include <ntqmap.h>
#include <ntqpixmap.h>
#include "dblistviewbase.h"
#include "datablocks/elementlist.h"
class TDEPopupMenu;
class RecipeDB;
class CategoryTree;
class CategoryCheckListView;
#define CATEGORYCHECKLISTITEM_RTTI 1005
#define CATEGORYLISTITEM_RTTI 1001
#define PSEUDOLISTITEM_RTTI 1008
/** Category listitems inherit this class to provide a common interface for accessing this information.
*/
class CategoryItemInfo
{
public:
CategoryItemInfo( const Element &category ) : ctyStored( category ), populated(false){}
bool isPopulated() const { return populated; }
void setPopulated( bool b ){ populated = b; }
Element element() const
{
return ctyStored;
}
int categoryId() const
{
return ctyStored.id;
}
TQString categoryName() const
{
return ctyStored.name;
}
protected:
Element ctyStored;
private:
bool populated;
};
class CategoryCheckListItem : public TQCheckListItem, public CategoryItemInfo
{
public:
CategoryCheckListItem( CategoryCheckListView* klv, const Element &category, bool exclusive = true );
CategoryCheckListItem( TQListViewItem* it, const Element &category, bool exclusive = true );
CategoryCheckListItem( CategoryCheckListView* klv, TQListViewItem* it, const Element &category, bool exclusive = true );
virtual TQString text( int column ) const;
virtual void setText( int column, const TQString &text );
int rtti() const
{
return CATEGORYCHECKLISTITEM_RTTI;
}
protected:
virtual void stateChange( bool );
void setChildrenState( bool );
void setParentsState( bool );
bool locked;
bool exclusive;
private:
CategoryCheckListView *m_listview;
};
class CategoryListItem : public TQListViewItem, public CategoryItemInfo
{
public:
CategoryListItem( TQListView* klv, const Element &category );
CategoryListItem( TQListViewItem* it, const Element &category );
CategoryListItem( TQListView* klv, TQListViewItem* it, const Element &category );
virtual TQString text( int column ) const;
virtual void setText( int column, const TQString &text );
int rtti() const
{
return CATEGORYLISTITEM_RTTI;
}
};
class CategoryListView : public DBListViewBase
{
Q_OBJECT
public:
CategoryListView( TQWidget *parent, RecipeDB * );
void populateAll( TQListViewItem *parent = 0 );
public slots:
void open( TQListViewItem *item );
protected:
virtual void init();
virtual void load( int limit, int offset );
/** so that it allows dropping into
* subchildren that aren't expandable. The code is taken from TDE's TDEListView with
* one line commented out.
*/
void findDrop( const TQPoint &pos, TQListViewItem *&parent, TQListViewItem *&after )
{
TQPoint p ( contentsToViewport( pos ) );
// Get the position to put it in
TQListViewItem *atpos = itemAt( p );
TQListViewItem *above;
if ( !atpos ) // put it at the end
above = lastItem();
else {
// Get the closest item before us ('atpos' or the one above, if any)
if ( p.y() - itemRect( atpos ).topLeft().y() < ( atpos->height() / 2 ) )
above = atpos->itemAbove();
else
above = atpos;
}
if ( above ) {
// if above has children, I might need to drop it as the first item there
if ( above->firstChild() && above->isOpen() ) {
parent = above;
after = 0;
return ;
}
// Now, we know we want to go after "above". But as a child or as a sibling ?
// We have to ask the "above" item if it accepts children.
// ### NOTE: Here is the one line commented out so that "above" always accepts children
//if (above->isExpandable())
{
// The mouse is sufficiently on the right ? - doesn't matter if 'above' has visible children
if ( p.x() >= depthToPixels( above->depth() + 1 ) ||
( above->isOpen() && above->childCount() > 0 ) )
{
parent = above;
after = 0L;
return ;
}
}
// Ok, there's one more level of complexity. We may want to become a new
// sibling, but of an upper-level group, rather than the "above" item
TQListViewItem * betterAbove = above->parent();
TQListViewItem * last = above;
while ( betterAbove ) {
// We are allowed to become a sibling of "betterAbove" only if we are
// after its last child
if ( last->nextSibling() == 0 ) {
if ( p.x() < depthToPixels ( betterAbove->depth() + 1 ) )
above = betterAbove; // store this one, but don't stop yet, there may be a better one
else
break; // not enough on the left, so stop
last = betterAbove;
betterAbove = betterAbove->parent(); // up one level
}
else
break; // we're among the child of betterAbove, not after the last one
}
}
// set as sibling
after = above;
parent = after ? after->parent() : 0L ;
}
protected slots:
virtual void removeCategory( int id ) = 0;
virtual void createCategory( const Element &category, int parent_id ) = 0;
virtual void modifyCategory( const Element &category );
virtual void modifyCategory( int id, int parent_id );
virtual void mergeCategories( int id1, int id2 );
virtual void checkCreateCategory( const Element &, int parent_id );
virtual void populate( TQListViewItem *item );
TQMap<int, TQListViewItem*> items_map;
private:
TQListViewItem *m_item_to_delete;
};
class StdCategoryListView : public CategoryListView
{
Q_OBJECT
public:
StdCategoryListView( TQWidget *parent, RecipeDB *, bool editable = false );
~StdCategoryListView();
protected:
virtual void removeCategory( int id );
virtual void createCategory( const Element &category, int parent_id );
void setPixmap( const TQPixmap &pixmap );
private slots:
void preparePopup();
void showPopup( TDEListView *, TQListViewItem *, const TQPoint & );
void createNew();
void remove
();
void rename();
void cut();
void paste();
void pasteAsSub();
void changeCategoryParent( TQListViewItem *item, TQListViewItem * /*afterFirst*/, TQListViewItem * /*afterNow*/ );
void modCategory( TQListViewItem* i );
void saveCategory( TQListViewItem* i );
private:
bool checkBounds( const TQString &name );
TDEPopupMenu *kpop;
TQListViewItem *clipboard_item;
TQListViewItem *clipboard_parent;
TQPixmap m_folder_icon;
};
class CategoryCheckListView : public CategoryListView
{
Q_OBJECT
public:
CategoryCheckListView( TQWidget *parent, RecipeDB *, bool exclusive=true, const ElementList &init_items_checked = ElementList() );
virtual void stateChange( CategoryCheckListItem*, bool );
ElementList selections() const{ return m_selections; }
protected:
virtual void removeCategory( int id );
virtual void createCategory( const Element &category, int parent_id );
virtual void load( int limit, int offset );
bool exclusive;
private:
ElementList m_selections;
};
class PseudoListItem : public TQListViewItem
{
public:
PseudoListItem( TQListView* lv ) : TQListViewItem(lv){}
PseudoListItem( TQListViewItem* it ) : TQListViewItem(it){}
protected:
int rtti() const { return PSEUDOLISTITEM_RTTI; }
};
#endif //CATEGORYLISTVIEW_H