/* * This file is part of the KFTPGrabber project * * Copyright (C) 2003-2005 by the KFTPGrabber developers * Copyright (C) 2003-2005 Jernej Kos * Copyright (C) 2004-2005 Max Howell * * 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 #include #include #include #include #include #include #include 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(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, SIGNAL(mapped(int)), 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, SIGNAL(clicked()), m_mapper, 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"