ckb-next  beta-v0.2.8 at branch testing
ckb-next driver for corsair devices
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MainWindow Class Reference

#include <src/ckb/mainwindow.h>

+ Inheritance diagram for MainWindow:
+ Collaboration diagram for MainWindow:

Public Slots

void showWindow ()
 
void stateChange (Qt::ApplicationState state)
 
void quitApp ()
 

Public Member Functions

 MainWindow (QWidget *parent=0)
 
 ~MainWindow ()
 
void toggleTrayIcon (bool visible)
 

Static Public Attributes

static MainWindowmainWindow = 0
 

Private Slots

void addDevice (Kb *device)
 
void removeDevice (Kb *device)
 
void updateVersion ()
 
void checkFwUpdates ()
 
void timerTick ()
 
void iconClicked (QSystemTrayIcon::ActivationReason reason)
 
void cleanup ()
 
void showFwUpdateNotification (QWidget *widget, float version)
 

Private Member Functions

void closeEvent (QCloseEvent *event)
 

Private Attributes

SettingsWidgetsettingsWidget
 
QList< KbWidget * > kbWidgets
 
QAction * restoreAction
 
QAction * closeAction
 
QMenu * trayIconMenu
 
QSystemTrayIcon * trayIcon
 
Ui::MainWindowui
 

Detailed Description

Definition at line 27 of file mainwindow.h.

Constructor & Destructor Documentation

MainWindow::MainWindow ( QWidget parent = 0)
explicit

Definition at line 35 of file mainwindow.cpp.

References Ui_MainWindow::actionExit, addDevice(), cleanup(), closeAction, configLabel, CkbSettings::get(), iconClicked(), KbManager::init(), KbManager::kbManager(), mainWindow, quitApp(), removeDevice(), restoreAction, KbManager::scanTimer(), settingsWidget, Ui_MainWindow::setupUi(), SettingsWidget::setVersion(), showWindow(), stateChange(), Ui_MainWindow::tabWidget, timerTick(), toggleTrayIcon(), trayIcon, trayIconMenu, ui, and updateVersion().

