diff --git a/src/layout.cpp b/src/layout.cpp index d37f2cd..de64f46 100644 --- a/src/layout.cpp +++ b/src/layout.cpp @@ -2,27 +2,38 @@ #include //initialize things and set up an icon :) -LayoutManager::LayoutManager( bool useTrayIcon, const QString &devdir, const QString &settingsDir ) : devdir(devdir), settingsDir(settingsDir), le(0) { +LayoutManager::LayoutManager( bool useTrayIcon, const QString &devdir, const QString &settingsDir ) + : devdir(devdir), settingsDir(settingsDir), + layoutGroup(new QActionGroup(this)), + titleAction(new QAction(this)), + updateDevicesAction(new QAction("Update &Joystick Devices",this)), + updateLayoutsAction(new QAction("Update &Layout List",this)), + quitAction(new QAction("&Quit",this)), + le(0) { //prepare the popup first. + titleAction->setEnabled(false); fillPopup(); - connect(&trayMenuPopup,SIGNAL(triggered(QAction*)),this, SLOT(trayMenu(QAction*))); //make a tray icon if (useTrayIcon) { QSystemTrayIcon *tray = new QSystemTrayIcon(this); - tray->setContextMenu(&trayMenuPopup); + tray->setContextMenu(&trayMenu); tray->setIcon(QIcon(ICON24)); tray->show(); connect(tray, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayClick(QSystemTrayIcon::ActivationReason))); } //or make a floating icon else { - FloatingIcon* icon = new FloatingIcon(QPixmap(ICON64),&trayMenuPopup,0,"tray"); + FloatingIcon* icon = new FloatingIcon(QPixmap(ICON64),&trayMenu,0,"tray"); connect(icon, SIGNAL( clicked()), this, SLOT( iconClick())); connect(icon, SIGNAL( closed()), qApp, SLOT( quit())); icon->show(); } + connect(updateLayoutsAction, SIGNAL(triggered()), this, SLOT(fillPopup())); + connect(updateDevicesAction, SIGNAL(triggered()), this, SLOT(updateJoyDevs())); + connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + //no layout loaded at start. setLayoutName(NL); } @@ -289,52 +300,53 @@ void LayoutManager::trayClick(QSystemTrayIcon::ActivationReason reason) { } } -void LayoutManager::trayMenu(QAction *menuItemAction) { +void LayoutManager::layoutTriggered() { + QAction *action = qobject_cast(sender()); //if they clicked on a Layout name, load it! - //note that the other options are handled with their own special functions - if (trayMenuPopup.actions().indexOf(menuItemAction) > 1 && menuItemAction->text() != "Quit" && - menuItemAction->text() != "Update layout list" && - menuItemAction->text() != "Update joystick devices") { - load(menuItemAction->text()); + if (action) { + load(action->data().toString()); } } void LayoutManager::fillPopup() { //start with an empty slate - trayMenuPopup.clear(); + trayMenu.clear(); //make a list of joystick devices - QString devs = "Joysticks: "; + QString title = "Joysticks: "; foreach (JoyPad *joypad, available) { - devs += QString("%1 ").arg(joypad->getIndex() + 1); + title += QString("%1 ").arg(joypad->getIndex() + 1); } - QAction *temp = trayMenuPopup.addAction(devs); - trayMenuPopup.addSeparator(/*temp*/); + trayMenu.setTitle(title); + titleAction->setText(title); + trayMenu.addAction(titleAction); + trayMenu.addSeparator(); //add in the Update options - QAction *tempAdd = new QAction("Update layout list", this); - connect(tempAdd, SIGNAL(triggered(bool)), this, SLOT(fillPopup())); - trayMenuPopup.addAction(tempAdd); - tempAdd = new QAction("Update joystick devices", this); - connect(tempAdd, SIGNAL(triggered(bool)), this, SLOT(updateJoyDevs())); - trayMenuPopup.addAction(tempAdd); - trayMenuPopup.addSeparator(/*temp*/); + trayMenu.addAction(updateLayoutsAction); + trayMenu.addAction(updateDevicesAction); + trayMenu.addSeparator(); //then add all the layout names QStringList names = getLayoutNames(); foreach (const QString &name, names) { - temp = trayMenuPopup.addAction(name); - temp->setCheckable(true); + QString title = name; + title.replace('&',"&&"); + QAction *action = trayMenu.addAction(title); + action->setData(name); + action->setCheckable(true); + action->setActionGroup(layoutGroup); //put a check by the current one ;) if (currentLayout == name) { - temp->setChecked(true); + action->setChecked(true); } + connect(action, SIGNAL(triggered()), this, SLOT(layoutTriggered())); } - trayMenuPopup.addSeparator(); + trayMenu.addSeparator(); //and, at the end, quit! - trayMenuPopup.addAction("Quit",qApp,SLOT(quit())); + trayMenu.addAction(quitAction); } void LayoutManager::updateJoyDevs() { diff --git a/src/layout.h b/src/layout.h index 42e551a..7205b86 100644 --- a/src/layout.h +++ b/src/layout.h @@ -62,12 +62,13 @@ class LayoutManager : public QObject { //when the tray icon is clicked void iconClick(); void trayClick(QSystemTrayIcon::ActivationReason reason); - //when the user selects an item on the tray's popup menu - void trayMenu(QAction* menuItemAction); //rebuild the popup menu with the current information void fillPopup(); //update the list of available joystick devices void updateJoyDevs(); + private slots: + //when the user selects an item on the tray's popup menu + void layoutTriggered(); private: //change to the given layout name and make all the necesary adjustments void setLayoutName(QString name); @@ -79,7 +80,13 @@ class LayoutManager : public QObject { //the layout that is currently in use QString currentLayout; //the popup menu from the tray/floating icon - QMenu trayMenuPopup; + QMenu trayMenu; + //known actions for the popup menu + QActionGroup *layoutGroup; + QAction *titleAction; + QAction *updateDevicesAction; + QAction *updateLayoutsAction; + QAction *quitAction; //if there is a LayoutEdit open, this points to it. Otherwise, NULL. QPointer le; diff --git a/src/main.cpp b/src/main.cpp index a9283b3..973f904 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,14 +21,14 @@ //variables needed in various functions in this file QPointer layoutManagerPtr; -//signal handler for SIGIO -//SIGIO means that a new layout should be loaded. It is saved in +//signal handler for SIGUSR2 +//SIGUSR2 means that a new layout should be loaded. It is saved in // ~/.qjoypad/layout, where the last used layout is put. -void catchSIGIO( int sig ) +void catchSIGUSR2( int sig ) { if (layoutManagerPtr) layoutManagerPtr->load(); //remember to catch this signal again next time. - signal( sig, catchSIGIO ); + signal( sig, catchSIGUSR2 ); } @@ -43,15 +43,6 @@ void catchSIGUSR1( int sig ) { } -/* A new feature to add? We'll see. -void catchSIGUSR2( int sig ) { - lm->trayClick(); - signal( sig, catchSIGUSR2 ); -} -*/ - - - int main( int argc, char **argv ) { //create a new event loop. This will be captured by the QApplication @@ -171,8 +162,7 @@ int main( int argc, char **argv ) QFile file( settingsDir + "layout"); if (file.open(QIODevice::WriteOnly)) { - QTextStream stream( &file ); - stream << layout; + QTextStream( &file ) << layout; file.close(); } } @@ -205,7 +195,7 @@ int main( int argc, char **argv ) if (update == true) kill(pid,SIGUSR1); if (!layout.isEmpty()) - kill(pid,SIGIO); + kill(pid,SIGUSR2); } //and quit. We don't need two instances. return 0; @@ -219,7 +209,7 @@ int main( int argc, char **argv ) pidFile.close(); } - if(forceTrayIcon) { + if (forceTrayIcon) { int sleepCounter = 0; while(!QSystemTrayIcon::isSystemTrayAvailable()) { sleep(1); @@ -243,9 +233,8 @@ int main( int argc, char **argv ) layoutManager.load(); //prepare the signal handlers - signal( SIGIO, catchSIGIO ); signal( SIGUSR1, catchSIGUSR1 ); -// signal( SIGUSR2, catchSIGUSR2 ); + signal( SIGUSR2, catchSIGUSR2 ); //and run the program! int result = app.exec();