Missed one file
[pierogi] / mainwindow.cpp
1 #include "mainwindow.h"
2 #include "ui_mainwindow.h"
3
4 #include <QtCore/QCoreApplication>
5 #include <QMutex>
6 #include <QtGui/QMessageBox>
7 #include <QPushButton>
8 #include <QDialog>
9 #include <QDialogButtonBox>
10 #include <QScrollArea>
11 #include <QSettings>
12
13 #include "pirkeysetmetadata.h"
14
15 #include "pirkeysetwidgetitem.h"
16 #include "pirselectkeysetform.h"
17 #include "pirselectdeviceform.h"
18 #include "pirpreferencesform.h"
19 #include "pirdocumentationform.h"
20 #include "piraboutform.h"
21 #include "dialogs/pirtabschoicedialog.h"
22 #include "dialogs/pirfavoritesdialog.h"
23
24 #include "pirkeysetmanager.h"
25 #include "pirpanelmanager.h"
26
27 //#define DEBUGGING
28 //#include <iostream>
29
30 // Some ugly globals used for thread communications:
31
32 // A global to show that a command is being processed:
33 bool commandInFlight = false;
34 QMutex commandIFMutex;
35
36 // The stopRepeatingFlag boolean is the method used to tell running commands
37 // in the worker thread to stop:
38 bool stopRepeatingFlag = false;
39 QMutex stopRepeatingMutex;
40
41
42 extern PIRMakeMgr makeManager;
43
44
45 MainWindow::MainWindow(QWidget *parent)
46   : QMainWindow(parent),
47     ui(new Ui::MainWindow),
48     selectKeysetForm(0),
49     selectDeviceForm(0),
50     preferencesForm(0),
51     documentationForm(0),
52     aboutForm(0),
53     myKeysets(0),
54     myPanels(0),
55     currentKeyset(1) // Zero is not a valid keyset any more
56 {
57   ui->setupUi(this);
58
59   // Make this a Maemo 5 stacked widget:
60   setAttribute(Qt::WA_Maemo5StackedWindow);
61
62   // Create the managers:
63   myKeysets = new PIRKeysetManager();
64   myPanels = new PIRPanelManager(this);
65
66   // Display the panels:
67   myPanels->updateTabSet();
68
69   // Construct the rest of the forms:
70   selectKeysetForm = new PIRSelectKeysetForm(this);
71   favoritesDialog = new PIRFavoritesDialog(this);
72   myKeysets->populateListWidgets(selectKeysetForm, favoritesDialog);
73
74   selectDeviceForm = new PIRSelectDeviceForm(this);
75   PIRKeysetMetaData::populateDevices(selectDeviceForm);
76
77   preferencesForm = new PIRPreferencesForm(this, myKeysets);
78
79   // Retrieve the user's preferences:
80   QSettings settings("pietrzak.org", "Pierogi");
81   if (settings.contains("currentKeysetName"))
82   {
83     myKeysets->findKeysetID(
84       settings.value("currentKeysetMake").toString(),
85       settings.value("currentKeysetName").toString(),
86       currentKeyset);
87   }
88
89   // Add the corner buttons:
90   insertCornerButtons();
91
92   enableButtons();
93
94   QListWidget *fkw = favoritesDialog->getFavoritesListWidget();
95
96   connect(
97     fkw,
98     SIGNAL(itemActivated(QListWidgetItem *)),
99     this,
100     SLOT(keysetSelectionChanged(QListWidgetItem *)),
101     Qt::QueuedConnection);
102
103   // Make sure the three selection lists don't show different selections:
104   QListWidget *klw = selectKeysetForm->getKeysetListWidget();
105   QListWidget *dlw = selectDeviceForm->getDeviceListWidget();
106
107   // favorites -> keyset name
108   connect(
109     fkw,
110     SIGNAL(itemActivated(QListWidgetItem *)),
111     klw,
112     SLOT(clearSelection()),
113     Qt::QueuedConnection);
114
115   // favorites -> device name
116   connect(
117     fkw,
118     SIGNAL(itemActivated(QListWidgetItem *)),
119     dlw,
120     SLOT(clearSelection()),
121     Qt::QueuedConnection);
122
123   // keyset name -> favorites
124   connect(
125     klw,
126     SIGNAL(itemActivated(QListWidgetItem *)),
127     fkw,
128     SLOT(clearSelection()),
129     Qt::QueuedConnection);
130
131   // device name -> favorites
132   connect(
133     dlw,
134     SIGNAL(itemActivated(QListWidgetItem *)),
135     fkw,
136     SLOT(clearSelection()),
137     Qt::QueuedConnection);
138
139   // keyset name -> device name
140   connect(
141     klw,
142     SIGNAL(itemActivated(QListWidgetItem *)),
143     dlw,
144     SLOT(clearSelection()),
145     Qt::QueuedConnection);
146
147   // device name -> keyset name
148   connect(
149     dlw,
150     SIGNAL(itemActivated(QListWidgetItem *)),
151     klw,
152     SLOT(clearSelection()),
153     Qt::QueuedConnection);
154
155 #ifndef DEBUGGING
156   // The PIRModprobe object should take care of setting up and shutting down
157   // the lirc_rx51 kernel module, if necessary:
158  
159   if (modprobeObj.loadRX51Module() != 0)
160   {
161     // Couldn't load module, quit:
162     QMessageBox errBox;
163     errBox.setText("Couldn't load lirc_rx51 kernel module!");
164     errBox.setIcon(QMessageBox::Warning);
165     errBox.exec();
166 //    throw; // Need a clean way to exit here!!!
167   }
168 #endif
169 }
170
171
172 MainWindow::~MainWindow()
173 {
174   delete myKeysets;
175   if (selectKeysetForm) delete selectKeysetForm;
176   if (selectDeviceForm) delete selectDeviceForm;
177 //  if (panelSelectionForm) delete panelSelectionForm;
178   if (documentationForm) delete documentationForm;
179   if (aboutForm) delete aboutForm;
180   delete ui;
181 }
182
183
184 void MainWindow::setOrientation(ScreenOrientation orientation)
185 {
186 #if defined(Q_OS_SYMBIAN)
187     // If the version of Qt on the device is < 4.7.2, that attribute won't work
188     if (orientation != ScreenOrientationAuto) {
189         const QStringList v = QString::fromAscii(qVersion()).split(QLatin1Char('.'));
190         if (v.count() == 3 && (v.at(0).toInt() << 16 | v.at(1).toInt() << 8 | v.at(2).toInt()) < 0x040702) {
191             qWarning("Screen orientation locking only supported with Qt 4.7.2 and above");
192             return;
193         }
194     }
195 #endif // Q_OS_SYMBIAN
196
197     Qt::WidgetAttribute attribute;
198     switch (orientation) {
199 #if QT_VERSION < 0x040702
200     // Qt < 4.7.2 does not yet have the Qt::WA_*Orientation attributes
201     case ScreenOrientationLockPortrait:
202         attribute = static_cast<Qt::WidgetAttribute>(128);
203         break;
204     case ScreenOrientationLockLandscape:
205         attribute = static_cast<Qt::WidgetAttribute>(129);
206         break;
207     default:
208     case ScreenOrientationAuto:
209         attribute = static_cast<Qt::WidgetAttribute>(130);
210         break;
211 #else // QT_VERSION < 0x040702
212     case ScreenOrientationLockPortrait:
213         attribute = Qt::WA_LockPortraitOrientation;
214         break;
215     case ScreenOrientationLockLandscape:
216         attribute = Qt::WA_LockLandscapeOrientation;
217         break;
218     default:
219     case ScreenOrientationAuto:
220         attribute = Qt::WA_AutoOrientation;
221         break;
222 #endif // QT_VERSION < 0x040702
223     };
224     setAttribute(attribute, true);
225 }
226
227 void MainWindow::showExpanded()
228 {
229 #if defined(Q_OS_SYMBIAN) || defined(Q_WS_SIMULATOR)
230     showFullScreen();
231 #elif defined(Q_WS_MAEMO_5)
232     showMaximized();
233 #else
234     show();
235 #endif
236 }
237
238
239 void MainWindow::enableButtons()
240 {
241   // Just to be sure, check to see if the keyset has been populated:
242   myKeysets->populateKeyset(this, currentKeyset);
243
244   if (preferencesForm)
245   {
246     unsigned int dk = preferencesForm->getDefaultKeyset();
247     if (preferencesForm->defaultControlsVolume() && dk)
248     {
249       myKeysets->populateKeyset(this, dk);
250       myPanels->enableButtons(myKeysets, currentKeyset, dk);
251     }
252     else
253     {
254       myPanels->enableButtons(myKeysets, currentKeyset);
255     }
256   }
257   else
258   {
259     myPanels->enableButtons(myKeysets, currentKeyset);
260   }
261 }
262
263
264 void MainWindow::useMainPanel()
265 {
266   myPanels->useMainPanel();
267 }
268
269
270 void MainWindow::useAltMainPanel()
271 {
272   myPanels->useAltMainPanel();
273 }
274
275
276 QString MainWindow::getCurrentMake()
277 {
278   return makeManager.getMakeString(myKeysets->getMake(currentKeyset));
279 }
280
281
282 QString MainWindow::getCurrentName()
283 {
284   return myKeysets->getDisplayName(currentKeyset);
285 }
286
287
288 QString MainWindow::getCurrentFullName()
289 {
290   return selectKeysetForm->getKeysetName();
291 }
292
293
294 void MainWindow::receivedExternalWarning(
295   const char *warning)
296 {
297   QMessageBox errBox;
298   errBox.setText(warning);
299   errBox.setIcon(QMessageBox::Warning);
300   errBox.exec();
301 }
302
303
304 // Menu actions:
305
306 void MainWindow::on_actionSelectKeyset_triggered()
307 {
308   selectKeysetForm->show();
309 }
310
311 void MainWindow::on_actionBrowse_Device_List_triggered()
312 {
313   selectDeviceForm->show();
314 }
315
316 void MainWindow::on_actionPreferences_triggered()
317 {
318   preferencesForm->show();
319 }
320
321 void MainWindow::on_actionAbout_triggered()
322 {
323   if (!aboutForm)
324   {
325     aboutForm = new PIRAboutForm(this);
326   }
327
328   aboutForm->show();
329 }
330
331 void MainWindow::on_actionDocumentation_triggered()
332 {
333   if (!documentationForm)
334   {
335     documentationForm = new PIRDocumentationForm(this);
336   }
337
338   documentationForm->show();
339 }
340
341
342 // Other actions:
343
344 void MainWindow::keysetSelectionChanged(
345   QListWidgetItem *item)
346 {
347   if (!item) return;  // Should probably display error message here!
348
349   PIRKeysetWidgetItem *kwi = dynamic_cast<PIRKeysetWidgetItem *>(item);
350
351   if (!kwi) return; // Also need to say something here
352
353   if (currentKeyset == kwi->getID())
354   {
355     // We're already on that keyset, so nothing to do:
356     return;
357   }
358
359   // Clean up and remove the current keyset:
360   myKeysets->clearKeyset(currentKeyset);
361   
362   currentKeyset = kwi->getID();
363
364   QSettings settings("pietrzak.org", "Pierogi");
365
366   settings.setValue(
367     "currentKeysetMake",
368     makeManager.getMakeString(kwi->getMake()));
369
370   settings.setValue(
371     "currentKeysetName",
372     myKeysets->getDisplayName(currentKeyset));
373
374   enableButtons();
375 }
376
377
378 void MainWindow::finalCleanup()
379 {
380   // Perform any necessary cleanup work here.
381
382   // Make certain that the thread stops repeating:
383   stopRepeating();
384 }
385
386
387 void MainWindow::addToFavorites(
388   PIRKeysetWidgetItem *kwi)
389 {
390   //Add keyset to the favorites:
391   favoritesDialog->addItem(new PIRKeysetWidgetItem(kwi));
392
393   // And, add the keyset id to the persistent list:
394   QSettings settings("pietrzak.org", "Pierogi");
395
396   int favSettingsSize = settings.beginReadArray("favorites");
397   settings.endArray();
398
399   settings.beginWriteArray("favorites");
400   settings.setArrayIndex(favSettingsSize);
401
402   settings.setValue(
403     "keysetMake",
404     makeManager.getMakeString(kwi->getMake()));
405
406   settings.setValue("keysetName", kwi->getInternalName());
407
408   settings.endArray();
409 }
410
411
412 void MainWindow::removeFromFavorites(
413   unsigned int keysetID)
414 {
415   favoritesDialog->removeItem(keysetID);
416
417   // Remove this item from the persistent list.  Well, actually, it seems a
418   // little more convenient to just blow away the existing list of favorites
419   // and rewrite it, as modifying an existing QSettings array in the middle
420   // seems a bit hard...
421   QSettings settings("pietrzak.org", "Pierogi");
422
423   settings.remove("favorites");
424
425   int count = favoritesDialog->getCount();
426
427   // If the count is empty, we can stop right here:
428   if (count == 0) return;
429
430   int index = 0;
431   unsigned int id;
432   PIRKeysetWidgetItem *kwi = NULL;
433   settings.beginWriteArray("favorites");
434   while (index < count)
435   {
436     kwi = favoritesDialog->getItem(index);
437
438     settings.setArrayIndex(index);
439     id = kwi->getID();
440
441     settings.setValue(
442       "keysetMake",
443       makeManager.getMakeString(myKeysets->getMake(id)));
444
445     settings.setValue("keysetName", myKeysets->getDisplayName(id));
446
447     ++index;
448   }
449   settings.endArray();
450 }
451
452
453 /*
454 void MainWindow::populateFavorites()
455 {
456   QSettings settings("pietrzak.org", "Pierogi");
457
458   int size = settings.beginReadArray("favorites");
459   int index = 0;
460   QString make;
461   QString name;
462   PIRKeysetWidgetItem *kwi;
463
464   while (index < size)
465   {
466     settings.setArrayIndex(index);
467     make = settings.value("keysetMake").toString();
468     name = settings.value("keysetName").toString();
469
470     kwi = myKeysets->makeKeysetItem(make, name);
471
472     // Did the item creation work?
473     if (kwi)
474     {
475       // Keyset does exist, so continue:
476       favoritesDialog->addItem(kwi);
477     }
478
479     ++index;
480   }
481
482   settings.endArray();
483 }
484 */
485
486
487 void MainWindow::startRepeating(
488   PIRKeyName name)
489 {
490   QMutexLocker locker(&commandIFMutex);
491   if (!commandInFlight)
492   {
493     commandInFlight = true;
494     emit buttonPressed(currentKeyset, name);
495   }
496 }
497
498
499 void MainWindow::startRepeating(
500   PIRKeyName name,
501   unsigned int keysetID)
502 {
503   QMutexLocker locker(&commandIFMutex);
504   if (!commandInFlight)
505   {
506     commandInFlight = true;
507     emit buttonPressed(keysetID, name);
508   }
509 }
510
511
512 void MainWindow::stopRepeating()
513 {
514   QMutexLocker locker(&stopRepeatingMutex);
515   stopRepeatingFlag = true;
516 }
517
518
519 void MainWindow::selectPrevFavKeyset()
520 {
521   favoritesDialog->selectPrevFavKeyset();
522 }
523
524
525 void MainWindow::selectNextFavKeyset()
526 {
527   favoritesDialog->selectNextFavKeyset();
528 }
529
530
531 void MainWindow::insertCornerButtons()
532 {
533   // Set up the dialog boxes:
534   PIRTabsChoiceDialog *tcd = new PIRTabsChoiceDialog(this);
535 //  favoritesDialog = new PIRFavoritesDialog(this);
536
537   // Next, set up the corner buttons:
538   QPushButton *button =
539     new QPushButton(QIcon(":/icons/folder_plus_icon&32.png"), "");
540
541   button->setFlat(true);
542
543   connect(
544     button,
545     SIGNAL(clicked()),
546     tcd,
547     SLOT(exec()),
548     Qt::QueuedConnection);
549
550   ui->mainTabWidget->setCornerWidget(button, Qt::TopRightCorner);
551
552   button =
553     new QPushButton(QIcon(":/icons/align_just_icon&32.png"), "");
554
555   button->setFlat(true);
556
557   connect(
558     button,
559     SIGNAL(clicked()),
560     favoritesDialog,
561     SLOT(exec()),
562     Qt::QueuedConnection);
563
564   ui->mainTabWidget->setCornerWidget(button, Qt::TopLeftCorner);
565 }
566
567
568 void MainWindow::disableUpdates()
569 {
570   ui->mainTabWidget->setUpdatesEnabled(false);
571 }
572
573
574 void MainWindow::enableUpdates()
575 {
576   ui->mainTabWidget->setUpdatesEnabled(true);
577 }
578
579
580 void MainWindow::clearTabs()
581 {
582   ui->mainTabWidget->clear();
583 }
584
585
586 void MainWindow::addTab(
587   QWidget *page,
588   QString label)
589 {
590   ui->mainTabWidget->addTab(page, label);
591 }
592
593 void MainWindow::setupTabs(
594   PIRTabBarName name)
595 {
596   myPanels->setupTabs(name);
597 }
598
599
600 bool MainWindow::selectNextKeyset()
601 {
602   return selectKeysetForm->selectNextKeyset();
603 }
604
605
606 bool MainWindow::selectPrevKeyset()
607 {
608   return selectKeysetForm->selectPrevKeyset();
609 }