|
|
|
/* ============================================================
|
|
|
|
*
|
|
|
|
* This file is a part of digiKam project
|
|
|
|
* http://www.digikam.org
|
|
|
|
*
|
|
|
|
* Date : 2005-04-24
|
|
|
|
* Description : icons view.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
|
|
|
|
* Copyright (C) 2006-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* ============================================================ */
|
|
|
|
|
|
|
|
#define RECT_EXTENSION 300
|
|
|
|
|
|
|
|
// C++ includes.
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
|
|
|
// TQt includes.
|
|
|
|
|
|
|
|
#include <tqtimer.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqvaluelist.h>
|
|
|
|
#include <tqptrdict.h>
|
|
|
|
#include <tqstyle.h>
|
|
|
|
#include <tqapplication.h>
|
|
|
|
#include <tqdrawutil.h>
|
|
|
|
|
|
|
|
// KDE includes.
|
|
|
|
|
|
|
|
#include <kcursor.h>
|
|
|
|
#include <kglobalsettings.h>
|
|
|
|
|
|
|
|
// Local includes.
|
|
|
|
|
|
|
|
#include "ddebug.h"
|
|
|
|
#include "iconitem.h"
|
|
|
|
#include "icongroupitem.h"
|
|
|
|
#include "iconview.h"
|
|
|
|
#include "iconview.moc"
|
|
|
|
|
|
|
|
namespace Digikam
|
|
|
|
{
|
|
|
|
|
|
|
|
class IconViewPriv
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
IconViewPriv()
|
|
|
|
{
|
|
|
|
firstGroup = 0;
|
|
|
|
lastGroup = 0;
|
|
|
|
currItem = 0;
|
|
|
|
anchorItem = 0;
|
|
|
|
clearing = false;
|
|
|
|
spacing = 10;
|
|
|
|
|
|
|
|
rubber = 0;
|
|
|
|
dragging = false;
|
|
|
|
pressedMoved = false;
|
|
|
|
|
|
|
|
firstContainer = 0;
|
|
|
|
lastContainer = 0;
|
|
|
|
|
|
|
|
showTips = false;
|
|
|
|
toolTipItem = 0;
|
|
|
|
toolTipTimer = 0;
|
|
|
|
rearrangeTimer = 0;
|
|
|
|
rearrangeTimerInterval = 0;
|
|
|
|
storedVisibleItem = 0;
|
|
|
|
needEmitSelectionChanged = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool clearing;
|
|
|
|
bool showTips;
|
|
|
|
bool pressedMoved;
|
|
|
|
bool dragging;
|
|
|
|
bool needEmitSelectionChanged; // store for slotRearrange
|
|
|
|
|
|
|
|
int spacing;
|
|
|
|
|
|
|
|
TQPtrDict<IconItem> selectedItems;
|
|
|
|
TQPtrDict<IconItem> prevSelectedItems;
|
|
|
|
|
|
|
|
TQRect* rubber;
|
|
|
|
|
|
|
|
TQPoint dragStartPos;
|
|
|
|
|
|
|
|
TQTimer* rearrangeTimer;
|
|
|
|
TQTimer* toolTipTimer;
|
|
|
|
|
|
|
|
IconItem* toolTipItem;
|
|
|
|
IconItem* currItem;
|
|
|
|
IconItem* anchorItem;
|
|
|
|
IconItem* storedVisibleItem; // store position for slotRearrange
|
|
|
|
|
|
|
|
IconGroupItem* firstGroup;
|
|
|
|
IconGroupItem* lastGroup;
|
|
|
|
|
|
|
|
int rearrangeTimerInterval;
|
|
|
|
|
|
|
|
struct ItemContainer
|
|
|
|
{
|
|
|
|
ItemContainer(ItemContainer *p, ItemContainer *n, const TQRect &r)
|
|
|
|
: prev(p), next(n), rect(r)
|
|
|
|
{
|
|
|
|
if (prev)
|
|
|
|
prev->next = this;
|
|
|
|
if (next)
|
|
|
|
next->prev = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
ItemContainer *prev, *next;
|
|
|
|
TQRect rect;
|
|
|
|
TQValueList<IconItem*> items;
|
|
|
|
} *firstContainer, *lastContainer;
|
|
|
|
|
|
|
|
struct SortableItem
|
|
|
|
{
|
|
|
|
IconGroupItem *group;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
IconView::IconView(TQWidget* parent, const char* name)
|
|
|
|
: TQScrollView(parent, name, TQt::WStaticContents|TQt::WNoAutoErase)
|
|
|
|
{
|
|
|
|
viewport()->setBackgroundMode(TQt::NoBackground);
|
|
|
|
viewport()->setFocusProxy(this);
|
|
|
|
viewport()->setFocusPolicy(TQ_WheelFocus);
|
|
|
|
viewport()->setMouseTracking(true);
|
|
|
|
|
|
|
|
d = new IconViewPriv;
|
|
|
|
d->rearrangeTimer = new TQTimer(this);
|
|
|
|
d->toolTipTimer = new TQTimer(this);
|
|
|
|
|
|
|
|
connect(d->rearrangeTimer, TQT_SIGNAL(timeout()),
|
|
|
|
this, TQT_SLOT(slotRearrange()));
|
|
|
|
|
|
|
|
connect(d->toolTipTimer, TQT_SIGNAL(timeout()),
|
|
|
|
this, TQT_SLOT(slotToolTip()));
|
|
|
|
|
|
|
|
setEnableToolTips(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
IconView::~IconView()
|
|
|
|
{
|
|
|
|
clear(false);
|
|
|
|
|
|
|
|
delete d->rearrangeTimer;
|
|
|
|
delete d->toolTipTimer;
|
|
|
|
delete d->rubber;
|
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
|
|
|
IconGroupItem* IconView::firstGroup() const
|
|
|
|
{
|
|
|
|
return d->firstGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
IconGroupItem* IconView::lastGroup() const
|
|
|
|
{
|
|
|
|
return d->lastGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
IconItem* IconView::firstItem() const
|
|
|
|
{
|
|
|
|
if (!d->firstGroup)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return d->firstGroup->firstItem();
|
|
|
|
}
|
|
|
|
|
|
|
|
IconItem* IconView::lastItem() const
|
|
|
|
{
|
|
|
|
if (!d->lastGroup)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return d->lastGroup->lastItem();
|
|
|
|
}
|
|
|
|
|
|
|
|
IconItem* IconView::currentItem() const
|
|
|
|
{
|
|
|
|
return d->currItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::setCurrentItem(IconItem* item)
|
|
|
|
{
|
|
|
|
d->currItem = item;
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
|
|
|
|
if (d->currItem)
|
|
|
|
{
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
ensureItemVisible(d->currItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IconItem* IconView::findItem(const TQPoint& pos)
|
|
|
|
{
|
|
|
|
IconViewPriv::ItemContainer *c = d->firstContainer;
|
|
|
|
for (; c; c = c->next)
|
|
|
|
{
|
|
|
|
if ( c->rect.contains(pos) )
|
|
|
|
{
|
|
|
|
for (TQValueList<IconItem*>::iterator it = c->items.begin();
|
|
|
|
it != c->items.end(); ++it)
|
|
|
|
{
|
|
|
|
IconItem* item = *it;
|
|
|
|
if (item->rect().contains(pos))
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
IconGroupItem* IconView::findGroup(const TQPoint& pos)
|
|
|
|
{
|
|
|
|
TQPoint p = viewportToContents(viewport()->mapFromGlobal(pos));
|
|
|
|
for (IconGroupItem* group = d->firstGroup; group; group = group->nextGroup())
|
|
|
|
{
|
|
|
|
TQRect rect = group->rect();
|
|
|
|
int bottom;
|
|
|
|
if (group == d->lastGroup)
|
|
|
|
bottom = contentsHeight();
|
|
|
|
else
|
|
|
|
bottom = group->nextGroup()->rect().top();
|
|
|
|
|
|
|
|
rect.setBottom(bottom);
|
|
|
|
|
|
|
|
if ( rect.contains(p) )
|
|
|
|
{
|
|
|
|
return group;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int IconView::count() const
|
|
|
|
{
|
|
|
|
int c = 0;
|
|
|
|
for (IconGroupItem* group = d->firstGroup; group; group = group->nextGroup())
|
|
|
|
{
|
|
|
|
c += group->count();
|
|
|
|
}
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int IconView::countSelected() const
|
|
|
|
{
|
|
|
|
int c = 0;
|
|
|
|
for (IconGroupItem* group = d->firstGroup; group; group = group->nextGroup())
|
|
|
|
{
|
|
|
|
for (IconItem *it = group->firstItem(); it; it = it->nextItem())
|
|
|
|
if (it->isSelected())
|
|
|
|
c++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
int IconView::groupCount() const
|
|
|
|
{
|
|
|
|
int c = 0;
|
|
|
|
for (IconGroupItem* group = d->firstGroup; group; group = group->nextGroup())
|
|
|
|
{
|
|
|
|
c++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::clear(bool update)
|
|
|
|
{
|
|
|
|
d->clearing = true;
|
|
|
|
|
|
|
|
d->toolTipItem = 0;
|
|
|
|
d->toolTipTimer->stop();
|
|
|
|
slotToolTip();
|
|
|
|
|
|
|
|
deleteContainers();
|
|
|
|
|
|
|
|
d->selectedItems.clear();
|
|
|
|
|
|
|
|
IconGroupItem *group = d->firstGroup;
|
|
|
|
while (group)
|
|
|
|
{
|
|
|
|
IconGroupItem *tmp = group->m_next;
|
|
|
|
delete group;
|
|
|
|
group = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
d->firstGroup = 0;
|
|
|
|
d->lastGroup = 0;
|
|
|
|
d->currItem = 0;
|
|
|
|
d->anchorItem = 0;
|
|
|
|
|
|
|
|
viewport()->setUpdatesEnabled(false);
|
|
|
|
resizeContents(0, 0);
|
|
|
|
setContentsPos(0, 0);
|
|
|
|
viewport()->setUpdatesEnabled(true);
|
|
|
|
|
|
|
|
if (update)
|
|
|
|
updateContents();
|
|
|
|
|
|
|
|
d->clearing = false;
|
|
|
|
|
|
|
|
emit signalSelectionChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::clearSelection()
|
|
|
|
{
|
|
|
|
bool wasBlocked = signalsBlocked();;
|
|
|
|
|
|
|
|
if (!wasBlocked)
|
|
|
|
blockSignals(true);
|
|
|
|
|
|
|
|
TQPtrDict<IconItem> selItems = d->selectedItems;
|
|
|
|
TQPtrDictIterator<IconItem> it( selItems );
|
|
|
|
for ( ; it.current(); ++it )
|
|
|
|
it.current()->setSelected(false, false);
|
|
|
|
|
|
|
|
d->selectedItems.clear();
|
|
|
|
|
|
|
|
if (!wasBlocked)
|
|
|
|
blockSignals(false);
|
|
|
|
|
|
|
|
emit signalSelectionChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::selectAll()
|
|
|
|
{
|
|
|
|
bool wasBlocked = signalsBlocked();
|
|
|
|
|
|
|
|
if (!wasBlocked)
|
|
|
|
blockSignals(true);
|
|
|
|
|
|
|
|
for (IconItem* item = firstItem(); item; item = item->nextItem())
|
|
|
|
{
|
|
|
|
if (!item->isSelected())
|
|
|
|
{
|
|
|
|
item->setSelected(true, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!wasBlocked)
|
|
|
|
blockSignals(false);
|
|
|
|
|
|
|
|
emit signalSelectionChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::invertSelection()
|
|
|
|
{
|
|
|
|
bool wasBlocked = signalsBlocked();
|
|
|
|
|
|
|
|
if (!wasBlocked)
|
|
|
|
blockSignals(true);
|
|
|
|
|
|
|
|
for (IconItem* item = firstItem(); item; item = item->nextItem())
|
|
|
|
{
|
|
|
|
if (!item->isSelected())
|
|
|
|
{
|
|
|
|
item->setSelected(true, false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->setSelected(false, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!wasBlocked)
|
|
|
|
blockSignals(false);
|
|
|
|
|
|
|
|
emit signalSelectionChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::selectItem(IconItem* item, bool select)
|
|
|
|
{
|
|
|
|
if (!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (select)
|
|
|
|
{
|
|
|
|
d->selectedItems.replace(item, item);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d->selectedItems.remove(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
emit signalSelectionChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::setStoredVisibleItem(IconItem *item)
|
|
|
|
{
|
|
|
|
d->storedVisibleItem = item;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::insertGroup(IconGroupItem* group)
|
|
|
|
{
|
|
|
|
if (!group)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!d->firstGroup)
|
|
|
|
{
|
|
|
|
d->firstGroup = group;
|
|
|
|
d->lastGroup = group;
|
|
|
|
group->m_prev = 0;
|
|
|
|
group->m_next = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d->lastGroup->m_next = group;
|
|
|
|
group->m_prev = d->lastGroup;
|
|
|
|
group->m_next = 0;
|
|
|
|
d->lastGroup = group;
|
|
|
|
}
|
|
|
|
|
|
|
|
d->storedVisibleItem = findFirstVisibleItem();
|
|
|
|
startRearrangeTimer();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::takeGroup(IconGroupItem* group)
|
|
|
|
{
|
|
|
|
if (!group)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// this is only to find an alternative visible item if all visible items
|
|
|
|
// are removed
|
|
|
|
IconGroupItem *alternativeVisibleGroup = 0;
|
|
|
|
d->storedVisibleItem = 0;
|
|
|
|
|
|
|
|
if (group == d->firstGroup)
|
|
|
|
{
|
|
|
|
d->firstGroup = d->firstGroup->m_next;
|
|
|
|
if (d->firstGroup)
|
|
|
|
d->firstGroup->m_prev = 0;
|
|
|
|
else
|
|
|
|
d->firstGroup = d->lastGroup = 0;
|
|
|
|
alternativeVisibleGroup = d->firstGroup;
|
|
|
|
}
|
|
|
|
else if (group == d->lastGroup)
|
|
|
|
{
|
|
|
|
d->lastGroup = d->lastGroup->m_prev;
|
|
|
|
if ( d->lastGroup )
|
|
|
|
d->lastGroup->m_next = 0;
|
|
|
|
else
|
|
|
|
d->firstGroup = d->lastGroup = 0;
|
|
|
|
alternativeVisibleGroup = d->lastGroup->m_prev;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IconGroupItem *i = group;
|
|
|
|
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;
|
|
|
|
|
|
|
|
if (i->m_prev)
|
|
|
|
alternativeVisibleGroup = i->m_prev;
|
|
|
|
else
|
|
|
|
alternativeVisibleGroup = i->m_next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!d->clearing)
|
|
|
|
{
|
|
|
|
d->storedVisibleItem = findFirstVisibleItem();
|
|
|
|
if (!d->storedVisibleItem && alternativeVisibleGroup)
|
|
|
|
{
|
|
|
|
// find an alternative visible item
|
|
|
|
d->storedVisibleItem = alternativeVisibleGroup->lastItem();
|
|
|
|
}
|
|
|
|
startRearrangeTimer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::insertItem(IconItem* item)
|
|
|
|
{
|
|
|
|
if (!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
d->storedVisibleItem = findFirstVisibleItem();
|
|
|
|
startRearrangeTimer();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::takeItem(IconItem* item)
|
|
|
|
{
|
|
|
|
if (!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// First remove item from any containers holding it
|
|
|
|
IconViewPriv::ItemContainer *tmp = d->firstContainer;
|
|
|
|
while (tmp)
|
|
|
|
{
|
|
|
|
tmp->items.remove(item);
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove from selected item list
|
|
|
|
d->selectedItems.remove(item);
|
|
|
|
// See bug 161084
|
|
|
|
if (d->selectedItems.count() || item->isSelected())
|
|
|
|
d->needEmitSelectionChanged = true;
|
|
|
|
|
|
|
|
if (d->toolTipItem == item)
|
|
|
|
{
|
|
|
|
d->toolTipItem = 0;
|
|
|
|
d->toolTipTimer->stop();
|
|
|
|
slotToolTip();
|
|
|
|
}
|
|
|
|
|
|
|
|
// if it is current item, change the current item
|
|
|
|
if (d->currItem == item)
|
|
|
|
{
|
|
|
|
d->currItem = item->nextItem();
|
|
|
|
if (!d->currItem)
|
|
|
|
d->currItem = item->prevItem();
|
|
|
|
// defer calling d->currItem->setSelected (and emitting the signals) to slotRearrange
|
|
|
|
}
|
|
|
|
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
|
|
|
|
if (!d->clearing)
|
|
|
|
{
|
|
|
|
d->storedVisibleItem = findFirstVisibleItem();
|
|
|
|
if (d->storedVisibleItem == item)
|
|
|
|
d->storedVisibleItem = d->currItem;
|
|
|
|
startRearrangeTimer();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::triggerRearrangement()
|
|
|
|
{
|
|
|
|
d->storedVisibleItem = findFirstVisibleItem();
|
|
|
|
startRearrangeTimer();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::setDelayedRearrangement(bool delayed)
|
|
|
|
{
|
|
|
|
// if it is known that e.g. several items will be added or deleted in the next time,
|
|
|
|
// but not from the same event queue thread stack location, it may be desirable to delay
|
|
|
|
// the rearrangeTimer a bit
|
|
|
|
if (delayed)
|
|
|
|
d->rearrangeTimerInterval = 50;
|
|
|
|
else
|
|
|
|
d->rearrangeTimerInterval = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::startRearrangeTimer()
|
|
|
|
{
|
|
|
|
// We want to reduce the number of updates, but not remove all updates
|
|
|
|
if (!d->rearrangeTimer->isActive())
|
|
|
|
d->rearrangeTimer->start(d->rearrangeTimerInterval, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::sort()
|
|
|
|
{
|
|
|
|
// first sort the groups
|
|
|
|
for (IconGroupItem* group = d->firstGroup; group;
|
|
|
|
group = group->nextGroup())
|
|
|
|
{
|
|
|
|
group->sort();
|
|
|
|
}
|
|
|
|
|
|
|
|
int gcount = groupCount();
|
|
|
|
|
|
|
|
// then sort the groups themselves
|
|
|
|
IconViewPriv::SortableItem *groups = new IconViewPriv::SortableItem[ gcount ];
|
|
|
|
|
|
|
|
IconGroupItem *group = d->firstGroup;
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
for ( ; group; group = group->m_next )
|
|
|
|
groups[ i++ ].group = group;
|
|
|
|
|
|
|
|
qsort( groups, gcount, sizeof( IconViewPriv::SortableItem ), cmpItems );
|
|
|
|
|
|
|
|
IconGroupItem *prev = 0;
|
|
|
|
group = 0;
|
|
|
|
|
|
|
|
for ( i = 0; i < (int)gcount; ++i )
|
|
|
|
{
|
|
|
|
group = groups[ i ].group;
|
|
|
|
if ( group )
|
|
|
|
{
|
|
|
|
group->m_prev = prev;
|
|
|
|
|
|
|
|
if ( group->m_prev )
|
|
|
|
group->m_prev->m_next = group;
|
|
|
|
|
|
|
|
group->m_next = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( i == 0 )
|
|
|
|
d->firstGroup = group;
|
|
|
|
|
|
|
|
if ( i == (int)gcount - 1 )
|
|
|
|
d->lastGroup = group;
|
|
|
|
prev = group;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete [] groups;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::slotRearrange()
|
|
|
|
{
|
|
|
|
sort();
|
|
|
|
arrangeItems();
|
|
|
|
|
|
|
|
// ensure there is a current item
|
|
|
|
if (!d->currItem)
|
|
|
|
{
|
|
|
|
// set the currItem to first item
|
|
|
|
if (d->firstGroup)
|
|
|
|
d->currItem = d->firstGroup->firstItem();
|
|
|
|
}
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
|
|
|
|
// ensure there is a selection
|
|
|
|
if (d->selectedItems.isEmpty() && d->currItem)
|
|
|
|
{
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
}
|
|
|
|
else if (d->needEmitSelectionChanged)
|
|
|
|
{
|
|
|
|
emit signalSelectionChanged();
|
|
|
|
}
|
|
|
|
d->needEmitSelectionChanged = false;
|
|
|
|
|
|
|
|
// set first visible item if they where stored before update was triggered
|
|
|
|
if (d->storedVisibleItem)
|
|
|
|
{
|
|
|
|
ensureItemVisible(d->storedVisibleItem);
|
|
|
|
// reset to 0
|
|
|
|
d->storedVisibleItem = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ensureItemVisible(d->currItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
viewport()->update();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IconView::arrangeItems()
|
|
|
|
{
|
|
|
|
int y = 0;
|
|
|
|
int itemW = tqitemRect().width();
|
|
|
|
int itemH = tqitemRect().height();
|
|
|
|
int maxW = 0;
|
|
|
|
|
|
|
|
int numItemsPerRow = visibleWidth()/(itemW + d->spacing);
|
|
|
|
|
|
|
|
bool changed = false;
|
|
|
|
|
|
|
|
IconGroupItem* group = d->firstGroup;
|
|
|
|
IconItem* item = 0;
|
|
|
|
while (group)
|
|
|
|
{
|
|
|
|
changed = group->move(y) || changed;
|
|
|
|
y += group->rect().height() + d->spacing;
|
|
|
|
|
|
|
|
item = group->firstItem();
|
|
|
|
|
|
|
|
int col = 0;
|
|
|
|
int x = d->spacing;
|
|
|
|
while (item)
|
|
|
|
{
|
|
|
|
changed = item->move(x, y) || changed;
|
|
|
|
x += itemW + d->spacing;
|
|
|
|
col++;
|
|
|
|
|
|
|
|
if (col >= numItemsPerRow)
|
|
|
|
{
|
|
|
|
x = d->spacing;
|
|
|
|
y += itemH + d->spacing;
|
|
|
|
col = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
maxW = TQMAX(maxW, x + itemW);
|
|
|
|
|
|
|
|
item = item->m_next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (col != 0)
|
|
|
|
{
|
|
|
|
y += itemH + d->spacing;
|
|
|
|
}
|
|
|
|
|
|
|
|
y += d->spacing;
|
|
|
|
|
|
|
|
group = group->m_next;
|
|
|
|
}
|
|
|
|
|
|
|
|
viewport()->setUpdatesEnabled(false);
|
|
|
|
resizeContents( maxW, y );
|
|
|
|
viewport()->setUpdatesEnabled(true);
|
|
|
|
|
|
|
|
rebuildContainers();
|
|
|
|
|
|
|
|
return changed;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQRect IconView::tqitemRect() const
|
|
|
|
{
|
|
|
|
return TQRect(0, 0, 100, 100);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQRect IconView::bannerRect() const
|
|
|
|
{
|
|
|
|
return TQRect(0, 0, visibleWidth(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::viewportPaintEvent(TQPaintEvent* pe)
|
|
|
|
{
|
|
|
|
TQRect r(pe->rect());
|
|
|
|
TQRegion paintRegion(pe->region());
|
|
|
|
|
|
|
|
TQPainter painter(viewport());
|
|
|
|
painter.setClipRegion(paintRegion);
|
|
|
|
|
|
|
|
// paint any group banners which intersect this paintevent rect
|
|
|
|
for (IconGroupItem* group = d->firstGroup; group; group = group->nextGroup())
|
|
|
|
{
|
|
|
|
TQRect br(contentsRectToViewport(group->rect()));
|
|
|
|
if (r.intersects(br))
|
|
|
|
{
|
|
|
|
group->paintBanner();
|
|
|
|
paintRegion -= TQRegion(br);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// now paint any items which intersect
|
|
|
|
for (IconViewPriv::ItemContainer* c = d->firstContainer; c;
|
|
|
|
c = c->next)
|
|
|
|
{
|
|
|
|
TQRect cr(contentsRectToViewport(c->rect));
|
|
|
|
|
|
|
|
if (r.intersects(cr))
|
|
|
|
{
|
|
|
|
|
|
|
|
for (TQValueList<IconItem*>::iterator it = c->items.begin();
|
|
|
|
it != c->items.end(); ++it)
|
|
|
|
{
|
|
|
|
IconItem* item = *it;
|
|
|
|
TQRect ir(contentsRectToViewport(item->rect()));
|
|
|
|
if (r.intersects(ir))
|
|
|
|
{
|
|
|
|
item->paintItem();
|
|
|
|
paintRegion -= TQRegion(ir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
painter.setClipRegion(paintRegion);
|
|
|
|
painter.fillRect(r, tqcolorGroup().base());
|
|
|
|
painter.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQRect IconView::contentsRectToViewport(const TQRect& r) const
|
|
|
|
{
|
|
|
|
TQRect vr = TQRect(contentsToViewport(TQPoint(r.x(), r.y())), r.size());
|
|
|
|
return vr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::resizeEvent(TQResizeEvent* e)
|
|
|
|
{
|
|
|
|
TQScrollView::resizeEvent(e);
|
|
|
|
triggerRearrangement();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::rebuildContainers()
|
|
|
|
{
|
|
|
|
deleteContainers();
|
|
|
|
|
|
|
|
IconItem *item = 0;
|
|
|
|
appendContainer();
|
|
|
|
|
|
|
|
if (d->firstGroup)
|
|
|
|
item = d->firstGroup->firstItem();
|
|
|
|
|
|
|
|
IconViewPriv::ItemContainer* c = d->lastContainer;
|
|
|
|
while (item)
|
|
|
|
{
|
|
|
|
if (c->rect.contains(item->rect()))
|
|
|
|
{
|
|
|
|
c->items.append(item);
|
|
|
|
item = item->nextItem();
|
|
|
|
}
|
|
|
|
else if (c->rect.intersects(item->rect()))
|
|
|
|
{
|
|
|
|
c->items.append( item );
|
|
|
|
c = c->next;
|
|
|
|
|
|
|
|
if (!c)
|
|
|
|
{
|
|
|
|
appendContainer();
|
|
|
|
c = d->lastContainer;
|
|
|
|
}
|
|
|
|
|
|
|
|
c->items.append(item);
|
|
|
|
item = item->nextItem();
|
|
|
|
c = c->prev;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (item->y() < c->rect.y() && c->prev)
|
|
|
|
{
|
|
|
|
c = c->prev;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
c = c->next;
|
|
|
|
if (!c)
|
|
|
|
{
|
|
|
|
appendContainer();
|
|
|
|
c = d->lastContainer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::appendContainer()
|
|
|
|
{
|
|
|
|
TQSize s( INT_MAX - 1, RECT_EXTENSION );
|
|
|
|
|
|
|
|
if (!d->firstContainer)
|
|
|
|
{
|
|
|
|
d->firstContainer =
|
|
|
|
new IconViewPriv::ItemContainer(0, 0, TQRect(TQPoint(0, 0), s));
|
|
|
|
d->lastContainer = d->firstContainer;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d->lastContainer = new IconViewPriv::ItemContainer(
|
|
|
|
d->lastContainer, 0, TQRect(d->lastContainer->rect.bottomLeft(), s));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::deleteContainers()
|
|
|
|
{
|
|
|
|
IconViewPriv::ItemContainer *c = d->firstContainer;
|
|
|
|
IconViewPriv::ItemContainer *tmp;
|
|
|
|
|
|
|
|
while (c)
|
|
|
|
{
|
|
|
|
tmp = c->next;
|
|
|
|
delete c;
|
|
|
|
c = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
d->firstContainer = d->lastContainer = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::leaveEvent(TQEvent *e)
|
|
|
|
{
|
|
|
|
// hide tooltip
|
|
|
|
d->toolTipItem = 0;
|
|
|
|
d->toolTipTimer->stop();
|
|
|
|
slotToolTip();
|
|
|
|
|
|
|
|
// if the mouse leaves the widget we are not dragging
|
|
|
|
// anymore
|
|
|
|
d->dragging = false;
|
|
|
|
|
|
|
|
TQScrollView::leaveEvent(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::focusOutEvent(TQFocusEvent* e)
|
|
|
|
{
|
|
|
|
// hide tooltip
|
|
|
|
d->toolTipItem = 0;
|
|
|
|
d->toolTipTimer->stop();
|
|
|
|
slotToolTip();
|
|
|
|
|
|
|
|
TQScrollView::focusOutEvent(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IconView::acceptToolTip(IconItem*, const TQPoint&)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::contentsMousePressEvent(TQMouseEvent* e)
|
|
|
|
{
|
|
|
|
d->pressedMoved = false;
|
|
|
|
|
|
|
|
// hide tooltip
|
|
|
|
d->toolTipItem = 0;
|
|
|
|
d->toolTipTimer->stop();
|
|
|
|
slotToolTip();
|
|
|
|
|
|
|
|
// Delete any existing rubber -------------------------------
|
|
|
|
if ( d->rubber )
|
|
|
|
{
|
|
|
|
TQPainter p;
|
|
|
|
p.begin(viewport());
|
|
|
|
p.setRasterOp(NotROP);
|
|
|
|
p.setPen(TQPen(color0, 1));
|
|
|
|
p.setBrush(NoBrush);
|
|
|
|
|
|
|
|
drawRubber(&p);
|
|
|
|
p.end();
|
|
|
|
delete d->rubber;
|
|
|
|
d->rubber = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e->button() == Qt::RightButton)
|
|
|
|
{
|
|
|
|
IconItem* item = findItem(e->pos());
|
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
IconItem* prevCurrItem = d->currItem;
|
|
|
|
d->currItem = item;
|
|
|
|
d->anchorItem = item;
|
|
|
|
if (prevCurrItem)
|
|
|
|
prevCurrItem->tqrepaint();
|
|
|
|
|
|
|
|
if (!item->isSelected())
|
|
|
|
item->setSelected(true, true);
|
|
|
|
item->tqrepaint();
|
|
|
|
|
|
|
|
emit signalRightButtonClicked(item, e->globalPos());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
clearSelection();
|
|
|
|
emit signalRightButtonClicked(e->globalPos());
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
IconItem *item = findItem(e->pos());
|
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
if (e->state() & TQt::ControlButton)
|
|
|
|
{
|
|
|
|
item->setSelected(!item->isSelected(), false);
|
|
|
|
}
|
|
|
|
else if (e->state() & TQt::ShiftButton)
|
|
|
|
{
|
|
|
|
blockSignals(true);
|
|
|
|
|
|
|
|
if (d->currItem)
|
|
|
|
{
|
|
|
|
clearSelection();
|
|
|
|
|
|
|
|
// select all items from/upto the current item
|
|
|
|
bool bwdSelect = false;
|
|
|
|
|
|
|
|
// find if the current item is before the clicked item
|
|
|
|
for (IconItem* it = item->prevItem(); it; it = it->prevItem())
|
|
|
|
{
|
|
|
|
if (it == d->currItem)
|
|
|
|
{
|
|
|
|
bwdSelect = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bwdSelect)
|
|
|
|
{
|
|
|
|
for (IconItem* it = item; it; it = it->prevItem())
|
|
|
|
{
|
|
|
|
it->setSelected(true, false);
|
|
|
|
if (it == d->currItem)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (IconItem* it = item; it; it = it->nextItem())
|
|
|
|
{
|
|
|
|
it->setSelected(true, false);
|
|
|
|
if (it == d->currItem)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->setSelected(true, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
blockSignals(false);
|
|
|
|
|
|
|
|
emit signalSelectionChanged();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!item->isSelected())
|
|
|
|
item->setSelected(true, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
IconItem* prevCurrItem = d->currItem;
|
|
|
|
d->currItem = item;
|
|
|
|
d->anchorItem = item;
|
|
|
|
|
|
|
|
if (prevCurrItem)
|
|
|
|
prevCurrItem->tqrepaint();
|
|
|
|
|
|
|
|
d->currItem->tqrepaint();
|
|
|
|
|
|
|
|
d->dragging = true;
|
|
|
|
d->dragStartPos = e->pos();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Press outside any item.
|
|
|
|
if (!(e->state() & TQt::ControlButton))
|
|
|
|
{
|
|
|
|
// unselect all if the ctrl button is not pressed
|
|
|
|
clearSelection();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// ctrl is pressed. make sure our current selection is not lost
|
|
|
|
d->prevSelectedItems.clear();
|
|
|
|
TQPtrDictIterator<IconItem> it( d->selectedItems );
|
|
|
|
|
|
|
|
for ( ; it.current(); ++it )
|
|
|
|
{
|
|
|
|
d->prevSelectedItems.insert(it.current(), it.current());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
d->rubber = new TQRect( e->x(), e->y(), 0, 0 );
|
|
|
|
|
|
|
|
TQPainter p;
|
|
|
|
p.begin( viewport() );
|
|
|
|
p.setRasterOp( NotROP );
|
|
|
|
p.setPen( TQPen( color0, 1 ) );
|
|
|
|
p.setBrush( NoBrush );
|
|
|
|
drawRubber( &p );
|
|
|
|
p.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::drawRubber(TQPainter* p)
|
|
|
|
{
|
|
|
|
if ( !p || !d->rubber )
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQRect r(d->rubber->normalize());
|
|
|
|
|
|
|
|
r = contentsRectToViewport(r);
|
|
|
|
|
|
|
|
TQPoint pnt(r.x(), r.y());
|
|
|
|
|
|
|
|
tqstyle().tqdrawPrimitive(TQStyle::PE_FocusRect, p,
|
|
|
|
TQRect( pnt.x(), pnt.y(),
|
|
|
|
r.width(), r.height() ),
|
|
|
|
tqcolorGroup(), TQStyle::Style_Default,
|
|
|
|
TQStyleOption(tqcolorGroup().base()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::contentsMouseMoveEvent(TQMouseEvent* e)
|
|
|
|
{
|
|
|
|
if (e->state() == Qt::NoButton)
|
|
|
|
{
|
|
|
|
IconItem* item = findItem(e->pos());
|
|
|
|
|
|
|
|
if(d->showTips)
|
|
|
|
{
|
|
|
|
if (!isActiveWindow())
|
|
|
|
{
|
|
|
|
d->toolTipItem = 0;
|
|
|
|
d->toolTipTimer->stop();
|
|
|
|
slotToolTip();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item != d->toolTipItem)
|
|
|
|
{
|
|
|
|
d->toolTipItem = 0;
|
|
|
|
d->toolTipTimer->stop();
|
|
|
|
slotToolTip();
|
|
|
|
|
|
|
|
if(acceptToolTip(item, e->pos()))
|
|
|
|
{
|
|
|
|
d->toolTipItem = item;
|
|
|
|
d->toolTipTimer->start(500, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(item == d->toolTipItem && !acceptToolTip(item, e->pos()))
|
|
|
|
{
|
|
|
|
d->toolTipItem = 0;
|
|
|
|
d->toolTipTimer->stop();
|
|
|
|
slotToolTip();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (KGlobalSettings::changeCursorOverIcon())
|
|
|
|
{
|
|
|
|
if (item && item->clickToOpenRect().contains(e->pos()))
|
|
|
|
setCursor(KCursor::handCursor());
|
|
|
|
else
|
|
|
|
unsetCursor();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
d->toolTipItem = 0;
|
|
|
|
d->toolTipTimer->stop();
|
|
|
|
slotToolTip();
|
|
|
|
|
|
|
|
if (d->dragging && (e->state() & Qt::LeftButton))
|
|
|
|
{
|
|
|
|
if ( (d->dragStartPos - e->pos()).manhattanLength()
|
|
|
|
> TQApplication::startDragDistance() )
|
|
|
|
{
|
|
|
|
startDrag();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!d->rubber)
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQRect oldRubber = TQRect(*d->rubber);
|
|
|
|
|
|
|
|
d->rubber->setRight( e->pos().x() );
|
|
|
|
d->rubber->setBottom( e->pos().y() );
|
|
|
|
|
|
|
|
TQRect nr = d->rubber->normalize();
|
|
|
|
TQRect rubberUnion = nr.unite(oldRubber.normalize());
|
|
|
|
|
|
|
|
bool changed = false;
|
|
|
|
|
|
|
|
TQRegion paintRegion;
|
|
|
|
viewport()->setUpdatesEnabled(false);
|
|
|
|
blockSignals(true);
|
|
|
|
|
|
|
|
IconViewPriv::ItemContainer *c = d->firstContainer;
|
|
|
|
for (; c; c = c->next)
|
|
|
|
{
|
|
|
|
if ( rubberUnion.intersects(c->rect) )
|
|
|
|
{
|
|
|
|
for (TQValueList<IconItem*>::iterator it = c->items.begin();
|
|
|
|
it != c->items.end(); ++it)
|
|
|
|
{
|
|
|
|
IconItem* item = *it;
|
|
|
|
if (nr.intersects(item->rect()))
|
|
|
|
{
|
|
|
|
if (!item->isSelected())
|
|
|
|
{
|
|
|
|
item->setSelected(true, false);
|
|
|
|
changed = true;
|
|
|
|
paintRegion += TQRect(item->rect());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (item->isSelected() && !d->prevSelectedItems.find(item))
|
|
|
|
{
|
|
|
|
item->setSelected(false, false);
|
|
|
|
changed = true;
|
|
|
|
paintRegion += TQRect(item->rect());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
blockSignals(false);
|
|
|
|
viewport()->setUpdatesEnabled(true);
|
|
|
|
|
|
|
|
TQRect r = *d->rubber;
|
|
|
|
*d->rubber = oldRubber;
|
|
|
|
|
|
|
|
TQPainter p;
|
|
|
|
p.begin( viewport() );
|
|
|
|
p.setRasterOp( NotROP );
|
|
|
|
p.setPen( TQPen( color0, 1 ) );
|
|
|
|
p.setBrush( NoBrush );
|
|
|
|
drawRubber( &p );
|
|
|
|
p.end();
|
|
|
|
|
|
|
|
if (changed)
|
|
|
|
{
|
|
|
|
paintRegion.translate(-contentsX(), -contentsY());
|
|
|
|
viewport()->tqrepaint(paintRegion);
|
|
|
|
}
|
|
|
|
|
|
|
|
ensureVisible(e->pos().x(), e->pos().y());
|
|
|
|
|
|
|
|
*d->rubber = r;
|
|
|
|
|
|
|
|
p.begin(viewport());
|
|
|
|
p.setRasterOp(NotROP);
|
|
|
|
p.setPen(TQPen(color0, 1));
|
|
|
|
p.setBrush(NoBrush);
|
|
|
|
drawRubber(&p);
|
|
|
|
p.end();
|
|
|
|
|
|
|
|
d->pressedMoved = true;
|
|
|
|
|
|
|
|
if (changed)
|
|
|
|
emit signalSelectionChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::contentsMouseReleaseEvent(TQMouseEvent* e)
|
|
|
|
{
|
|
|
|
d->dragging = false;
|
|
|
|
d->prevSelectedItems.clear();
|
|
|
|
|
|
|
|
if (d->rubber)
|
|
|
|
{
|
|
|
|
TQPainter p;
|
|
|
|
p.begin( viewport() );
|
|
|
|
p.setRasterOp( NotROP );
|
|
|
|
p.setPen( TQPen( color0, 1 ) );
|
|
|
|
p.setBrush( NoBrush );
|
|
|
|
|
|
|
|
drawRubber( &p );
|
|
|
|
p.end();
|
|
|
|
|
|
|
|
delete d->rubber;
|
|
|
|
d->rubber = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e->state() == Qt::LeftButton)
|
|
|
|
{
|
|
|
|
if (d->pressedMoved)
|
|
|
|
{
|
|
|
|
emit signalSelectionChanged();
|
|
|
|
d->pressedMoved = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// click on item
|
|
|
|
IconItem *item = findItem(e->pos());
|
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
IconItem* prevCurrItem = d->currItem;
|
|
|
|
item->setSelected(true, true);
|
|
|
|
d->currItem = item;
|
|
|
|
d->anchorItem = item;
|
|
|
|
if (prevCurrItem)
|
|
|
|
prevCurrItem->tqrepaint();
|
|
|
|
if (KGlobalSettings::singleClick())
|
|
|
|
{
|
|
|
|
if (item->clickToOpenRect().contains(e->pos()))
|
|
|
|
{
|
|
|
|
itemClickedToOpen(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::contentsWheelEvent(TQWheelEvent* e)
|
|
|
|
{
|
|
|
|
d->toolTipItem = 0;
|
|
|
|
d->toolTipTimer->stop();
|
|
|
|
slotToolTip();
|
|
|
|
viewport()->update();
|
|
|
|
|
|
|
|
TQScrollView::contentsWheelEvent(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::contentsMouseDoubleClickEvent(TQMouseEvent *e)
|
|
|
|
{
|
|
|
|
if (KGlobalSettings::singleClick())
|
|
|
|
return;
|
|
|
|
|
|
|
|
IconItem *item = findItem(e->pos());
|
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
itemClickedToOpen(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::keyPressEvent(TQKeyEvent* e)
|
|
|
|
{
|
|
|
|
bool handled = false;
|
|
|
|
|
|
|
|
if (!firstItem())
|
|
|
|
return;
|
|
|
|
|
|
|
|
switch ( e->key() )
|
|
|
|
{
|
|
|
|
case Key_Home:
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = firstItem();
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
if (tmp)
|
|
|
|
tmp->tqrepaint();
|
|
|
|
|
|
|
|
firstItem()->setSelected(true, true);
|
|
|
|
ensureItemVisible(firstItem());
|
|
|
|
handled = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Key_End:
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = lastItem();
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
if (tmp)
|
|
|
|
tmp->tqrepaint();
|
|
|
|
|
|
|
|
lastItem()->setSelected(true, true);
|
|
|
|
ensureItemVisible(lastItem());
|
|
|
|
handled = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Key_Enter:
|
|
|
|
case Key_Return:
|
|
|
|
{
|
|
|
|
if (d->currItem)
|
|
|
|
{
|
|
|
|
emit signalReturnPressed(d->currItem);
|
|
|
|
handled = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Key_Right:
|
|
|
|
{
|
|
|
|
IconItem *item = 0;
|
|
|
|
|
|
|
|
if (d->currItem)
|
|
|
|
{
|
|
|
|
if (d->currItem->nextItem())
|
|
|
|
{
|
|
|
|
if (e->state() & TQt::ControlButton)
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = d->currItem->nextItem();
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
tmp->tqrepaint();
|
|
|
|
d->currItem->tqrepaint();
|
|
|
|
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
else if (e->state() & TQt::ShiftButton)
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = d->currItem->nextItem();
|
|
|
|
tmp->tqrepaint();
|
|
|
|
|
|
|
|
// if the anchor is behind us, move forward preserving
|
|
|
|
// the previously selected item. otherwise unselect the
|
|
|
|
// previously selected item
|
|
|
|
if (!anchorIsBehind())
|
|
|
|
tmp->setSelected(false, false);
|
|
|
|
|
|
|
|
d->currItem->setSelected(true, false);
|
|
|
|
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = d->currItem->nextItem();
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
tmp->tqrepaint();
|
|
|
|
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d->currItem = firstItem();
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
ensureItemVisible(item);
|
|
|
|
handled = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Key_Left:
|
|
|
|
{
|
|
|
|
IconItem *item = 0;
|
|
|
|
|
|
|
|
if (d->currItem)
|
|
|
|
{
|
|
|
|
if (d->currItem->prevItem())
|
|
|
|
{
|
|
|
|
if (e->state() & TQt::ControlButton)
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = d->currItem->prevItem();
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
tmp->tqrepaint();
|
|
|
|
d->currItem->tqrepaint();
|
|
|
|
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
else if (e->state() & TQt::ShiftButton)
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = d->currItem->prevItem();
|
|
|
|
tmp->tqrepaint();
|
|
|
|
|
|
|
|
// if the anchor is ahead of us, move forward preserving
|
|
|
|
// the previously selected item. otherwise unselect the
|
|
|
|
// previously selected item
|
|
|
|
if (anchorIsBehind())
|
|
|
|
tmp->setSelected(false, false);
|
|
|
|
|
|
|
|
d->currItem->setSelected(true, false);
|
|
|
|
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = d->currItem->prevItem();
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
tmp->tqrepaint();
|
|
|
|
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d->currItem = firstItem();
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
ensureItemVisible(item);
|
|
|
|
handled = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Key_Up:
|
|
|
|
{
|
|
|
|
IconItem *item = 0;
|
|
|
|
|
|
|
|
if (d->currItem)
|
|
|
|
{
|
|
|
|
int x = d->currItem->x() + tqitemRect().width()/2;
|
|
|
|
int y = d->currItem->y() - d->spacing*2;
|
|
|
|
|
|
|
|
IconItem *it = 0;
|
|
|
|
|
|
|
|
while (!it && y > 0)
|
|
|
|
{
|
|
|
|
it = findItem(TQPoint(x,y));
|
|
|
|
y -= d->spacing * 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (it)
|
|
|
|
{
|
|
|
|
if (e->state() & TQt::ControlButton)
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = it;
|
|
|
|
d->anchorItem = it;
|
|
|
|
tmp->tqrepaint();
|
|
|
|
d->currItem->tqrepaint();
|
|
|
|
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
else if (e->state() & TQt::ShiftButton)
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = it;
|
|
|
|
tmp->tqrepaint();
|
|
|
|
|
|
|
|
clearSelection();
|
|
|
|
if (anchorIsBehind())
|
|
|
|
{
|
|
|
|
for (IconItem* i = d->currItem; i; i = i->prevItem())
|
|
|
|
{
|
|
|
|
i->setSelected(true, false);
|
|
|
|
if (i == d->anchorItem)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (IconItem* i = d->currItem; i; i = i->nextItem())
|
|
|
|
{
|
|
|
|
i->setSelected(true, false);
|
|
|
|
if (i == d->anchorItem)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = it;
|
|
|
|
d->anchorItem = it;
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
tmp->tqrepaint();
|
|
|
|
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d->currItem = firstItem();
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
ensureItemVisible(item);
|
|
|
|
handled = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Key_Down:
|
|
|
|
{
|
|
|
|
IconItem *item = 0;
|
|
|
|
|
|
|
|
if (d->currItem)
|
|
|
|
{
|
|
|
|
int x = d->currItem->x() + tqitemRect().width()/2;
|
|
|
|
int y = d->currItem->y() + tqitemRect().height() + d->spacing*2;
|
|
|
|
|
|
|
|
IconItem *it = 0;
|
|
|
|
|
|
|
|
while (!it && y < contentsHeight())
|
|
|
|
{
|
|
|
|
it = findItem(TQPoint(x,y));
|
|
|
|
y += d->spacing * 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (it)
|
|
|
|
{
|
|
|
|
if (e->state() & TQt::ControlButton)
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = it;
|
|
|
|
d->anchorItem = it;
|
|
|
|
tmp->tqrepaint();
|
|
|
|
d->currItem->tqrepaint();
|
|
|
|
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
else if (e->state() & TQt::ShiftButton)
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = it;
|
|
|
|
tmp->tqrepaint();
|
|
|
|
|
|
|
|
clearSelection();
|
|
|
|
if (anchorIsBehind())
|
|
|
|
{
|
|
|
|
for (IconItem* i = d->currItem; i; i = i->prevItem())
|
|
|
|
{
|
|
|
|
i->setSelected(true, false);
|
|
|
|
if (i == d->anchorItem)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (IconItem* i = d->currItem; i; i = i->nextItem())
|
|
|
|
{
|
|
|
|
i->setSelected(true, false);
|
|
|
|
if (i == d->anchorItem)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = it;
|
|
|
|
d->anchorItem = it;
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
tmp->tqrepaint();
|
|
|
|
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d->currItem = firstItem();
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
ensureItemVisible(item);
|
|
|
|
handled = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Key_Next:
|
|
|
|
{
|
|
|
|
IconItem *item = 0;
|
|
|
|
|
|
|
|
if (d->currItem)
|
|
|
|
{
|
|
|
|
TQRect r( 0, d->currItem->y() + visibleHeight(),
|
|
|
|
contentsWidth(), visibleHeight() );
|
|
|
|
IconItem *ni = findFirstVisibleItem(r, false);
|
|
|
|
|
|
|
|
if (!ni)
|
|
|
|
{
|
|
|
|
r = TQRect( 0, d->currItem->y() + tqitemRect().height(),
|
|
|
|
contentsWidth(), contentsHeight() );
|
|
|
|
ni = findLastVisibleItem(r, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ni)
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = ni;
|
|
|
|
d->anchorItem = ni;
|
|
|
|
item = ni;
|
|
|
|
tmp->tqrepaint();
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d->currItem = firstItem();
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
ensureItemVisible(item);
|
|
|
|
handled = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Key_Prior:
|
|
|
|
{
|
|
|
|
IconItem *item = 0;
|
|
|
|
|
|
|
|
if (d->currItem)
|
|
|
|
{
|
|
|
|
TQRect r(0, d->currItem->y() - visibleHeight(),
|
|
|
|
contentsWidth(), visibleHeight() );
|
|
|
|
|
|
|
|
IconItem *ni = findFirstVisibleItem(r, false);
|
|
|
|
|
|
|
|
if (!ni)
|
|
|
|
{
|
|
|
|
r = TQRect( 0, 0, contentsWidth(), d->currItem->y() );
|
|
|
|
ni = findFirstVisibleItem(r, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ni)
|
|
|
|
{
|
|
|
|
IconItem* tmp = d->currItem;
|
|
|
|
d->currItem = ni;
|
|
|
|
d->anchorItem = ni;
|
|
|
|
item = ni;
|
|
|
|
tmp->tqrepaint();
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d->currItem = firstItem();
|
|
|
|
d->anchorItem = d->currItem;
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
item = d->currItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
ensureItemVisible(item);
|
|
|
|
handled = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Key_Space is used as a global shortcut in DigikamApp.
|
|
|
|
// Ctrl+Space comes through, Shift+Space is filtered out.
|
|
|
|
case Key_Space:
|
|
|
|
{
|
|
|
|
if (d->currItem)
|
|
|
|
{
|
|
|
|
if ( (e->state() & TQt::ControlButton) || (e->state() & TQt::ShiftButton) )
|
|
|
|
{
|
|
|
|
d->currItem->setSelected(!d->currItem->isSelected(), false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!d->currItem->isSelected())
|
|
|
|
d->currItem->setSelected(true, true);
|
|
|
|
}
|
|
|
|
handled = true;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case Key_Menu:
|
|
|
|
{
|
|
|
|
if (d->currItem)
|
|
|
|
{
|
|
|
|
if (!d->currItem->isSelected())
|
|
|
|
d->currItem->setSelected(true, false);
|
|
|
|
|
|
|
|
ensureItemVisible(d->currItem);
|
|
|
|
|
|
|
|
TQRect r(tqitemRect());
|
|
|
|
int w = r.width();
|
|
|
|
int h = r.height();
|
|
|
|
TQPoint p(d->currItem->x() + w / 2, d->currItem->y() + h / 2);
|
|
|
|
|
|
|
|
emit signalRightButtonClicked(d->currItem, mapToGlobal(contentsToViewport(p)));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!handled)
|
|
|
|
{
|
|
|
|
e->ignore();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
emit signalSelectionChanged();
|
|
|
|
viewport()->update();
|
|
|
|
d->toolTipItem = 0;
|
|
|
|
d->toolTipTimer->stop();
|
|
|
|
slotToolTip();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IconView::anchorIsBehind() const
|
|
|
|
{
|
|
|
|
if (!d->anchorItem || !d->currItem)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (IconItem* it = d->anchorItem; it; it = it->nextItem())
|
|
|
|
{
|
|
|
|
if (it == d->currItem)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void IconView::startDrag()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::ensureItemVisible(IconItem *item)
|
|
|
|
{
|
|
|
|
if ( !item )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( item->y() == firstItem()->y() )
|
|
|
|
{
|
|
|
|
TQRect r(tqitemRect());
|
|
|
|
int w = r.width();
|
|
|
|
ensureVisible( item->x() + w / 2, 0, w/2+1, 0 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TQRect r(tqitemRect());
|
|
|
|
int w = r.width();
|
|
|
|
int h = r.height();
|
|
|
|
ensureVisible( item->x() + w / 2, item->y() + h / 2,
|
|
|
|
w / 2 + 1, h / 2 + 1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
IconItem* IconView::findFirstVisibleItem(bool useThumbnailRect) const
|
|
|
|
{
|
|
|
|
TQRect r(contentsX(), contentsY(), visibleWidth(), visibleHeight());
|
|
|
|
return findFirstVisibleItem(r, useThumbnailRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
IconItem* IconView::findLastVisibleItem(bool useThumbnailRect) const
|
|
|
|
{
|
|
|
|
TQRect r(contentsX(), contentsY(), visibleWidth(), visibleHeight());
|
|
|
|
return findLastVisibleItem(r, useThumbnailRect);
|
|
|
|
}
|
|
|
|
|
|
|
|
IconItem* IconView::findFirstVisibleItem(const TQRect& r, bool useThumbnailRect) const
|
|
|
|
{
|
|
|
|
IconViewPriv::ItemContainer *c = d->firstContainer;
|
|
|
|
bool alreadyIntersected = false;
|
|
|
|
IconItem* i = 0;
|
|
|
|
for ( ; c; c = c->next )
|
|
|
|
{
|
|
|
|
if ( c->rect.intersects( r ) )
|
|
|
|
{
|
|
|
|
alreadyIntersected = true;
|
|
|
|
for (TQValueList<IconItem*>::iterator it = c->items.begin();
|
|
|
|
it != c->items.end(); ++it)
|
|
|
|
{
|
|
|
|
IconItem *item = *it;
|
|
|
|
|
|
|
|
// if useThumbnailRect, we only check for the clickToOpenRect, which is the thumbnail,
|
|
|
|
// otherwise, we take the whole item rect
|
|
|
|
if ( r.intersects( useThumbnailRect ? item->clickToOpenRect() : item->rect() ) )
|
|
|
|
{
|
|
|
|
if ( !i )
|
|
|
|
{
|
|
|
|
i = item;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TQRect r2 = item->rect();
|
|
|
|
TQRect r3 = i->rect();
|
|
|
|
if ( r2.y() < r3.y() )
|
|
|
|
i = item;
|
|
|
|
else if ( r2.y() == r3.y() &&
|
|
|
|
r2.x() < r3.x() )
|
|
|
|
i = item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( alreadyIntersected )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
IconItem* IconView::findLastVisibleItem(const TQRect& r, bool useThumbnailRect) const
|
|
|
|
{
|
|
|
|
IconViewPriv::ItemContainer *c = d->firstContainer;
|
|
|
|
IconItem *i = 0;
|
|
|
|
bool alreadyIntersected = false;
|
|
|
|
for ( ; c; c = c->next )
|
|
|
|
{
|
|
|
|
if ( c->rect.intersects( r ) )
|
|
|
|
{
|
|
|
|
alreadyIntersected = true;
|
|
|
|
for (TQValueList<IconItem*>::iterator it = c->items.begin();
|
|
|
|
it != c->items.end(); ++it)
|
|
|
|
{
|
|
|
|
IconItem *item = *it;
|
|
|
|
|
|
|
|
if ( r.intersects( useThumbnailRect ? item->clickToOpenRect() : item->rect() ) )
|
|
|
|
{
|
|
|
|
if ( !i )
|
|
|
|
{
|
|
|
|
i = item;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TQRect r2 = item->rect();
|
|
|
|
TQRect r3 = i->rect();
|
|
|
|
if ( r2.y() > r3.y() )
|
|
|
|
i = item;
|
|
|
|
else if ( r2.y() == r3.y() &&
|
|
|
|
r2.x() > r3.x() )
|
|
|
|
i = item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if ( alreadyIntersected )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::drawFrameRaised(TQPainter* p)
|
|
|
|
{
|
|
|
|
TQRect r = frameRect();
|
|
|
|
int lwidth = lineWidth();
|
|
|
|
|
|
|
|
const TQColorGroup & g = tqcolorGroup();
|
|
|
|
|
|
|
|
qDrawShadeRect( p, r, g, false, lwidth,
|
|
|
|
midLineWidth() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::drawFrameSunken(TQPainter* p)
|
|
|
|
{
|
|
|
|
TQRect r = frameRect();
|
|
|
|
int lwidth = lineWidth();
|
|
|
|
|
|
|
|
const TQColorGroup & g = tqcolorGroup();
|
|
|
|
|
|
|
|
qDrawShadeRect( p, r, g, true, lwidth,
|
|
|
|
midLineWidth() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::setEnableToolTips(bool val)
|
|
|
|
{
|
|
|
|
d->showTips = val;
|
|
|
|
if (!val)
|
|
|
|
{
|
|
|
|
d->toolTipItem = 0;
|
|
|
|
d->toolTipTimer->stop();
|
|
|
|
slotToolTip();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::slotToolTip()
|
|
|
|
{
|
|
|
|
emit signalShowToolTip(d->toolTipItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconView::itemClickedToOpen(IconItem* item)
|
|
|
|
{
|
|
|
|
if (!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
IconItem* prevCurrItem = d->currItem;
|
|
|
|
d->currItem = item;
|
|
|
|
d->anchorItem = item;
|
|
|
|
|
|
|
|
if (prevCurrItem)
|
|
|
|
prevCurrItem->tqrepaint();
|
|
|
|
|
|
|
|
item->setSelected(true);
|
|
|
|
emit signalDoubleClicked(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
int IconView::cmpItems(const void *n1, const void *n2)
|
|
|
|
{
|
|
|
|
if ( !n1 || !n2 )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
IconViewPriv::SortableItem *i1 = (IconViewPriv::SortableItem *)n1;
|
|
|
|
IconViewPriv::SortableItem *i2 = (IconViewPriv::SortableItem *)n2;
|
|
|
|
|
|
|
|
return i1->group->compare( i2->group );
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Digikam
|
|
|
|
|