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.
digikam/digikam/digikam/icongroupitem.cpp

308 lines
5.9 KiB

/* ============================================================
*
* This file is a part of digiKam project
* http://www.digikam.org
*
* Date : 2005-04-24
* Description : icons group item.
*
* Copyright (C) 2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
*
* 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, or (at your option)
* any later version.
*
* This program 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 General Public License for more details.
*
* ============================================================ */
// C Ansi includes.
#include <cstdlib>
// TQt includes.
#include <tqpixmap.h>
#include <tqpalette.h>
// Local includes.
#include "iconview.h"
#include "iconitem.h"
#include "icongroupitem.h"
namespace Digikam
{
class IconGroupItemPriv
{
public:
IconGroupItemPriv()
{
view = 0;
firstItem = 0;
lastItem = 0;
y = 0;
count = 0;
clearing = false;
}
IconView* view;
IconItem* firstItem;
IconItem* lastItem;
int y;
int count;
bool clearing;
struct SortableItem
{
IconItem *item;
};
};
IconGroupItem::IconGroupItem(IconView* parent)
{
d = new IconGroupItemPriv;
d->view = parent;
m_next = 0;
m_prev = 0;
parent->insertGroup(this);
}
IconGroupItem::~IconGroupItem()
{
clear(false);
d->view->takeGroup(this);
delete d;
}
IconView* IconGroupItem::iconView() const
{
return d->view;
}
IconGroupItem* IconGroupItem::nextGroup() const
{
return m_next;
}
IconGroupItem* IconGroupItem::prevGroup() const
{
return m_prev;
}
TQRect IconGroupItem::rect() const
{
TQRect r = d->view->bannerRect();
r.moveBy(0, d->y);
return r;
}
int IconGroupItem::y() const
{
return d->y;
}
IconItem* IconGroupItem::firstItem() const
{
return d->firstItem;
}
IconItem* IconGroupItem::lastItem() const
{
return d->lastItem;
}
void IconGroupItem::insertItem(IconItem* item)
{
if (!item)
return;
if (!d->firstItem)
{
d->firstItem = item;
d->lastItem = item;
item->m_prev = 0;
item->m_next = 0;
}
else
{
d->lastItem->m_next = item;
item->m_prev = d->lastItem;
item->m_next = 0;
d->lastItem = item;
}
d->count++;
d->view->insertItem(item);
}
void IconGroupItem::takeItem(IconItem* item)
{
if (!item)
return;
// take item triggers update
d->view->takeItem(item);
d->count--;
if (item == d->firstItem)
{
d->firstItem = d->firstItem->m_next;
if (d->firstItem)
d->firstItem->m_prev = 0;
else
d->firstItem = d->lastItem = 0;
}
else if (item == d->lastItem)
{
d->lastItem = d->lastItem->m_prev;
if ( d->lastItem )
d->lastItem->m_next = 0;
else
d->firstItem = d->lastItem = 0;
}
else
{
IconItem *i = item;
if (i)
{
if (i->m_prev )
i->m_prev->m_next = i->m_next;
if ( i->m_next )
i->m_next->m_prev = i->m_prev;
}
}
}
int IconGroupItem::count() const
{
return d->count;
}
int IconGroupItem::index(IconItem* item) const
{
if ( !item )
return -1;
if ( item == d->firstItem )
return 0;
else if ( item == d->lastItem )
return d->count - 1;
else
{
IconItem *i = d->firstItem;
int j = 0;
while ( i && i != item )
{
i = i->m_next;
++j;
}
return i ? j : -1;
}
}
void IconGroupItem::clear(bool update)
{
d->clearing = true;
IconItem *item = d->firstItem;
while (item)
{
IconItem *tmp = item->m_next;
delete item;
item = tmp;
}
d->firstItem = 0;
d->lastItem = 0;
d->count = 0;
if (update)
d->view->triggerRearrangement();
d->clearing = false;
}
void IconGroupItem::sort()
{
IconGroupItemPriv::SortableItem *items
= new IconGroupItemPriv::SortableItem[ count() ];
IconItem *item = d->firstItem;
int i = 0;
for ( ; item; item = item->m_next )
items[ i++ ].item = item;
qsort( items, count(), sizeof( IconGroupItemPriv::SortableItem ), cmpItems );
IconItem *prev = 0;
item = 0;
for ( i = 0; i < (int)count(); ++i ) {
item = items[ i ].item;
if ( item ) {
item->m_prev = prev;
if ( item->m_prev )
item->m_prev->m_next = item;
item->m_next = 0;
}
if ( i == 0 )
d->firstItem = item;
if ( i == (int)count() - 1 )
d->lastItem = item;
prev = item;
}
delete [] items;
}
bool IconGroupItem::move(int y)
{
if (d->y == y)
return false;
d->y = y;
return true;
}
void IconGroupItem::paintBanner()
{
TQRect r(rect());
TQPixmap pix(r.width(), r.height());
pix.fill(d->view->colorGroup().base());
r = TQRect(d->view->contentsToViewport(TQPoint(r.x(), r.y())),
TQSize(r.width(), r.height()));
bitBlt(d->view->viewport(), r.x(), r.y(), &pix,
0, 0, r.width(), r.height());
}
int IconGroupItem::compare(IconGroupItem*)
{
return 0;
}
int IconGroupItem::cmpItems(const void *n1, const void *n2)
{
if ( !n1 || !n2 )
return 0;
IconGroupItemPriv::SortableItem *i1 = (IconGroupItemPriv::SortableItem *)n1;
IconGroupItemPriv::SortableItem *i2 = (IconGroupItemPriv::SortableItem *)n2;
return i1->item->compare( i2->item );
}
} // namespace Digikam