/*************************************************************************** kilemultitabbar.cpp - description ------------------- begin : 2001 copyright : (C) 2001,2002,2003 by Joseph Wenninger (C) 2007 by Michel Ludwig ***************************************************************************/ /*************************************************************************** This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ***************************************************************************/ //FIXME: remove for the KDE4 version again and push the fix for hidden widgets // upstream #include "kilemultitabbar.h" #include "kilemultitabbar_p.h" #include "kilemultitabbar.moc" #include "kilemultitabbar_p.moc" #include #include #include #include #include #include #include #include #include #include "kiledebug.h" #include #include #define NEARBYINT(i) ((int(float(i) + 0.5))) class KileMultiTabBarTabPrivate { public: TQPixmap pix; }; KileMultiTabBarInternal::KileMultiTabBarInternal(TQWidget *parent, KileMultiTabBar::KileMultiTabBarMode bm):TQScrollView(parent) { m_expandedTabSize=-1; m_showActiveTabTexts=false; m_tabs.setAutoDelete(true); m_barMode=bm; setHScrollBarMode(AlwaysOff); setVScrollBarMode(AlwaysOff); if (bm==KileMultiTabBar::Vertical) { box=new TQWidget(viewport()); mainLayout=new TQVBoxLayout(box); mainLayout->setAutoAdd(true); box->setFixedWidth(24); setFixedWidth(24); } else { box=new TQWidget(viewport()); mainLayout=new TQHBoxLayout(box); mainLayout->setAutoAdd(true); box->setFixedHeight(24); setFixedHeight(24); } addChild(box); setFrameStyle(NoFrame); viewport()->setBackgroundMode(TQt::PaletteBackground); /* box->setPaletteBackgroundColor(TQt::red); setPaletteBackgroundColor(TQt::green);*/ } void KileMultiTabBarInternal::setStyle(enum KileMultiTabBar::KileMultiTabBarStyle style) { m_style=style; for (uint i=0;isetStyle(m_style); if ( (m_style==KileMultiTabBar::KDEV3) || (m_style==KileMultiTabBar::KDEV3ICON ) ) { delete mainLayout; mainLayout=0; resizeEvent(0); } else if (mainLayout==0) { if (m_barMode==KileMultiTabBar::Vertical) { box=new TQWidget(viewport()); mainLayout=new TQVBoxLayout(box); box->setFixedWidth(24); setFixedWidth(24); } else { box=new TQWidget(viewport()); mainLayout=new TQHBoxLayout(box); box->setFixedHeight(24); setFixedHeight(24); } addChild(box); for (uint i=0;iadd(m_tabs.at(i)); mainLayout->setAutoAdd(true); } viewport()->repaint(); } void KileMultiTabBarInternal::drawContents ( TQPainter * paint, int clipx, int clipy, int clipw, int cliph ) { TQScrollView::drawContents (paint , clipx, clipy, clipw, cliph ); if (m_position==KileMultiTabBar::Right) { paint->setPen(colorGroup().shadow()); paint->drawLine(0,0,0,viewport()->height()); paint->setPen(colorGroup().background().dark(120)); paint->drawLine(1,0,1,viewport()->height()); } else if (m_position==KileMultiTabBar::Left) { paint->setPen(colorGroup().light()); paint->drawLine(23,0,23,viewport()->height()); paint->drawLine(22,0,22,viewport()->height()); paint->setPen(colorGroup().shadow()); paint->drawLine(0,0,0,viewport()->height()); } else if (m_position==KileMultiTabBar::Bottom) { paint->setPen(colorGroup().shadow()); paint->drawLine(0,0,viewport()->width(),0); paint->setPen(colorGroup().background().dark(120)); paint->drawLine(0,1,viewport()->width(),1); } else { paint->setPen(colorGroup().light()); paint->drawLine(0,23,viewport()->width(),23); paint->drawLine(0,22,viewport()->width(),22); /* paint->setPen(colorGroup().shadow()); paint->drawLine(0,0,0,viewport()->height());*/ } } void KileMultiTabBarInternal::contentsMousePressEvent(TQMouseEvent *ev) { ev->ignore(); } void KileMultiTabBarInternal::mousePressEvent(TQMouseEvent *ev) { ev->ignore(); } #define CALCDIFF(m_tabs,diff,i) if (m_lines>(int)lines) {\ /*KILE_DEBUG()<<"i="<geometry()< visibleTabList; for(KileMultiTabBarTab *tab = m_tabs.first(); tab; tab = m_tabs.next()) { if(tab->isVisible()) { visibleTabList.push_back(tab); } } if ( (m_style==KileMultiTabBar::KDEV3) || (m_style==KileMultiTabBar::KDEV3ICON) ){ box->setGeometry(0,0,width(),height()); int lines=1; uint space; float tmp=0; if ((m_position==KileMultiTabBar::Bottom) || (m_position==KileMultiTabBar::Top)) space=width(); else space=height(); int cnt=0; //CALCULATE LINES const uint tabCount = visibleTabList.count(); for (uint i=0;ineededSize(); if (tmp>space) { if (cnt>1)i--; else if (i==(tabCount-1)) break; cnt=0; tmp=0; lines++; } } //SET SIZE & PLACE float diff=0; cnt=0; if ((m_position==KileMultiTabBar::Bottom) || (m_position==KileMultiTabBar::Top)) { setFixedHeight(lines*24); box->setFixedHeight(lines*24); m_lines=height()/24-1; lines=0; CALCDIFF(visibleTabList,diff,0) tmp=-diff; //KILE_DEBUG()<<"m_lines recalculated="<neededSize()+diff; if (tmp>space) { //KILE_DEBUG()<<"about to start new line"<1) { CALCDIFF(visibleTabList,diff,i) i--; } else { //KILE_DEBUG()<<"placing line on old line"<neededSize()<<"/"<::iterator i = visibleTabList.begin(); i != visibleTabList.end(); ++i) { size += (m_barMode == KileMultiTabBar::Vertical ? (*i)->height() : (*i)->width()); } if ((m_position==KileMultiTabBar::Bottom) || (m_position==KileMultiTabBar::Top)) box->setGeometry(0,0,size,height()); else box->setGeometry(0,0,width(),size); } } void KileMultiTabBarInternal::showActiveTabTexts(bool show) { m_showActiveTabTexts=show; } KileMultiTabBarTab* KileMultiTabBarInternal::tab(int id) const { for (TQPtrListIterator it(m_tabs);it.current();++it){ if (it.current()->id()==id) return it.current(); } return 0; } bool KileMultiTabBarInternal::eventFilter(TQObject *, TQEvent *e) { if (e->type()==TQEvent::Resize || e->type()==TQEvent::Hide || e->type()==TQEvent::Show) resizeEvent(0); return false; } int KileMultiTabBarInternal::appendTab(const TQPixmap &pic ,int id,const TQString& text) { KileMultiTabBarTab *tab; m_tabs.append(tab= new KileMultiTabBarTab(pic,text,id,box,m_position,m_style)); tab->installEventFilter(this); tab->showActiveTabText(m_showActiveTabTexts); if (m_style==KileMultiTabBar::KONQSBC) { if (m_expandedTabSizeneededSize()) { m_expandedTabSize=tab->neededSize(); for (uint i=0;isetSize(m_expandedTabSize); } else tab->setSize(m_expandedTabSize); } else tab->updateState(); tab->show(); resizeEvent(0); return 0; } void KileMultiTabBarInternal::removeTab(int id) { for (uint pos=0;posid()==id) { m_tabs.remove(pos); resizeEvent(0); break; } } } void KileMultiTabBarInternal::setPosition(enum KileMultiTabBar::KileMultiTabBarPosition pos) { m_position=pos; for (uint i=0;isetTabsPosition(m_position); viewport()->repaint(); } KileMultiTabBarButton::KileMultiTabBarButton(const TQPixmap& pic,const TQString& text, TQPopupMenu *popup, int id,TQWidget *parent,KileMultiTabBar::KileMultiTabBarPosition pos,KileMultiTabBar::KileMultiTabBarStyle style) :TQPushButton(TQIconSet(),text,parent),m_style(style) { setIconSet(pic); setText(text); m_position=pos; if (popup) setPopup(popup); setFlat(true); setFixedHeight(24); setFixedWidth(24); m_id=id; TQToolTip::add(this,text); connect(this,TQ_SIGNAL(clicked()),this,TQ_SLOT(slotClicked())); } KileMultiTabBarButton::KileMultiTabBarButton(const TQString& text, TQPopupMenu *popup, int id,TQWidget *parent,KileMultiTabBar::KileMultiTabBarPosition pos,KileMultiTabBar::KileMultiTabBarStyle style) :TQPushButton(TQIconSet(),text,parent),m_style(style) { setText(text); m_position=pos; if (popup) setPopup(popup); setFlat(true); setFixedHeight(24); setFixedWidth(24); m_id=id; TQToolTip::add(this,text); connect(this,TQ_SIGNAL(clicked()),this,TQ_SLOT(slotClicked())); } KileMultiTabBarButton::~KileMultiTabBarButton() { } int KileMultiTabBarButton::id() const{ return m_id; } void KileMultiTabBarButton::setText(const TQString& text) { TQString s = text; s = s.replace("&", TQString()); // we do not allow accelerators to be set // This is a little hack to avoid TDEAcceleratorManager // provide us with accelerators as the class name of the // widget is no longer KMultiTabBar. TQPushButton::setText(s); m_text = s; TQToolTip::add(this,s); } void KileMultiTabBarButton::slotClicked() { emit clicked(m_id); } void KileMultiTabBarButton::setPosition(KileMultiTabBar::KileMultiTabBarPosition pos) { m_position=pos; repaint(); } void KileMultiTabBarButton::setStyle(KileMultiTabBar::KileMultiTabBarStyle style) { m_style=style; repaint(); } void KileMultiTabBarButton::hideEvent( TQHideEvent* he) { TQPushButton::hideEvent(he); KileMultiTabBar *tb=dynamic_cast(parentWidget()); if (tb) tb->updateSeparator(); } void KileMultiTabBarButton::showEvent( TQShowEvent* he) { TQPushButton::showEvent(he); KileMultiTabBar *tb=dynamic_cast(parentWidget()); if (tb) tb->updateSeparator(); } TQSize KileMultiTabBarButton::sizeHint() const { constPolish(); int w = 0, h = 0; // calculate contents size... #ifndef TQT_NO_ICONSET if ( iconSet() && !iconSet()->isNull() ) { int iw = iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).width() + 4; int ih = iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).height(); w += iw; h = TQMAX( h, ih ); } #endif if ( isMenuButton() ) w += style().pixelMetric(TQStyle::PM_MenuButtonIndicator, this); if ( pixmap() ) { TQPixmap *pm = (TQPixmap *)pixmap(); w += pm->width(); h += pm->height(); } else { TQString s( text() ); bool empty = s.isEmpty(); if ( empty ) s = TQString::fromLatin1("XXXX"); TQFontMetrics fm = fontMetrics(); TQSize sz = fm.size( ShowPrefix, s ); if(!empty || !w) w += sz.width(); if(!empty || !h) h = TQMAX(h, sz.height()); } return (style().sizeFromContents(TQStyle::CT_ToolButton, this, TQSize(w, h)). expandedTo(TQApplication::globalStrut())); } KileMultiTabBarTab::KileMultiTabBarTab(const TQPixmap& pic, const TQString& text, int id,TQWidget *parent,KileMultiTabBar::KileMultiTabBarPosition pos, KileMultiTabBar::KileMultiTabBarStyle style) :KileMultiTabBarButton(text,0,id,parent,pos,style), m_showActiveTabText(false) { d=new KileMultiTabBarTabPrivate(); setIcon(pic); m_expandedSize=24; setToggleButton(true); } KileMultiTabBarTab::~KileMultiTabBarTab() { delete d; } void KileMultiTabBarTab::setTabsPosition(KileMultiTabBar::KileMultiTabBarPosition pos) { if ((pos!=m_position) && ((pos==KileMultiTabBar::Left) || (pos==KileMultiTabBar::Right))) { if (!d->pix.isNull()) { TQWMatrix temp;// (1.0F, 0.0F, 0.0F, -1.0F, 0.0F, 0.0F); temp.rotate(180); d->pix=d->pix.xForm(temp); setIconSet(d->pix); } } setPosition(pos); // repaint(); } void KileMultiTabBarTab::setIcon(const TQString& icon) { TQPixmap pic=SmallIcon(icon); setIcon(pic); } void KileMultiTabBarTab::setIcon(const TQPixmap& icon) { if (m_style!=KileMultiTabBar::KDEV3) { if ((m_position==KileMultiTabBar::Left) || (m_position==KileMultiTabBar::Right)) { TQWMatrix rotateMatrix; if (m_position==KileMultiTabBar::Left) rotateMatrix.rotate(90); else rotateMatrix.rotate(-90); TQPixmap pic=icon.xForm(rotateMatrix); //TODO FIX THIS, THIS SHOWS WINDOW d->pix=pic; setIconSet(pic); } else setIconSet(icon); } } void KileMultiTabBarTab::slotClicked() { updateState(); KileMultiTabBarButton::slotClicked(); } void KileMultiTabBarTab::setState(bool b) { setOn(b); updateState(); } void KileMultiTabBarTab::updateState() { if (m_style!=KileMultiTabBar::KONQSBC) { if ((m_style==KileMultiTabBar::KDEV3) || (m_style==KileMultiTabBar::KDEV3ICON) || (isOn())) { TQPushButton::setText(m_text); } else { KILE_DEBUG()<<"KileMultiTabBarTab::updateState(): setting text to an empty TQString***************"<height(),this->width());//KileMultiTabBarButton::sizeHint(); else sh=TQSize(this->width(),this->height()); } else sh=TQSize(width,height); TQPixmap pixmap( sh.width(),height); ///,sh.height()); pixmap.fill(eraseColor()); TQPainter painter(&pixmap); TQStyle::SFlags st=TQStyle::Style_Default; st|=TQStyle::Style_Enabled; if (isOn()) st|=TQStyle::Style_On; style().drawControl(TQStyle::CE_PushButton,&painter,this, TQRect(0,0,pixmap.width(),pixmap.height()), colorGroup(),st); style().drawControl(TQStyle::CE_PushButtonLabel,&painter,this, TQRect(0,0,pixmap.width(),pixmap.height()), colorGroup(),st); switch (m_position) { case KileMultiTabBar::Left: paint->rotate(-90); paint->drawPixmap(1-pixmap.width(),0,pixmap); break; case KileMultiTabBar::Right: paint->rotate(90); paint->drawPixmap(0,1-pixmap.height(),pixmap); break; default: paint->drawPixmap(0,0,pixmap); break; } // style().drawControl(TQStyle::CE_PushButtonLabel,painter,this, TQRect(0,0,pixmap.width(),pixmap.height()), // colorGroup(),TQStyle::Style_Enabled); } void KileMultiTabBarTab::drawButtonClassic(TQPainter *paint) { TQPixmap pixmap; if ( iconSet()) pixmap = iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ); paint->fillRect(0, 0, 24, 24, colorGroup().background()); if (!isOn()) { if (m_position==KileMultiTabBar::Right) { paint->fillRect(0,0,21,21,TQBrush(colorGroup().background())); paint->setPen(colorGroup().background().dark(150)); paint->drawLine(0,22,23,22); paint->drawPixmap(12-pixmap.width()/2,12-pixmap.height()/2,pixmap); paint->setPen(colorGroup().shadow()); paint->drawLine(0,0,0,23); paint->setPen(colorGroup().background().dark(120)); paint->drawLine(1,0,1,23); } else if ((m_position==KileMultiTabBar::Bottom) || (m_position==KileMultiTabBar::Top)) { paint->fillRect(0,1,23,22,TQBrush(colorGroup().background())); paint->drawPixmap(12-pixmap.width()/2,12-pixmap.height()/2,pixmap); paint->setPen(colorGroup().background().dark(120)); paint->drawLine(23,0,23,23); paint->setPen(colorGroup().light()); paint->drawLine(0,22,23,22); paint->drawLine(0,23,23,23); paint->setPen(colorGroup().shadow()); paint->drawLine(0,0,23,0); paint->setPen(colorGroup().background().dark(120)); paint->drawLine(0,1,23,1); } else { paint->setPen(colorGroup().background().dark(120)); paint->drawLine(0,23,23,23); paint->fillRect(0,0,23,21,TQBrush(colorGroup().background())); paint->drawPixmap(12-pixmap.width()/2,12-pixmap.height()/2,pixmap); paint->setPen(colorGroup().light()); paint->drawLine(23,0,23,23); paint->drawLine(22,0,22,23); paint->setPen(colorGroup().shadow()); paint->drawLine(0,0,0,23); } } else { if (m_position==KileMultiTabBar::Right) { paint->setPen(colorGroup().shadow()); paint->drawLine(0,height()-1,23,height()-1); paint->drawLine(0,height()-2,23,height()-2); paint->drawLine(23,0,23,height()-1); paint->drawLine(22,0,22,height()-1); paint->fillRect(0,0,21,height()-3,TQBrush(colorGroup().light())); paint->drawPixmap(10-pixmap.width()/2,10-pixmap.height()/2,pixmap); if (m_showActiveTabText) { if (height()<25+4) return; TQPixmap tpixmap(height()-25-3, width()-2); TQPainter painter(&tpixmap); painter.fillRect(0,0,tpixmap.width(),tpixmap.height(),TQBrush(colorGroup().light())); painter.setPen(colorGroup().text()); painter.drawText(0,+width()/2+TQFontMetrics(TQFont()).height()/2,m_text); paint->rotate(90); KILE_DEBUG()<<"tpixmap.width:"<drawPixmap(25,-tpixmap.height()+1,tpixmap); } } else if (m_position==KileMultiTabBar::Top) { paint->fillRect(0,0,width()-1,23,TQBrush(colorGroup().light())); paint->drawPixmap(10-pixmap.width()/2,10-pixmap.height()/2,pixmap); if (m_showActiveTabText) { paint->setPen(colorGroup().text()); paint->drawText(25,height()/2+TQFontMetrics(TQFont()).height()/2,m_text); } } else if (m_position==KileMultiTabBar::Bottom) { paint->setPen(colorGroup().shadow()); paint->drawLine(0,23,width()-1,23); paint->drawLine(0,22,width()-1,22); paint->fillRect(0,0,width()-1,21,TQBrush(colorGroup().light())); paint->drawPixmap(10-pixmap.width()/2,10-pixmap.height()/2,pixmap); if (m_showActiveTabText) { paint->setPen(colorGroup().text()); paint->drawText(25,height()/2+TQFontMetrics(TQFont()).height()/2,m_text); } } else { paint->setPen(colorGroup().shadow()); paint->drawLine(0,height()-1,23,height()-1); paint->drawLine(0,height()-2,23,height()-2); paint->fillRect(0,0,23,height()-3,TQBrush(colorGroup().light())); paint->drawPixmap(10-pixmap.width()/2,10-pixmap.height()/2,pixmap); if (m_showActiveTabText) { if (height()<25+4) return; TQPixmap tpixmap(height()-25-3, width()-2); TQPainter painter(&tpixmap); painter.fillRect(0,0,tpixmap.width(),tpixmap.height(),TQBrush(colorGroup().light())); painter.setPen(colorGroup().text()); painter.drawText(tpixmap.width()-TQFontMetrics(TQFont()).width(m_text),+width()/2+TQFontMetrics(TQFont()).height()/2,m_text); paint->rotate(-90); KILE_DEBUG()<<"tpixmap.width:"<drawPixmap(-24-tpixmap.width(),2,tpixmap); } } } } KileMultiTabBar::KileMultiTabBar(KileMultiTabBarMode bm, TQWidget *parent,const char *name):TQWidget(parent,name) { m_buttons.setAutoDelete(false); if (bm==Vertical) { m_l=new TQVBoxLayout(this); setSizePolicy(TQSizePolicy::Fixed, TQSizePolicy::Expanding, true); // setFixedWidth(24); } else { m_l=new TQHBoxLayout(this); setSizePolicy(TQSizePolicy::Expanding, TQSizePolicy::Fixed, true); // setFixedHeight(24); } m_l->setMargin(0); m_l->setAutoAdd(false); m_internal=new KileMultiTabBarInternal(this,bm); setPosition((bm==KileMultiTabBar::Vertical)?KileMultiTabBar::Right:KileMultiTabBar::Bottom); setStyle(VSNET); // setStyle(KDEV3); //setStyle(KONQSBC); m_l->insertWidget(0,m_internal); m_l->insertWidget(0,m_btnTabSep=new TQFrame(this)); m_btnTabSep->setFixedHeight(4); m_btnTabSep->setFrameStyle(TQFrame::Panel | TQFrame::Sunken); m_btnTabSep->setLineWidth(2); m_btnTabSep->hide(); updateGeometry(); } KileMultiTabBar::~KileMultiTabBar() { } /*int KileMultiTabBar::insertButton(TQPixmap pic,int id ,const TQString&) { (new TDEToolbarButton(pic,id,m_internal))->show(); return 0; }*/ int KileMultiTabBar::appendButton(const TQPixmap &pic ,int id,TQPopupMenu *popup,const TQString&) { KileMultiTabBarButton *btn; m_buttons.append(btn= new KileMultiTabBarButton(pic,TQString(), popup,id,this,m_position,m_internal->m_style)); m_l->insertWidget(0,btn); btn->show(); m_btnTabSep->show(); return 0; } void KileMultiTabBar::updateSeparator() { bool hideSep=true; for (TQPtrListIterator it(m_buttons);it.current();++it){ if (it.current()->isVisibleTo(this)) { hideSep=false; break; } } if (hideSep) m_btnTabSep->hide(); else m_btnTabSep->show(); } int KileMultiTabBar::appendTab(const TQPixmap &pic ,int id ,const TQString& text) { m_internal->appendTab(pic,id,text); return 0; } KileMultiTabBarButton* KileMultiTabBar::button(int id) const { for (TQPtrListIterator it(m_buttons);it.current();++it){ if (it.current()->id()==id) return it.current(); } return 0; } KileMultiTabBarTab* KileMultiTabBar::tab(int id) const { return m_internal->tab(id); } void KileMultiTabBar::removeButton(int id) { for (uint pos=0;posid()==id) { m_buttons.take(pos)->deleteLater(); break; } } if (m_buttons.count()==0) m_btnTabSep->hide(); } void KileMultiTabBar::removeTab(int id) { m_internal->removeTab(id); } void KileMultiTabBar::setTab(int id,bool state) { KileMultiTabBarTab *ttab=tab(id); if (ttab) { ttab->setState(state); } } bool KileMultiTabBar::isTabRaised(int id) const { KileMultiTabBarTab *ttab=tab(id); if (ttab) { return ttab->isOn(); } return false; } void KileMultiTabBar::showActiveTabTexts(bool show) { m_internal->showActiveTabTexts(show); } void KileMultiTabBar::setStyle(KileMultiTabBarStyle style) { m_internal->setStyle(style); } KileMultiTabBar::KileMultiTabBarStyle KileMultiTabBar::tabStyle() const { return m_internal->m_style; } void KileMultiTabBar::setPosition(KileMultiTabBarPosition pos) { m_position=pos; m_internal->setPosition(pos); for (uint i=0;isetPosition(pos); } KileMultiTabBar::KileMultiTabBarPosition KileMultiTabBar::position() const { return m_position; } void KileMultiTabBar::fontChange(const TQFont& /* oldFont */) { for (uint i=0;icount();i++) tabs()->at(i)->resize(); repaint(); } TQPtrList* KileMultiTabBar::tabs() {return m_internal->tabs();} TQPtrList* KileMultiTabBar::buttons() {return &m_buttons;}