File indexing completed on 2024-03-24 04:05:24

0001 //
0002 // C++ Implementation: cSessionManager
0003 //
0004 // Description: Session manager.
0005 //
0006 /*
0007 Copyright 2002-2008 Tomas Mecir <kmuddy@kmuddy.com>
0008 
0009 This program is free software; you can redistribute it and/or
0010 modify it under the terms of the GNU General Public License as
0011 published by the Free Software Foundation; either version 2 of 
0012 the License, or (at your option) any later version.
0013 
0014 This program is distributed in the hope that it will be useful,
0015 but WITHOUT ANY WARRANTY; without even the implied warranty of
0016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017 GNU General Public License for more details.
0018 
0019 You should have received a copy of the GNU General Public License
0020 along with this program.  If not, see <http://www.gnu.org/licenses/>.
0021 */
0022 
0023 #include "csessionmanager.h"
0024 
0025 #include "cactionmanager.h"
0026 #include "cconnection.h"
0027 #include "cglobalsettings.h"
0028 #include "cinputline.h"
0029 #include "csession.h"
0030 #include "ctabwidget.h"
0031 #include "ctelnet.h"
0032 #include "kmuddy.h"
0033 
0034 #include <KLocalizedString>
0035 
0036 #include <QIcon>
0037 
0038 struct cSessionManagerPrivate {
0039   cTabWidget *widget;
0040 
0041   cActionManager *am;
0042 
0043   /** icons for the tab bar */
0044   QIcon iconOk, iconNo, iconFlag;
0045 
0046   /** should the tab bar be displayed even if there is only one connection? */
0047   bool wantTabBar;
0048 };
0049 
0050 cSessionManager *cSessionManager::_self = nullptr;
0051 
0052 cSessionManager::cSessionManager () : cActionBase ("session-manager", 0)
0053 {
0054   d = new cSessionManagerPrivate;
0055   d->widget = nullptr;
0056   cActionManager::self()->setActiveSession (0);
0057   d->am = cActionManager::self();
0058 
0059   //icons for tabs
0060   d->iconOk = QIcon::fromTheme ("dialog-ok");
0061   d->iconNo = QIcon::fromTheme ("dialog-cancel");
0062   d->iconFlag = QIcon::fromTheme ("flag");
0063 
0064   addGlobalEventHandler ("global-settings-changed", 50, PT_NOTHING);
0065 }
0066 
0067 cSessionManager::~cSessionManager ()
0068 {
0069   removeGlobalEventHandler ("global-settings-changed");
0070   delete d;
0071 }
0072 
0073 cSessionManager *cSessionManager::self()
0074 {
0075   if (!_self) _self = new cSessionManager;
0076   return _self;
0077 }
0078 
0079 void cSessionManager::eventNothingHandler (QString event, int)
0080 {
0081   if (event == "global-settings-changed") {
0082     setAlwaysTabBar (cGlobalSettings::self()->getBool ("always-tab-bar"));
0083   }
0084 }
0085 
0086 int cSessionManager::count ()
0087 {
0088   return d->am->sessions();
0089 }
0090 
0091 void cSessionManager::setMainWidget (cTabWidget *widget)
0092 {
0093   d->widget = widget;
0094 }
0095 
0096 int cSessionManager::activeSession ()
0097 {
0098   return cActionManager::self()->activeSession();
0099 }
0100 
0101 int cSessionManager::getSessionByTab (int tab)
0102 {
0103   cSession *sess = (cSession *) d->widget->widget (tab);
0104   if (!sess) return -1;
0105   return sess->sess();
0106 }
0107 
0108 int cSessionManager::getTabBySession (int sess)
0109 {
0110   if (!d->am->sessionExists (sess)) return -1;
0111   cSession *s = dynamic_cast<cSession *>(d->am->object ("session", sess));
0112   if (!s) return -1;
0113   return d->widget->indexOf (s);
0114 }
0115 
0116 int cSessionManager::addSession (bool profile)
0117 {
0118   if (KMuddy::isGoingDown())
0119     return 0;
0120 
0121   //first, one very special case - if we only have one session
0122   //and that one is not connected, we return that session
0123   //and don't add any new one. This session will be used for
0124   //the connection that is being established.
0125   if (count() == 1)
0126   {
0127     int which = d->am->sessionList().front();
0128     cTelnet *telnet = dynamic_cast<cTelnet *>(d->am->object ("telnet", which));
0129     if (!telnet->isConnected())
0130     {
0131       cActionManager::self()->setSessionAttrib (which, "profile", profile?1:0);
0132       cGlobalSettings::self()->notifyChange ();
0133       return which;
0134     }
0135     //else: continue
0136   }
0137 
0138   //now for the standard operation
0139 
0140   //find a first free session ID for the connection
0141   int which = 1;
0142   while (true) {
0143     if (!d->am->sessionExists (which)) break;
0144     ++which;
0145   }
0146 
0147   d->am->registerSession (which);
0148   cActionManager::self()->setSessionAttrib (which, "profile", profile?1:0);
0149   cSession *session = new cSession (which, d->widget);
0150   d->widget->addTab (session, i18n ("No connection"));
0151   setIcon (which, IconNo);
0152 
0153   // inform everyone
0154   d->am->invokeEvent ("session-created", 0, which);
0155   d->am->invokeEvent ("created", which);
0156   
0157   setSession (which);
0158   //just to be sure...
0159   cActionManager::self()->setActiveSession (which);
0160 
0161   //apply global settings to the newly created session
0162   //this also shows/hides the tabbar if needed
0163   cGlobalSettings::self()->notifyChange ();
0164 
0165   return which;
0166 }
0167 
0168 bool cSessionManager::removeSession (int which, bool dontClose)
0169 {
0170   if (KMuddy::isGoingDown())
0171     return false;
0172 
0173   //reconnect shortcut
0174   QString reconnectText = KMuddy::self()->reconnectText ();
0175   
0176   if (!d->am->sessionExists (which))
0177     return false;
0178 
0179   //now the special case - only one session; we do almost nothing!
0180   if (count() == 1)
0181   {
0182     setSessionName (which, i18n ("No connection"));
0183     //no connection...
0184     setIcon (which, IconNo);
0185     cConnection *connection = dynamic_cast<cConnection *>(d->am->object ("connection", which));
0186     connection->setConnectionClosed (false);
0187     connection->updateMenus ();
0188     d->am->invokeEvent ("message", which, reconnectText);
0189     if (!d->wantTabBar)
0190       d->widget->hideTabBar ();
0191     return true;
0192   }
0193 
0194   if (!dontClose)
0195   {
0196     //inform everyone
0197     d->am->invokeEvent ("session-destroyed", 0, which);
0198     d->am->invokeEvent ("destroyed", which);
0199     //remove widget
0200     d->widget->removeTab (getTabBySession (which));
0201     cSession *sess = dynamic_cast<cSession *>(d->am->object ("session", which));
0202     delete sess;
0203     d->am->unregisterSession (which);
0204 
0205     //hide the tabbar if needed
0206     if ((!d->wantTabBar) && (count() <= 1))
0207       d->widget->hideTabBar ();
0208   }
0209   else
0210   {
0211     setSessionName (which, i18n ("Connection closed."));
0212     setIcon (which, IconNo);
0213     cConnection *connection = dynamic_cast<cConnection *>(d->am->object ("connection", which));
0214     connection->setConnectionClosed (true);
0215     connection->updateMenus ();
0216     d->am->invokeEvent ("message", which, reconnectText);
0217   }
0218 
0219   return true;
0220 }
0221 
0222 void cSessionManager::setSession (int which)
0223 {
0224   if (!d->am->sessionExists (which))
0225     return;
0226   //this also invokes changeSession, which updates active session
0227   d->widget->setCurrentIndex (getTabBySession (which));
0228 }
0229 
0230 void cSessionManager::changeSession (int which)
0231 {
0232   d->am->invokeEvent ("deactivated", which);
0233   d->am->invokeEvent ("session-deactivated", 0, which);
0234 
0235   cActionManager::self()->setActiveSession (which);
0236 
0237   //disable flashing (if enabled)
0238   cSession *sess = dynamic_cast<cSession *>(d->am->object ("session", which));
0239   if (sess && sess->flashing())
0240   {
0241     sess->setFlashing (false);
0242 
0243     //if flashing was on, icon could be wrong - fix it
0244     cTelnet *telnet = dynamic_cast<cTelnet *>(d->am->object ("telnet", which));
0245     setIcon (which, telnet->isConnected () ? IconOk : IconNo);
0246   }
0247 
0248   d->am->invokeEvent ("session-activated", 0, which);
0249   d->am->invokeEvent ("activated", which);
0250 
0251   //global caption
0252   int tab = getTabBySession (which);
0253   KMuddy::self()->setCaption (d->widget->tabText (tab));
0254 
0255   //update menus (active items and such)
0256   int s = activeSession();
0257   cConnection *connection = dynamic_cast<cConnection *>(d->am->object ("connection", s));
0258   if (!connection) return; // session not initialised yet
0259   connection->updateMenus ();
0260 
0261   // update windows
0262   KMuddy::self()->updateWindows ();
0263 
0264   //give focus to the input line
0265   //cInputLine::focus[In/Out]Event also restores selections :)
0266   cInputLine *inputline = dynamic_cast<cInputLine *>(d->am->object ("inputline", s));
0267   inputline->setFocus ();
0268 }
0269 
0270 void cSessionManager::setSessionName (int which, QString name, bool defName)
0271 {
0272   cSession *sess = dynamic_cast<cSession *>(d->am->object ("session", which));
0273   sess->setName (name, defName);
0274   //update the name - maybe it wasn't changed?
0275   name = sess->name();
0276   int tab = getTabBySession (which);
0277   d->widget->setTabText (tab, name);
0278   //change icon to Ok (we'll change it later if it's not correct)
0279   setIcon (which, IconOk);
0280   if (which == activeSession ())
0281     KMuddy::self()->setCaption (name);
0282 }
0283 
0284 bool cSessionManager::alwaysTabBar ()
0285 {
0286   return d->wantTabBar;
0287 }
0288 
0289 void cSessionManager::setAlwaysTabBar (bool value)
0290 {
0291   d->wantTabBar = value;
0292   if (d->widget == nullptr)
0293     return;
0294   bool show = true;
0295   if ((!value) && (count() == 1)) show = false;
0296   show ? d->widget->showTabBar() : d->widget->hideTabBar();
0297 }
0298 
0299 void cSessionManager::setIcon (int sess, ProfileIcon icon)
0300 {
0301   int tab = getTabBySession (sess);
0302   QIcon i;
0303   switch (icon) {
0304     case IconOk: i = d->iconOk; break;
0305     case IconNo: i = d->iconNo; break;
0306     case IconFlag: i = d->iconFlag; break;
0307   }
0308   d->widget->setTabIcon (tab, i);
0309 }
0310 
0311 void cSessionManager::setNotifyFlag (int sess)
0312 {
0313   cSession *session = dynamic_cast<cSession *>(d->am->object ("session", sess));
0314   session->setFlashing (true);
0315 
0316   cConnection *connection = dynamic_cast<cConnection *>(d->am->object ("connection", sess));
0317   bool connClosed = connection->connectionClosed();
0318   setIcon (sess, connClosed ? IconNo : IconFlag);
0319 }
0320 
0321