35  :
36  QMainWindow(parent),
37  ui(new Ui::MainWindow)
38 {
39  ui->setupUi(this);
40  mainWindow = this;
41 
42  // Start device manager
43  KbManager::init(CKB_VERSION_STR);
44  connect(KbManager::kbManager(), SIGNAL(kbConnected(Kb*)), this, SLOT(addDevice(Kb*)));
45  connect(KbManager::kbManager(), SIGNAL(kbDisconnected(Kb*)), this, SLOT(removeDevice(Kb*)));
46  connect(KbManager::kbManager(), SIGNAL(versionUpdated()), this, SLOT(updateVersion()));
47  connect(KbManager::scanTimer(), SIGNAL(timeout()), this, SLOT(timerTick()));
48 
49  // Set up tray icon
50  restoreAction = new QAction(tr("Restore"), this);
51  closeAction = new QAction(tr("Quit ckb"), this);
52 #ifdef USE_LIBAPPINDICATOR
53  QString desktop = std::getenv("XDG_CURRENT_DESKTOP");
54  unityDesktop = (desktop.toLower() == "unity");
55 
56  if(unityDesktop){
57  trayIcon = 0;
58 
59  indicatorMenu = gtk_menu_new();
60  indicatorMenuRestoreItem = gtk_menu_item_new_with_label("Restore");
61  indicatorMenuQuitItem = gtk_menu_item_new_with_label("Quit ckb");
62 
63  gtk_menu_shell_append(GTK_MENU_SHELL(indicatorMenu), indicatorMenuRestoreItem);
64  gtk_menu_shell_append(GTK_MENU_SHELL(indicatorMenu), indicatorMenuQuitItem);
65 
66  g_signal_connect(indicatorMenuQuitItem, "activate",
67  G_CALLBACK(quitIndicator), this);
68  g_signal_connect(indicatorMenuRestoreItem, "activate",
69  G_CALLBACK(restoreIndicator), this);
70 
71  gtk_widget_show(indicatorMenuRestoreItem);
72  gtk_widget_show(indicatorMenuQuitItem);
73 
74  indicator = app_indicator_new("ckb", "indicator-messages", APP_INDICATOR_CATEGORY_APPLICATION_STATUS);
75 
76  app_indicator_set_status(indicator, APP_INDICATOR_STATUS_ACTIVE);
77  app_indicator_set_menu(indicator, GTK_MENU(indicatorMenu));
78  app_indicator_set_icon(indicator, "ckb");
79  } else
80 #endif // USE_LIBAPPINDICATOR
81  {
82  trayIconMenu = new QMenu(this);
83  trayIconMenu->addAction(restoreAction);
84  trayIconMenu->addAction(closeAction);
85  trayIcon = new QSystemTrayIcon(QIcon(":/img/ckb-logo.png"), this);
86  trayIcon->setContextMenu(trayIconMenu);
87  connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconClicked(QSystemTrayIcon::ActivationReason)));
88  }
89  toggleTrayIcon(!CkbSettings::get("Program/SuppressTrayIcon").toBool());
90 
91 #ifdef Q_OS_MACX
92  // Make a custom "Close" menu action for OSX, as the default one brings up the "still running" popup unnecessarily
93  QMenuBar* menuBar = new QMenuBar(this);
94  setMenuBar(menuBar);
95  this->menuBar()->addMenu("ckb")->addAction(closeAction);
96 #else
97  // On linux, add a handler for Ctrl+Q
98  new QShortcut(QKeySequence("Ctrl+Q"), this, SLOT(quitApp()));
99 #endif
100 
101  connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(quitApp()));
102  connect(closeAction, SIGNAL(triggered()), this, SLOT(quitApp()));
103  connect(restoreAction, SIGNAL(triggered()), this, SLOT(showWindow()));
104  connect(qApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(stateChange(Qt::ApplicationState)));
105 
106  connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(cleanup()));
107 
108  ui->tabWidget->addTab(settingsWidget = new SettingsWidget(this), configLabel);
109  settingsWidget->setVersion("ckb-next " CKB_VERSION_STR);
110 }
void stateChange(Qt::ApplicationState state)
Definition: mainwindow.cpp:276
static KbManager * kbManager()
Definition: kbmanager.h:23
Ui::MainWindow * ui
Definition: mainwindow.h:75
void cleanup()
Definition: mainwindow.cpp:295
void quitApp()
Definition: mainwindow.cpp:291
void showWindow()
Definition: mainwindow.cpp:270
static QVariant get(const QString &key, const QVariant &defaultValue=QVariant())
void toggleTrayIcon(bool visible)
Definition: mainwindow.cpp:112
void removeDevice(Kb *device)
Definition: mainwindow.cpp:139
QMenu * trayIconMenu
Definition: mainwindow.h:53
static QTimer * scanTimer()
Definition: kbmanager.h:43
QAction * restoreAction
Definition: mainwindow.h:43
static const QString configLabel
Definition: mainwindow.cpp:15
void updateVersion()
Definition: mainwindow.cpp:153
Definition: kb.h:11
static void init(QString guiVersion)
Definition: kbmanager.cpp:12
QSystemTrayIcon * trayIcon
Definition: mainwindow.h:54
static MainWindow * mainWindow
Definition: mainwindow.h:35
QTabWidget * tabWidget
Definition: ui_mainwindow.h:31
void setVersion(const QString &version)
void setupUi(QMainWindow *MainWindow)
Definition: ui_mainwindow.h:33
void iconClicked(QSystemTrayIcon::ActivationReason reason)
Definition: mainwindow.cpp:257
QAction * closeAction
Definition: mainwindow.h:44
SettingsWidget * settingsWidget
Definition: mainwindow.h:40
void timerTick()
Definition: mainwindow.cpp:223
void addDevice(Kb *device)
Definition: mainwindow.cpp:121
QAction * actionExit
Definition: ui_mainwindow.h:27

+ Here is the call graph for this function:

MainWindow::~MainWindow ( )

Definition at line 303 of file mainwindow.cpp.

References cleanup(), and ui.

303  {
304  cleanup();
305  delete ui;
306 }
Ui::MainWindow * ui
Definition: mainwindow.h:75
void cleanup()
Definition: mainwindow.cpp:295

+ Here is the call graph for this function:

Member Function Documentation

void MainWindow::addDevice ( Kb device)
privateslot

Definition at line 121 of file mainwindow.cpp.

References KbWidget::device, kbWidgets, KbWidget::name(), Ui_MainWindow::tabWidget, ui, and updateVersion().

Referenced by MainWindow().

