#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())
msocket->close();
}
+MSessionClient* MSessionClient::instance()
+{
+ return sessionclientinstance;
+}
+
+
bool MSessionClient::isConnected() const
{
return msocket!=nullptr && msocket->isOpen();
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;
}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();
///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();
///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:
--- /dev/null
+//
+// 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
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);
#define PRESELECTLAST "preselectLast"
#define SELECTABLE "selectable/"
#define INMENU "inmenu/"
+#define INCLIENT "inclient/"
#define PRESELECTION "preselection"
#define PRESELECTCHANGE "preselectChange"
}
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());
}
}
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();
static bool selectable(QString client);
static bool inMenu(QString client);
+ static bool inClientMenu(QString client);
static bool preselectLast();
static QString preselection();
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
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");
}
</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>&Save</source>
<translation>&Speichern</translation>
</message>
<message>
- <location filename="login.cpp" line="281"/>
+ <location filename="login.cpp" line="286"/>
<source>&Cancel</source>
<translation>&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>&Configuration...</source>
<translation>&Konfigurieren...</translation>
</message>
<message>
- <location filename="sman.cpp" line="333"/>
+ <location filename="sman.cpp" line="334"/>
<source>Start &Expert Client</source>
<translation>Starte &Experten-Programm</translation>
</message>
<message>
- <location filename="sman.cpp" line="334"/>
+ <location filename="sman.cpp" line="335"/>
<source>Start &Wizard</source>
<translation>Starte &Wizard</translation>
</message>
<message>
- <location filename="sman.cpp" line="335"/>
+ <location filename="sman.cpp" line="336"/>
<source>Start &Statistics Client</source>
<translation>Starte &Statistik-Programm</translation>
</message>
<message>
- <location filename="sman.cpp" line="336"/>
+ <location filename="sman.cpp" line="337"/>
<source>Start &Print@Home Daemon</source>
<translation>Starte &Print@Home Hintergrundprogramm</translation>
</message>
<message>
- <location filename="sman.cpp" line="337"/>
+ <location filename="sman.cpp" line="338"/>
<source>&Quit Session</source>
<translation>Session &Beenden</translation>
</message>
</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>&Save</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="login.cpp" line="281"/>
+ <location filename="login.cpp" line="286"/>
<source>&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>&Configuration...</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="sman.cpp" line="333"/>
+ <location filename="sman.cpp" line="334"/>
<source>Start &Expert Client</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="sman.cpp" line="334"/>
+ <location filename="sman.cpp" line="335"/>
<source>Start &Wizard</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="sman.cpp" line="335"/>
+ <location filename="sman.cpp" line="336"/>
<source>Start &Statistics Client</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="sman.cpp" line="336"/>
+ <location filename="sman.cpp" line="337"/>
<source>Start &Print@Home Daemon</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="sman.cpp" line="337"/>
+ <location filename="sman.cpp" line="338"/>
<source>&Quit Session</source>
<translation type="unfinished"></translation>
</message>
#include "MTBackup"
#include "MTGetAllUsers"
+#include "sclimenu.h"
+
MOverview::MOverview(QString pk)
:MTabWin(pk),entrancetab(nullptr)
{
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);