Add client session menu
authorKonrad Rosenbaum <konrad@silmor.de>
Mon, 11 Jul 2016 10:55:21 +0000 (12:55 +0200)
committerKonrad Rosenbaum <konrad@silmor.de>
Mon, 11 Jul 2016 10:55:21 +0000 (12:55 +0200)
sesscli/scli.cpp
sesscli/scli.h
sesscli/sclimenu.h [new file with mode: 0644]
sessman/login.cpp
sessman/login.h
sessman/sman.cpp
sessman/smoke-sm_de.ts
sessman/smoke-sm_en.ts
src/mwin/overview.cpp

index 5bf5751..c6751d9 100644 (file)
 #include <QCoreApplication>
 #include <QEventLoop>
 #include <QLocalServer>
+#include <QPointer>
 #include <QProcess>
 #include <QRegExp>
 #include <QStringList>
 #include <QTimer>
 
+static QPointer<MSessionClient> sessionclientinstance;
+
 MSessionClient::MSessionClient()
 {
+       sessionclientinstance=this;
        //check parameters for socket name
        QString sms;
        for(QString arg:qApp->arguments())
@@ -94,6 +98,12 @@ MSessionClient::~MSessionClient()
                msocket->close();
 }
 
+MSessionClient* MSessionClient::instance()
+{
+       return sessionclientinstance;
+}
+
+
 bool MSessionClient::isConnected() const
 {
        return msocket!=nullptr && msocket->isOpen();
@@ -160,11 +170,11 @@ void MSessionClient::socketLost()
 
 void MSessionClient::readSocket()
 {
-       while(msocket->canReadLine()){
+       while(msocket && msocket->canReadLine()){
                const QString line=QString::fromUtf8(msocket->readLine()).trimmed();
                const int pos=line.indexOf(' ');
                const QString cmd=pos>0?line.left(pos):line;
-               const QString par=pos>0?line.mid(pos+1):QString();
+               const QString par=pos>0?line.mid(pos+1).trimmed():QString();
                qDebug()<<"Received session manager command"<<cmd<<"with param"<<(cmd!="sid"?par:"(censored)");
                if(cmd=="sid"){
                        msid=par;
@@ -179,6 +189,12 @@ void MSessionClient::readSocket()
                }else if(cmd=="newmenu"){
                        mmenu.clear();
                }else if(cmd=="menu"){
+                       const int pos=par.indexOf(' ');
+                       if(pos<2){
+                               qDebug()<<"Warning: received invalid menu command. Ignoring it.";
+                               continue;
+                       }
+                       mmenu.append(QPair<QString,QString>(par.left(pos),par.mid(pos+1)));
                }else if(cmd=="endmenu"){
                        qDebug()<<"New Menu received from Session Manager!";
                        emit menuChanged();
index 5a874ae..0fafdae 100644 (file)
@@ -34,6 +34,10 @@ public:
        ///Disconnect the session client.
        virtual ~MSessionClient();
 
+       ///returns the current instance of the Session Client class
+       ///returns nullptr if there is no instance
+       static MSessionClient*instance();
+
        ///Wait until a session is available or the Session Manager quits.
        ///\returns true if a session is available, false on error
        virtual bool waitForSessionAvailable();
@@ -49,6 +53,7 @@ public:
        ///Returns true if the client is connected to a manager. If false there is something wrong.
        virtual bool isConnected()const;
 
+       ///retrieves and returns the menu entries of the session manager
        virtual QList<QPair<QString,QString>> menuEntries()const;
 
 public slots:
diff --git a/sesscli/sclimenu.h b/sesscli/sclimenu.h
new file mode 100644 (file)
index 0000000..c1382f4
--- /dev/null
@@ -0,0 +1,44 @@
+//
+// C++ Interface: Session Client
+//
+// Description: Session Client Menu Convenience Function.
+//
+//
+// Author: Konrad Rosenbaum <konrad@silmor.de>, (C) 2016
+//
+// Copyright: See README/COPYING.GPL files that come with this distribution
+//
+//
+
+#ifndef MAGICSMOKE_SC_SCLIMENU_H
+#define MAGICSMOKE_SC_SCLIMENU_H
+
+#include "scli.h"
+#include <QMenu>
+#include <QSignalMapper>
+#include <QAction>
+
+
+///creates a menu that allows (limited) control over the session manager
+///returns nullptr if the menu could not be retrieved
+///\param menu if not NULL: the menu to fill, if NULL: a new menu will be created, please do not forget to take ownership of the new menu
+inline QMenu* MSessionClient_createMenuObject(QMenu*menu=nullptr)
+{
+       //retrieve if necessary
+       auto inst=MSessionClient::instance();
+       auto mmenu=inst->menuEntries();
+       if(mmenu.isEmpty())return nullptr;
+       //generate menu
+       QMenu*m=menu?menu:new QMenu;
+       QSignalMapper*sm=new QSignalMapper(m);
+       for(auto entry:mmenu){
+               QAction*a=m->addAction(entry.second,sm,SLOT(map()));
+               sm->setMapping(a,entry.first);
+       }
+       QObject::connect(sm,SIGNAL(mapped(QString)),inst,SLOT(execServerCommand(QString)));
+       return m;
+}
+
+
+
+#endif
index b91ef90..9976746 100644 (file)
@@ -256,16 +256,21 @@ MClientConfig::MClientConfig ( QWidget* parent, Qt::WindowFlags f ) : QDialog (
                mpresel->addItem(entry.second.remove('&'),entry.first);
                //choices
                fl->addRow(entry.second,hl=new QHBoxLayout);
-               QCheckBox*m,*p;
+               QCheckBox*m,*p,*c;
                hl->addWidget(p=new QCheckBox(tr("Show in Preselection")));
                p->setChecked(selectable(entry.first));
                QFrame*f;
                hl->addWidget(f=new QFrame);
                f->setFrameShadow(QFrame::Sunken);
                f->setFrameShape(QFrame::VLine);
-               hl->addWidget(m=new QCheckBox(tr("Show in Menu")));
+               hl->addWidget(m=new QCheckBox(tr("Show in Tray Menu")));
                m->setChecked(inMenu(entry.first));
-               mclients.insert(entry.first,QPair<QCheckBox*,QCheckBox*>(m,p));
+               hl->addWidget(f=new QFrame);
+               f->setFrameShadow(QFrame::Sunken);
+               f->setFrameShape(QFrame::VLine);
+               hl->addWidget(c=new QCheckBox(tr("Show in Client Menu")));
+               c->setChecked(inClientMenu(entry.first));
+               mclients.insert(entry.first,s_checkbox(m,p,c));
        }
        if(!preselectLast()&&pos>=0)
                mpresel->setCurrentIndex(pos);
@@ -286,6 +291,7 @@ MClientConfig::MClientConfig ( QWidget* parent, Qt::WindowFlags f ) : QDialog (
 #define PRESELECTLAST "preselectLast"
 #define SELECTABLE "selectable/"
 #define INMENU "inmenu/"
+#define INCLIENT "inclient/"
 #define PRESELECTION "preselection"
 #define PRESELECTCHANGE "preselectChange"
 
@@ -304,8 +310,9 @@ void MClientConfig::saveData()
        }
 
        for(QString k:mclients.keys()){
-               set.setValue(CCFG_SETTINGS INMENU + k,mclients[k].first->isChecked());
-               set.setValue(CCFG_SETTINGS SELECTABLE + k,mclients[k].second->isChecked());
+               set.setValue(CCFG_SETTINGS INMENU + k,mclients[k].menu->isChecked());
+               set.setValue(CCFG_SETTINGS SELECTABLE + k,mclients[k].presel->isChecked());
+               set.setValue(CCFG_SETTINGS INCLIENT + k,mclients[k].client->isChecked());
        }
 }
 
@@ -324,6 +331,11 @@ bool MClientConfig::inMenu ( QString client )
        return QSettings().value(CCFG_SETTINGS INMENU + client ,true).toBool();
 }
 
+bool MClientConfig::inClientMenu ( QString client )
+{
+       return QSettings().value(CCFG_SETTINGS INCLIENT + client ,true).toBool();
+}
+
 QString MClientConfig::preselection()
 {
        return QSettings().value(CCFG_SETTINGS PRESELECTION,"").toString();
index d8943d1..5527ea9 100644 (file)
@@ -67,6 +67,7 @@ public:
 
        static bool selectable(QString client);
        static bool inMenu(QString client);
+       static bool inClientMenu(QString client);
 
        static bool preselectLast();
        static QString preselection();
@@ -78,7 +79,16 @@ private slots:
 private:
        QCheckBox*mallowchange;
        QComboBox*mpresel;
-       QMap<QString,QPair<QCheckBox*,QCheckBox*>>mclients;
+       struct s_checkbox{
+               QCheckBox*presel=nullptr,*menu=nullptr,*client=nullptr;
+               s_checkbox(){}
+               s_checkbox(QCheckBox*m,QCheckBox*p,QCheckBox*c):presel(p),menu(m),client(c){}
+               s_checkbox(const s_checkbox&)=default;
+               s_checkbox(s_checkbox&&)=default;
+               s_checkbox& operator=(const s_checkbox&)=default;
+               s_checkbox& operator=(s_checkbox&&)=default;
+       };
+       QMap<QString,s_checkbox>mclients;
 };
 
 #endif
index 36de1bf..eff6959 100644 (file)
@@ -238,7 +238,8 @@ void MSessionManager::sendMenu(QLocalSocket*s)
        s->write("newmenu\n");
        //send "menu command entry-text" for each entry
        for(auto entry:menuItems())
-               s->write(QString("menu %1 %2\n").arg(entry.first).arg(entry.second).toUtf8());
+               if(MClientConfig::inClientMenu(entry.first))
+                       s->write(QString("menu %1 %2\n").arg(entry.first).arg(entry.second).toUtf8());
        s->write("endmenu\n");
 }
 
index 2276be9..71a2c13 100644 (file)
     </message>
     <message>
         <location filename="login.cpp" line="266"/>
-        <source>Show in Menu</source>
-        <translation>In Kontextmenü zeigen</translation>
+        <source>Show in Tray Menu</source>
+        <oldsource>Show in Menu</oldsource>
+        <translation>In SysTray-Menü zeigen</translation>
     </message>
     <message>
-        <location filename="login.cpp" line="277"/>
+        <location filename="login.cpp" line="271"/>
+        <source>Show in Client Menu</source>
+        <translation>In Client-Programm-Menü zeigen</translation>
+    </message>
+    <message>
+        <location filename="login.cpp" line="282"/>
         <source>&amp;Save</source>
         <translation>&amp;Speichern</translation>
     </message>
     <message>
-        <location filename="login.cpp" line="281"/>
+        <location filename="login.cpp" line="286"/>
         <source>&amp;Cancel</source>
         <translation>&amp;Abbrechen</translation>
     </message>
         <translation>MagicSmoke Session Manager, warte auf Login...</translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="267"/>
+        <location filename="sman.cpp" line="268"/>
         <source>Warning</source>
         <translation>Warnung</translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="267"/>
+        <location filename="sman.cpp" line="268"/>
         <source>Cannot start a client while not logged in!</source>
         <translation>Programm kann nicht gestartet werden wenn noch kein Login besteht!</translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="298"/>
+        <location filename="sman.cpp" line="299"/>
         <source>MagicSmoke Session Manager, logged in as %1 at %2.</source>
         <translation>MagicSmoke Session Manager, eingeloggt als %1 auf Profil %2.</translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="332"/>
+        <location filename="sman.cpp" line="333"/>
         <source>&amp;Configuration...</source>
         <translation>&amp;Konfigurieren...</translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="333"/>
+        <location filename="sman.cpp" line="334"/>
         <source>Start &amp;Expert Client</source>
         <translation>Starte &amp;Experten-Programm</translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="334"/>
+        <location filename="sman.cpp" line="335"/>
         <source>Start &amp;Wizard</source>
         <translation>Starte &amp;Wizard</translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="335"/>
+        <location filename="sman.cpp" line="336"/>
         <source>Start &amp;Statistics Client</source>
         <translation>Starte &amp;Statistik-Programm</translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="336"/>
+        <location filename="sman.cpp" line="337"/>
         <source>Start &amp;Print@Home Daemon</source>
         <translation>Starte &amp;Print@Home Hintergrundprogramm</translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="337"/>
+        <location filename="sman.cpp" line="338"/>
         <source>&amp;Quit Session</source>
         <translation>Session &amp;Beenden</translation>
     </message>
index 1b2b2f8..a9a1cc4 100644 (file)
     </message>
     <message>
         <location filename="login.cpp" line="266"/>
-        <source>Show in Menu</source>
+        <source>Show in Tray Menu</source>
+        <oldsource>Show in Menu</oldsource>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="login.cpp" line="277"/>
+        <location filename="login.cpp" line="271"/>
+        <source>Show in Client Menu</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="login.cpp" line="282"/>
         <source>&amp;Save</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="login.cpp" line="281"/>
+        <location filename="login.cpp" line="286"/>
         <source>&amp;Cancel</source>
         <translation type="unfinished"></translation>
     </message>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="267"/>
+        <location filename="sman.cpp" line="268"/>
         <source>Warning</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="267"/>
+        <location filename="sman.cpp" line="268"/>
         <source>Cannot start a client while not logged in!</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="298"/>
+        <location filename="sman.cpp" line="299"/>
         <source>MagicSmoke Session Manager, logged in as %1 at %2.</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="332"/>
+        <location filename="sman.cpp" line="333"/>
         <source>&amp;Configuration...</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="333"/>
+        <location filename="sman.cpp" line="334"/>
         <source>Start &amp;Expert Client</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="334"/>
+        <location filename="sman.cpp" line="335"/>
         <source>Start &amp;Wizard</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="335"/>
+        <location filename="sman.cpp" line="336"/>
         <source>Start &amp;Statistics Client</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="336"/>
+        <location filename="sman.cpp" line="337"/>
         <source>Start &amp;Print@Home Daemon</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="sman.cpp" line="337"/>
+        <location filename="sman.cpp" line="338"/>
         <source>&amp;Quit Session</source>
         <translation type="unfinished"></translation>
     </message>
index e4cc47c..caf0881 100644 (file)
@@ -67,6 +67,8 @@
 #include "MTBackup"
 #include "MTGetAllUsers"
 
+#include "sclimenu.h"
+
 MOverview::MOverview(QString pk)
        :MTabWin(pk),entrancetab(nullptr)
 {
@@ -148,6 +150,8 @@ MOverview::MOverview(QString pk)
        m2->addAction(tr("&OpenOffice settings..."),this,SLOT(openOfficeSettings()));
        m2->addAction(tr("&Barcode Scanner settings..."),this,SLOT(barcodeSettings()));
 
+       MSessionClient_createMenuObject(m->addMenu(tr("&Session Manager")));
+
        //make sure webrequest knows its settings
        webSettings(false);