121  {
122  // Connected already?
123  foreach(KbWidget* w, kbWidgets){
124  if(w->device == device)
125  return;
126  }
127  // Add the keyboard
128  KbWidget* widget = new KbWidget(this, device);
129  kbWidgets.append(widget);
130  // Add to tabber; switch to this device if on the settings screen
131  int count = ui->tabWidget->count();
132  ui->tabWidget->insertTab(count - 1, widget, widget->name());
133  if(ui->tabWidget->currentIndex() == count)
134  ui->tabWidget->setCurrentIndex(count - 1);
135  // Update connected device count
136  updateVersion();
137 }
Ui::MainWindow * ui
Definition: mainwindow.h:75
QString name() const
Definition: kbwidget.h:25
void updateVersion()
Definition: mainwindow.cpp:153
QTabWidget * tabWidget
Definition: ui_mainwindow.h:31
QList< KbWidget * > kbWidgets
Definition: mainwindow.h:41
Kb * device
Definition: kbwidget.h:24

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MainWindow::checkFwUpdates ( )
privateslot

Definition at line 172 of file mainwindow.cpp.

References KbWidget::device, Kb::features, Kb::firmware, KbWidget::hasShownNewFW, kbWidgets, mainWindow, KbWidget::updateFwButton(), and KbFirmware::versionForBoard().

Referenced by timerTick().

172  {
173  if(!mainWindow->isVisible())
174  return;
175  foreach(KbWidget* w, kbWidgets){
176  // Display firmware upgrade notification if a new version is available
177  float version = KbFirmware::versionForBoard(w->device->features);
178  if(version > w->device->firmware.toFloat()){
179  if(w->hasShownNewFW)
180  continue;
181  w->hasShownNewFW = true;
182  w->updateFwButton();
183  // Don't run this method here because it will lock up the timer and prevent devices from working properly
184  // Use a queued invocation instead
185  metaObject()->invokeMethod(this, "showFwUpdateNotification", Qt::QueuedConnection, Q_ARG(QWidget*, w), Q_ARG(float, version));
186  // Don't display more than one of these at once
187  return;
188  }
189  }
190 }
void updateFwButton()
Definition: kbwidget.cpp:326
QString firmware
Definition: kb.h:18
bool hasShownNewFW
Definition: kbwidget.h:28
static MainWindow * mainWindow
Definition: mainwindow.h:35
QString features
Definition: kb.h:18
QList< KbWidget * > kbWidgets
Definition: mainwindow.h:41
Kb * device
Definition: kbwidget.h:24
static float versionForBoard(const QString &features, bool waitForComplete=false)
Definition: kbfirmware.h:22

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MainWindow::cleanup ( )
privateslot

Definition at line 295 of file mainwindow.cpp.

References CkbSettings::cleanUp(), kbWidgets, and KbManager::stop().

Referenced by MainWindow(), and ~MainWindow().

295  {
296  foreach(KbWidget* w, kbWidgets)
297  delete w;
298  kbWidgets.clear();
299  KbManager::stop();
301 }
static void stop()
Definition: kbmanager.cpp:19
static void cleanUp()
Definition: ckbsettings.cpp:46
QList< KbWidget * > kbWidgets
Definition: mainwindow.h:41

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MainWindow::closeEvent ( QCloseEvent *  event)
private

Definition at line 209 of file mainwindow.cpp.

References CkbSettings::get(), and CkbSettings::set().

209  {
210  // If the window is hidden already or the event is non-spontaneous (can happen on OSX when using the Quit menu), accept it and close
211  if(!event->spontaneous() || isHidden()){
212  event->accept();
213  return;
214  }
215  if(!CkbSettings::get("Popups/BGWarning").toBool()){
216  QMessageBox::information(this, "ckb", "ckb will still run in the background.\nTo close it, choose Exit from the tray menu\nor click \"Quit ckb\" on the Settings screen.");
217  CkbSettings::set("Popups/BGWarning", true);
218  }
219  hide();
220  event->ignore();
221 }
static void set(const QString &key, const QVariant &value)
static QVariant get(const QString &key, const QVariant &defaultValue=QVariant())

+ Here is the call graph for this function:

void MainWindow::iconClicked ( QSystemTrayIcon::ActivationReason  reason)
privateslot

Definition at line 257 of file mainwindow.cpp.

References showWindow().

Referenced by MainWindow().

257  {
258  // On Linux, hide/show the app when the tray icon is clicked
259  // On OSX this just shows the menu
260 #ifndef Q_OS_MACX
261  if(reason == QSystemTrayIcon::DoubleClick || reason == QSystemTrayIcon::Trigger){
262  if(isVisible())
263  hide();
264  else
265  showWindow();
266  }
267 #endif
268 }
void showWindow()
Definition: mainwindow.cpp:270

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MainWindow::quitApp ( )
slot

Definition at line 291 of file mainwindow.cpp.

Referenced by MainWindow().

291  {
292  qApp->quit();
293 }

