|
|
|
/* ============================================================
|
|
|
|
*
|
|
|
|
* 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 <kconfig.h>
|
|
|
|
#include <kdeversion.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()
|
|
|
|
{
|
|
|
|
KConfig *config = kapp->config();
|
|
|
|
config->setGroup(TQString("%1").tqarg(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()
|
|
|
|
{
|
|
|
|
KConfig *config = kapp->config();
|
|
|
|
config->setGroup(TQString("%1").tqarg(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
|