--- src/groupchatdlg.h~	2008-02-10 04:03:59 +0300
+++ src/groupchatdlg.h	2008-03-13 00:29:06 +0300
@@ -126,6 +126,7 @@ private slots:
 	void openWhiteboard();
 #endif
 	void chatEditCreated();
+	void forceClose();
 
 public:
 	class Private;
@@ -133,6 +134,7 @@ public:
 private:
 	Private *d;
 	Ui::GroupChatDlg ui_;
+	bool force_close;
 
 	void doAlert();
 	void appendSysMsg(const QString &, bool, const QDateTime &ts=QDateTime());
--- src/groupchatdlg.cpp~	2008-03-13 00:25:36 +0300
+++ src/groupchatdlg.cpp	2008-03-19 10:41:31 +0300
@@ -104,7 +104,7 @@ public:
 	QString self, prev_self;
 	QString password;
 	bool nonAnonymous;     // got status code 100 ?
-	IconAction *act_find, *act_clear, *act_icon, *act_configure;
+	IconAction *act_find, *act_clear, *act_icon, *act_configure, *act_exitchat;
 #ifdef WHITEBOARDING
 	IconAction *act_whiteboard;
 #endif
@@ -488,6 +488,7 @@ GCMainDlg::GCMainDlg(PsiAccount *pa, con
   	if ( PsiOptions::instance()->getOption("options.ui.mac.use-brushed-metal-windows").toBool() )
 		setAttribute(Qt::WA_MacMetalStyle);
 	nicknumber=0;
+	force_close = false;
 	d = new Private(this);
 	d->self = d->prev_self = j.resource();
 	account()->dialogRegister(this, jid());
@@ -546,6 +547,9 @@ GCMainDlg::GCMainDlg(PsiAccount *pa, con
 	connect(d->act_whiteboard, SIGNAL(activated()), SLOT(openWhiteboard()));
 #endif
 
+	d->act_exitchat = new IconAction(tr("Exit chat"), "psi/close", tr("E&xit chat"), 0, this);
+	connect(d->act_exitchat, SIGNAL(activated()), SLOT(forceClose()));
+
 	connect(pa->psi()->iconSelectPopup(), SIGNAL(textSelected(QString)), d, SLOT(addEmoticon(QString)));
 	d->act_icon = new IconAction( tr( "Select icon" ), "psi/smile", tr( "Select icon" ), 0, this );
 	d->act_icon->setMenu( pa->psi()->iconSelectPopup() );
@@ -557,6 +561,7 @@ GCMainDlg::GCMainDlg(PsiAccount *pa, con
 #ifdef WHITEBOARDING
 	ui_.toolbar->addAction(d->act_whiteboard);
 #endif
+	ui_.toolbar->addAction(d->act_exitchat);
 	ui_.toolbar->addWidget(new StretchWidget(ui_.toolbar));
 	ui_.toolbar->addAction(d->act_icon);
 	ui_.toolbar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Maximum);
@@ -567,7 +572,7 @@ GCMainDlg::GCMainDlg(PsiAccount *pa, con
 	connect(d->act_send,SIGNAL(activated()), SLOT(mle_returnPressed()));
 	d->act_close = new QAction(this);
 	addAction(d->act_close);
-	connect(d->act_close,SIGNAL(activated()), SLOT(close()));
+	connect(d->act_close,SIGNAL(activated()), SLOT(forceClose()));
 	d->act_scrollup = new QAction(this);
 	addAction(d->act_scrollup);
 	connect(d->act_scrollup,SIGNAL(activated()), SLOT(scrollUp()));
@@ -605,6 +610,9 @@ GCMainDlg::GCMainDlg(PsiAccount *pa, con
 	setShortcuts();
 	invalidateTab();
 	setConnecting();
+
+	// close when application exit
+	connect(QApplication::instance(), SIGNAL(aboutToQuit()), this,  SLOT(forceClose()));
 }
 
 GCMainDlg::~GCMainDlg()
@@ -656,7 +664,21 @@ void GCMainDlg::scrollDown() {
 
 void GCMainDlg::closeEvent(QCloseEvent *e)
 {
+    if( force_close )
+    {
 	e->accept();
+    }
+    else
+    {
+	e->ignore();
+	showMinimized();
+    }
+}
+
+void GCMainDlg::forceClose()
+{
+    force_close = true;
+    close();
 }
 
 void GCMainDlg::resizeEvent(QResizeEvent* e)
@@ -1061,7 +1085,7 @@ void GCMainDlg::presence(const QString &
 			else {
 				QMessageBox::information(this,tr("Room Destroyed"), message);
 			}
-			close();
+			forceClose();
 		}
 		if ( !d->connecting && options_->getOption("options.muc.show-joins").toBool() ) {
 			QString message;
@@ -1077,7 +1101,7 @@ void GCMainDlg::presence(const QString &
 					// Ban
 					if (nick == d->self) {
 						mucInfoDialog(tr("Banned"), tr("You have been banned from the room"), s.mucItem().actor(), s.mucItem().reason());
-						close();
+						forceClose();
 					}
 
 					if (!s.mucItem().actor().isEmpty())
@@ -1098,7 +1122,7 @@ void GCMainDlg::presence(const QString &
 					// Kick
 					if (nick == d->self) {
 						mucInfoDialog(tr("Kicked"), tr("You have been kicked from the room"), s.mucItem().actor(), s.mucItem().reason());
-						close();
+						forceClose();
 					}
 
 					if (!s.mucItem().actor().isEmpty())
@@ -1113,7 +1137,7 @@ void GCMainDlg::presence(const QString &
 					// Remove due to affiliation change
 					if (nick == d->self) {
 						mucInfoDialog(tr("Removed"), tr("You have been removed from the room due to an affiliation change"), s.mucItem().actor(), s.mucItem().reason());
-						close();
+						forceClose();
 					}
 
 					if (!s.mucItem().actor().isEmpty())
@@ -1129,7 +1153,7 @@ void GCMainDlg::presence(const QString &
 					// Remove due to members only
 					if (nick == d->self) {
 						mucInfoDialog(tr("Removed"), tr("You have been removed from the room because the room was made members only"), s.mucItem().actor(), s.mucItem().reason());
-						close();
+						forceClose();
 					}
 
 					if (!s.mucItem().actor().isEmpty())
@@ -1522,6 +1546,9 @@ void GCMainDlg::buildMenu()
 	d->pm_settings->insertSeparator();
 
 	d->act_icon->addTo( d->pm_settings );
+
+	d->pm_settings->insertSeparator();
+	d->act_exitchat->addTo( d->pm_settings );
 }
 
 void GCMainDlg::chatEditCreated()
@@ -1567,7 +1594,7 @@ GCFindDlg::GCFindDlg(const QString &str,
 	hb = new QHBoxLayout(vb);
 	hb->addStretch(1);
 	QPushButton *pb_close = new QPushButton(tr("&Close"), this);
-	connect(pb_close, SIGNAL(clicked()), SLOT(close()));
+	connect(pb_close, SIGNAL(clicked()), SLOT(forceClose()));
 	hb->addWidget(pb_close);
 	QPushButton *pb_find = new QPushButton(tr("&Find"), this);
 	pb_find->setDefault(true);
--- src/tabs/tabdlg.h~	2008-05-23 02:45:33 +0400
+++ src/tabs/tabdlg.h	2008-05-23 03:11:39 +0400
@@ -111,7 +111,7 @@ public slots:
 	void addTab(TabbableWidget *tab);
 	void setLooks();
 	void closeCurrentTab();
-	void closeTab(TabbableWidget*, bool doclose = true);
+	bool closeTab(TabbableWidget*, bool doclose = true);
 	void selectTab(TabbableWidget*);
 	void activated();
 	void optionsUpdate();
@@ -135,6 +135,7 @@ private slots:
 	void menu_sendTabTo(QAction *act);
 	void queuedSendTabTo(TabbableWidget* chat, TabDlg *dest);
 	void showTabMenu(int tab, QPoint pos, QContextMenuEvent * event);
+	void forceClose();
 
 private:
 	TabDlgDelegate *delegate_;
@@ -152,6 +153,7 @@ private:
 	bool userManagement_;
 	bool tabBarSingles_;
 	bool simplifiedCaption_;
+	bool force_close;
 
 	QSize chatSize_;
 
--- src/tabs/tabdlg.cpp~	2008-05-18 14:52:16 +0400
+++ src/tabs/tabdlg.cpp	2008-06-05 22:07:37 +0400
@@ -38,6 +38,7 @@
 #include "shortcutmanager.h"
 #include "chatdlg.h"
 #include "tabmanager.h"
+#include "groupchatdlg.h"
 
 #ifdef Q_WS_WIN
 #include <windows.h>
@@ -126,6 +127,7 @@ TabDlg::TabDlg(TabManager* tabManager, Q
 		, userManagement_(true)
 		, tabBarSingles_(true)
 		, simplifiedCaption_(false) {
+	force_close = false;
 	if (delegate_) {
 		delegate_->create(this);
 	}
@@ -174,6 +176,8 @@ TabDlg::TabDlg(TabManager* tabManager, Q
 	} else {
 		resize(ChatDlg::defaultSize()); //TODO: no!
 	}
+	// to accept QCloseEvent when application exit
+	connect(QApplication::instance(), SIGNAL(aboutToQuit()), this,  SLOT(forceClose()));
 }
 
 TabDlg::~TabDlg()
@@ -413,11 +417,17 @@ void TabDlg::removeTabWithNoChecks(Tabba
  * \param chat Chat to remove.
  * \param doclose Whether the chat is 'closed' while removing it.
  */ 
-void TabDlg::closeTab(TabbableWidget* chat, bool doclose)
+bool TabDlg::closeTab(TabbableWidget* chat, bool doclose)
 {
 	if (!chat || (doclose && !chat->readyToHide())) {
-		return;
+		return false;
+	}
+
+	// check is groupchat
+	if( doclose && qobject_cast<GCMainDlg*>(chat) ) {
+	    return false;
 	}
+
 	setUpdatesEnabled(false);
 	chat->hide();
 	removeTabWithNoChecks(chat);
@@ -431,6 +441,7 @@ void TabDlg::closeTab(TabbableWidget* ch
 		chat->close();
 	}
 	setUpdatesEnabled(true);
+	return true;
 }
 
 void TabDlg::selectTab(TabbableWidget* chat)
@@ -496,8 +507,16 @@ void TabDlg::closeEvent(QCloseEvent* clo
 			return;
 		}
 	}
+	bool all_closed = true;
 	foreach(TabbableWidget* tab, tabs_) {
-		closeTab(tab);
+		if( !closeTab(tab) )
+		    all_closed = false;
+	}
+	if( force_close || all_closed ) {
+	    closeEvent->accept();
+	} else {
+	    closeEvent->ignore();
+	    showMinimized();
 	}
 }
 
@@ -755,3 +774,9 @@ void TabDlg::setSimplifiedCaptionEnabled
 	simplifiedCaption_ = enabled;
 	updateCaption();
 }
+
+void TabDlg::forceClose()
+{
+    force_close = true;
+    close();
+}
