/*************************************************************************** * * * 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 3 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "TabFrame.h" #include "FlowLayout.h" #include "TabButton.h" #include "WulforUtil.h" #include "ArenaWidgetManager.h" #include "DebugHelper.h" #include "GlobalTimer.h" #if QT_VERSION >= 0x050000 #include #else #include #endif #include #include #include TabFrame::TabFrame(QWidget *parent) : QFrame(parent) { DEBUG_BLOCK setAcceptDrops(true); fr_layout = new FlowLayout(this); fr_layout->setContentsMargins(0, 0, 0, 0); setMinimumHeight(20); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); shortcuts << (new QShortcut(QKeySequence(Qt::ALT + Qt::Key_1), this)) << (new QShortcut(QKeySequence(Qt::ALT + Qt::Key_2), this)) << (new QShortcut(QKeySequence(Qt::ALT + Qt::Key_3), this)) << (new QShortcut(QKeySequence(Qt::ALT + Qt::Key_4), this)) << (new QShortcut(QKeySequence(Qt::ALT + Qt::Key_5), this)) << (new QShortcut(QKeySequence(Qt::ALT + Qt::Key_6), this)) << (new QShortcut(QKeySequence(Qt::ALT + Qt::Key_7), this)) << (new QShortcut(QKeySequence(Qt::ALT + Qt::Key_8), this)) << (new QShortcut(QKeySequence(Qt::ALT + Qt::Key_9), this)) << (new QShortcut(QKeySequence(Qt::ALT + Qt::Key_0), this)); for (const auto &s : shortcuts){ s->setContext(Qt::ApplicationShortcut); connect(s, SIGNAL(activated()), this, SLOT(slotShorcuts())); } connect(GlobalTimer::getInstance(), SIGNAL(second()), this, SLOT(redraw())); } TabFrame::~TabFrame(){ DEBUG_BLOCK auto it = tbtn_map.begin(); for (; it != tbtn_map.end(); ++it){ TabButton *btn = const_cast(it.key()); btn->deleteLater(); } } void TabFrame::resizeEvent(QResizeEvent *e){ e->accept(); QFrame::updateGeometry(); } bool TabFrame::eventFilter(QObject *obj, QEvent *e){ TabButton *btn = qobject_cast(obj); QWheelEvent *w_e = reinterpret_cast(e); if (btn && (e->type() == QEvent::Wheel) && w_e){ int numDegrees = (w_e->delta() < 0)? (-1*w_e->delta()/8) : (w_e->delta()/8); int numSteps = numDegrees/15; std::function f = [this]() { this->nextTab(); }; if (w_e->delta() < 0) f = [this]() { this->prevTab(); }; for (int i = 0; i < numSteps; i++) f(); return true; } return QFrame::eventFilter(obj, e); } QSize TabFrame::sizeHint() const { QSize s(fr_layout->sizeHint().width() , fr_layout->heightForWidth(width())); return s; } QSize TabFrame::minimumSizeHint() const{ return sizeHint(); } void TabFrame::removeWidget(ArenaWidget *awgt){ DEBUG_BLOCK if (!awgt_map.contains(awgt)) return; TabButton *btn = const_cast(awgt_map.value(awgt)); fr_layout->removeWidget(btn); tbtn_map.remove(btn); awgt_map.remove(awgt); btn->deleteLater(); historyPurge(awgt); historyPop(); if (awgt->toolButton()) awgt->toolButton()->setChecked(false); } void TabFrame::insertWidget(ArenaWidget *awgt){ DEBUG_BLOCK if (awgt_map.contains(awgt) || (awgt && (awgt->state() & ArenaWidget::Hidden)) || !awgt) return; TabButton *btn = new TabButton(); btn->setText(awgt->getArenaShortTitle().left(32)); btn->setToolTip(WulforUtil::getInstance()->compactToolTipText(awgt->getArenaTitle(), 60, "\n")); btn->setWidgetIcon(awgt->getPixmap()); btn->setContextMenuPolicy(Qt::CustomContextMenu); btn->installEventFilter(this); fr_layout->addWidget(btn); awgt_map.insert(awgt, btn); tbtn_map.insert(btn, awgt); if (awgt->toolButton()) awgt->toolButton()->setChecked(true); connect(btn, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotContextMenu())); connect(btn, SIGNAL(clicked()), this, SLOT(buttonClicked())); connect(btn, SIGNAL(closeRequest()), this, SLOT(closeRequsted())); connect(btn, SIGNAL(dropped(TabButton*)), this, SLOT(slotDropped(TabButton*))); } bool TabFrame::hasWidget(ArenaWidget *awgt) const{ DEBUG_BLOCK return awgt_map.contains(awgt); } void TabFrame::mapped(ArenaWidget *awgt){ DEBUG_BLOCK if (!awgt_map.contains(awgt)) return; TabButton *btn = const_cast(awgt_map.value(awgt)); btn->setChecked(true); btn->setFocus(); historyPush(awgt); } void TabFrame::updated ( ArenaWidget* awgt ) { DEBUG_BLOCK if (awgt->state() & ArenaWidget::Hidden){ removeWidget(awgt); } else if (!awgt_map.contains(awgt)){ insertWidget(awgt); } } void TabFrame::redraw() { DEBUG_BLOCK auto it = tbtn_map.begin(); for (; it != tbtn_map.end(); ++it){ TabButton *btn = const_cast(it.key()); ArenaWidget *awgt = const_cast(it.value()); btn->setText(awgt->getArenaShortTitle().left(32)); btn->setToolTip(WulforUtil::getInstance()->compactToolTipText(awgt->getArenaTitle(), 60, "\n")); btn->setWidgetIcon(awgt->getPixmap()); if (awgt->state() & ArenaWidget::Hidden) continue; else btn->resetGeometry(); } } void TabFrame::historyPush(ArenaWidget *awgt){ DEBUG_BLOCK historyPurge(awgt); history.push_back(awgt); } void TabFrame::historyPurge(ArenaWidget *awgt){ DEBUG_BLOCK if (history.contains(awgt)) history.removeAt(history.indexOf(awgt)); } void TabFrame::historyPop(){ DEBUG_BLOCK if (history.isEmpty() && fr_layout->count() > 0){ QLayoutItem *item = fr_layout->itemAt(0); if (!item) return; TabButton *btn = qobject_cast(item->widget()); if (btn) ArenaWidgetManager::getInstance()->activate(tbtn_map[btn]); return; } else if (history.isEmpty()){ ArenaWidgetManager::getInstance()->activate(NULL); return; } ArenaWidget *awgt = history.takeLast(); ArenaWidgetManager::getInstance()->activate(awgt); } void TabFrame::buttonClicked(){ DEBUG_BLOCK TabButton *btn = qobject_cast(sender()); if (!(btn && tbtn_map.contains(btn))) return; btn->setFocus(); ArenaWidgetManager::getInstance()->activate(tbtn_map[btn]); } void TabFrame::closeRequsted() { DEBUG_BLOCK TabButton *btn = qobject_cast(sender()); if (!(btn && tbtn_map.contains(btn))) return; ArenaWidget *awgt = const_cast(tbtn_map[btn]); ArenaWidgetManager::getInstance()->rem(awgt); } void TabFrame::nextTab(){ DEBUG_BLOCK TabButton *next = NULL; for (int i = 0; i < fr_layout->count(); i++){ TabButton *t = qobject_cast(fr_layout->itemAt(i)->widget()); if (t && t->isChecked()){ if (i == (fr_layout->count()-1)){ next = qobject_cast(fr_layout->itemAt(0)->widget()); break; } next = qobject_cast(fr_layout->itemAt(i+1)->widget()); break; } } if (!next) return; ArenaWidgetManager::getInstance()->activate(tbtn_map[next]); } void TabFrame::prevTab(){ DEBUG_BLOCK TabButton *next = NULL; for (int i = 0; i < fr_layout->count(); i++){ TabButton *t = qobject_cast(fr_layout->itemAt(i)->widget()); if (t && t->isChecked()){ if (!i){ next = qobject_cast(fr_layout->itemAt(fr_layout->count()-1)->widget()); break; } next = qobject_cast(fr_layout->itemAt(i-1)->widget()); break; } } if (!next) return; ArenaWidgetManager::getInstance()->activate(tbtn_map[next]); } void TabFrame::slotShorcuts(){ DEBUG_BLOCK QShortcut *sh = qobject_cast(sender()); if (!sh) return; int index = shortcuts.indexOf(sh); if (index >= 0 && fr_layout->count() >= (index + 1)){ TabButton *next = qobject_cast(fr_layout->itemAt(index)->widget()); if (!next) return; ArenaWidgetManager::getInstance()->activate(tbtn_map[next]); } } void TabFrame::slotContextMenu() { DEBUG_BLOCK TabButton *btn = qobject_cast(sender()); if (!(btn && tbtn_map.contains(btn))) return; ArenaWidget *awgt = const_cast(tbtn_map[btn]); if (awgt) { QMenu *widget_menu = awgt->getMenu(); if (widget_menu) { widget_menu->exec(btn->mapToGlobal(btn->rect().bottomLeft())); } else { widget_menu = new QMenu(this); widget_menu->addAction(WulforUtil::getInstance()->getPixmap(WulforUtil::eiEDITDELETE), tr("Close")); if (widget_menu->exec(QCursor::pos())) ArenaWidgetManager::getInstance()->rem(awgt); delete widget_menu; } } } void TabFrame::slotDropped(TabButton *dropped){ DEBUG_BLOCK TabButton *on = qobject_cast(sender()); if (!(on && dropped && on != dropped)) return; fr_layout->place(on, dropped); } void TabFrame::moveLeft(){ DEBUG_BLOCK for (int i = 0; i < fr_layout->count(); i++){ QLayoutItem *item = const_cast(fr_layout->itemAt(i)); TabButton *t = qobject_cast(item->widget()); if (t && t->isChecked()){ fr_layout->moveLeft(item); break; } } } void TabFrame::moveRight(){ DEBUG_BLOCK for (int i = 0; i < fr_layout->count(); i++){ QLayoutItem *item = const_cast(fr_layout->itemAt(i)); TabButton *t = qobject_cast(item->widget()); if (t && t->isChecked()){ fr_layout->moveRight(item); break; } } } void TabFrame::toggled ( ArenaWidget* awgt ) { DEBUG_BLOCK if (!awgt) return; if (!(awgt->state() & ArenaWidget::Singleton)) return; if (awgt->state() & ArenaWidget::Hidden) ArenaWidgetManager::getInstance()->activate(awgt); else ArenaWidgetManager::getInstance()->rem(awgt); }