+ Here is the caller graph for this function:

void MainWindow::removeDevice ( Kb device)
privateslot

Definition at line 139 of file mainwindow.cpp.

References KbWidget::device, kbWidgets, Ui_MainWindow::tabWidget, ui, and updateVersion().

Referenced by MainWindow().

139  {
140  foreach(KbWidget* w, kbWidgets){
141  // Remove this device from the UI
142  if(w->device == device){
143  int i = kbWidgets.indexOf(w);
144  ui->tabWidget->removeTab(i);
145  kbWidgets.removeAt(i);
146  w->deleteLater();
147  }
148  }
149  // Update connected device count
150  updateVersion();
151 }
Ui::MainWindow * ui
Definition: mainwindow.h:75
void updateVersion()
Definition: mainwindow.cpp:153
QTabWidget * tabWidget
Definition: ui_mainwindow.h:31
QList< KbWidget * > kbWidgets
Definition: mainwindow.h:41
Kb * device
Definition: kbwidget.h:24

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MainWindow::showFwUpdateNotification ( QWidget widget,
float  version 
)
privateslot

Definition at line 192 of file mainwindow.cpp.

References KbWidget::device, kbWidgets, KbWidget::showFwUpdate(), KbWidget::showLastTab(), showWindow(), Ui_MainWindow::tabWidget, ui, and Kb::usbModel.

192  {
193  static bool isShowing = false;
194  if(isShowing)
195  return;
196  isShowing = true;
197  showWindow();
198  KbWidget* w = (KbWidget*)widget;
199  // Ask for update
200  if(QMessageBox::information(this, "Firmware update", tr("A new firmware is available for your %1 (v%2)\nWould you like to install it now?").arg(w->device->usbModel, QString::number(version, 'f', 2)), QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No), QMessageBox::Yes) == QMessageBox::Yes){
201  // If accepted, switch to firmware tab and bring up update window
202  w->showLastTab();
203  ui->tabWidget->setCurrentIndex(kbWidgets.indexOf(w));
204  w->showFwUpdate();
205  }
206  isShowing = false;
207 }
Ui::MainWindow * ui
Definition: mainwindow.h:75
void showWindow()
Definition: mainwindow.cpp:270
void showFwUpdate()
Definition: kbwidget.h:38
void showLastTab()
Definition: kbwidget.cpp:68
QString usbModel
Definition: kb.h:16
QTabWidget * tabWidget
Definition: ui_mainwindow.h:31
QList< KbWidget * > kbWidgets
Definition: mainwindow.h:41
Kb * device
Definition: kbwidget.h:24

+ Here is the call graph for this function:

void MainWindow::showWindow ( )
slot

Definition at line 270 of file mainwindow.cpp.

Referenced by iconClicked(), MainWindow(), showFwUpdateNotification(), stateChange(), and timerTick().

270  {
271  showNormal();
272  raise();
273  activateWindow();
274 }

+ Here is the caller graph for this function:

void MainWindow::stateChange ( Qt::ApplicationState  state)
slot

Definition at line 276 of file mainwindow.cpp.

References showWindow().

Referenced by MainWindow().

276  {
277  // On OSX it's possible for the app to be brought to the foreground without the window actually reappearing.
278  // We want to make sure it's shown when this happens.
279 #ifdef Q_OS_MAC
280  static quint64 lastStateChange = 0;
281  quint64 now = QDateTime::currentMSecsSinceEpoch();
282  if(state == Qt::ApplicationActive){
283  // This happens once at startup so ignore it. Also don't allow it to be called more than once every 2s.
284  if(lastStateChange != 0 && now >= lastStateChange + 2 * 1000)
285  showWindow();
286  lastStateChange = now;
287  }
288 #endif
289 }
void showWindow()
Definition: mainwindow.cpp:270

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MainWindow::timerTick ( )
privateslot

Definition at line 223 of file mainwindow.cpp.

References appShare, checkFwUpdates(), KbFirmware::checkUpdates(), CkbSettings::get(), SettingsWidget::pollUpdates(), settingsWidget, and showWindow().

Referenced by MainWindow().

