3 // For the Pierogi IR remote control app.
5 // Copyright (C) 2012 by John Pietrzak (john@pietrzak.org)
7 // Licensed under the GNU GPL version 2.0 or later.
9 #include "mainwindow.h"
10 #include "ui_mainwindow.h"
12 #include <QtCore/QCoreApplication>
14 #include <QtGui/QMessageBox>
15 #include <QPushButton>
17 #include <QDialogButtonBox>
18 #include <QScrollArea>
22 //#include "pirtabwidget.h"
24 #include "pirkeysetmetadata.h"
26 #include "pirkeysetwidgetitem.h"
27 #include "pirselectkeysetform.h"
28 #include "pirselectdeviceform.h"
29 #include "pirpreferencesform.h"
30 #include "pirdocumentationform.h"
31 #include "piraboutform.h"
32 #include "dialogs/pirtabschoicedialog.h"
33 #include "dialogs/pirfavoritesdialog.h"
35 #include "pirkeysetmanager.h"
36 #include "pirpanelmanager.h"
37 #include "macros/pirmacromanager.h"
42 // Some ugly globals used for thread communications:
44 // A global to show that a command is being processed:
45 bool commandInFlight = false;
46 QMutex commandIFMutex;
48 // The stopRepeatingFlag boolean is the method used to tell running commands
49 // in the worker thread to stop:
50 bool stopRepeatingFlag = false;
51 QMutex stopRepeatingMutex;
54 extern PIRMakeMgr makeManager;
57 MainWindow::MainWindow(QWidget *parent)
58 : QMainWindow(parent),
59 ui(new Ui::MainWindow),
69 currentKeyset(1) // Zero is not a valid keyset any more
71 // Create the tab widget:
72 // myTabWidget = new PIRTabWidget(ui->centralWidget, this);
76 // Make this a Maemo 5 stacked widget:
77 setAttribute(Qt::WA_Maemo5StackedWindow);
79 // Create the managers:
80 myKeysets = new PIRKeysetManager();
81 myMacros = new PIRMacroManager(this);
82 myPanels = new PIRPanelManager(this);
84 // Display the panels:
85 myPanels->updateTabSet();
87 // Construct the rest of the forms:
88 selectKeysetForm = new PIRSelectKeysetForm(this);
89 favoritesDialog = new PIRFavoritesDialog(this);
90 myKeysets->populateListWidgets(selectKeysetForm, favoritesDialog);
91 selectKeysetForm->populateKeysetComboBox(myPanels->getKeysetComboBox());
93 selectDeviceForm = new PIRSelectDeviceForm(this);
94 PIRKeysetMetaData::populateDevices(selectDeviceForm);
96 preferencesForm = new PIRPreferencesForm(this, myKeysets);
98 // Retrieve the user's preferences:
99 QSettings settings("pietrzak.org", "Pierogi");
100 if (settings.contains("currentKeysetName"))
102 myKeysets->findKeysetID(
103 settings.value("currentKeysetMake").toString(),
104 settings.value("currentKeysetName").toString(),
108 selectKeysetForm->selectKeyset(currentKeyset);
110 // Add the corner buttons:
111 insertCornerButtons();
113 // Set up all the buttons:
115 myPanels->updateUserButtons();
117 // Make sure the three selection lists don't show different selections:
118 QListWidget *klw = selectKeysetForm->getKeysetListWidget();
119 QListWidget *dlw = selectDeviceForm->getDeviceListWidget();
121 // keyset name -> device name
124 SIGNAL(itemActivated(QListWidgetItem *)),
126 SLOT(clearSelection()),
127 Qt::QueuedConnection);
129 // device name -> keyset name
132 SIGNAL(itemActivated(QListWidgetItem *)),
134 SLOT(clearSelection()),
135 Qt::QueuedConnection);
138 // The PIRModprobe object should take care of setting up and shutting down
139 // the lirc_rx51 kernel module, if necessary:
141 if (modprobeObj.loadRX51Module() != 0)
143 // Couldn't load module, quit:
145 errBox.setText("Couldn't load lirc_rx51 kernel module!");
146 errBox.setIcon(QMessageBox::Warning);
148 // throw; // Need a clean way to exit here!!!
154 MainWindow::~MainWindow()
156 if (aboutForm) delete aboutForm;
157 if (documentationForm) delete documentationForm;
158 if (preferencesForm) delete preferencesForm;
159 if (selectDeviceForm) delete selectDeviceForm;
160 if (favoritesDialog) delete favoritesDialog;
161 if (selectKeysetForm) delete selectKeysetForm;
163 if (myPanels) delete myPanels;
164 if (myMacros) delete myMacros;
165 if (myKeysets) delete myKeysets;
170 void MainWindow::setOrientation(ScreenOrientation orientation)
172 #if defined(Q_OS_SYMBIAN)
173 // If the version of Qt on the device is < 4.7.2, that attribute won't work
174 if (orientation != ScreenOrientationAuto) {
175 const QStringList v = QString::fromAscii(qVersion()).split(QLatin1Char('.'));
176 if (v.count() == 3 && (v.at(0).toInt() << 16 | v.at(1).toInt() << 8 | v.at(2).toInt()) < 0x040702) {
177 qWarning("Screen orientation locking only supported with Qt 4.7.2 and above");
181 #endif // Q_OS_SYMBIAN
183 Qt::WidgetAttribute attribute;
184 switch (orientation) {
185 #if QT_VERSION < 0x040702
186 // Qt < 4.7.2 does not yet have the Qt::WA_*Orientation attributes
187 case ScreenOrientationLockPortrait:
188 attribute = static_cast<Qt::WidgetAttribute>(128);
190 case ScreenOrientationLockLandscape:
191 attribute = static_cast<Qt::WidgetAttribute>(129);
194 case ScreenOrientationAuto:
195 attribute = static_cast<Qt::WidgetAttribute>(130);
197 #else // QT_VERSION < 0x040702
198 case ScreenOrientationLockPortrait:
199 attribute = Qt::WA_LockPortraitOrientation;
201 case ScreenOrientationLockLandscape:
202 attribute = Qt::WA_LockLandscapeOrientation;
205 case ScreenOrientationAuto:
206 attribute = Qt::WA_AutoOrientation;
208 #endif // QT_VERSION < 0x040702
210 setAttribute(attribute, true);
213 void MainWindow::showExpanded()
215 #if defined(Q_OS_SYMBIAN) || defined(Q_WS_SIMULATOR)
217 #elif defined(Q_WS_MAEMO_5)
225 void MainWindow::enableButtons()
227 // Just to be sure, check to see if the keyset has been populated:
228 myKeysets->populateKeyset(this, currentKeyset);
232 unsigned int dk = preferencesForm->getDefaultKeyset();
233 if (preferencesForm->defaultControlsVolume() && dk)
235 myKeysets->populateKeyset(this, dk);
236 myPanels->enableButtons(myKeysets, currentKeyset, dk);
240 myPanels->enableButtons(myKeysets, currentKeyset);
245 myPanels->enableButtons(myKeysets, currentKeyset);
250 void MainWindow::useMainPanel()
252 myPanels->useMainPanel();
256 void MainWindow::useAltMainPanel()
258 myPanels->useAltMainPanel();
262 QString MainWindow::getCurrentMake()
264 return makeManager.getMakeString(myKeysets->getMake(currentKeyset));
268 QString MainWindow::getCurrentName()
270 return myKeysets->getDisplayName(currentKeyset);
274 QString MainWindow::getCurrentFullName()
276 return selectKeysetForm->getCurrentKeysetName();
280 QString MainWindow::getKeysetMake(
283 return makeManager.getMakeString(myKeysets->getMake(id));
287 QString MainWindow::getKeysetName(
290 return myKeysets->getDisplayName(id);
294 QString MainWindow::getFullKeysetName(
297 return selectKeysetForm->getKeysetName(id);
301 bool MainWindow::findKeysetID(
306 return myKeysets->findKeysetID(make, name, id);
310 void MainWindow::receivedExternalWarning(
314 errBox.setText(warning);
315 errBox.setIcon(QMessageBox::Warning);
322 void MainWindow::on_actionSelectKeyset_triggered()
324 selectKeysetForm->show();
327 void MainWindow::on_actionBrowse_Device_List_triggered()
329 selectDeviceForm->show();
332 void MainWindow::on_actionPreferences_triggered()
334 preferencesForm->show();
337 void MainWindow::on_actionAbout_triggered()
341 aboutForm = new PIRAboutForm(this);
347 void MainWindow::on_actionDocumentation_triggered()
349 if (!documentationForm)
351 documentationForm = new PIRDocumentationForm(this);
354 documentationForm->show();
360 void MainWindow::keysetSelectionChanged(
361 QListWidgetItem *item)
363 if (!item) return; // Should probably display error message here!
365 PIRKeysetWidgetItem *kwi = dynamic_cast<PIRKeysetWidgetItem *>(item);
367 if (!kwi) return; // Also need to say something here
369 if (currentKeyset == kwi->getID())
371 // We're already on that keyset, so nothing to do:
375 // Clean up and remove the current keyset:
376 myKeysets->clearKeyset(currentKeyset);
378 currentKeyset = kwi->getID();
380 QSettings settings("pietrzak.org", "Pierogi");
384 makeManager.getMakeString(kwi->getMake()));
388 myKeysets->getDisplayName(currentKeyset));
394 void MainWindow::finalCleanup()
396 // Perform any necessary cleanup work here.
398 // Make certain that the thread stops repeating:
403 void MainWindow::addToFavorites(
404 PIRKeysetWidgetItem *kwi)
406 //Add keyset to the favorites:
407 favoritesDialog->addItem(new PIRKeysetWidgetItem(kwi));
409 // And, add the keyset id to the persistent list:
410 QSettings settings("pietrzak.org", "Pierogi");
412 int favSettingsSize = settings.beginReadArray("favorites");
415 settings.beginWriteArray("favorites");
416 settings.setArrayIndex(favSettingsSize);
420 makeManager.getMakeString(kwi->getMake()));
422 settings.setValue("keysetName", kwi->getInternalName());
428 void MainWindow::removeFromFavorites(
429 unsigned int keysetID)
431 favoritesDialog->removeItem(keysetID);
433 // Remove this item from the persistent list. Well, actually, it seems a
434 // little more convenient to just blow away the existing list of favorites
435 // and rewrite it, as modifying an existing QSettings array in the middle
436 // seems a bit hard...
437 QSettings settings("pietrzak.org", "Pierogi");
439 settings.remove("favorites");
441 int count = favoritesDialog->getCount();
443 // If the count is empty, we can stop right here:
444 if (count == 0) return;
448 PIRKeysetWidgetItem *kwi = NULL;
449 settings.beginWriteArray("favorites");
450 while (index < count)
452 kwi = favoritesDialog->getItem(index);
454 settings.setArrayIndex(index);
459 makeManager.getMakeString(myKeysets->getMake(id)));
461 settings.setValue("keysetName", myKeysets->getDisplayName(id));
470 void MainWindow::populateFavorites()
472 QSettings settings("pietrzak.org", "Pierogi");
474 int size = settings.beginReadArray("favorites");
478 PIRKeysetWidgetItem *kwi;
482 settings.setArrayIndex(index);
483 make = settings.value("keysetMake").toString();
484 name = settings.value("keysetName").toString();
486 kwi = myKeysets->makeKeysetItem(make, name);
488 // Did the item creation work?
491 // Keyset does exist, so continue:
492 favoritesDialog->addItem(kwi);
503 bool MainWindow::startRepeating(
506 QMutexLocker locker(&commandIFMutex);
507 if (!commandInFlight)
509 commandInFlight = true;
510 emit buttonPressed(currentKeyset, name);
520 bool MainWindow::startRepeating(
522 unsigned int keysetID)
524 QMutexLocker locker(&commandIFMutex);
525 if (!commandInFlight)
527 commandInFlight = true;
528 emit buttonPressed(keysetID, name);
538 void MainWindow::stopRepeating()
540 QMutexLocker locker(&stopRepeatingMutex);
541 stopRepeatingFlag = true;
545 void MainWindow::selectPrevFavKeyset()
547 favoritesDialog->selectPrevFavKeyset();
551 void MainWindow::selectNextFavKeyset()
553 favoritesDialog->selectNextFavKeyset();
557 void MainWindow::insertCornerButtons()
559 // Set up the dialog boxes:
560 PIRTabsChoiceDialog *tcd = new PIRTabsChoiceDialog(this);
561 // favoritesDialog = new PIRFavoritesDialog(this);
563 // Next, set up the corner buttons:
564 QPushButton *button =
565 new QPushButton(QIcon(":/icons/folder_plus_icon&32.png"), "");
567 button->setFlat(true);
574 Qt::QueuedConnection);
576 ui->mainTabWidget->setCornerWidget(button, Qt::TopRightCorner);
577 // myTabWidget->setCornerWidget(button, Qt::TopRightCorner);
580 new QPushButton(QIcon(":/icons/align_just_icon&32.png"), "");
582 button->setFlat(true);
589 Qt::QueuedConnection);
591 ui->mainTabWidget->setCornerWidget(button, Qt::TopLeftCorner);
592 // myTabWidget->setCornerWidget(button, Qt::TopLeftCorner);
596 void MainWindow::disableUpdates()
598 ui->mainTabWidget->setUpdatesEnabled(false);
599 // myTabWidget->setUpdatesEnabled(false);
603 void MainWindow::enableUpdates()
605 ui->mainTabWidget->setUpdatesEnabled(true);
606 // myTabWidget->setUpdatesEnabled(true);
610 void MainWindow::clearTabs()
612 ui->mainTabWidget->clear();
613 // myTabWidget->clear();
617 void MainWindow::addTab(
621 ui->mainTabWidget->addTab(page, label);
622 // myTabWidget->addTab(page, label);
625 void MainWindow::setupTabs(
628 myPanels->setupTabs(name);
632 bool MainWindow::selectNextKeyset()
634 return selectKeysetForm->selectNextKeyset();
638 bool MainWindow::selectPrevKeyset()
640 return selectKeysetForm->selectPrevKeyset();
644 bool MainWindow::selectFirstKeyset()
646 return selectKeysetForm->selectFirstKeyset();
650 void MainWindow::openCurrentKeysetDialog()
652 selectKeysetForm->openCurrentKeysetDialog();
656 void MainWindow::updateKeysetSelection(
657 unsigned int targetID)
659 selectKeysetForm->selectKeyset(targetID);
663 PIRMacroPack *MainWindow::getUserPack()
665 return myMacros->getUserPack();
669 PIRMacroPack *MainWindow::getMultitapPack()
671 return myMacros->getMultitapPack();
675 void MainWindow::handleKeypress(
678 myMacros->handleKeypress(key);
683 void MainWindow::handleKeyRelease(
690 void MainWindow::gotoPreviousTabs()
692 myPanels->gotoPreviousTabs();
696 void MainWindow::gotoNextTabs()
698 myPanels->gotoNextTabs();
703 void MainWindow::keyPressEvent(
709 myMacros->handleKeypress('A');
712 myMacros->handleKeypress('B');
715 myMacros->handleKeypress('C');
718 myMacros->handleKeypress('D');
721 myMacros->handleKeypress('E');
724 myMacros->handleKeypress('F');
727 myMacros->handleKeypress('G');
730 myMacros->handleKeypress('H');
733 myMacros->handleKeypress('I');
736 myMacros->handleKeypress('J');
739 myMacros->handleKeypress('K');
742 myMacros->handleKeypress('L');
745 myMacros->handleKeypress('M');
748 myMacros->handleKeypress('N');
751 myMacros->handleKeypress('O');
754 myMacros->handleKeypress('P');
757 myMacros->handleKeypress('Q');
760 myMacros->handleKeypress('R');
763 myMacros->handleKeypress('S');
766 myMacros->handleKeypress('T');
769 myMacros->handleKeypress('U');
772 myMacros->handleKeypress('V');
775 myMacros->handleKeypress('W');
778 myMacros->handleKeypress('X');
781 myMacros->handleKeypress('Y');
784 myMacros->handleKeypress('Z');
787 myMacros->handleKeypress(' ');
791 myPanels->gotoPreviousTabs();
794 myPanels->gotoNextTabs();
799 startRepeating(VolumeDown_Key);
802 startRepeating(VolumeUp_Key);
805 case Qt::Key_Backspace:
806 startRepeating(Power_Key);
809 startRepeating(Mute_Key);
813 QMainWindow::keyPressEvent(event);
821 void MainWindow::keyReleaseEvent(
832 case Qt::Key_Backspace:
838 QMainWindow::keyReleaseEvent(event);
845 bool MainWindow::hasMacroButton(
846 unsigned int buttonID)
848 return myMacros->hasMacroButton(buttonID);
852 QString MainWindow::getMacroButtonText(
853 unsigned int buttonID)
855 return myMacros->getMacroButtonText(buttonID);
859 void MainWindow::executeMacroButton(
860 unsigned int buttonID)
862 myMacros->executeMacroButton(buttonID);
866 void MainWindow::updateUserButtons()
868 myPanels->updateUserButtons();
872 void MainWindow::storeMacros()
874 myMacros->storeSettings();
878 void MainWindow::setMacroKbdFocus(
881 myMacros->setKbdFocus(index);
885 void MainWindow::setMacroBtnFocus(
888 myMacros->setBtnFocus(index);
892 void MainWindow::switchToTab(
895 int count = ui->mainTabWidget->count();
899 ui->mainTabWidget->setCurrentIndex(0);
901 else if (tabNumber >= count)
903 ui->mainTabWidget->setCurrentIndex(count-1);
907 ui->mainTabWidget->setCurrentIndex(tabNumber);