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/libs/widgets/common/sidebar.cpp

364 lines
8.1 KiB

/* ============================================================
*
* This file is a part of digiKam project
* http://www.digikam.org
*
* Date : 2005-03-22
* Description : a widget to manage sidebar in gui.
*
* Copyright (C) 2005-2006 by Joern Ahrens <joern.ahrens@kdemail.net>
* Copyright (C) 2006-2008 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.
*
* ============================================================ */
/** @file sidebar.cpp */
// TQt includes.
#include <tqsplitter.h>
#include <tqwidgetstack.h>
#include <tqdatastream.h>
#include <tqtimer.h>
// KDE includes.
#include <kapplication.h>
#include <tdeconfig.h>
#include <tdeversion.h>
#include <kiconloader.h>
// Local includes.
#include "ddebug.h"
#include "sidebar.h"
#include "sidebar.moc"
namespace Digikam
{
class SidebarPriv
{
public:
SidebarPriv()
{
minimizedDefault = false;
minimized = false;
isMinimized = false;
tabs = 0;
activeTab = -1;
minSize = 0;
maxSize = 0;
dragSwitchId = -1;
stack = 0;
splitter = 0;
dragSwitchTimer = 0;
}
bool minimizedDefault;
bool minimized;
bool isMinimized; // Backup of minimized status (used with Fullscreen)
int tabs;
int activeTab;
int minSize;
int maxSize;
int dragSwitchId;
TQWidgetStack *stack;
TQSplitter *splitter;
TQSize bigSize;
TQTimer *dragSwitchTimer;
Sidebar::Side side;
};
Sidebar::Sidebar(TQWidget *parent, const char *name, Side side, bool minimizedDefault)
: KMultiTabBar(KMultiTabBar::Vertical, parent, name)
{
d = new SidebarPriv;
d->minimizedDefault = minimizedDefault;
d->side = side;
d->dragSwitchTimer = new TQTimer(this);
connect(d->dragSwitchTimer, TQT_SIGNAL(timeout()),
this, TQT_SLOT(slotDragSwitchTimer()));
}
Sidebar::~Sidebar()
{
saveViewState();
delete d;
}
void Sidebar::updateMinimumWidth()
{
int width = 0;
for (int i = 0; i < d->tabs; i++)
{
TQWidget *w = d->stack->widget(i);
if (w && w->width() > width)
width = w->width();
}
d->stack->setMinimumWidth(width);
}
void Sidebar::setSplitter(TQSplitter *sp)
{
#if KDE_IS_VERSION(3,3,0)
setStyle(KMultiTabBar::VSNET);
#else
setStyle(KMultiTabBar::KDEV3);
#endif
d->splitter = sp;
d->stack = new TQWidgetStack(d->splitter);
if(d->side == Left)
setPosition(KMultiTabBar::Left);
else
setPosition(KMultiTabBar::Right);
}
TQSplitter* Sidebar::splitter() const
{
return d->splitter;
}
void Sidebar::loadViewState()
{
TDEConfig *config = kapp->config();
config->setGroup(TQString("%1").arg(name()));
int tab = config->readNumEntry("ActiveTab", 0);
bool minimized = config->readBoolEntry("Minimized", d->minimizedDefault);
// validate
if(tab >= d->tabs || tab < 0)
tab = 0;
if (minimized)
{
d->activeTab = tab;
//setTab(d->activeTab, true);
d->stack->raiseWidget(d->activeTab);
emit signalChangedTab(d->stack->visibleWidget());
}
else
{
d->activeTab = -1;
}
clicked(tab);
}
void Sidebar::saveViewState()
{
TDEConfig *config = kapp->config();
config->setGroup(TQString("%1").arg(name()));
config->writeEntry("ActiveTab", d->activeTab);
config->writeEntry("Minimized", d->minimized);
config->sync();
}
void Sidebar::backup()
{
d->isMinimized = d->minimized;
if (!d->isMinimized)
shrink();
KMultiTabBar::hide();
}
void Sidebar::restore()
{
if (!d->isMinimized)
expand();
KMultiTabBar::show();
}
void Sidebar::appendTab(TQWidget *w, const TQPixmap &pic, const TQString &title)
{
w->reparent(d->stack, TQPoint(0, 0));
KMultiTabBar::appendTab(pic, d->tabs, title);
d->stack->addWidget(w, d->tabs);
tab(d->tabs)->setAcceptDrops(true);
tab(d->tabs)->installEventFilter(this);
connect(tab(d->tabs), TQT_SIGNAL(clicked(int)),
this, TQT_SLOT(clicked(int)));
d->tabs++;
}
void Sidebar::deleteTab(TQWidget *w)
{
int tab = d->stack->id(w);
if(tab < 0)
return;
if(tab == d->activeTab)
d->activeTab = -1;
d->stack->removeWidget(d->stack->widget(tab));
removeTab(tab);
d->tabs--;
updateMinimumWidth();
//TODO show another widget
}
void Sidebar::clicked(int tab)
{
if(tab >= d->tabs || tab < 0)
return;
if(tab == d->activeTab)
{
d->stack->isHidden() ? expand() : shrink();
}
else
{
if(d->activeTab >= 0)
setTab(d->activeTab, false);
d->activeTab = tab;
setTab(d->activeTab, true);
d->stack->raiseWidget(d->activeTab);
if(d->minimized)
expand();
emit signalChangedTab(d->stack->visibleWidget());
}
}
void Sidebar::setActiveTab(TQWidget *w)
{
int tab = d->stack->id(w);
if(tab < 0)
return;
if(d->activeTab >= 0)
setTab(d->activeTab, false);
d->activeTab = tab;
setTab(d->activeTab, true);
d->stack->raiseWidget(d->activeTab);
if(d->minimized)
expand();
emit signalChangedTab(d->stack->visibleWidget());
}
TQWidget* Sidebar::getActiveTab()
{
return d->stack->visibleWidget();
}
void Sidebar::shrink()
{
d->minimized = true;
d->bigSize = size();
d->minSize = minimumWidth();
d->maxSize = maximumWidth();
d->stack->hide();
KMultiTabBarTab* tab = tabs()->first();
if (tab)
setFixedWidth(tab->width());
else
setFixedWidth(width());
emit signalViewChanged();
}
void Sidebar::expand()
{
d->minimized = false;
d->stack->show();
resize(d->bigSize);
setMinimumWidth(d->minSize);
setMaximumWidth(d->maxSize);
emit signalViewChanged();
}
bool Sidebar::isExpanded()
{
return !d->minimized;
}
bool Sidebar::eventFilter(TQObject *obj, TQEvent *ev)
{
TQPtrList<KMultiTabBarTab>* pTabs = tabs();
for (TQPtrListIterator<KMultiTabBarTab> it(*pTabs); it.current(); ++it)
{
if ( TQT_BASE_OBJECT(obj) == TQT_BASE_OBJECT(*it) )
{
if ( ev->type() == TQEvent::DragEnter)
{
TQDragEnterEvent *e = static_cast<TQDragEnterEvent *>(ev);
enterEvent(e);
e->accept(true);
return false;
}
else if (ev->type() == TQEvent::DragMove)
{
if (!d->dragSwitchTimer->isActive())
{
d->dragSwitchTimer->start(800, true);
d->dragSwitchId = (*it)->id();
}
return false;
}
else if (ev->type() == TQEvent::DragLeave)
{
d->dragSwitchTimer->stop();
TQDragLeaveEvent *e = static_cast<TQDragLeaveEvent *>(ev);
leaveEvent(e);
return false;
}
else if (ev->type() == TQEvent::Drop)
{
d->dragSwitchTimer->stop();
TQDropEvent *e = static_cast<TQDropEvent *>(ev);
leaveEvent(e);
return false;
}
else
{
return false;
}
}
}
// Else, pass the event on to the parent class
return KMultiTabBar::eventFilter(obj, ev);
}
void Sidebar::slotDragSwitchTimer()
{
clicked(d->dragSwitchId);
}
} // namespace Digikam