223  {
224  // Check shared memory for changes
225  if(appShare.lock()){
226  void* data = appShare.data();
227  QStringList commands = QString((const char*)data).split("\n");
228  // Restore PID, remove all other data
229  snprintf((char*)appShare.data(), appShare.size(), "PID %ld", (long)getpid());
230  appShare.unlock();
231  // Parse commands
232  foreach(const QString& line, commands){
233  // Old ckb option line - bring application to foreground
234  if(line == "Open")
235  showWindow();
236  if(line.startsWith("Option ")){
237  // New ckb option line
238  QString option = line.split(" ")[1];
239  if(option == "Open")
240  // Bring to foreground
241  showWindow();
242  else if(option == "Close")
243  // Quit application
244  qApp->quit();
245  }
246  }
247  }
248  // Check for firmware updates (when appropriate)
249  if(!CkbSettings::get("Program/DisableAutoFWCheck").toBool()){
251  checkFwUpdates();
252  }
253  // Poll for setting updates
255 }
void checkFwUpdates()
Definition: mainwindow.cpp:172
void showWindow()
Definition: mainwindow.cpp:270
static QVariant get(const QString &key, const QVariant &defaultValue=QVariant())
QSharedMemory appShare
static bool checkUpdates()
Definition: kbfirmware.h:15
SettingsWidget * settingsWidget
Definition: mainwindow.h:40

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void MainWindow::toggleTrayIcon ( bool  visible)

Definition at line 112 of file mainwindow.cpp.

References trayIcon.

Referenced by MainWindow(), and ExtraSettingsWidget::on_trayBox_clicked().

112  {
113 #ifdef USE_LIBAPPINDICATOR
114  if(unityDesktop)
115  app_indicator_set_status(indicator, visible ? APP_INDICATOR_STATUS_ACTIVE : APP_INDICATOR_STATUS_PASSIVE);
116  else
117 #endif // USE_LIBAPPINDICATOR
118  trayIcon->setVisible(visible);
119 }
QSystemTrayIcon * trayIcon
Definition: mainwindow.h:54

+ Here is the caller graph for this function:

void MainWindow::updateVersion ( )
privateslot

Definition at line 153 of file mainwindow.cpp.

References KbManager::ckbDaemonVersion(), KbManager::ckbDaemonVersionF(), KbManager::ckbGuiVersionF(), DAEMON_UNAVAILABLE_STR, kbWidgets, SettingsWidget::setStatus(), and settingsWidget.

Referenced by addDevice(), MainWindow(), and removeDevice().

153  {
154  QString daemonVersion = KbManager::ckbDaemonVersion();
155  if(daemonVersion == DAEMON_UNAVAILABLE_STR){
156  settingsWidget->setStatus("Driver inactive");
157  return;
158  }
159  int count = kbWidgets.count();
160  // Warn if the daemon version doesn't match the GUI
161  QString daemonWarning;
162  if(daemonVersion != CKB_VERSION_STR)
163  daemonWarning = "<br /><br /><b>Warning:</b> Driver version mismatch (" + daemonVersion + "). Please upgrade ckb" + QString(KbManager::ckbDaemonVersionF() > KbManager::ckbGuiVersionF() ? "" : "-daemon") + ". If the problem persists, try rebooting.";
164  if(count == 0)
165  settingsWidget->setStatus("No devices connected" + daemonWarning);
166  else if(count == 1)
167  settingsWidget->setStatus("1 device connected" + daemonWarning);
168  else
169  settingsWidget->setStatus(QString("%1 devices connected").arg(count) + daemonWarning);
170 }
void setStatus(const QString &text)
static float ckbDaemonVersionF()
Definition: kbmanager.h:31
static float ckbGuiVersionF()
Definition: kbmanager.h:30
#define DAEMON_UNAVAILABLE_STR
Definition: kbmanager.h:12
SettingsWidget * settingsWidget
Definition: mainwindow.h:40
static QString ckbDaemonVersion()
Definition: kbmanager.h:27
QList< KbWidget * > kbWidgets
Definition: mainwindow.h:41

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Field Documentation

QAction* MainWindow::closeAction
private

Definition at line 44 of file mainwindow.h.

Referenced by MainWindow().

QList<KbWidget*> MainWindow::kbWidgets
private
MainWindow * MainWindow::mainWindow = 0
static
QAction* MainWindow::restoreAction
private

Definition at line 43 of file mainwindow.h.

Referenced by MainWindow().

SettingsWidget* MainWindow::settingsWidget
private

Definition at line 40 of file mainwindow.h.

Referenced by MainWindow(), timerTick(), and updateVersion().

QSystemTrayIcon* MainWindow::trayIcon
private

Definition at line 54 of file mainwindow.h.

Referenced by MainWindow(), and toggleTrayIcon().

QMenu* MainWindow::trayIconMenu
private

Definition at line 53 of file mainwindow.h.

Referenced by MainWindow().

Ui::MainWindow* MainWindow::ui
private

The documentation for this class was generated from the following files: