summaryrefslogtreecommitdiff
path: root/src/fqterm/fqterm_wndmgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/fqterm/fqterm_wndmgr.cpp')
-rw-r--r--src/fqterm/fqterm_wndmgr.cpp381
1 files changed, 381 insertions, 0 deletions
diff --git a/src/fqterm/fqterm_wndmgr.cpp b/src/fqterm/fqterm_wndmgr.cpp
new file mode 100644
index 0000000..0e90b1c
--- /dev/null
+++ b/src/fqterm/fqterm_wndmgr.cpp
@@ -0,0 +1,381 @@
+/***************************************************************************
+ * 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 <stdio.h>
+
+#include <QApplication>
+#include <QEvent>
+#include <QKeyEvent>
+#include <QIcon>
+#include <QKeySequence>
+#include <QMdiArea>
+#include <QMdiSubWindow>
+#include <QTabBar>
+#include <QMouseEvent>
+#include <QMenu>
+#include <QMessageBox>
+#include <QToolButton>
+#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 <Python.h>
+#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 &param, 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 wont display untill 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"