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.
394 lines
11 KiB
394 lines
11 KiB
/*
|
|
* This file is part of the KFTPGrabber project
|
|
*
|
|
* Copyright (C) 2003-2005 by the KFTPGrabber developers
|
|
* Copyright (C) 2003-2005 Jernej Kos <kostko@jweb-network.net>
|
|
* Copyright (C) 2004-2005 Max Howell <max.howell@methylblue.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 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
|
|
* warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
|
|
* NON-INFRINGEMENT. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Steet, Fifth Floor, Boston,
|
|
* MA 02110-1301, USA.
|
|
*
|
|
* In addition, as a special exception, the copyright holders give
|
|
* permission to link the code of portions of this program with the
|
|
* OpenSSL library under certain conditions as described in each
|
|
* individual source file, and distribute linked combinations
|
|
* including the two.
|
|
* You must obey the GNU General Public License in all respects
|
|
* for all of the code used other than OpenSSL. If you modify
|
|
* file(s) with this exception, you may extend this exception to your
|
|
* version of the file(s), but you are not obligated to do so. If you
|
|
* do not wish to do so, delete this exception statement from your
|
|
* version. If you delete this exception statement from all source
|
|
* files in the program, then also delete it here.
|
|
*/
|
|
|
|
#include "misc.h"
|
|
#include "sidebar.h"
|
|
#include "multitabbar.h"
|
|
|
|
#include <tdeapplication.h>
|
|
#include <tdeconfig.h>
|
|
#include <kiconloader.h>
|
|
#include <tdelocale.h>
|
|
|
|
#include <tqcursor.h>
|
|
#include <tqpainter.h>
|
|
#include <tqsignalmapper.h>
|
|
#include <tqstyle.h>
|
|
|
|
namespace KFTPWidgets {
|
|
|
|
class Splitter : public TQWidget {
|
|
public:
|
|
Splitter(Sidebar *w)
|
|
: TQWidget(w, "divider"),
|
|
m_position(w->m_position)
|
|
{
|
|
if (m_position == Sidebar::Left)
|
|
setCursor(TQCursor(SplitHCursor));
|
|
else
|
|
setCursor(TQCursor(SplitVCursor));
|
|
|
|
styleChange(style());
|
|
}
|
|
|
|
virtual void paintEvent(TQPaintEvent*)
|
|
{
|
|
TQPainter p(this);
|
|
parentWidget()->style().drawPrimitive(TQStyle::PE_Splitter, &p, rect(), colorGroup(), m_position == Sidebar::Left ? TQStyle::Style_Horizontal : 0);
|
|
}
|
|
|
|
virtual void styleChange(TQStyle&)
|
|
{
|
|
if (m_position == Sidebar::Left)
|
|
setFixedWidth(style().pixelMetric(TQStyle::PM_SplitterWidth, this));
|
|
else
|
|
setFixedHeight(style().pixelMetric(TQStyle::PM_SplitterWidth, this));
|
|
}
|
|
|
|
virtual void mouseMoveEvent(TQMouseEvent *e)
|
|
{
|
|
static_cast<Sidebar*>(parent())->mouseMovedOverSplitter(e);
|
|
}
|
|
private:
|
|
Sidebar::Position m_position;
|
|
};
|
|
|
|
Sidebar::Sidebar(TQWidget *parent, Position position)
|
|
: TQWidget(parent, "Sidebar"),
|
|
m_position(position),
|
|
m_divider(new KFTPWidgets::Splitter(this)),
|
|
m_content(new TQVBox(this)),
|
|
m_tabBar(new MultiTabBar(position == Left ? MultiTabBar::Vertical : MultiTabBar::Horizontal, this)),
|
|
m_sidebarBox(new TQWidget(this)),
|
|
m_currentIndex(-1),
|
|
m_lastIndex(-1),
|
|
m_mapper(new TQSignalMapper(this))
|
|
{
|
|
m_tabBar->setStyle(MultiTabBar::AMAROK);
|
|
m_tabBar->setPosition(m_position == Left ? MultiTabBar::Left : MultiTabBar::Bottom);
|
|
m_tabBar->showActiveTabTexts(true);
|
|
|
|
if (m_position == Left) {
|
|
m_pos = m_tabBar->sizeHint().width() + 5;
|
|
|
|
m_tabBar->setFixedWidth(m_pos);
|
|
m_tabBar->move(0, 3);
|
|
|
|
TQVBoxLayout *layout = new TQVBoxLayout(m_sidebarBox);
|
|
layout->addSpacing(3);
|
|
layout->setAutoAdd(true);
|
|
|
|
m_sidebarBox->move(m_pos, 0);
|
|
m_sidebarBox->hide();
|
|
m_divider->hide();
|
|
m_content->setSpacing(1);
|
|
} else {
|
|
m_pos = m_tabBar->sizeHint().height() + 5;
|
|
m_tabBar->setFixedHeight(m_pos);
|
|
|
|
TQVBoxLayout *layout = new TQVBoxLayout(m_sidebarBox);
|
|
layout->setAutoAdd(true);
|
|
|
|
m_sidebarBox->hide();
|
|
m_divider->hide();
|
|
m_content->setSpacing(1);
|
|
}
|
|
|
|
connect(m_mapper, TQ_SIGNAL(mapped(int)), TQ_SLOT(showHideSidebar(int)));
|
|
}
|
|
|
|
void Sidebar::setVisible(bool visible)
|
|
{
|
|
if (m_position == Left) {
|
|
m_pos = m_tabBar->sizeHint().width() + 5;
|
|
m_tabBar->setFixedWidth(visible ? m_pos : 0);
|
|
} else {
|
|
m_pos = m_tabBar->sizeHint().height() + 5;
|
|
m_tabBar->setFixedHeight(visible ? m_pos : 0);
|
|
}
|
|
|
|
if (m_currentIndex != -1)
|
|
showHideSidebar(m_currentIndex);
|
|
|
|
if (visible)
|
|
m_tabBar->show();
|
|
else
|
|
m_tabBar->hide();
|
|
|
|
adjustWidgetSizes();
|
|
}
|
|
|
|
Sidebar::~Sidebar()
|
|
{
|
|
TDEConfig *config;
|
|
// Save the currently selected sidebar
|
|
if (m_position == Left) {
|
|
config = KFTPGrabberBase::config(TQString("Sidebar_%1").arg("Left"));
|
|
} else {
|
|
config = KFTPGrabberBase::config(TQString("Sidebar_%1").arg("Bottom"));
|
|
}
|
|
if (m_currentIndex != -1) {
|
|
config->writeEntry("CurrentSidebar", currentSidebar()->name());
|
|
} else {
|
|
config->writeEntry("CurrentSidebar", TQString::null);
|
|
}
|
|
if (m_position == Left) {
|
|
config->writeEntry("Size", m_sidebarBox->width());
|
|
} else {
|
|
config->writeEntry("Size", m_sidebarBox->height());
|
|
}
|
|
}
|
|
|
|
void Sidebar::polish()
|
|
{
|
|
TQWidget::polish();
|
|
|
|
TDEConfig *config = KFTPGrabberBase::config(TQString("Sidebar_%1").arg(m_position == Left ? "Left" : "Bottom"));
|
|
const int index = indexForName(config->readEntry("CurrentSidebar"));
|
|
|
|
if (m_position == Left) {
|
|
uint M = 0;
|
|
for (SidebarList::ConstIterator it = m_sidebars.begin(), end = m_sidebars.end(); it != end; ++it) {
|
|
const uint m = (*it)->minimumWidth();
|
|
if (m > M) M = m;
|
|
}
|
|
|
|
const int width = config->readNumEntry("Size", sidebar(index)->sizeHint().width());
|
|
|
|
if (M > 250) {
|
|
M = 250;
|
|
}
|
|
|
|
m_sidebarBox->setMinimumWidth(M);
|
|
m_sidebarBox->resize(width, height());
|
|
} else {
|
|
uint M = 0;
|
|
for (SidebarList::ConstIterator it = m_sidebars.begin(), end = m_sidebars.end(); it != end; ++it) {
|
|
const uint m = (*it)->minimumHeight();
|
|
if (m > M) M = m;
|
|
}
|
|
|
|
const int height = config->readNumEntry("Size", sidebar(index)->height());
|
|
|
|
if (M > 250) {
|
|
M = 250;
|
|
}
|
|
|
|
m_sidebarBox->setMinimumHeight(M);
|
|
m_sidebarBox->resize(width(), height);
|
|
}
|
|
|
|
// If any sidebar should be open, open it
|
|
if (index != -1)
|
|
showHideSidebar(index);
|
|
}
|
|
|
|
void Sidebar::adjustWidgetSizes()
|
|
{
|
|
if (m_position == Left) {
|
|
const uint w = width();
|
|
const uint h = height();
|
|
const uint mxW = maxSidebarWidth();
|
|
const uint p = (m_pos < mxW) ? m_pos : mxW;
|
|
const uint ppw = p + m_divider->width();
|
|
const uint tbw = m_tabBar->width();
|
|
|
|
m_divider->move(p, 0);
|
|
|
|
const uint offset = !m_divider->isHidden() ? ppw : tbw;
|
|
|
|
m_sidebarBox->resize(p - tbw, h);
|
|
m_content->setGeometry(offset, 0, w - offset, h);
|
|
} else {
|
|
const uint w = width();
|
|
const uint h = height();
|
|
const uint mxH = maxSidebarHeight();
|
|
const uint p = (m_pos < mxH) ? m_pos : mxH;
|
|
const uint pph = p + m_divider->height();
|
|
const uint tbh = m_tabBar->height();
|
|
|
|
m_divider->move(0, h - pph);
|
|
|
|
const uint offset = !m_divider->isHidden() ? pph : tbh;
|
|
|
|
m_sidebarBox->setGeometry(0, h - p, w, p - tbh);
|
|
m_content->setGeometry(0, 0, w, h - offset);
|
|
m_tabBar->move(0, h - tbh);
|
|
}
|
|
}
|
|
|
|
void Sidebar::mouseMovedOverSplitter(TQMouseEvent *e)
|
|
{
|
|
const uint oldPos = m_pos;
|
|
uint newPos;
|
|
uint minPos;
|
|
uint maxPos;
|
|
|
|
if (m_position == Left) {
|
|
newPos = mapFromGlobal(e->globalPos()).x();
|
|
minPos = m_tabBar->width() + m_sidebarBox->minimumWidth();
|
|
maxPos = maxSidebarWidth();
|
|
} else {
|
|
newPos = height() - mapFromGlobal(e->globalPos()).y();
|
|
minPos = m_tabBar->height() + m_sidebarBox->minimumHeight();
|
|
maxPos = maxSidebarHeight();
|
|
}
|
|
|
|
if (newPos < minPos)
|
|
m_pos = minPos;
|
|
else if (newPos > maxPos)
|
|
m_pos = maxPos;
|
|
else
|
|
m_pos = newPos;
|
|
|
|
if (m_pos != oldPos)
|
|
adjustWidgetSizes();
|
|
}
|
|
|
|
bool Sidebar::event(TQEvent *e)
|
|
{
|
|
switch (e->type()) {
|
|
case TQEvent::LayoutHint: {
|
|
if (m_position == Left) {
|
|
setMinimumWidth(m_tabBar->minimumWidth() + m_divider->minimumWidth() + m_sidebarBox->width() + m_content->minimumWidth());
|
|
} else {
|
|
setMinimumHeight(m_tabBar->minimumHeight() + m_divider->minimumHeight() + m_sidebarBox->height() + m_content->minimumHeight());
|
|
}
|
|
break;
|
|
}
|
|
case TQEvent::Resize: {
|
|
if (m_position == Left) {
|
|
m_divider->resize(0, height());
|
|
m_tabBar->resize(0, height());
|
|
} else {
|
|
m_divider->resize(width(), 0);
|
|
m_tabBar->resize(width(), 0);
|
|
}
|
|
|
|
adjustWidgetSizes();
|
|
return true;
|
|
}
|
|
default: break;
|
|
}
|
|
|
|
return TQWidget::event(e);
|
|
}
|
|
|
|
void Sidebar::addSidebar(TQWidget *widget, const TQString &title, const TQString &icon)
|
|
{
|
|
const int id = m_tabBar->tabs()->count(); // the next available id
|
|
const TQString name(widget->name());
|
|
TQWidget *tab;
|
|
|
|
widget->reparent(m_sidebarBox, TQPoint());
|
|
widget->hide();
|
|
|
|
m_tabBar->appendTab(SmallIcon(icon), id, title);
|
|
tab = m_tabBar->tab(id);
|
|
tab->setFocusPolicy(TQWidget::NoFocus);
|
|
|
|
// We use a SignalMapper to show/hide the corresponding browser when tabs are clicked
|
|
connect(tab, TQ_SIGNAL(clicked()), m_mapper, TQ_SLOT(map()));
|
|
m_mapper->setMapping(tab, id);
|
|
|
|
m_sidebars.push_back(widget);
|
|
}
|
|
|
|
void Sidebar::showHideSidebar(int index)
|
|
{
|
|
const int prevIndex = m_currentIndex;
|
|
|
|
if (m_currentIndex != -1) {
|
|
// First we need to hide the currentBrowser
|
|
m_currentIndex = -1;
|
|
|
|
m_sidebars[prevIndex]->hide();
|
|
m_tabBar->setTab(prevIndex, false);
|
|
}
|
|
|
|
if (index == prevIndex) {
|
|
// Close the sidebar
|
|
m_sidebarBox->hide();
|
|
m_divider->hide();
|
|
|
|
adjustWidgetSizes();
|
|
} else if ((uint) index < m_sidebars.count()) {
|
|
// Open up target
|
|
TQWidget* const target = m_sidebars[index];
|
|
m_currentIndex = index;
|
|
|
|
m_divider->show();
|
|
target->show();
|
|
target->setFocus();
|
|
m_sidebarBox->show();
|
|
m_tabBar->setTab(index, true);
|
|
|
|
if (prevIndex == -1) {
|
|
if (m_position == Left) {
|
|
m_pos = m_sidebarBox->width() + m_tabBar->width();
|
|
} else {
|
|
m_pos = currentSidebar()->height() + m_tabBar->height();
|
|
}
|
|
|
|
adjustWidgetSizes();
|
|
}
|
|
}
|
|
}
|
|
|
|
TQWidget *Sidebar::sidebar(const TQString &name) const
|
|
{
|
|
for (SidebarList::ConstIterator it = m_sidebars.begin(), end = m_sidebars.end(); it != end; ++it) {
|
|
if (name == (*it)->name())
|
|
return *it;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int Sidebar::indexForName(const TQString &name) const
|
|
{
|
|
for (uint x = 0; x < m_sidebars.count(); ++x) {
|
|
if (name == m_sidebars[x]->name())
|
|
return x;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
}
|
|
|
|
#include "sidebar.moc"
|