/*************************************************************************** * fqterm, a terminal emulator for both BBS and *nix. * * Copyright (C) 2008 fqterm development group. * * * * 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 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. * * * * 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 St, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ ///////////////////////////////////////////////////////////////// //TODO: This class has too many overlap with MDI Area. //It should inherit the QMdiArea... ///////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include "fqterm_frame.h" #include "fqterm_path.h" #include "fqterm_screen.h" #include "fqterm_trace.h" #include "fqterm_window.h" #include "fqterm_wndmgr.h" #ifdef HAVE_PYTHON #include #endif //HAVE_PYTHON namespace FQTerm { //constructor FQTermWndMgr::FQTermWndMgr(QWidget *parent, const char *name) : QMdiArea(parent), subWindowMax_(true), subWindowSize_(640, 480), tabBar_(NULL) { tabBar_ = new FQTermTabBar(this); tabBar_->setShape(QTabBar::RoundedSouth); FQ_VERIFY(connect(tabBar_, SIGNAL(currentChanged(int)), this, SLOT(activateTheWindow(int)))); FQ_VERIFY(connect(tabBar_, SIGNAL(rightClicked(int,const QPoint&)), this, SLOT(onTabRightClicked(int,const QPoint&)))); FQ_VERIFY(connect(tabBar_, SIGNAL(doubleClicked(int,const QPoint&)), this, SLOT(onTabDoubleClicked(int,const QPoint&)))); setObjectName(name); termFrame_ = (FQTermFrame*)parent; isAfterRemoved_ = false; } //destructor FQTermWndMgr::~FQTermWndMgr(){} //remove window-tab-iconset bool FQTermWndMgr::closeWindow(FQTermWindow *mw) { FQ_FUNC_TRACE("wndmgr", 3); QMdiSubWindow* subWindow = FQToMDI(mw); if (subWindow) { return subWindow->close(); } return false; } bool FQTermWndMgr::closeAllWindow() { FQ_FUNC_TRACE("wndmgr", 3); bool anyConnected = false; for (int i = 0; i < subWindowList().size(); ++i) { FQTermWindow * window = (FQTermWindow *)(subWindowList()[i]->widget()); if (window->isConnected()) { anyConnected = true; break; } } bool warn = FQTermPref::getInstance()->openWarnOnClose_; if (anyConnected && warn) { QMessageBox mb(tr("FQTerm"), tr("Still connected, do you really want to exit?"), QMessageBox::Warning, QMessageBox::Yes|QMessageBox::Default, QMessageBox::No | QMessageBox::Escape, 0, this); if (mb.exec() != QMessageBox::Yes) { return false; } } FQTermPref::getInstance()->openWarnOnClose_ = false; while (count() > 0) { bool closed = subWindowList().at(0)->close(); if (!closed) { FQTermPref::getInstance()->openWarnOnClose_ = warn; return false; } } FQTermPref::getInstance()->openWarnOnClose_ = warn; return true; } //active the window when switch the tab void FQTermWndMgr::activateTheWindow(int n) { FQ_FUNC_TRACE("wndmgr", 3); if (n < 0 || n >= count() || subWindowList().at(n) == activeSubWindow()) return; QMdiSubWindow *subWindow = subWindowList().at(n); // Fix the refresh bug by send PaintEvent to session screen. //subWindow->setFocus(); setActiveSubWindow(subWindow); } //blink the tab when message come in void FQTermWndMgr::blinkTheTab(FQTermWindow *mw, bool bVisible) { FQ_FUNC_TRACE("wndmgr", 10); static QIcon a_icon(getPath(RESOURCE) + "pic/tabpad.png"); static QIcon b_icon(getPath(RESOURCE) + "pic/transp.png"); //find where it is QMdiSubWindow* subWindow = FQToMDI(mw); if (!subWindow) return; int n = subWindowList().indexOf(subWindow); QIcon *icon = icons_.at(n); //FIXME: QIcon::Automatic if (bVisible) { icon->addFile(getPath(RESOURCE) + "pic/tabpad.png"); tabBar_->setTabIcon(n, a_icon); } else { //,QIcon::Automatic); icon->addFile(getPath(RESOURCE) + "pic/transp.png"); tabBar_->setTabIcon(n, b_icon); } //,QIcon::Automatic); tabBar_->update(); } //return the number of connected window int FQTermWndMgr::count() { return subWindowList().count(); } FQTermWindow *FQTermWndMgr::activeWindow() { return MDIToFQ(activeSubWindow()); } bool FQTermWndMgr::afterRemove() { if (isAfterRemoved_) { isAfterRemoved_ = false; return true; } else { return false; } } void FQTermWndMgr::refreshAllExcept(FQTermWindow *termWindow) { for (int i = 0; i < subWindowList().count(); ++i) { FQTermWindow * window = (FQTermWindow *)(subWindowList()[i]->widget()); if (window != termWindow) { window->repaintScreen(); } } } FQTermWindow* FQTermWndMgr::newWindow( const FQTermParam ¶m, FQTermConfig* config, QIcon* icon, int index /*= -1*/ ) { FQTermWindow *window = new FQTermWindow(config, termFrame_, param, index, this, 0); //add window-tab-icon to window manager QMdiSubWindow* subWindow = addSubWindow(window); subWindow->setAttribute(Qt::WA_OpaquePaintEvent); subWindow->setAttribute(Qt::WA_DeleteOnClose); icons_.append(icon); if (count() == 1) { termFrame_->enableMenuToolBar(true); } //if no this call, the tab won't display until you resize the window int idx = tabBar_->addTab(*icon, window->windowTitle()); tabBar_->updateGeometry(); tabBar_->update(); subWindow->resize(subWindowSize_); if (subWindowMax_) { subWindow->setWindowFlags(Qt::SubWindow | Qt::CustomizeWindowHint | Qt::WindowMinMaxButtonsHint); subWindow->showMaximized(); } else { subWindow->setWindowFlags(Qt::SubWindow | (Qt::CustomizeWindowHint | Qt::WindowMinMaxButtonsHint | Qt::WindowSystemMenuHint)); subWindow->show(); } tabBar_->setTabData(idx, qVariantFromValue((QObject*)window)); FQ_VERIFY(connect(window, SIGNAL(destroyed(QObject*)), this ,SLOT(onSubWindowClosed(QObject*)))); FQ_VERIFY(connect(window, SIGNAL(resizeSignal(FQTermWindow*)), this, SLOT(subWindowResized(FQTermWindow*)))); FQ_VERIFY(connect(this, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(onSubWindowActivated(QMdiSubWindow*)))); FQ_VERIFY(connect(window, SIGNAL(blinkTheTab(FQTermWindow*, bool)), this, SLOT(blinkTheTab(FQTermWindow*, bool)))); FQ_VERIFY(connect(window, SIGNAL(refreshOthers(FQTermWindow*)), this, SLOT(refreshAllExcept(FQTermWindow*)))); FQ_VERIFY(connect(window, SIGNAL(connectionClosed(FQTermWindow*)), this, SLOT(closeWindow(FQTermWindow*)), Qt::QueuedConnection)); return window; } void FQTermWndMgr::onSubWindowClosed(QObject* obj) { for (int i = 0; i < tabBar_->count(); ++i) { if (tabBar_->tabData(i) == qVariantFromValue(obj)) { if (count() == 0) { termFrame_->enableMenuToolBar(false); } if (i == tabBar_->currentIndex()) isAfterRemoved_ = true; tabBar_->removeTab(i); icons_.removeAt(i); } } } //--------------------------- //record subwindows' size //--------------------------- void FQTermWndMgr::subWindowResized(FQTermWindow *mw) { QMdiSubWindow* subWindow = FQToMDI(mw); if (!subWindow) return; Qt::WindowFlags wfs = subWindow->windowFlags(); if (!(subWindowMax_ = subWindow->isMaximized())){ if (!subWindow->isMinimized()) { subWindowSize_ = subWindow->frameSize(); } subWindow->setWindowFlags(wfs | Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint); } else { subWindow->setWindowFlags(wfs & ~Qt::WindowSystemMenuHint); } } void FQTermWndMgr::cascade() { QSize oldSize = subWindowSize_; cascadeSubWindows(); foreach(QMdiSubWindow* subWindow, subWindowList()) { if (subWindow) { subWindow->resize(oldSize); } } } void FQTermWndMgr::tile() { tileSubWindows(); } void FQTermWndMgr::activateNextWindow() { activateTheWindow((activeWindowIndex() + 1) % count()); } void FQTermWndMgr::activatePrevWindow() { activateTheWindow((activeWindowIndex() - 1 + count()) % count()); } FQTermWindow * FQTermWndMgr::nthWindow(int n) { return (FQTermWindow *)(subWindowList()[n]->widget()); } void FQTermWndMgr::onSubWindowActivated(QMdiSubWindow * subWindow) { int n = subWindowList().indexOf(subWindow); if (n == -1) return; FQTermWindow* mw = MDIToFQ(subWindow); if (mw->isMaximized() && afterRemove()) { mw->showNormal(); mw->showMaximized(); } if (tabBar_->currentIndex() != n) { FQ_VERIFY(disconnect(this, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(onSubWindowActivated(QMdiSubWindow*)))); tabBar_->setCurrentIndex(n); FQ_VERIFY(connect(this, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(onSubWindowActivated(QMdiSubWindow*)))); } termFrame_->updateMenuToolBar(); } void FQTermWndMgr::onTabRightClicked(int index, const QPoint& p) { QMenu* menu = FQToMDI(nthWindow(index))->systemMenu(); menu->popup(p); } void FQTermWndMgr::onTabDoubleClicked(int index, const QPoint& p) { closeWindow(nthWindow(index)); } FQTermWindow* FQTermWndMgr::MDIToFQ( QMdiSubWindow* subWindow ) { if (!subWindowList().contains(subWindow)) return NULL; return (FQTermWindow*)subWindow->widget(); } QMdiSubWindow* FQTermWndMgr::FQToMDI( FQTermWindow* window ) { for (int i = 0; i < subWindowList().count(); ++i) { if ((FQTermWindow*)(subWindowList()[i]->widget()) == window) { return subWindowList()[i]; } } return NULL; } int FQTermWndMgr::FQToIndex( FQTermWindow* window ) { return subWindowList().indexOf(FQToMDI(window)); } bool FQTermWndMgr::event( QEvent* e ) { if (e->type() == QEvent::ShortcutOverride) { QKeyEvent* ke = (QKeyEvent*)e; if (ke->key() == Qt::Key_W && ke->modifiers() == Qt::ControlModifier) { ke->accept(); return true; } } return QMdiArea::event(e); } void FQTermTabBar::mouseReleaseEvent( QMouseEvent * me ) { int index = tabAt(me->pos()); if (index != -1 && me->button() == Qt::RightButton && me->modifiers() == Qt::NoModifier) { emit rightClicked(index, mapToGlobal(me->pos())); } } void FQTermTabBar::mouseDoubleClickEvent( QMouseEvent * me ) { int index = tabAt(me->pos()); if (index != -1 && me->button() == Qt::LeftButton && me->modifiers() == Qt::NoModifier) { emit doubleClicked(index, mapToGlobal(me->pos())); } } } // namespace FQTerm #include "fqterm_wndmgr.moc"