Merge lp:~daggerstab/stellarium/oculars-gui-improvement into lp:stellarium

Proposed by Bogdan Marinov
Status: Merged
Merged at revision: 5050
Proposed branch: lp:~daggerstab/stellarium/oculars-gui-improvement
Merge into: lp:stellarium
Diff against target: 3693 lines (+2317/-478)
16 files modified
doc/plugIns.doxygen (+8/-1)
plugins/Oculars/resources/Oculars.qrc (+16/-9)
plugins/Oculars/src/CMakeLists.txt (+3/-0)
plugins/Oculars/src/Oculars.cpp (+467/-170)
plugins/Oculars/src/Oculars.hpp (+47/-14)
plugins/Oculars/src/gui/OcularDialog.cpp (+154/-12)
plugins/Oculars/src/gui/OcularDialog.hpp (+12/-2)
plugins/Oculars/src/gui/OcularsGuiPanel.cpp (+954/-0)
plugins/Oculars/src/gui/OcularsGuiPanel.hpp (+137/-0)
plugins/Oculars/src/gui/PropertyBasedTableModel.cpp (+26/-0)
plugins/Oculars/src/gui/PropertyBasedTableModel.hpp (+3/-0)
plugins/Oculars/src/gui/ocularDialog.ui (+352/-200)
src/gui/StelGui.cpp (+2/-0)
src/gui/StelGui.hpp (+4/-0)
src/gui/StelGuiItems.cpp (+123/-70)
src/gui/StelGuiItems.hpp (+9/-0)
To merge this branch: bzr merge lp:~daggerstab/stellarium/oculars-gui-improvement
Reviewer Review Type Date Requested Status
Alexander Wolf Approve
treaves Pending
Review via email: mp+83349@code.launchpad.net

This proposal supersedes a proposal from 2011-11-13.

Description of the change

The original name of this branch was "plugins-gui-improvements", but I've changed it to better reflect the contents. It introduces two main changes.

One is a small change to StelGui allowing plug-ins to draw on the same QGraphics widget as the rest of Stellarium's GUI elements.

All of the other changes are to the Oculars plug-in:
- A GUI control panel with buttons has been added in the upper-right corner of the screen. It can be toggled in the configuration window.
- I found what was the problem with the keyboard shortcuts in the pop-up menu. Now it uses the standard "underlined letters" approach and the plug-in is usable with the keyboard only. The menu has been restructured to avoid duplicate shortcut keys.
- The "About" tab of the configuration window is now dynamically filled, including the proper names of the shortcut codes. It should be able to automatically display "Ctrl" and "Cmd" on the appropriate platforms (this should be tested). This will also make easier to make it translateable.
- Buttons allowing change of the order of the items in the lists in the configuration window.
- Fixed the inappropriate flipping of the binoculars view that happened sometimes.
- Fixed a bug with changing the key binding of the "actionShow_Ocular" action.
- And some other stuff - see the revision log below.

I was going to bump the version number, but apparently it is tracked only in the configuration file. As there have been no changes to the format, I decided to skip it.

There were a few more things that I'd like to do, but I'll do them after the merge, if I bother at all.

And if the merge is approved, I'd like to be the one to do it.

To post a comment you must log in.
Revision history for this message
treaves (treaves) wrote : Posted in a previous version of this proposal

The menu still does not work for me; I hit the letters, and nothing happens. This could be a Qt bug however. Not sure.

Revision history for this message
treaves (treaves) wrote : Posted in a previous version of this proposal

As the menu didn't work before, that it still does not is no big deal.

review: Approve
Revision history for this message
Bogdan Marinov (daggerstab) wrote : Posted in a previous version of this proposal

OK, according to Alexander Wolf, the latest revision enables the shortcuts on Mac. Apparently, they are disabled by default because they don't fit in Apple's design philosophy or something.

More info:
http://doc.qt.nokia.com/stable/qshortcut.html#details
http://doc.qt.nokia.com/stable/qtglobal.html#qt_set_sequence_auto_mnemonic

Unfortunately, this means that the underlines indicating the shortcuts are simply not displayed on a Mac and, by default, on Windows 7 (though this can be changed in the user settings). And this kills the whole idea. :(

Something that needs to be experimented with: using QActions like in your orignal implementation, but with setting their shortcut context to Qt::WidgetShortcut or some of the other values:
http://doc.qt.nokia.com/stable/qaction.html#shortcutContext-prop

QMenu::addAction() returns a pointer to the action, so calling setShortcut() for each menu item will be easy.

I don't have time to experiment with this right now, so I'm inclined to merge the code in its current implementation and make the adjustment later.

Revision history for this message
Alexander Wolf (alexwolf) wrote :

Shortcuts on Mac are underlined

Revision history for this message
Alexander Wolf (alexwolf) :
review: Approve
Revision history for this message
Bogdan Marinov (daggerstab) wrote :

Really? According to the Qt documentation, they shouldn't be. :)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'doc/plugIns.doxygen'
2--- doc/plugIns.doxygen 2010-12-03 12:04:33 +0000
3+++ doc/plugIns.doxygen 2011-11-24 21:50:30 +0000
4@@ -48,7 +48,14 @@
5 @section code Coding
6 A plugin should contain a main class deriving from the StelModule class as well as an instance of the StelPluginInterface which allows Stellarium to load it. At startup, the StelModuleMgr will load the library, and an instance of the StelModule it contains will be instantiated and added to the list of other "normal" StelModules.
7
8-<em>Plugin developers - please note that classes used in plugins must inherit code from the core which is published under the GUN GPL. <b>If you distribute a binary plugin, you must do so under the terms of the same GNU GPL license that Stellarium uses.</b> No sneaky closed-source shenanigans now.</em>
9+A plugin can interact with the users in many ways, not limited to:
10+ - painting directly on the viewport like other StelModules (see the examples below);
11+ - defining <a href="http://doc.qt.nokia.com/latest/qaction.html">QActions</a> triggered with keyboard shortcut combinations with StelGui::addGuiActions();
12+ - buttons (StelButton) added to the bottom button bar (BottomStelBar; see the examples below);
13+ - windows (subclasses of StelDialog) that can be designed with Qt's UI editor (see the examples and the configuration windows of the official plugins);
14+ - custom controls displayed anywhere on the screen based on any of the classes that inherit <a href="http://doc.qt.nokia.com/latest/qgraphicsitem.html">QGraphicsItem</a> (see <a href="http://doc.qt.nokia.com/latest/graphicsview.html">the documentation of Qt's Graphics View Framework</a>). To get a base widget to work on, use StelGui::getSkyGui().
15+
16+<em>Plugin developers - please note that classes used in plugins must inherit code from the core which is published under the GNU GPL. <strong>If you distribute a binary plugin, you must do so under the terms of the same GNU General Public License that Stellarium uses</strong> (as of August 2011, this is GNU GPL "version 2 or any later version"). No sneaky closed-source shenanigans now.</em>
17
18 @section examplePlugins Example Plugins
19
20
21=== modified file 'plugins/Oculars/resources/Oculars.qrc'
22--- plugins/Oculars/resources/Oculars.qrc 2010-03-26 13:37:41 +0000
23+++ plugins/Oculars/resources/Oculars.qrc 2011-11-24 21:50:30 +0000
24@@ -1,10 +1,17 @@
25-<!DOCTYPE RCC>
26-<RCC version="1.0">
27- <qresource prefix="ocular" >
28- <file>bt_ocular_on.png</file>
29- <file>bt_ocular_off.png</file>
30- <file>normalStyle.css</file>
31- <file>nightStyle.css</file>
32- <file>default_ocular.ini</file>
33- </qresource>
34+<RCC>
35+ <qresource prefix="/ocular">
36+ <file>bt_ocular_on.png</file>
37+ <file>bt_ocular_off.png</file>
38+ <file>normalStyle.css</file>
39+ <file>nightStyle.css</file>
40+ <file>default_ocular.ini</file>
41+ <file>bt_crosshairs_off.png</file>
42+ <file>bt_crosshairs_on.png</file>
43+ <file>bt_sensor_off.png</file>
44+ <file>bt_sensor_on.png</file>
45+ <file>bt_telrad_off.png</file>
46+ <file>bt_telrad_on.png</file>
47+ <file>bt_settings_off.png</file>
48+ <file>bt_settings_on.png</file>
49+ </qresource>
50 </RCC>
51
52=== added file 'plugins/Oculars/resources/bt_crosshairs_off.png'
53Binary files plugins/Oculars/resources/bt_crosshairs_off.png 1970-01-01 00:00:00 +0000 and plugins/Oculars/resources/bt_crosshairs_off.png 2011-11-24 21:50:30 +0000 differ
54=== added file 'plugins/Oculars/resources/bt_crosshairs_on.png'
55Binary files plugins/Oculars/resources/bt_crosshairs_on.png 1970-01-01 00:00:00 +0000 and plugins/Oculars/resources/bt_crosshairs_on.png 2011-11-24 21:50:30 +0000 differ
56=== modified file 'plugins/Oculars/resources/bt_ocular_off.png'
57Binary files plugins/Oculars/resources/bt_ocular_off.png 2010-01-22 17:37:33 +0000 and plugins/Oculars/resources/bt_ocular_off.png 2011-11-24 21:50:30 +0000 differ
58=== modified file 'plugins/Oculars/resources/bt_ocular_on.png'
59Binary files plugins/Oculars/resources/bt_ocular_on.png 2010-01-22 17:37:33 +0000 and plugins/Oculars/resources/bt_ocular_on.png 2011-11-24 21:50:30 +0000 differ
60=== added file 'plugins/Oculars/resources/bt_sensor_off.png'
61Binary files plugins/Oculars/resources/bt_sensor_off.png 1970-01-01 00:00:00 +0000 and plugins/Oculars/resources/bt_sensor_off.png 2011-11-24 21:50:30 +0000 differ
62=== added file 'plugins/Oculars/resources/bt_sensor_on.png'
63Binary files plugins/Oculars/resources/bt_sensor_on.png 1970-01-01 00:00:00 +0000 and plugins/Oculars/resources/bt_sensor_on.png 2011-11-24 21:50:30 +0000 differ
64=== added file 'plugins/Oculars/resources/bt_settings_off.png'
65Binary files plugins/Oculars/resources/bt_settings_off.png 1970-01-01 00:00:00 +0000 and plugins/Oculars/resources/bt_settings_off.png 2011-11-24 21:50:30 +0000 differ
66=== added file 'plugins/Oculars/resources/bt_settings_on.png'
67Binary files plugins/Oculars/resources/bt_settings_on.png 1970-01-01 00:00:00 +0000 and plugins/Oculars/resources/bt_settings_on.png 2011-11-24 21:50:30 +0000 differ
68=== added file 'plugins/Oculars/resources/bt_telrad_off.png'
69Binary files plugins/Oculars/resources/bt_telrad_off.png 1970-01-01 00:00:00 +0000 and plugins/Oculars/resources/bt_telrad_off.png 2011-11-24 21:50:30 +0000 differ
70=== added file 'plugins/Oculars/resources/bt_telrad_on.png'
71Binary files plugins/Oculars/resources/bt_telrad_on.png 1970-01-01 00:00:00 +0000 and plugins/Oculars/resources/bt_telrad_on.png 2011-11-24 21:50:30 +0000 differ
72=== modified file 'plugins/Oculars/src/CMakeLists.txt'
73--- plugins/Oculars/src/CMakeLists.txt 2011-01-06 20:50:30 +0000
74+++ plugins/Oculars/src/CMakeLists.txt 2011-11-24 21:50:30 +0000
75@@ -19,6 +19,8 @@
76 gui/OcularDialog.cpp
77 gui/PropertyBasedTableModel.hpp
78 gui/PropertyBasedTableModel.cpp
79+ gui/OcularsGuiPanel.hpp
80+ gui/OcularsGuiPanel.cpp
81 )
82
83 SET(Oculars_RES ../resources/Oculars.qrc)
84@@ -39,6 +41,7 @@
85 Telescope.hpp
86 gui/OcularDialog.hpp
87 gui/PropertyBasedTableModel.hpp
88+ gui/OcularsGuiPanel.hpp
89 )
90
91 # After this call, Oculars_MOC_SRCS = moc_Oculars.cxx
92
93=== modified file 'plugins/Oculars/src/Oculars.cpp'
94--- plugins/Oculars/src/Oculars.cpp 2011-11-12 22:55:30 +0000
95+++ plugins/Oculars/src/Oculars.cpp 2011-11-24 21:50:30 +0000
96@@ -1,5 +1,6 @@
97 /*
98 * Copyright (C) 2009 Timothy Reaves
99+ * Copyright (C) 2011 Bogdan Marinov
100 *
101 * This program is free software; you can redistribute it and/or
102 * modify it under the terms of the GNU General Public License
103@@ -17,6 +18,7 @@
104 */
105
106 #include "Oculars.hpp"
107+#include "OcularsGuiPanel.hpp"
108
109 #include "GridLinesMgr.hpp"
110 #include "LabelMgr.hpp"
111@@ -33,8 +35,10 @@
112 #include "StelGuiItems.hpp"
113 #include "StelMainWindow.hpp"
114 #include "StelTranslator.hpp"
115+#include "SkyGui.hpp"
116
117 #include <QAction>
118+#include <QGraphicsWidget>
119 #include <QKeyEvent>
120 #include <QDebug>
121 #include <QMenu>
122@@ -51,6 +55,10 @@
123 #include <GL/glu.h> /* Header File For The GLU Library */
124 #endif
125
126+#ifdef Q_WS_MAC
127+extern void qt_set_sequence_auto_mnemonic(bool b);
128+#endif
129+
130 static QSettings *settings; //!< The settings as read in from the ini file.
131
132 /* ********************************************************************* */
133@@ -74,7 +82,7 @@
134 StelPluginInfo info;
135 info.id = "Oculars";
136 info.displayedName = N_("Oculars");
137- info.authors = "Timothy Reaves";
138+ info.authors = "Timothy Reaves, Bogdan Marinov";
139 info.contact = "treaves@silverfieldstech.com";
140 info.description = N_("Shows the sky as if looking through a telescope eyepiece. (Only magnification and field of view are simulated.) It can also show a sensor frame and a Telrad sight.");
141 return info;
142@@ -89,7 +97,16 @@
143 #pragma mark Instance Methods
144 #endif
145 /* ********************************************************************* */
146-Oculars::Oculars() : pxmapGlow(NULL), pxmapOnIcon(NULL), pxmapOffIcon(NULL), toolbarButton(NULL)
147+Oculars::Oculars():
148+ pxmapGlow(NULL),
149+ pxmapOnIcon(NULL),
150+ pxmapOffIcon(NULL),
151+ toolbarButton(NULL),
152+ actionShowOcular(0),
153+ actionShowCrosshairs(0),
154+ actionShowSensor(0),
155+ actionShowTelrad(0),
156+ guiPanel(0)
157 {
158 flagShowCCD = false;
159 flagShowOculars = false;
160@@ -118,12 +135,17 @@
161
162 setObjectName("Oculars");
163
164+#ifdef Q_WS_MAC
165+ qt_set_sequence_auto_mnemonic(true);
166+#endif
167 }
168
169 Oculars::~Oculars()
170 {
171 delete ocularDialog;
172 ocularDialog = NULL;
173+ if (guiPanel)
174+ delete guiPanel;
175
176 if (pxmapGlow)
177 delete pxmapGlow;
178@@ -211,7 +233,7 @@
179 if (flagShowTelrad) {
180 paintTelrad();
181 } else if (flagShowOculars){
182- // Insure there is a selected ocular & telescope
183+ // Ensure there is a selected ocular & telescope
184 if (selectedCCDIndex > ccds.count()) {
185 qWarning() << "Oculars: the selected sensor index of "
186 << selectedCCDIndex << " is greater than the sensor count of "
187@@ -238,17 +260,37 @@
188 paintCrosshairs();
189 }
190 }
191+ if (guiPanelEnabled)
192+ {
193+ // Reset the state to allow the panel to be painted normally
194+ glDisable(GL_TEXTURE_2D);
195+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
196+ glEnable(GL_BLEND);
197+ }
198+ else
199+ {
200+ // Paint the information in the upper-right hand corner
201+ paintText(core);
202+ }
203+ }
204+ } else if (flagShowCCD) {
205+ paintCCDBounds();
206+ if (guiPanelEnabled)
207+ {
208+ // Reset the state to allow the panel to be painted normally
209+ glDisable(GL_TEXTURE_2D);
210+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
211+ glEnable(GL_BLEND);
212+ }
213+ else
214+ {
215 // Paint the information in the upper-right hand corner
216 paintText(core);
217 }
218- } else if (flagShowCCD) {
219- paintCCDBounds();
220- // Paint the information in the upper-right hand corner
221- paintText(core);
222- }
223+ }
224 }
225
226-//! Determine which "layer" the plagin's drawing will happen on.
227+//! Determine which "layer" the plugin's drawing will happen on.
228 double Oculars::getCallOrder(StelModuleActionName actionName) const
229 {
230 // TODO; this really doesn't seem to have any effect. I've tried everything from -100 to +100,
231@@ -287,12 +329,7 @@
232 movementManager->setFlagTracking(true);
233 } else {
234 // remove the usage label if it is being displayed.
235- if (usageMessageLabelID > -1) {
236- LabelMgr *labelManager = GETSTELMODULE(LabelMgr);
237- labelManager->setLabelShow(usageMessageLabelID, false);
238- labelManager->deleteLabel(usageMessageLabelID);
239- usageMessageLabelID = -1;
240- }
241+ hideUsageMessageIfDisplayed();
242 }
243 } else if(flagShowOculars) {
244 //TODO: this is broke in Stellarium.
245@@ -465,9 +502,12 @@
246 selectedTelescopeIndex = 0;
247 }
248
249- ocularDialog = new OcularDialog(&ccds, &oculars, &telescopes);
250+ ocularDialog = new OcularDialog(this, &ccds, &oculars, &telescopes);
251 initializeActivationActions();
252 determineMaxEyepieceAngle();
253+
254+ guiPanelEnabled = settings->value("enable_control_panel", false).toBool();
255+ enableGuiPanel(guiPanelEnabled);
256 } catch (std::runtime_error& e) {
257 qWarning() << "WARNING: unable to locate ocular.ini file or create a default one for Ocular plugin: " << e.what();
258 ready = false;
259@@ -553,12 +593,84 @@
260 }
261 }
262
263+void Oculars::enableGuiPanel(bool enable)
264+{
265+ if (enable)
266+ {
267+ if (!guiPanel)
268+ {
269+ StelApp& app = StelApp::getInstance();
270+ StelGui* gui = dynamic_cast<StelGui*>(app.getGui());
271+ Q_ASSERT(gui);
272+ guiPanel = new OcularsGuiPanel(this, gui->getSkyGui());
273+ }
274+ }
275+ else
276+ {
277+ if (guiPanel)
278+ {
279+ guiPanel->hide();
280+ delete guiPanel;
281+ guiPanel = 0;
282+ }
283+ }
284+ guiPanelEnabled = enable;
285+ settings->setValue("enable_control_panel", enable);
286+ settings->sync();
287+}
288+
289 /* ********************************************************************* */
290 #if 0
291 #pragma mark -
292 #pragma mark Slots Methods
293 #endif
294 /* ********************************************************************* */
295+void Oculars::updateLists()
296+{
297+ if (oculars.isEmpty())
298+ {
299+ selectedOcularIndex = -1;
300+ actionShowOcular->setChecked(false);
301+ }
302+ else
303+ {
304+ if (selectedOcularIndex >= oculars.count())
305+ selectedOcularIndex = oculars.count() - 1;
306+
307+ if (flagShowOculars)
308+ emit selectedOcularChanged();
309+ }
310+
311+ if (telescopes.isEmpty())
312+ {
313+ selectedTelescopeIndex = -1;
314+ actionShowOcular->setChecked(false);
315+ actionShowSensor->setChecked(false);
316+ }
317+ else
318+ {
319+ if (selectedTelescopeIndex >= telescopes.count())
320+ selectedTelescopeIndex = telescopes.count() - 1;
321+
322+ if (flagShowOculars || flagShowCCD)
323+ emit selectedTelescopeChanged();
324+ }
325+
326+ if (ccds.isEmpty())
327+ {
328+ selectedCCDIndex = -1;
329+ actionShowSensor->setChecked(false);
330+ }
331+ else
332+ {
333+ if (selectedCCDIndex >= ccds.count())
334+ selectedCCDIndex = ccds.count() - 1;
335+
336+ if (flagShowCCD)
337+ emit selectedCCDChanged();
338+ }
339+}
340+
341 void Oculars::ccdRotationReset()
342 {
343 ccdRotationAngle = 0.0;
344@@ -566,14 +678,25 @@
345
346 void Oculars::enableOcular(bool enableOcularMode)
347 {
348- // If showing a CCD, cancel it.
349- if (flagShowCCD) {
350- flagShowCCD = false;
351- selectedCCDIndex = -1;
352- }
353-
354- if (enableOcularMode) {
355- // Check to insure that we have enough oculars & telescopes, as they may have been edited in the config dialog
356+ if (enableOcularMode)
357+ {
358+ // Close the sensor view if it's displayed
359+ if (flagShowCCD)
360+ {
361+ if (actionShowSensor->isChecked())
362+ actionShowSensor->setChecked(false);
363+ flagShowCCD = false;
364+ selectedCCDIndex = -1;
365+ }
366+
367+ // Close the Telrad sight if it's displayed
368+ if (flagShowTelrad)
369+ {
370+ if (actionShowTelrad->isChecked())
371+ actionShowTelrad->setChecked(false);
372+ }
373+
374+ // Check to ensure that we have enough oculars & telescopes, as they may have been edited in the config dialog
375 if (oculars.count() == 0) {
376 selectedOcularIndex = -1;
377 qWarning() << "No oculars found";
378@@ -596,11 +719,11 @@
379 StelCore *core = StelApp::getInstance().getCore();
380 LabelMgr* labelManager = GETSTELMODULE(LabelMgr);
381
382- // Toggle the plugin on & off. To toggle on, we want to ensure there is a selected object.
383+ // Toggle the ocular view on & off. To toggle on, we want to ensure there is a selected object.
384 if (!flagShowOculars && requireSelection && !StelApp::getInstance().getStelObjectMgr().getWasSelected() ) {
385 if (usageMessageLabelID == -1) {
386 QFontMetrics metrics(font);
387- QString labelText = "Please select an object before enabling Ocular.";
388+ QString labelText = "Please select an object before switching to ocular view.";
389 StelProjector::StelProjectorParams projectorParams = core->getCurrentStelProjectorParams();
390 int xPosition = projectorParams.viewportCenter[0];
391 xPosition = xPosition - 0.5 * (metrics.width(labelText));
392@@ -610,21 +733,20 @@
393 true, font.pixelSize(), "#99FF99");
394 }
395 // we didn't accept the new status - make sure the toolbar button reflects this
396- StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
397- Q_ASSERT(gui);
398- disconnect(gui->getGuiActions("actionShow_Ocular"), SIGNAL(toggled(bool)), this, SLOT(enableOcular(bool)));
399- gui->getGuiActions("actionShow_Ocular")->setChecked(false);
400- connect(gui->getGuiActions("actionShow_Ocular"), SIGNAL(toggled(bool)), this, SLOT(enableOcular(bool)));
401+ disconnect(actionShowOcular, SIGNAL(toggled(bool)),
402+ this, SLOT(enableOcular(bool)));
403+ actionShowOcular->setChecked(false);
404+ connect(actionShowOcular, SIGNAL(toggled(bool)),
405+ this, SLOT(enableOcular(bool)));
406 } else {
407 if (selectedOcularIndex != -1) {
408 // remove the usage label if it is being displayed.
409- if (usageMessageLabelID > -1) {
410- labelManager->setLabelShow(usageMessageLabelID, false);
411- labelManager->deleteLabel(usageMessageLabelID);
412- usageMessageLabelID = -1;
413- }
414+ hideUsageMessageIfDisplayed();
415 flagShowOculars = enableOcularMode;
416 zoom(false);
417+ //BM: I hope this is the right place...
418+ if (guiPanel)
419+ guiPanel->showOcularGui();
420 }
421 }
422 }
423@@ -632,7 +754,7 @@
424 void Oculars::decrementCCDIndex()
425 {
426 selectedCCDIndex--;
427- if (selectedCCDIndex == -2) {
428+ if (selectedCCDIndex == -1) {
429 selectedCCDIndex = ccds.count() - 1;
430 }
431 emit(selectedCCDChanged());
432@@ -671,136 +793,165 @@
433
434 void Oculars::displayPopupMenu()
435 {
436- QMenu* popup = new QMenu();
437+ QMenu* popup = new QMenu(&StelMainWindow::getInstance());
438
439- if (flagShowOculars) {
440+ if (flagShowOculars)
441+ {
442 // We are in Oculars mode
443 // We want to show all of the Oculars, and if the current ocular is not a binocular,
444 // we will also show the telescopes.
445- if (oculars.count() > 0) {
446- popup->addAction("previous ocular", this, SLOT(decrementOcularIndex()), Qt::Key_1);
447- popup->addAction("next ocular", this, SLOT(incrementOcularIndex()), Qt::Key_2);
448- QMenu* submenu = new QMenu("select ocular", popup);
449+ if (!oculars.isEmpty())
450+ {
451+ popup->addAction("&Previous ocular", this, SLOT(decrementOcularIndex()));
452+ popup->addAction("&Next ocular", this, SLOT(incrementOcularIndex()));
453+ QMenu* submenu = new QMenu("Select &ocular", popup);
454 int availableOcularCount = 0;
455- for (int index = 0; index < oculars.count(); ++index) {
456+ for (int index = 0; index < oculars.count(); ++index)
457+ {
458+ QString label;
459+ if (availableOcularCount < 10)
460+ {
461+ label = QString("&%1: %2").arg(availableOcularCount).arg(oculars[index]->name());
462+ }
463+ else
464+ {
465+ label = oculars[index]->name();
466+ }
467+ //BM: Does this happen at all any more?
468+ QAction* action = 0;
469 if (selectedTelescopeIndex == -1) {
470 if (oculars[index]->isBinoculars()) {
471- QAction* action = submenu->addAction(oculars[index]->name(), ocularsSignalMapper, SLOT(map()),
472- QKeySequence(QString("%1").arg(availableOcularCount++)));
473+ action = submenu->addAction(label, ocularsSignalMapper, SLOT(map()));
474+ availableOcularCount++;
475 ocularsSignalMapper->setMapping(action, QString("%1").arg(index));
476 }
477 } else {
478- QAction* action = submenu->addAction(oculars[index]->name(), ocularsSignalMapper, SLOT(map()),
479- QKeySequence(QString("%1").arg(availableOcularCount++)));
480+ action = submenu->addAction(label, ocularsSignalMapper, SLOT(map()));
481+ availableOcularCount++;
482 ocularsSignalMapper->setMapping(action, QString("%1").arg(index));
483 }
484- }
485- popup->addMenu(submenu);
486- popup->addSeparator();
487- }
488-
489- if (telescopes.count() > 0 && (selectedOcularIndex > -1 && !oculars[selectedOcularIndex]->isBinoculars())) {
490- popup->addAction("previous telescope", this, SLOT(decrementTelescopeIndex()), Qt::Key_3);
491- popup->addAction("next telescope", this, SLOT(incrementTelescopeIndex()), Qt::Key_4);
492- QMenu* submenu = new QMenu("select telescope", popup);
493- for (int index = 0; index < telescopes.count(); ++index) {
494- QAction* action = submenu->addAction(telescopes[index]->name(), telescopesSignalMapper, SLOT(map()),
495- QKeySequence(QString("%1").arg(index)));
496- telescopesSignalMapper->setMapping(action, QString("%1").arg(index));
497- }
498- popup->addMenu(submenu);
499- popup->addSeparator();
500- }
501-
502- popup->addAction("toggle crosshair", this, SLOT(toggleCrosshair()), Qt::Key_5);
503+ if (action && index == selectedOcularIndex)
504+ {
505+ action->setCheckable(true);
506+ action->setChecked(true);
507+ }
508+ }
509+ popup->addMenu(submenu);
510+ popup->addSeparator();
511+ }
512+
513+ // If there is more than one telescope, show the prev/next/list complex.
514+ // If the selected ocular is a binoculars, show nothing.
515+ if (telescopes.count() > 1 && (selectedOcularIndex > -1 && !oculars[selectedOcularIndex]->isBinoculars()))
516+ {
517+ QMenu* submenu = addTelescopeSubmenu(popup);
518+ popup->addMenu(submenu);
519+ popup->addSeparator();
520+ }
521+
522+ QAction* action = popup->addAction("Toggle &crosshair");
523+ action->setCheckable(true);
524+ action->setChecked(flagShowCrosshairs);
525+ connect(action, SIGNAL(toggled(bool)),
526+ actionShowCrosshairs, SLOT(setChecked(bool)));
527 } else {
528- int outerMenuLevel = 1;
529- // We are not in Oculars mode
530- // We want to show the CCD's, and if a CCD is selected, the Telescopes (as a CCD requires a telescope),
531- // and the general menu items.
532- QAction* action = new QAction("Configure Oculars", popup);
533- action->setCheckable(TRUE);
534- action->setShortcut(QString("%1").arg(outerMenuLevel++));
535- connect(action, SIGNAL(toggled(bool)), ocularDialog, SLOT(setVisible(bool)));
536- connect(ocularDialog, SIGNAL(visibleChanged(bool)), action, SLOT(setChecked(bool)));
537+ // We are not in ocular mode
538+ // We want to show the CCD's, and if a CCD is selected, the telescopes
539+ //(as a CCD requires a telescope) and the general menu items.
540+ QAction* action = new QAction("Configure &Oculars", popup);
541+ action->setCheckable(true);
542+ action->setChecked(ocularDialog->visible());
543+ connect(action, SIGNAL(triggered(bool)),
544+ ocularDialog, SLOT(setVisible(bool)));
545 popup->addAction(action);
546 popup->addSeparator();
547
548 if (!flagShowTelrad) {
549- popup->addAction("Toggle CCD", this, SLOT(toggleCCD()), QKeySequence(QString("%1").arg(outerMenuLevel++)));
550+ QAction* action = popup->addAction("Toggle &CCD");
551+ action->setCheckable(true);
552+ action->setChecked(flagShowCCD);
553+ connect(action, SIGNAL(toggled(bool)),
554+ actionShowSensor, SLOT(setChecked(bool)));
555 }
556
557 if (!flagShowCCD) {
558- popup->addAction("Toggle Telrad", this,
559- SLOT(toggleTelrad()), QKeySequence(QString("%1").arg(outerMenuLevel++)));
560+ QAction* action = popup->addAction("Toggle &Telrad");
561+ action->setCheckable(true);
562+ action->setChecked(flagShowTelrad);
563+ connect(action, SIGNAL(toggled(bool)),
564+ actionShowTelrad, SLOT(setChecked(bool)));
565 }
566-
567+
568 popup->addSeparator();
569- if (selectedCCDIndex > -1 && selectedTelescopeIndex > -1) {
570- popup->addAction("previous CCD", this,
571- SLOT(decrementCCDIndex()), QKeySequence(QString("%1").arg(outerMenuLevel++)));
572- popup->addAction("next CCD", this,
573- SLOT(incrementCCDIndex()), QKeySequence(QString("%1").arg(outerMenuLevel++)));
574- QMenu* submenu = new QMenu("select CCD", popup);
575- for (int index = 0; index < ccds.count(); ++index) {
576- QAction* action = submenu->addAction(ccds[index]->name(), ccdsSignalMapper, SLOT(map()),
577- QKeySequence(QString("%1").arg(index)));
578+ if (flagShowCCD && selectedCCDIndex > -1 && selectedTelescopeIndex > -1)
579+ {
580+ popup->addAction("&Previous CCD", this, SLOT(decrementCCDIndex()));
581+ popup->addAction("&Next CCD", this, SLOT(incrementCCDIndex()));
582+ QMenu* submenu = new QMenu("&Select CCD", popup);
583+ for (int index = 0; index < ccds.count(); ++index)
584+ {
585+ QString label;
586+ if (index < 10)
587+ {
588+ label = QString("&%1: %2").arg(index).arg(ccds[index]->name());
589+ }
590+ else
591+ {
592+ label = ccds[index]->name();
593+ }
594+ QAction* action = submenu->addAction(label, ccdsSignalMapper, SLOT(map()));
595+ if (index == selectedCCDIndex)
596+ {
597+ action->setCheckable(true);
598+ action->setChecked(true);
599+ }
600 ccdsSignalMapper->setMapping(action, QString("%1").arg(index));
601 }
602 popup->addMenu(submenu);
603
604- submenu = new QMenu("Rotate CCD", popup);
605+ submenu = new QMenu("&Rotate CCD", popup);
606 QAction* rotateAction = NULL;
607- rotateAction = submenu->addAction(QString("-90") + QChar(0x00B0),
608- ccdRotationSignalMapper, SLOT(map()), Qt::Key_1);
609+ rotateAction = submenu->addAction(QString("&1: -90") + QChar(0x00B0),
610+ ccdRotationSignalMapper, SLOT(map()));
611 ccdRotationSignalMapper->setMapping(rotateAction, QString("-90"));
612- rotateAction = submenu->addAction(QString("-45") + QChar(0x00B0),
613- ccdRotationSignalMapper, SLOT(map()), Qt::Key_2);
614+ rotateAction = submenu->addAction(QString("&2: -45") + QChar(0x00B0),
615+ ccdRotationSignalMapper, SLOT(map()));
616 ccdRotationSignalMapper->setMapping(rotateAction, QString("-45"));
617- rotateAction = submenu->addAction(QString("-15") + QChar(0x00B0),
618- ccdRotationSignalMapper, SLOT(map()), Qt::Key_3);
619+ rotateAction = submenu->addAction(QString("&3: -15") + QChar(0x00B0),
620+ ccdRotationSignalMapper, SLOT(map()));
621 ccdRotationSignalMapper->setMapping(rotateAction, QString("-15"));
622- rotateAction = submenu->addAction(QString("-5") + QChar(0x00B0),
623- ccdRotationSignalMapper, SLOT(map()), Qt::Key_4);
624+ rotateAction = submenu->addAction(QString("&4: -5") + QChar(0x00B0),
625+ ccdRotationSignalMapper, SLOT(map()));
626 ccdRotationSignalMapper->setMapping(rotateAction, QString("-5"));
627- rotateAction = submenu->addAction(QString("-1") + QChar(0x00B0),
628- ccdRotationSignalMapper, SLOT(map()), Qt::Key_5);
629+ rotateAction = submenu->addAction(QString("&5: -1") + QChar(0x00B0),
630+ ccdRotationSignalMapper, SLOT(map()));
631 ccdRotationSignalMapper->setMapping(rotateAction, QString("-1"));
632- rotateAction = submenu->addAction(QString("+1") + QChar(0x00B0),
633- ccdRotationSignalMapper, SLOT(map()), Qt::Key_6);
634+ rotateAction = submenu->addAction(QString("&6: +1") + QChar(0x00B0),
635+ ccdRotationSignalMapper, SLOT(map()));
636 ccdRotationSignalMapper->setMapping(rotateAction, QString("1"));
637- rotateAction = submenu->addAction(QString("+5") + QChar(0x00B0),
638- ccdRotationSignalMapper, SLOT(map()), Qt::Key_7);
639+ rotateAction = submenu->addAction(QString("&7: +5") + QChar(0x00B0),
640+ ccdRotationSignalMapper, SLOT(map()));
641 ccdRotationSignalMapper->setMapping(rotateAction, QString("5"));
642- rotateAction = submenu->addAction(QString("+15") + QChar(0x00B0),
643- ccdRotationSignalMapper, SLOT(map()), Qt::Key_8);
644+ rotateAction = submenu->addAction(QString("&8: +15") + QChar(0x00B0),
645+ ccdRotationSignalMapper, SLOT(map()));
646 ccdRotationSignalMapper->setMapping(rotateAction, QString("15"));
647- rotateAction = submenu->addAction(QString("+45") + QChar(0x00B0),
648- ccdRotationSignalMapper, SLOT(map()), Qt::Key_9);
649+ rotateAction = submenu->addAction(QString("&9: +45") + QChar(0x00B0),
650+ ccdRotationSignalMapper, SLOT(map()));
651 ccdRotationSignalMapper->setMapping(rotateAction, QString("45"));
652- rotateAction = submenu->addAction(QString("+90") + QChar(0x00B0),
653- ccdRotationSignalMapper, SLOT(map()), Qt::Key_0);
654+ rotateAction = submenu->addAction(QString("&0: +90") + QChar(0x00B0),
655+ ccdRotationSignalMapper, SLOT(map()));
656 ccdRotationSignalMapper->setMapping(rotateAction, QString("90"));
657- rotateAction = submenu->addAction("Reset", this, SLOT(ccdRotationReset()), Qt::Key_R);
658+ rotateAction = submenu->addAction("&Reset", this, SLOT(ccdRotationReset()));
659 popup->addMenu(submenu);
660
661 popup->addSeparator();
662 }
663- if (selectedCCDIndex > -1 && telescopes.count() > 0) {
664- popup->addAction("previous telescope", this,
665- SLOT(decrementTelescopeIndex()), QKeySequence(QString("%1").arg(outerMenuLevel++)));
666- popup->addAction("next telescope", this,
667- SLOT(incrementTelescopeIndex()), QKeySequence(QString("%1").arg(outerMenuLevel++)));
668- QMenu* submenu = new QMenu("select telescope", popup);
669- for (int index = 0; index < telescopes.count(); ++index) {
670- QAction* action = submenu->addAction(telescopes[index]->name(), telescopesSignalMapper, SLOT(map()),
671- QKeySequence(QString("%1").arg(index)));
672- telescopesSignalMapper->setMapping(action, QString("%1").arg(index));
673- }
674+ if (flagShowCCD && selectedCCDIndex > -1 && telescopes.count() > 1)
675+ {
676+ QMenu* submenu = addTelescopeSubmenu(popup);
677 popup->addMenu(submenu);
678 popup->addSeparator();
679 }
680-
681 }
682
683 popup->exec(QCursor::pos());
684@@ -811,7 +962,7 @@
685 {
686 selectedCCDIndex++;
687 if (selectedCCDIndex == ccds.count()) {
688- selectedCCDIndex = -1;
689+ selectedCCDIndex = 0;
690 }
691 emit(selectedCCDChanged());
692 }
693@@ -850,6 +1001,10 @@
694 void Oculars::rotateCCD(QString amount)
695 {
696 ccdRotationAngle += amount.toInt();
697+ if (ccdRotationAngle >= 360)
698+ ccdRotationAngle -= 360;
699+ if (ccdRotationAngle <= -360)
700+ ccdRotationAngle += 360;
701 }
702
703 void Oculars::selectCCDAtIndex(QString indexString)
704@@ -891,46 +1046,103 @@
705 }
706 }
707
708-void Oculars::toggleCCD()
709+void Oculars::toggleCCD(bool show)
710 {
711- StelCore *core = StelApp::getInstance().getCore();
712- StelMovementMgr *movementManager = core->getMovementMgr();
713- if (flagShowCCD) {
714+ //If there are no sensors...
715+ if (ccds.isEmpty() || telescopes.isEmpty())
716+ {
717+ //TODO: BM: Make this an on-screen message and/or disable the button
718+ //if there are no sensors.
719+ if (show)
720+ qWarning() << "Oculars plugin: Unable to display a sensor boundary:"
721+ << "No sensors or telescopes are defined.";
722 flagShowCCD = false;
723 selectedCCDIndex = -1;
724- movementManager->zoomTo(movementManager->getInitFov());
725- movementManager->setFlagTracking(false);
726- } else {
727- // Check to insure that we have enough CCDs & telescopes, as they may have been edited in the config dialog
728- if (ccds.count() == 0) {
729- selectedCCDIndex = -1;
730- qDebug() << "No CCDs found";
731- } else if (ccds.count() > 0 && selectedCCDIndex == -1) {
732+ show = false;
733+ if (actionShowSensor->isChecked())
734+ actionShowSensor->setChecked(false);
735+ }
736+
737+ if (show)
738+ {
739+ //Mutually exclusive with the ocular mode
740+ hideUsageMessageIfDisplayed();
741+ if (flagShowOculars)
742+ {
743+ if (actionShowOcular->isChecked())
744+ actionShowOcular->setChecked(false);
745+ }
746+
747+ if (flagShowTelrad)
748+ {
749+ if (actionShowTelrad->isChecked())
750+ actionShowTelrad->setChecked(false);
751+ }
752+
753+ if (selectedTelescopeIndex < 0)
754+ selectedTelescopeIndex = 0;
755+ if (selectedCCDIndex < 0)
756 selectedCCDIndex = 0;
757- }
758- if (telescopes.count() == 0) {
759- selectedTelescopeIndex = -1;
760- qDebug() << "No telescopes found";
761- } else if (telescopes.count() > 0 && selectedTelescopeIndex == -1) {
762- selectedTelescopeIndex = 0;
763- }
764- if (!ready || selectedCCDIndex == -1 || selectedTelescopeIndex == -1 ) {
765- qDebug() << "The Oculars module has been disabled.";
766- return;
767- }
768 flagShowCCD = true;
769 setScreenFOVForCCD();
770- }
771-}
772-
773-void Oculars::toggleCrosshair()
774-{
775- flagShowCrosshairs = !flagShowCrosshairs;
776+
777+ if (guiPanel)
778+ guiPanel->showCcdGui();
779+ }
780+ else
781+ {
782+ flagShowCCD = false;
783+
784+ //Zoom out
785+ StelCore *core = StelApp::getInstance().getCore();
786+ StelMovementMgr *movementManager = core->getMovementMgr();
787+ movementManager->zoomTo(movementManager->getInitFov());
788+ movementManager->setFlagTracking(false);
789+
790+ if (guiPanel)
791+ guiPanel->foldGui();
792+ }
793+}
794+
795+void Oculars::toggleCCD()
796+{
797+ if (flagShowCCD)
798+ toggleCCD(false);
799+ else
800+ toggleCCD(true);
801+}
802+
803+void Oculars::toggleCrosshairs(bool show)
804+{
805+ if (show && flagShowOculars)
806+ {
807+ flagShowCrosshairs = true;
808+ }
809+ else
810+ {
811+ flagShowCrosshairs = false;
812+ }
813+}
814+
815+void Oculars::toggleTelrad(bool show)
816+{
817+ if (show)
818+ {
819+ hideUsageMessageIfDisplayed();
820+ if (actionShowOcular->isChecked())
821+ actionShowOcular->setChecked(false);
822+ if (actionShowSensor->isChecked())
823+ actionShowSensor->setChecked(false);
824+ }
825+ flagShowTelrad = show;
826 }
827
828 void Oculars::toggleTelrad()
829 {
830- flagShowTelrad = !flagShowTelrad;
831+ if (flagShowTelrad)
832+ toggleTelrad(false);
833+ else
834+ toggleTelrad(true);
835 }
836
837 /* ********************************************************************* */
838@@ -953,12 +1165,13 @@
839 //the necessary button is created to prevent the button from being checked
840 //the first time this action is checked. See:
841 //http://doc.qt.nokia.com/4.7/signalsandslots.html#signals
842- gui->addGuiActions("actionShow_Ocular",
843- N_("Ocular view"),
844- settings->value("bindings/toggle_oculars", "Ctrl+O").toString(),
845- N_("Plugin Key Bindings"),
846- true);
847- gui->getGuiActions("actionShow_Ocular")->setChecked(flagShowOculars);
848+ QString shortcutStr = settings->value("bindings/toggle_oculars", "Ctrl+O").toString();
849+ actionShowOcular = gui->addGuiActions("actionShow_Ocular",
850+ N_("Ocular view"),
851+ shortcutStr,
852+ group,
853+ true);
854+ actionShowOcular->setChecked(flagShowOculars);
855 // Make a toolbar button
856 try {
857 pxmapGlow = new QPixmap(":/graphicGui/glow32x32.png");
858@@ -968,19 +1181,56 @@
859 *pxmapOnIcon,
860 *pxmapOffIcon,
861 *pxmapGlow,
862- gui->getGuiActions("actionShow_Ocular"));
863+ actionShowOcular);
864 gui->getButtonBar()->addButton(toolbarButton, "065-pluginsGroup");
865 } catch (std::runtime_error& e) {
866 qWarning() << "WARNING: unable create toolbar button for Oculars plugin: " << e.what();
867 }
868- connect(gui->getGuiActions("actionShow_Ocular"), SIGNAL(toggled(bool)), this, SLOT(enableOcular(bool)));
869-
870- gui->addGuiActions("actionShow_Ocular_Menu",
871- N_("Oculars popup menu"),
872- settings->value("bindings/popup_navigator", "Alt+O").toString(),
873- group,
874- true);
875- connect(gui->getGuiActions("actionShow_Ocular_Menu"), SIGNAL(toggled(bool)), this, SLOT(displayPopupMenu()));
876+ connect(actionShowOcular, SIGNAL(toggled(bool)),
877+ this, SLOT(enableOcular(bool)));
878+
879+ shortcutStr = settings->value("bindings/popup_navigator", "Alt+O").toString();
880+ actionMenu = gui->addGuiActions("actionShow_Ocular_Menu",
881+ N_("Oculars popup menu"),
882+ shortcutStr,
883+ group,
884+ true);
885+ connect(actionMenu, SIGNAL(toggled(bool)),
886+ this, SLOT(displayPopupMenu()));
887+
888+ actionShowCrosshairs = gui->addGuiActions("actionShow_Ocular_Crosshairs",
889+ N_("Crosshairs"),
890+ QString(),
891+ group,
892+ true);
893+ connect(actionShowCrosshairs, SIGNAL(toggled(bool)),
894+ this, SLOT(toggleCrosshairs(bool)));
895+
896+ actionShowSensor = gui->addGuiActions("actionShow_Sensor",
897+ N_("Sensor"),
898+ QString(),
899+ group,
900+ true);
901+ connect(actionShowSensor, SIGNAL(toggled(bool)),
902+ this, SLOT(toggleCCD(bool)));
903+
904+ actionShowTelrad = gui->addGuiActions("actionShow_Telrad",
905+ N_("Telrad"),
906+ QString(),
907+ group,
908+ true);
909+ connect(actionShowTelrad, SIGNAL(toggled(bool)),
910+ this, SLOT(toggleTelrad(bool)));
911+
912+ actionConfiguration = gui->addGuiActions("actionOpen_Oculars_Configuration",
913+ N_("Oculars plugin configuration"),
914+ QString(),
915+ group,
916+ true);
917+ connect(actionConfiguration, SIGNAL(toggled(bool)),
918+ ocularDialog, SLOT(setVisible(bool)));
919+ connect(ocularDialog, SIGNAL(visibleChanged(bool)),
920+ actionConfiguration, SLOT(setChecked(bool)));
921
922 connect(this, SIGNAL(selectedCCDChanged()), this, SLOT(instrumentChanged()));
923 connect(this, SIGNAL(selectedCCDChanged()), this, SLOT(setScreenFOVForCCD()));
924@@ -1354,7 +1604,13 @@
925 Ocular *ocular = oculars[selectedOcularIndex];
926 Telescope *telescope = NULL;
927 // Only consider flip is we're not binoculars
928- if (!ocular->isBinoculars()) {
929+ if (ocular->isBinoculars())
930+ {
931+ core->setFlipHorz(false);
932+ core->setFlipVert(false);
933+ }
934+ else
935+ {
936 telescope = telescopes[selectedTelescopeIndex];
937 core->setFlipHorz(telescope->isHFlipped());
938 core->setFlipVert(telescope->isVFlipped());
939@@ -1368,3 +1624,44 @@
940 movementManager->zoomTo(actualFOV, 0.0);
941 }
942
943+void Oculars::hideUsageMessageIfDisplayed()
944+{
945+ if (usageMessageLabelID > -1)
946+ {
947+ LabelMgr *labelManager = GETSTELMODULE(LabelMgr);
948+ labelManager->setLabelShow(usageMessageLabelID, false);
949+ labelManager->deleteLabel(usageMessageLabelID);
950+ usageMessageLabelID = -1;
951+ }
952+}
953+
954+QMenu* Oculars::addTelescopeSubmenu(QMenu *parent)
955+{
956+ Q_ASSERT(parent);
957+
958+ QMenu* submenu = new QMenu("&Telescope", parent);
959+ submenu->addAction("&Previous telescope", this, SLOT(decrementTelescopeIndex()));
960+ submenu->addAction("&Next telescope", this, SLOT(incrementTelescopeIndex()));
961+ submenu->addSeparator();
962+ for (int index = 0; index < telescopes.count(); ++index)
963+ {
964+ QString label;
965+ if (index < 10)
966+ {
967+ label = QString("&%1: %2").arg(index).arg(telescopes[index]->name());
968+ }
969+ else
970+ {
971+ label = telescopes[index]->name();
972+ }
973+ QAction* action = submenu->addAction(label, telescopesSignalMapper, SLOT(map()));
974+ if (index == selectedTelescopeIndex)
975+ {
976+ action->setCheckable(true);
977+ action->setChecked(true);
978+ }
979+ telescopesSignalMapper->setMapping(action, QString("%1").arg(index));
980+ }
981+
982+ return submenu;
983+}
984
985=== modified file 'plugins/Oculars/src/Oculars.hpp'
986--- plugins/Oculars/src/Oculars.hpp 2011-03-24 16:25:59 +0000
987+++ plugins/Oculars/src/Oculars.hpp 2011-11-24 21:50:30 +0000
988@@ -1,5 +1,6 @@
989 /*
990 * Copyright (C) 2009 Timothy Reaves
991+ * Copyright (C) 2011 Bogdan Marinov
992 *
993 * This program is free software; you can redistribute it and/or
994 * modify it under the terms of the GNU General Public License
995@@ -32,7 +33,9 @@
996 #define MIN_OCULARS_INI_VERSION 0.12
997
998 QT_BEGIN_NAMESPACE
999+class QAction;
1000 class QKeyEvent;
1001+class QMenu;
1002 class QMouseEvent;
1003 class QPixmap;
1004 class QSettings;
1005@@ -41,10 +44,13 @@
1006
1007 class StelButton;
1008
1009-//! This is an example of a plug-in which can be dynamically loaded into stellarium
1010+//! Main class of the Oculars plug-in.
1011 class Oculars : public StelModule
1012 {
1013 Q_OBJECT
1014+ //BM: Temporary, until the GUI is finalized and some other method of getting
1015+ //info from the main class is implemented.
1016+ friend class OcularsGuiPanel;
1017
1018 public:
1019 Oculars();
1020@@ -69,6 +75,10 @@
1021 virtual void update(double) {;}
1022
1023 public slots:
1024+ //! Update the ocular, telescope and sensor lists after the removal of a member.
1025+ //! Necessary because of the way model/view management in the OcularDialog
1026+ //! is implemented.
1027+ void updateLists();
1028 void ccdRotationReset();
1029 void decrementCCDIndex();
1030 void decrementOcularIndex();
1031@@ -80,13 +90,20 @@
1032 void incrementCCDIndex();
1033 void incrementOcularIndex();
1034 void incrementTelescopeIndex();
1035- void rotateCCD(QString amount); //<! amount must be a number.
1036- void selectCCDAtIndex(QString indexString); //<! indexString must be an integer, in the range of -1:ccds.count()
1037- void selectOcularAtIndex(QString indexString); //<! indexString must be an integer, in the range of -1:oculars.count()
1038- void selectTelescopeAtIndex(QString indexString); //<! indexString must be an integer, in the range of -1:telescopes.count()
1039+ void rotateCCD(QString amount); //!< amount must be a number.
1040+ void selectCCDAtIndex(QString indexString); //!< indexString must be an integer, in the range of -1:ccds.count()
1041+ void selectOcularAtIndex(QString indexString); //!< indexString must be an integer, in the range of -1:oculars.count()
1042+ void selectTelescopeAtIndex(QString indexString); //!< indexString must be an integer, in the range of -1:telescopes.count()
1043+ //! Toggles the sensor frame overlay.
1044+ void toggleCCD(bool show);
1045+ //! Toggles the sensor frame overlay (overloaded for blind switching).
1046 void toggleCCD();
1047- void toggleCrosshair();
1048+ void toggleCrosshairs(bool show = true);
1049+ //! Toggles the Telrad sight overlay.
1050+ void toggleTelrad(bool show);
1051+ //! Toggles the Telrad sight overlay (overloaded for blind switching).
1052 void toggleTelrad();
1053+ void enableGuiPanel(bool enable = true);
1054
1055 signals:
1056 void selectedCCDChanged();
1057@@ -142,13 +159,18 @@
1058 //! This method is called by the zoom() method, when this plugin is toggled on; it resets the zoomed view.
1059 void zoomOcular();
1060
1061+ void hideUsageMessageIfDisplayed();
1062+
1063+ //! Creates the sub-menu listing telescopes in the pop-up menu.
1064+ QMenu* addTelescopeSubmenu(QMenu* parent);
1065+
1066 //! A list of all the oculars defined in the ini file. Must have at least one, or module will not run.
1067 QList<CCD *> ccds;
1068 QList<Ocular *> oculars;
1069 QList<Telescope *> telescopes;
1070- int selectedCCDIndex; //<! index of the current CCD, in the range of -1:ccds.count(). -1 means no CCD is selected.
1071- int selectedOcularIndex; //<! index of the current ocular, in the range of -1:oculars.count(). -1 means no ocular is selected.
1072- int selectedTelescopeIndex; //<! index of the current telescope, in the range of -1:telescopes.count(). -1 means none is selected.
1073+ int selectedCCDIndex; //!< index of the current CCD, in the range of -1:ccds.count(). -1 means no CCD is selected.
1074+ int selectedOcularIndex; //!< index of the current ocular, in the range of -1:oculars.count(). -1 means no ocular is selected.
1075+ int selectedTelescopeIndex; //!< index of the current telescope, in the range of -1:telescopes.count(). -1 means none is selected.
1076
1077 QFont font; //!< The font used for drawing labels.
1078 bool flagShowCCD; //!< flag used to track f we are in CCD mode.
1079@@ -164,15 +186,17 @@
1080 bool flagEclipticLine; //!< Flag to track if EclipticLine was displayed at activation.
1081 bool flagMeridianLine; //!< Flag to track if MeridianLine was displayed at activation.
1082
1083- double ccdRotationAngle; //<! The angle to rotate the CCD bounding box. */
1084+ double ccdRotationAngle; //!< The angle to rotate the CCD bounding box. */
1085 double maxEyepieceAngle; //!< The maximum aFOV of any eyepiece.
1086 bool requireSelection; //!< Read from the ini file, whether an object is required to be selected to zoom in.
1087 bool useMaxEyepieceAngle; //!< Read from the ini file, whether to scale the mask based aFOV.
1088+ //! Display the GUI control panel
1089+ bool guiPanelEnabled;
1090
1091- QSignalMapper* ccdRotationSignalMapper; //<! Used to rotate the CCD. */
1092- QSignalMapper* ccdsSignalMapper; //<! Used to determine which CCD was selected from the popup navigator. */
1093- QSignalMapper* ocularsSignalMapper; //<! Used to determine which ocular was selected from the popup navigator. */
1094- QSignalMapper* telescopesSignalMapper; //<! Used to determine which telescope was selected from the popup navigator. */
1095+ QSignalMapper* ccdRotationSignalMapper; //!< Used to rotate the CCD. */
1096+ QSignalMapper* ccdsSignalMapper; //!< Used to determine which CCD was selected from the popup navigator. */
1097+ QSignalMapper* ocularsSignalMapper; //!< Used to determine which ocular was selected from the popup navigator. */
1098+ QSignalMapper* telescopesSignalMapper; //!< Used to determine which telescope was selected from the popup navigator. */
1099
1100 // for toolbar button
1101 QPixmap* pxmapGlow;
1102@@ -183,6 +207,15 @@
1103 OcularDialog *ocularDialog;
1104 bool ready; //!< A flag that determines that this module is usable. If false, we won't open.
1105
1106+ QAction* actionShowOcular;
1107+ QAction* actionShowCrosshairs;
1108+ QAction* actionShowSensor;
1109+ QAction* actionShowTelrad;
1110+ QAction* actionConfiguration;
1111+ QAction* actionMenu;
1112+
1113+ class OcularsGuiPanel* guiPanel;
1114+
1115 //Styles
1116 QByteArray normalStyleSheet;
1117 QByteArray nightStyleSheet;
1118
1119=== modified file 'plugins/Oculars/src/gui/OcularDialog.cpp'
1120--- plugins/Oculars/src/gui/OcularDialog.cpp 2011-11-12 22:55:30 +0000
1121+++ plugins/Oculars/src/gui/OcularDialog.cpp 2011-11-24 21:50:30 +0000
1122@@ -1,5 +1,6 @@
1123 /*
1124 * Copyright (C) 2009 Timothy Reaves
1125+ * Copyright (C) 2011 Bogdan Marinov
1126 *
1127 * This program is free software; you can redistribute it and/or
1128 * modify it under the terms of the GNU General Public License
1129@@ -37,10 +38,8 @@
1130 #include <QStandardItemModel>
1131 #include <limits>
1132
1133-OcularDialog::OcularDialog(QList<CCD *>* ccds, QList<Ocular *>* oculars, QList<Telescope *>* telescopes) :
1134- ccdMapper(0),
1135- ocularMapper(0),
1136- telescopeMapper(0)
1137+OcularDialog::OcularDialog(Oculars* pluginPtr, QList<CCD *>* ccds, QList<Ocular *>* oculars, QList<Telescope *>* telescopes) :
1138+ plugin(pluginPtr)
1139 {
1140 ui = new Ui_ocularDialogForm;
1141 this->ccds = ccds;
1142@@ -116,7 +115,7 @@
1143 if(dialog) {
1144 StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
1145 Q_ASSERT(gui);
1146- const StelStyle pluginStyle = GETSTELMODULE(Oculars)->getModuleStyleSheet(gui->getStelStyle());
1147+ const StelStyle pluginStyle = plugin->getModuleStyleSheet(gui->getStelStyle());
1148 dialog->setStyleSheet(pluginStyle.qtStyleSheet);
1149 ui->textBrowser->document()->setDefaultStyleSheet(QString(pluginStyle.htmlStyleSheet));
1150 }
1151@@ -138,6 +137,7 @@
1152 {
1153 ccdTableModel->removeRows(ui->ccdListView->currentIndex().row(), 1);
1154 ui->ccdListView->setCurrentIndex(ccdTableModel->index(0, 1));
1155+ plugin->updateLists();
1156 }
1157
1158 void OcularDialog::deleteSelectedOcular()
1159@@ -147,6 +147,7 @@
1160 } else {
1161 ocularTableModel->removeRows(ui->ocularListView->currentIndex().row(), 1);
1162 ui->ocularListView->setCurrentIndex(ocularTableModel->index(0, 1));
1163+ plugin->updateLists();
1164 }
1165 }
1166
1167@@ -157,6 +158,7 @@
1168 } else {
1169 telescopeTableModel->removeRows(ui->telescopeListView->currentIndex().row(), 1);
1170 ui->telescopeListView->setCurrentIndex(telescopeTableModel->index(0, 1));
1171+ plugin->updateLists();
1172 }
1173 }
1174
1175@@ -178,6 +180,66 @@
1176 ui->telescopeListView->setCurrentIndex(telescopeTableModel->index(telescopeTableModel->rowCount() - 1, 1));
1177 }
1178
1179+void OcularDialog::moveUpSelectedSensor()
1180+{
1181+ int index = ui->ccdListView->currentIndex().row();
1182+ if (index > 0)
1183+ {
1184+ ccdTableModel->moveRowUp(index);
1185+ plugin->updateLists();
1186+ }
1187+}
1188+
1189+void OcularDialog::moveUpSelectedOcular()
1190+{
1191+ int index = ui->ocularListView->currentIndex().row();
1192+ if (index > 0)
1193+ {
1194+ ocularTableModel->moveRowUp(index);
1195+ plugin->updateLists();
1196+ }
1197+}
1198+
1199+void OcularDialog::moveUpSelectedTelescope()
1200+{
1201+ int index = ui->ocularListView->currentIndex().row();
1202+ if (index > 0)
1203+ {
1204+ telescopeTableModel->moveRowUp(index);
1205+ plugin->updateLists();
1206+ }
1207+}
1208+
1209+void OcularDialog::moveDownSelectedSensor()
1210+{
1211+ int index = ui->ccdListView->currentIndex().row();
1212+ if (index >= 0 && index < ccdTableModel->rowCount() - 1)
1213+ {
1214+ ccdTableModel->moveRowDown(index);
1215+ plugin->updateLists();
1216+ }
1217+}
1218+
1219+void OcularDialog::moveDownSelectedOcular()
1220+{
1221+ int index = ui->ocularListView->currentIndex().row();
1222+ if (index >= 0 && index < ocularTableModel->rowCount() - 1)
1223+ {
1224+ ocularTableModel->moveRowDown(index);
1225+ plugin->updateLists();
1226+ }
1227+}
1228+
1229+void OcularDialog::moveDownSelectedTelescope()
1230+{
1231+ int index = ui->telescopeListView->currentIndex().row();
1232+ if (index >= 0 && index < telescopeTableModel->rowCount() - 1)
1233+ {
1234+ telescopeTableModel->moveRowDown(index);
1235+ plugin->updateLists();
1236+ }
1237+}
1238+
1239 /* ********************************************************************* */
1240 #if 0
1241 #pragma mark -
1242@@ -189,7 +251,7 @@
1243 Oculars::appSettings()->setValue("bindings/toggle_oculars", newString);
1244 StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
1245 Q_ASSERT(gui);
1246- QAction* action = gui->getGuiActions("toggle_oculars");
1247+ QAction* action = gui->getGuiActions("actionShow_Ocular");
1248 if (action != NULL) {
1249 action->setShortcut(QKeySequence(newString.trimmed()));
1250 }
1251@@ -223,7 +285,7 @@
1252 bool useMaxImageCircle = Oculars::appSettings()->value("use_max_exit_circle",01.0).toBool();
1253 if (shouldScale != useMaxImageCircle) {
1254 Oculars::appSettings()->setValue("use_max_exit_circle", shouldScale);
1255- Oculars::appSettings()->sync();\
1256+ Oculars::appSettings()->sync();
1257 emit(scaleImageCircleChanged(shouldScale));
1258 }
1259 }
1260@@ -246,6 +308,9 @@
1261 connect(ui->closeStelWindow, SIGNAL(clicked()), this, SLOT(close()));
1262 connect(ui->scaleImageCircleCheckBox, SIGNAL(stateChanged(int)), this, SLOT(scaleImageCircleStateChanged(int)));
1263 connect(ui->requireSelectionCheckBox, SIGNAL(stateChanged(int)), this, SLOT(requireSelectionStateChanged(int)));
1264+ connect(ui->checkBoxControlPanel, SIGNAL(clicked(bool)),
1265+ plugin, SLOT(enableGuiPanel(bool)));
1266+
1267 // The add & delete buttons
1268 connect(ui->addCCD, SIGNAL(clicked()), this, SLOT(insertNewCCD()));
1269 connect(ui->deleteCCD, SIGNAL(clicked()), this, SLOT(deleteSelectedCCD()));
1270@@ -275,11 +340,30 @@
1271 ui->togglePluginLineEdit->setText(bindingString);
1272 bindingString = Oculars::appSettings()->value("bindings/popup_navigator", "Alt+O").toString();
1273 ui->togglePopupNavigatorWindowLineEdit->setText(bindingString);
1274- connect(ui->togglePluginLineEdit, SIGNAL(textEdited(const QString&)),
1275- this, SLOT(keyBindingTogglePluginChanged(const QString&)));
1276- connect(ui->togglePopupNavigatorWindowLineEdit, SIGNAL(textEdited(const QString&)),
1277- this, SLOT(keyBindingPopupNavigatorConfigChanged(const QString&)));
1278-
1279+ connect(ui->togglePluginLineEdit, SIGNAL(textEdited(const QString&)),
1280+ this, SLOT(keyBindingTogglePluginChanged(const QString&)));
1281+ connect(ui->togglePopupNavigatorWindowLineEdit, SIGNAL(textEdited(const QString&)),
1282+ this, SLOT(keyBindingPopupNavigatorConfigChanged(const QString&)));
1283+
1284+ initAboutText();
1285+ connect(ui->togglePluginLineEdit, SIGNAL(textEdited(QString)),
1286+ this, SLOT(initAboutText()));
1287+ connect(ui->togglePopupNavigatorWindowLineEdit, SIGNAL(textEdited(QString)),
1288+ this, SLOT(initAboutText()));
1289+
1290+ connect(ui->pushButtonMoveOcularUp, SIGNAL(pressed()),
1291+ this, SLOT(moveUpSelectedOcular()));
1292+ connect(ui->pushButtonMoveOcularDown, SIGNAL(pressed()),
1293+ this, SLOT(moveDownSelectedOcular()));
1294+ connect(ui->pushButtonMoveSensorUp, SIGNAL(pressed()),
1295+ this, SLOT(moveUpSelectedSensor()));
1296+ connect(ui->pushButtonMoveSensorDown, SIGNAL(pressed()),
1297+ this, SLOT(moveDownSelectedSensor()));
1298+ connect(ui->pushButtonMoveTelescopeUp, SIGNAL(pressed()),
1299+ this, SLOT(moveUpSelectedTelescope()));
1300+ connect(ui->pushButtonMoveTelescopeDown, SIGNAL(pressed()),
1301+ this, SLOT(moveDownSelectedTelescope()));
1302+
1303 // The CCD mapper
1304 ccdMapper = new QDataWidgetMapper();
1305 ccdMapper->setModel(ccdTableModel);
1306@@ -331,7 +415,65 @@
1307 if (Oculars::appSettings()->value("use_max_exit_circle", 0.0).toBool()) {
1308 ui->scaleImageCircleCheckBox->setCheckState(Qt::Checked);
1309 }
1310+ if (Oculars::appSettings()->value("enable_control_panel", false).toBool())
1311+ {
1312+ ui->checkBoxControlPanel->setChecked(true);
1313+ }
1314
1315 //Initialize the style
1316 updateStyle();
1317 }
1318+
1319+void OcularDialog::initAboutText()
1320+{
1321+ //BM: Most of the text for now is the original contents of the About widget.
1322+ QString html = "<html><head><title></title></head><body>";
1323+
1324+ html += "<h1>Oculars plug-in</h1>";
1325+
1326+ //Authors
1327+ QString authors = "Authors: <a href=\"mailto:treaves@silverfieldstech.com\">Timothy Reaves</a>, Bogdan Marinov";
1328+ html += "<h3>" + authors + "</h3>";
1329+
1330+ //Overview
1331+ html += "<h2>Overview</h2>";
1332+
1333+ html += "<p>This plugin is intended to simulate what you would see through an eyepiece. This configuration dialog can be used to add, modify, or delete eyepieces and telescopes, as well as CCD Sensors. Your first time running the app will populate some samples to get your started.</p>";
1334+ html += "<p>You can choose to scale the image you see on the screen. This is intended to show you a better comparison of what one eyepiece/telescope combination will be like as compared to another. The same eyepiece in two different telescopes of differing focal length will produce two different exit circles, changing the view someone. The trade-off of this is that, with the image scaled, a good deal of the screen can be wasted. Therefor I recommend that you leave it off, unless you feel you have a need of it.</p>";
1335+ html += "<p>You can toggle a crosshair in the view. Ideally, I wanted this to be aligned to North. I've been unable to do so. So currently it aligns to the top of the screen.</p>";
1336+ html += QString("<p>You can toggle a Telrad finder; this can only be done when you have not turned on the Ocular view. This feature draws three concentric circles of 0.5%1, 2.0%1, and 4.0%1, helping you see what you would expect to see with the naked eye through the Telrad (or similar) finder.</p>").arg(QChar(0x00B0));
1337+ html += "<p>If you find any issues, please let me know. Enjoy!</p>";
1338+
1339+ //Keys
1340+ html += "<h2>Hot Keys</h2>";
1341+ html += "<p>The plug-in's key bindings can be edited in the General Tab.</p>";
1342+
1343+ StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
1344+ Q_ASSERT(gui);
1345+ QAction* actionOcular = gui->getGuiActions("actionShow_Ocular");
1346+ Q_ASSERT(actionOcular);
1347+ QAction* actionMenu = gui->getGuiActions("actionShow_Ocular_Menu");
1348+ Q_ASSERT(actionMenu);
1349+ QKeySequence ocularShortcut = actionOcular->shortcut();
1350+ QString ocularString = ocularShortcut.toString(QKeySequence::NativeText);
1351+ ocularString = Qt::escape(ocularString);
1352+ if (ocularString.isEmpty())
1353+ ocularString = "[no key defined]";
1354+ QKeySequence menuShortcut = actionMenu->shortcut();
1355+ QString menuString = menuShortcut.toString(QKeySequence::NativeText);
1356+ menuString = Qt::escape(menuString);
1357+ if (menuString.isEmpty())
1358+ menuString = "[no key defined]";
1359+
1360+ html += "<ul>";
1361+ html += "<li>";
1362+ html += QString("<strong>%1:</strong> Switches on/off the ocular overlay.").arg(ocularString);
1363+ html += "</li>";
1364+
1365+ html += "<li>";
1366+ html += QString("<strong>%1:</strong> Opens the pop-up navigation menu.").arg(menuString);
1367+ html += "</li>";
1368+ html += "</ul>";
1369+ html += "</body></html>";
1370+ ui->textBrowser->setHtml(html);
1371+}
1372
1373=== modified file 'plugins/Oculars/src/gui/OcularDialog.hpp'
1374--- plugins/Oculars/src/gui/OcularDialog.hpp 2011-03-24 16:25:59 +0000
1375+++ plugins/Oculars/src/gui/OcularDialog.hpp 2011-11-24 21:50:30 +0000
1376@@ -1,5 +1,6 @@
1377 /*
1378 * Copyright (C) 2009 Timothy Reaves
1379+ * Copyright (C) 2011 Bogdan Marinov
1380 *
1381 * This program is free software; you can redistribute it and/or
1382 * modify it under the terms of the GNU General Public License
1383@@ -38,17 +39,17 @@
1384 class QStandardItemModel;
1385 QT_END_NAMESPACE
1386
1387+class Oculars;
1388
1389 class OcularDialog : public StelDialog
1390 {
1391 Q_OBJECT
1392
1393 public:
1394- OcularDialog(QList<CCD *>* ccds, QList<Ocular *>* oculars, QList<Telescope *>* telescopes);
1395+ OcularDialog(Oculars* plugin, QList<CCD *>* ccds, QList<Ocular *>* oculars, QList<Telescope *>* telescopes);
1396 virtual ~OcularDialog();
1397 //! Notify that the application style changed
1398 void styleChanged();
1399- void setOculars(QList<Ocular*> theOculars);
1400 void updateStyle();
1401
1402 public slots:
1403@@ -59,6 +60,12 @@
1404 void insertNewCCD();
1405 void insertNewOcular();
1406 void insertNewTelescope();
1407+ void moveUpSelectedSensor();
1408+ void moveUpSelectedOcular();
1409+ void moveUpSelectedTelescope();
1410+ void moveDownSelectedSensor();
1411+ void moveDownSelectedOcular();
1412+ void moveDownSelectedTelescope();
1413 void languageChanged();
1414
1415 signals:
1416@@ -73,10 +80,13 @@
1417 private slots:
1418 void keyBindingTogglePluginChanged(const QString& newString);
1419 void keyBindingPopupNavigatorConfigChanged(const QString& newString);
1420+ void initAboutText();
1421 void requireSelectionStateChanged(int state);
1422 void scaleImageCircleStateChanged(int state);
1423
1424 private:
1425+ Oculars* plugin;
1426+
1427 QDataWidgetMapper* ccdMapper;
1428 QList<CCD *>* ccds;
1429 PropertyBasedTableModel* ccdTableModel;
1430
1431=== added file 'plugins/Oculars/src/gui/OcularsGuiPanel.cpp'
1432--- plugins/Oculars/src/gui/OcularsGuiPanel.cpp 1970-01-01 00:00:00 +0000
1433+++ plugins/Oculars/src/gui/OcularsGuiPanel.cpp 2011-11-24 21:50:30 +0000
1434@@ -0,0 +1,954 @@
1435+/*
1436+Oculars plug-in for Stellarium: graphical user interface widget
1437+Copyright (C) 2011 Bogdan Marinov
1438+
1439+This program is free software; you can redistribute it and/or
1440+modify it under the terms of the GNU General Public License
1441+as published by the Free Software Foundation; either version 2
1442+of the License, or (at your option) any later version.
1443+
1444+This program is distributed in the hope that it will be useful,
1445+but WITHOUT ANY WARRANTY; without even the implied warranty of
1446+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1447+GNU General Public License for more details.
1448+
1449+You should have received a copy of the GNU General Public License
1450+along with this program; if not, write to the Free Software
1451+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1452+*/
1453+
1454+#include "Oculars.hpp"
1455+#include "OcularsGuiPanel.hpp"
1456+#include "StelApp.hpp"
1457+#include "StelGui.hpp"
1458+#include "StelGuiItems.hpp"
1459+
1460+#include <QAction>
1461+#include <QGridLayout>
1462+#include <QGraphicsLinearLayout>
1463+#include <QGraphicsPathItem>
1464+#include <QGraphicsProxyWidget>
1465+#include <QLabel>
1466+#include <QPainter>
1467+#include <QPen>
1468+#include <QPushButton>
1469+#include <QSignalMapper>
1470+#include <QWidget>
1471+
1472+OcularsGuiPanel::OcularsGuiPanel(Oculars* plugin,
1473+ QGraphicsWidget *parent,
1474+ Qt::WindowFlags wFlags):
1475+ QGraphicsWidget(parent, wFlags),
1476+ ocularsPlugin(plugin),
1477+ parentWidget(parent),
1478+ borderPath(0)
1479+{
1480+ //setVisible(false);
1481+ //setMinimumSize(0, 0);
1482+ setMaximumSize(300, 400);
1483+ //setPreferredSize(230, 100);
1484+ setContentsMargins(0, 0, 0, 0);
1485+ //TODO: set font?
1486+
1487+ //First create the layout and populate it, then set it?
1488+ mainLayout = new QGraphicsLinearLayout(Qt::Vertical);
1489+ //layout->setContentsMargins(0, 0, 0, 0);
1490+ //layout->setSpacing(0);
1491+
1492+ //Button bar
1493+ buttonBar = new QGraphicsWidget();
1494+ mainLayout->addItem(buttonBar);
1495+
1496+ //QPixmap leftBackground(":/graphicGui/btbg-left.png");
1497+ //QPixmap middleBackground(":/graphicGui/btbg-middle.png");
1498+ //QPixmap rightBackground(":/graphicGui/btbg-right.png");
1499+
1500+ StelApp& stelApp = StelApp::getInstance();
1501+ buttonOcular = new StelButton(buttonBar,
1502+ QPixmap(":/ocular/bt_ocular_on.png"),
1503+ QPixmap(":/ocular/bt_ocular_off.png"),
1504+ QPixmap(),
1505+ ocularsPlugin->actionShowOcular,
1506+ true); //No background
1507+ buttonOcular->setToolTip("Ocular");
1508+ //buttonOcular->setBackgroundPixmap(leftBackground);
1509+ buttonOcular->setParentItem(buttonBar);
1510+
1511+ //Hack to avoid buttonOcular being left "checked" if it has been toggled
1512+ //without any object selected.
1513+ disconnect(ocularsPlugin->actionShowOcular, SIGNAL(toggled(bool)),
1514+ ocularsPlugin, SLOT(enableOcular(bool)));
1515+ connect(ocularsPlugin->actionShowOcular, SIGNAL(toggled(bool)),
1516+ ocularsPlugin, SLOT(enableOcular(bool)));
1517+
1518+ buttonCrosshairs = new StelButton(buttonBar,
1519+ QPixmap(":/ocular/bt_crosshairs_on.png"),
1520+ QPixmap(":/ocular/bt_crosshairs_off.png"),
1521+ QPixmap(),
1522+ ocularsPlugin->actionShowCrosshairs,
1523+ true);
1524+ buttonCrosshairs->setToolTip("Crosshairs");
1525+ buttonCrosshairs->setVisible(false);
1526+
1527+ buttonCcd = new StelButton(buttonBar,
1528+ QPixmap(":/ocular/bt_sensor_on.png"),
1529+ QPixmap(":/ocular/bt_sensor_off.png"),
1530+ QPixmap(),
1531+ ocularsPlugin->actionShowSensor,
1532+ true);
1533+ buttonCcd->setToolTip("Sensor");
1534+
1535+ buttonTelrad = new StelButton(buttonBar,
1536+ QPixmap(":/ocular/bt_telrad_on.png"),
1537+ QPixmap(":/ocular/bt_telrad_off.png"),
1538+ QPixmap(),
1539+ ocularsPlugin->actionShowTelrad,
1540+ true);
1541+ buttonTelrad->setToolTip("Telrad circles");
1542+
1543+ buttonConfiguration = new StelButton(buttonBar,
1544+ QPixmap(":/ocular/bt_settings_on.png"),
1545+ QPixmap(":/ocular/bt_settings_off.png"),
1546+ QPixmap(),
1547+ ocularsPlugin->actionConfiguration,
1548+ true);
1549+ buttonConfiguration->setToolTip("Oculars plugin configuration window");
1550+
1551+ qreal buttonHeight = buttonOcular->boundingRect().height();
1552+ buttonBar->setMinimumHeight(buttonHeight);
1553+ buttonBar->setMaximumHeight(buttonHeight);
1554+
1555+ setLayout(mainLayout);
1556+
1557+ //Widgets with control and information fields
1558+ ocularControls = new QGraphicsWidget(this);
1559+ ocularControls->setParentItem(this);
1560+ ocularControls->setVisible(false);
1561+ ccdControls = new QGraphicsWidget(this);
1562+ ccdControls->setParentItem(this);
1563+ ccdControls->setVisible(false);
1564+ telescopeControls = new QGraphicsWidget(this);
1565+ telescopeControls->setParentItem(this);
1566+ telescopeControls->setVisible(false);
1567+
1568+ fieldOcularName = new QGraphicsTextItem(ocularControls);
1569+ fieldOcularFl = new QGraphicsTextItem(ocularControls);
1570+ fieldOcularAfov = new QGraphicsTextItem(ocularControls);
1571+ fieldCcdName = new QGraphicsTextItem(ccdControls);
1572+ fieldCcdDimensions = new QGraphicsTextItem(ccdControls);
1573+ fieldCcdRotation = new QGraphicsTextItem(ccdControls);
1574+ fieldTelescopeName = new QGraphicsTextItem(telescopeControls);
1575+ fieldMagnification = new QGraphicsTextItem(telescopeControls);
1576+ fieldFov = new QGraphicsTextItem(telescopeControls);
1577+
1578+ QFont newFont = font();
1579+ newFont.setPixelSize(12);
1580+ setControlsFont(newFont);
1581+ //setControlsColor(QColor::fromRgbF(0.9, 0.91, 0.95, 0.9));
1582+
1583+ //Traditional field width from Ocular ;)
1584+ QFontMetrics fm(fieldOcularName->font());
1585+ int maxWidth = fm.width(QString("MMMMMMMMMMMMMMMMMMM"));
1586+ int lineHeight = fm.height();
1587+
1588+ fieldOcularName->setTextWidth(maxWidth);
1589+ fieldOcularFl->setTextWidth(maxWidth);
1590+ fieldOcularAfov->setTextWidth(maxWidth);
1591+ fieldCcdName->setTextWidth(maxWidth);
1592+ fieldCcdDimensions->setTextWidth(maxWidth);
1593+ fieldCcdRotation->setTextWidth(maxWidth);
1594+ fieldTelescopeName->setTextWidth(maxWidth);
1595+ fieldMagnification->setTextWidth(maxWidth);
1596+ fieldFov->setTextWidth(maxWidth);
1597+
1598+ QPixmap pa(":/graphicGui/btTimeRewind-on.png");
1599+ QPixmap prevArrow = pa.scaledToHeight(lineHeight, Qt::SmoothTransformation);
1600+ QPixmap paOff(":/graphicGui/btTimeRewind-off.png");
1601+ QPixmap prevArrowOff = paOff.scaledToHeight(lineHeight, Qt::SmoothTransformation);
1602+ QPixmap na(":/graphicGui/btTimeForward-on.png");
1603+ QPixmap nextArrow = na.scaledToHeight(lineHeight, Qt::SmoothTransformation);
1604+ QPixmap naOff(":/graphicGui/btTimeForward-off.png");
1605+ QPixmap nextArrowOff = naOff.scaledToHeight(lineHeight, Qt::SmoothTransformation);
1606+
1607+ QAction* defaultAction = new QAction(this);
1608+ defaultAction->setCheckable(false);
1609+ prevOcularButton = new StelButton(ocularControls,
1610+ prevArrow,
1611+ prevArrowOff,
1612+ QPixmap(),
1613+ defaultAction);
1614+ prevOcularButton->setToolTip("Previous ocular");
1615+ nextOcularButton = new StelButton(ocularControls,
1616+ nextArrow,
1617+ nextArrowOff,
1618+ QPixmap(),
1619+ defaultAction);
1620+ nextOcularButton->setToolTip("Next ocular");
1621+ prevCcdButton = new StelButton(ccdControls,
1622+ prevArrow,
1623+ prevArrowOff,
1624+ QPixmap(),
1625+ defaultAction);
1626+ prevCcdButton->setToolTip("Previous CCD frame");
1627+ nextCcdButton = new StelButton(ccdControls,
1628+ nextArrow,
1629+ nextArrowOff,
1630+ QPixmap(),
1631+ defaultAction);
1632+ nextCcdButton->setToolTip("Next CCD frame");
1633+ prevTelescopeButton = new StelButton(telescopeControls,
1634+ prevArrow,
1635+ prevArrowOff,
1636+ QPixmap(),
1637+ defaultAction);
1638+ prevTelescopeButton->setToolTip("Previous telescope");
1639+ nextTelescopeButton = new StelButton(telescopeControls,
1640+ nextArrow,
1641+ nextArrowOff,
1642+ QPixmap(),
1643+ defaultAction);
1644+ nextTelescopeButton->setToolTip("Next telescope");
1645+
1646+ connect(nextOcularButton, SIGNAL(triggered()),
1647+ ocularsPlugin, SLOT(incrementOcularIndex()));
1648+ connect(nextCcdButton, SIGNAL(triggered()),
1649+ ocularsPlugin, SLOT(incrementCCDIndex()));
1650+ connect(nextTelescopeButton, SIGNAL(triggered()),
1651+ ocularsPlugin, SLOT(incrementTelescopeIndex()));
1652+ connect(prevOcularButton, SIGNAL(triggered()),
1653+ ocularsPlugin, SLOT(decrementOcularIndex()));
1654+ connect(prevCcdButton, SIGNAL(triggered()),
1655+ ocularsPlugin, SLOT(decrementCCDIndex()));
1656+ connect(prevTelescopeButton, SIGNAL(triggered()),
1657+ ocularsPlugin, SLOT(decrementTelescopeIndex()));
1658+
1659+ QColor cOn(255, 255, 255);
1660+ QColor cOff(102, 102, 102);
1661+ QColor cHover(162, 162, 162);
1662+ QString degrees = QString("-15%1").arg(QChar(0x00B0));
1663+ int degreesW = fm.width(degrees);
1664+ QPixmap pOn = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cOn);
1665+ QPixmap pOff = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cOff);
1666+ QPixmap pHover = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cHover);
1667+ rotateCcdMinus15Button = new StelButton(ccdControls,
1668+ pOn,
1669+ pOff,
1670+ pHover,
1671+ defaultAction,
1672+ true);
1673+ rotateCcdMinus15Button->setToolTip("Rotate the sensor frame 15 degrees counterclockwise");
1674+
1675+ degrees = QString("-5%1").arg(QChar(0x00B0));
1676+ degreesW = fm.width(degrees);
1677+ pOn = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cOn);
1678+ pOff = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cOff);
1679+ pHover = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cHover);
1680+ rotateCcdMinus5Button = new StelButton(ccdControls,
1681+ pOn,
1682+ pOff,
1683+ pHover,
1684+ defaultAction,
1685+ true);
1686+ rotateCcdMinus5Button->setToolTip("Rotate the sensor frame 5 degrees counterclockwise");
1687+
1688+ degrees = QString("-1%1").arg(QChar(0x00B0));
1689+ degreesW = fm.width(degrees);
1690+ pOn = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cOn);
1691+ pOff = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cOff);
1692+ pHover = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cHover);
1693+ rotateCcdMinus1Button = new StelButton(ccdControls,
1694+ pOn,
1695+ pOff,
1696+ pHover,
1697+ defaultAction,
1698+ true);
1699+ rotateCcdMinus1Button->setToolTip("Rotate the sensor frame 1 degree counterclockwise");
1700+
1701+ degrees = QString("0%1").arg(QChar(0x00B0));
1702+ degreesW = fm.width(degrees);
1703+ pOn = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cOn);
1704+ pOff = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cOff);
1705+ pHover = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cHover);
1706+ resetCcdRotationButton = new StelButton(ccdControls,
1707+ pOn,
1708+ pOff,
1709+ pHover,
1710+ defaultAction,
1711+ true);
1712+ resetCcdRotationButton->setToolTip("Reset the sensor frame rotation");
1713+
1714+ degrees = QString("+1%1").arg(QChar(0x00B0));
1715+ degreesW = fm.width(degrees);
1716+ pOn = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cOn);
1717+ pOff = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cOff);
1718+ pHover = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cHover);
1719+ rotateCcdPlus1Button = new StelButton(ccdControls,
1720+ pOn,
1721+ pOff,
1722+ pHover,
1723+ defaultAction,
1724+ true);
1725+ rotateCcdPlus1Button->setToolTip("Rotate the sensor frame 1 degree clockwise");
1726+
1727+ degrees = QString("+5%1").arg(QChar(0x00B0));
1728+ degreesW = fm.width(degrees);
1729+ pOn = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cOn);
1730+ pOff = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cOff);
1731+ pHover = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cHover);
1732+ rotateCcdPlus5Button = new StelButton(ccdControls,
1733+ pOn,
1734+ pOff,
1735+ pHover,
1736+ defaultAction,
1737+ true);
1738+ rotateCcdPlus5Button->setToolTip("Rotate the sensor frame 5 degrees clockwise");
1739+
1740+ degrees = QString("+15%1").arg(QChar(0x00B0));
1741+ degreesW = fm.width(degrees);
1742+ pOn = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cOn);
1743+ pOff = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cOff);
1744+ pHover = createPixmapFromText(degrees, degreesW, lineHeight, newFont, cHover);
1745+ rotateCcdPlus15Button = new StelButton(ccdControls,
1746+ pOn,
1747+ pOff,
1748+ pHover,
1749+ defaultAction,
1750+ true);
1751+ rotateCcdPlus15Button->setToolTip("Rotate the sensor frame 15 degrees clockwise");
1752+
1753+ QSignalMapper* sm = ocularsPlugin->ccdRotationSignalMapper;
1754+ sm->setMapping(rotateCcdMinus15Button, QString("-15"));
1755+ sm->setMapping(rotateCcdMinus5Button, QString("-5"));
1756+ sm->setMapping(rotateCcdMinus1Button, QString("-1"));
1757+ sm->setMapping(rotateCcdPlus1Button, QString("1"));
1758+ sm->setMapping(rotateCcdPlus5Button, QString("5"));
1759+ sm->setMapping(rotateCcdPlus15Button, QString("15"));
1760+
1761+ connect(rotateCcdMinus15Button, SIGNAL(triggered()),
1762+ sm, SLOT(map()));
1763+ connect(rotateCcdMinus5Button, SIGNAL(triggered()),
1764+ sm, SLOT(map()));
1765+ connect(rotateCcdMinus1Button, SIGNAL(triggered()),
1766+ sm, SLOT(map()));
1767+ connect(rotateCcdPlus1Button, SIGNAL(triggered()),
1768+ sm, SLOT(map()));
1769+ connect(rotateCcdPlus5Button, SIGNAL(triggered()),
1770+ sm, SLOT(map()));
1771+ connect(rotateCcdPlus15Button, SIGNAL(triggered()),
1772+ sm, SLOT(map()));
1773+ connect(resetCcdRotationButton, SIGNAL(triggered()),
1774+ ocularsPlugin, SLOT(ccdRotationReset()));
1775+
1776+ connect(rotateCcdMinus15Button, SIGNAL(triggered()),
1777+ this, SLOT(updateCcdControls()));
1778+ connect(rotateCcdMinus5Button, SIGNAL(triggered()),
1779+ this, SLOT(updateCcdControls()));
1780+ connect(rotateCcdMinus1Button, SIGNAL(triggered()),
1781+ this, SLOT(updateCcdControls()));
1782+ connect(rotateCcdPlus1Button, SIGNAL(triggered()),
1783+ this, SLOT(updateCcdControls()));
1784+ connect(rotateCcdPlus5Button, SIGNAL(triggered()),
1785+ this, SLOT(updateCcdControls()));
1786+ connect(rotateCcdPlus15Button, SIGNAL(triggered()),
1787+ this, SLOT(updateCcdControls()));
1788+ connect(resetCcdRotationButton, SIGNAL(triggered()),
1789+ this, SLOT(updateCcdControls()));
1790+
1791+
1792+ //Set the layout and update the size
1793+ qreal width = 2*prevOcularButton->boundingRect().width() + maxWidth;
1794+ qreal left, right, top, bottom;
1795+ mainLayout->getContentsMargins(&left, &top, &right, &bottom);
1796+ ocularControls->setMaximumWidth(width);
1797+ ccdControls->setMaximumWidth(width);
1798+ telescopeControls->setMaximumWidth(width);
1799+ resize(width + left + right, 10);
1800+ buttonBar->resize(width, size().height());
1801+ updateMainButtonsPositions();
1802+
1803+
1804+ //Border/background for the widget
1805+ borderPath = new QGraphicsPathItem();
1806+ borderPath->setZValue(100);
1807+ QBrush borderBrush(QColor::fromRgbF(0.22, 0.22, 0.23, 0.2));
1808+ borderPath->setBrush(borderBrush);
1809+ QPen borderPen = QPen(QColor::fromRgbF(0.7,0.7,0.7,0.5));
1810+ borderPen.setWidthF(1.);
1811+ borderPath->setPen(borderPen);
1812+ borderPath->setParentItem(parentWidget);
1813+
1814+ updatePosition();
1815+ connect (parentWidget, SIGNAL(geometryChanged()),
1816+ this, SLOT(updatePosition()));
1817+
1818+ //Connecting other slots
1819+ connect(ocularsPlugin, SIGNAL(selectedOcularChanged()),
1820+ this, SLOT(updateOcularControls()));
1821+ connect(ocularsPlugin, SIGNAL(selectedCCDChanged()),
1822+ this, SLOT(updateCcdControls()));
1823+ connect(ocularsPlugin, SIGNAL(selectedTelescopeChanged()),
1824+ this, SLOT(updateTelescopeControls()));
1825+
1826+ //Night mode
1827+ connect(&stelApp, SIGNAL(colorSchemeChanged(const QString&)),
1828+ this, SLOT(setColorScheme(const QString&)));
1829+ setColorScheme(stelApp.getCurrentStelStyle());
1830+}
1831+
1832+OcularsGuiPanel::~OcularsGuiPanel()
1833+{
1834+ if (borderPath)
1835+ delete borderPath;
1836+}
1837+
1838+void OcularsGuiPanel::showOcularGui()
1839+{
1840+ setPreferredHeight(0);//WTF?
1841+ if (ocularsPlugin->flagShowOculars)
1842+ {
1843+ updateOcularControls();
1844+ }
1845+ else
1846+ {
1847+ setOcularControlsVisible(false);
1848+ setTelescopeControlsVisible(false);
1849+ updatePosition();
1850+ }
1851+}
1852+
1853+void OcularsGuiPanel::showCcdGui()
1854+{
1855+ updateCcdControls();
1856+}
1857+
1858+void OcularsGuiPanel::foldGui()
1859+{
1860+ //qDebug() << "hidePanel()";
1861+ setOcularControlsVisible(false);
1862+ setCcdControlsVisible(false);
1863+ setTelescopeControlsVisible(false);
1864+ updatePosition();
1865+}
1866+
1867+void OcularsGuiPanel::updatePosition()
1868+{
1869+ updateGeometry();
1870+ /*qDebug() << "Widget:" << size()
1871+ << "Buttonbar:" << buttonBar->size()
1872+ << "Ocular" << ocularControls->size()
1873+ << "CCD" << ccdControls->size()
1874+ << "Telescope" << telescopeControls->size()
1875+ << "Layout" << mainLayout->geometry();*/
1876+ qreal xPos = parentWidget->size().width() - size().width();
1877+ qreal yPos = 0;
1878+ setPos(xPos, yPos);
1879+
1880+ //Update border/shading
1881+ QPainterPath newBorderPath;
1882+ double cornerRadius = 12.0;
1883+ QPointF verticalBorderStart = geometry().topLeft();
1884+ QPointF horizontalBorderEnd = geometry().bottomRight();
1885+ QPointF cornerArcStart(verticalBorderStart.x(),
1886+ horizontalBorderEnd.y() - cornerRadius);
1887+ newBorderPath.moveTo(verticalBorderStart);
1888+ newBorderPath.lineTo(cornerArcStart);
1889+ newBorderPath.arcTo(cornerArcStart.x(), cornerArcStart.y(), cornerRadius, cornerRadius, 180, 90);
1890+ newBorderPath.lineTo(horizontalBorderEnd);
1891+ newBorderPath.lineTo(horizontalBorderEnd.x(), verticalBorderStart.y());
1892+ borderPath->setPath(newBorderPath);
1893+}
1894+
1895+void OcularsGuiPanel::updateOcularControls()
1896+{
1897+ setCcdControlsVisible(false);
1898+
1899+ //Get the name
1900+ int index = ocularsPlugin->selectedOcularIndex;
1901+ Ocular* ocular = ocularsPlugin->oculars[index];
1902+ Q_ASSERT(ocular);
1903+ QString name = ocular->name();
1904+ QString fullName;
1905+ if (name.isEmpty())
1906+ {
1907+ fullName = QString("Ocular #%1").arg(index);
1908+ }
1909+ else
1910+ {
1911+ fullName = QString("Ocular #%1: %2").arg(index).arg(name);
1912+ }
1913+ fieldOcularName->setPlainText(fullName);
1914+
1915+ qreal posX = 0.;
1916+ qreal posY = 0.;
1917+ qreal widgetWidth = 0.;
1918+ qreal widgetHeight = 0.;
1919+
1920+ //Prev button
1921+ qreal heightAdjustment = (fieldOcularName->boundingRect().height() - prevOcularButton->boundingRect().height()) / 2.;
1922+ prevOcularButton->setPos(posX, round(posY + heightAdjustment));
1923+ posX += prevOcularButton->boundingRect().width();
1924+ widgetWidth += prevOcularButton->boundingRect().width();
1925+
1926+ //Name field
1927+ fieldOcularName->setPos(posX, posY);
1928+ posX += fieldOcularName->boundingRect().width();
1929+ widgetWidth += fieldOcularName->boundingRect().width();
1930+
1931+ //Next button
1932+ nextOcularButton->setPos(posX, posY + heightAdjustment);
1933+ widgetWidth += nextOcularButton->boundingRect().width();
1934+
1935+ posX = prevOcularButton->boundingRect().width();
1936+ posY += fieldOcularName->boundingRect().height();
1937+ widgetHeight += fieldOcularName->boundingRect().height();
1938+
1939+
1940+ if (ocular->isBinoculars())
1941+ {
1942+ fieldOcularFl->setVisible(false);
1943+ fieldOcularAfov->setVisible(false);
1944+ }
1945+ else
1946+ {
1947+ double focalLength = ocular->effectiveFocalLength();
1948+ QString focalLengthString = QString("Ocular FL: %1mm").arg(focalLength);
1949+ fieldOcularFl->setPlainText(focalLengthString);
1950+ fieldOcularFl->setToolTip("Focal length of the ocular");
1951+ fieldOcularFl->setPos(posX, posY);
1952+ posY += fieldOcularFl->boundingRect().height();
1953+ widgetHeight += fieldOcularFl->boundingRect().height();
1954+
1955+ double apparentFov = ocular->appearentFOV();
1956+ //TODO: This one could be better. Even in LTR languages the degree sign
1957+ //is to the right of the value?
1958+ QString apparentFovString =
1959+ QString("Ocular aFOV: %1%2").arg(apparentFov).arg(QChar(0x00B0));
1960+ fieldOcularAfov->setPlainText(apparentFovString);
1961+ fieldOcularAfov->setToolTip("Apparent field of view of the ocular");
1962+ fieldOcularAfov->setPos(posX, posY);
1963+ widgetHeight += fieldOcularAfov->boundingRect().height();
1964+
1965+ fieldOcularFl->setVisible(true);
1966+ fieldOcularAfov->setVisible(true);
1967+ }
1968+
1969+ ocularControls->setMinimumSize(widgetWidth, widgetHeight);
1970+ ocularControls->resize(widgetWidth, widgetHeight);
1971+ setOcularControlsVisible(true);
1972+
1973+ updateTelescopeControls();//Contains a call to updatePosition()
1974+}
1975+
1976+void OcularsGuiPanel::updateCcdControls()
1977+{
1978+ setOcularControlsVisible(false);
1979+
1980+ //Get the name
1981+ int index = ocularsPlugin->selectedCCDIndex;
1982+ CCD* ccd = ocularsPlugin->ccds[index];
1983+ Q_ASSERT(ccd);
1984+ QString name = ccd->name();
1985+ QString fullName;
1986+ if (name.isEmpty())
1987+ {
1988+ fullName = QString("Sensor #%1").arg(index);
1989+ }
1990+ else
1991+ {
1992+ fullName = QString("Sensor #%1: %2").arg(index).arg(name);
1993+ }
1994+ fieldCcdName->setPlainText(fullName);
1995+
1996+ qreal posX = 0.;
1997+ qreal posY = 0.;
1998+ qreal widgetWidth = 0.;
1999+ qreal widgetHeight = 0.;
2000+
2001+ //Prev button
2002+ qreal heightAdjustment = (fieldCcdName->boundingRect().height() - prevCcdButton->boundingRect().height()) / 2.;
2003+ prevCcdButton->setPos(posX, posY + heightAdjustment);
2004+ posX += prevCcdButton->boundingRect().width();
2005+ widgetWidth += prevCcdButton->boundingRect().width();
2006+
2007+ //Name field
2008+ fieldCcdName->setPos(posX, posY);
2009+ posX += fieldCcdName->boundingRect().width();
2010+ widgetWidth += fieldCcdName->boundingRect().width();
2011+
2012+ //Next button
2013+ nextCcdButton->setPos(posX, posY + heightAdjustment);
2014+ widgetWidth += nextCcdButton->boundingRect().width();
2015+
2016+ posX = prevCcdButton->boundingRect().width();
2017+ posY = fieldCcdName->boundingRect().height();
2018+ widgetHeight += fieldCcdName->boundingRect().height();
2019+
2020+ //We need the current telescope
2021+ index = ocularsPlugin->selectedTelescopeIndex;
2022+ Telescope* telescope = ocularsPlugin->telescopes[index];
2023+ Q_ASSERT(telescope);
2024+ double fovX = ((int)(ccd->getActualFOVx(telescope) * 1000.0)) / 1000.0;
2025+ double fovY = ((int)(ccd->getActualFOVy(telescope) * 1000.0)) / 1000.0;
2026+ //TODO: Again, the symbol could be handled simpler.
2027+ QString dimensions = QString("Dimensions: %1%2 %3 %4%5").arg(fovX).arg(QChar(0x00B0)).arg(QChar(0x00D7)).arg(fovY).arg(QChar(0x00B0));
2028+ fieldCcdDimensions->setPlainText(dimensions);
2029+ fieldCcdDimensions->setPos(posX, posY);
2030+ posY += fieldCcdDimensions->boundingRect().height();
2031+ widgetHeight += fieldCcdDimensions->boundingRect().height();
2032+
2033+ QString rotation = QString("Rotation (angle): %1%2").arg(ocularsPlugin->ccdRotationAngle, 0, 'f', 2).arg(QChar(0x00B0));
2034+ fieldCcdRotation->setPlainText(rotation);
2035+ fieldCcdRotation->setPos(posX, posY);
2036+ posY += fieldCcdRotation->boundingRect().height();
2037+ widgetHeight += fieldCcdRotation->boundingRect().height();
2038+
2039+ int rotationButtonsWidth = rotateCcdMinus15Button->boundingRect().width();
2040+ rotationButtonsWidth += rotateCcdMinus5Button->boundingRect().width();
2041+ rotationButtonsWidth += rotateCcdMinus1Button->boundingRect().width();
2042+ rotationButtonsWidth += resetCcdRotationButton->boundingRect().width();
2043+ rotationButtonsWidth += rotateCcdPlus1Button->boundingRect().width();
2044+ rotationButtonsWidth += rotateCcdPlus5Button->boundingRect().width();
2045+ rotationButtonsWidth += rotateCcdPlus15Button->boundingRect().width();
2046+ int spacing = (fieldCcdRotation->boundingRect().width() - rotationButtonsWidth) / 6;
2047+ posX = fieldCcdRotation->x();
2048+ rotateCcdMinus15Button->setPos(posX, posY);
2049+ posX += rotateCcdMinus15Button->boundingRect().width() + spacing;
2050+ rotateCcdMinus5Button->setPos(posX, posY);
2051+ posX += rotateCcdMinus5Button->boundingRect().width() + spacing;
2052+ rotateCcdMinus1Button->setPos(posX, posY);
2053+ posX += rotateCcdMinus1Button->boundingRect().width() + spacing;
2054+ resetCcdRotationButton->setPos(posX, posY);
2055+ posX += resetCcdRotationButton->boundingRect().width() + spacing;
2056+ rotateCcdPlus1Button->setPos(posX, posY);
2057+ posX += rotateCcdPlus1Button->boundingRect().width() + spacing;
2058+ rotateCcdPlus5Button->setPos(posX, posY);
2059+ posX += rotateCcdPlus5Button->boundingRect().width() + spacing;
2060+ rotateCcdPlus15Button->setPos(posX, posY);
2061+ widgetHeight += rotateCcdMinus15Button->boundingRect().height();
2062+
2063+ ccdControls->setMinimumSize(widgetWidth, widgetHeight);
2064+ ccdControls->resize(widgetWidth, widgetHeight);
2065+ setCcdControlsVisible(true);
2066+
2067+ updateTelescopeControls();//Contains a call to updatePosition()
2068+}
2069+
2070+void OcularsGuiPanel::updateTelescopeControls()
2071+{
2072+ //Get the name
2073+ int index = ocularsPlugin->selectedTelescopeIndex;
2074+ Telescope* telescope = ocularsPlugin->telescopes[index];
2075+ Q_ASSERT(telescope);
2076+ QString name = telescope->name();
2077+ QString fullName;
2078+ if (name.isEmpty())
2079+ {
2080+ fullName = QString("Telescope #%1").arg(index);
2081+ }
2082+ else
2083+ {
2084+ fullName = QString("Telescope #%1: %2").arg(index).arg(name);
2085+ }
2086+ fieldTelescopeName->setPlainText(fullName);
2087+
2088+ qreal posX = 0.;
2089+ qreal posY = 0.;
2090+ qreal widgetWidth = 0.;
2091+ qreal widgetHeight = 0.;
2092+
2093+ //Prev button
2094+ qreal heightAdjustment = (fieldTelescopeName->boundingRect().height() - prevTelescopeButton->boundingRect().height()) / 2.;
2095+ prevTelescopeButton->setPos(posX, posY + heightAdjustment);
2096+ posX += prevTelescopeButton->boundingRect().width();
2097+ widgetWidth += prevTelescopeButton->boundingRect().width();
2098+
2099+ //Name field
2100+ fieldTelescopeName->setPos(posX, posY);
2101+ posX += fieldTelescopeName->boundingRect().width();
2102+ widgetWidth += fieldTelescopeName->boundingRect().height();
2103+
2104+ //Next button
2105+ nextTelescopeButton->setPos(posX, posY + heightAdjustment);
2106+ widgetWidth += nextTelescopeButton->boundingRect().width();
2107+
2108+ posX = prevTelescopeButton->boundingRect().width();
2109+ posY += fieldTelescopeName->boundingRect().height();
2110+ widgetHeight += fieldTelescopeName->boundingRect().height();
2111+
2112+ if (ocularsPlugin->flagShowOculars)
2113+ {
2114+ //We need the current ocular
2115+ int index = ocularsPlugin->selectedOcularIndex;
2116+ Ocular* ocular = ocularsPlugin->oculars[index];
2117+ Q_ASSERT(ocular);
2118+
2119+ if (ocular->isBinoculars())
2120+ {
2121+ prevTelescopeButton->setVisible(false);
2122+ nextTelescopeButton->setVisible(false);
2123+ fieldTelescopeName->setVisible(false);
2124+ posY = 0.;
2125+ widgetHeight = 0.;
2126+
2127+ fieldMagnification->setToolTip("Magnification provided by these binoculars");
2128+ fieldFov->setToolTip("Actual field of view provided by these binoculars");
2129+ }
2130+ else
2131+ {
2132+ prevTelescopeButton->setVisible(true);
2133+ nextTelescopeButton->setVisible(true);
2134+ fieldTelescopeName->setVisible(true);
2135+
2136+ fieldMagnification->setToolTip("Magnification provided by this ocular/telescope combination");
2137+ fieldFov->setToolTip("Actual field of view provided by this ocular/telescope combination");
2138+ }
2139+
2140+ //WTF? Rounding?
2141+ double magnification = ((int)(ocular->magnification(telescope) * 10.0)) / 10.0;
2142+ //TODO: Again, this can be simpler
2143+ QString magnificationString =
2144+ QString("Magnification: %1%2").arg(magnification).arg(QChar(0x00D7));
2145+ fieldMagnification->setPlainText(magnificationString);
2146+ fieldMagnification->setPos(posX, posY);
2147+ posY += fieldMagnification->boundingRect().height();
2148+ widgetHeight += fieldMagnification->boundingRect().height();
2149+
2150+ double fov = ((int)(ocular->actualFOV(telescope) * 10000.00)) / 10000.0;
2151+ //TODO: Again, this can be simpler
2152+ QString fovString = QString("FOV: %1%2").arg(fov).arg(QChar(0x00B0));
2153+ fieldFov->setPlainText(fovString);
2154+ fieldFov->setPos(posX, posY);
2155+ widgetHeight += fieldFov->boundingRect().height();
2156+
2157+ fieldMagnification->setVisible(true);
2158+ fieldFov->setVisible(true);
2159+ }
2160+ else
2161+ {
2162+ prevTelescopeButton->setVisible(true);
2163+ nextTelescopeButton->setVisible(true);
2164+ fieldTelescopeName->setVisible(true);
2165+
2166+ fieldMagnification->setVisible(false);
2167+ fieldFov->setVisible(false);
2168+ }
2169+
2170+ telescopeControls->setMinimumSize(widgetWidth, widgetHeight);
2171+ telescopeControls->resize(widgetWidth, widgetHeight);
2172+ setTelescopeControlsVisible(true);
2173+
2174+ updatePosition();
2175+}
2176+
2177+void OcularsGuiPanel::setOcularControlsVisible(bool show)
2178+{
2179+ if (show)
2180+ {
2181+ if (!ocularControls->isVisible())
2182+ {
2183+ ocularControls->setVisible(true);
2184+ mainLayout->insertItem(0, ocularControls);
2185+ }
2186+ }
2187+ else
2188+ {
2189+ if (ocularControls->isVisible())
2190+ {
2191+ mainLayout->removeItem(ocularControls);
2192+ ocularControls->setVisible(false);
2193+ }
2194+ }
2195+ buttonCrosshairs->setVisible(show);
2196+ updateMainButtonsPositions();
2197+}
2198+
2199+void OcularsGuiPanel::setCcdControlsVisible(bool show)
2200+{
2201+ if (show)
2202+ {
2203+ if (!ccdControls->isVisible())
2204+ {
2205+ ccdControls->setVisible(true);
2206+ mainLayout->insertItem(0, ccdControls);
2207+ }
2208+ }
2209+ else
2210+ {
2211+ if (ccdControls->isVisible())
2212+ {
2213+ mainLayout->removeItem(ccdControls);
2214+ ccdControls->setVisible(false);
2215+ }
2216+ }
2217+}
2218+
2219+void OcularsGuiPanel::setTelescopeControlsVisible(bool show)
2220+{
2221+ if (show)
2222+ {
2223+ if (!telescopeControls->isVisible())
2224+ {
2225+ telescopeControls->setVisible(true);
2226+ mainLayout->insertItem(1, telescopeControls);
2227+ }
2228+ }
2229+ else
2230+ {
2231+ if (telescopeControls->isVisible())
2232+ {
2233+ mainLayout->removeItem(telescopeControls);
2234+ telescopeControls->setVisible(false);
2235+ }
2236+ }
2237+ mainLayout->invalidate();
2238+ mainLayout->activate();
2239+ resize(mainLayout->geometry().width(),
2240+ mainLayout->geometry().height());
2241+}
2242+
2243+void OcularsGuiPanel::updateMainButtonsPositions()
2244+{
2245+ Q_ASSERT(buttonOcular);
2246+ Q_ASSERT(buttonCrosshairs);
2247+ Q_ASSERT(buttonCrosshairs);
2248+ Q_ASSERT(buttonCcd);
2249+ Q_ASSERT(buttonTelrad);
2250+ Q_ASSERT(buttonConfiguration);
2251+
2252+ int n = buttonCrosshairs->isVisible() ? 5 : 4;
2253+ qreal width = n * buttonOcular->getButtonPixmapWidth();
2254+
2255+ //Relative position inside the parent widget
2256+ qreal posX = 0.;
2257+ qreal posY = 0.;
2258+ qreal spacing = 0.;
2259+ if (prevTelescopeButton)
2260+ {
2261+ width += 2 * prevTelescopeButton->getButtonPixmapWidth();
2262+ posX = prevTelescopeButton->getButtonPixmapWidth();
2263+ }
2264+ if (buttonOcular->parentItem())
2265+ {
2266+ qreal parentWidth = buttonOcular->parentItem()->boundingRect().width();
2267+ int nGaps = n - 1;//n buttons have n-1 gaps
2268+ //posX = round((parentWidth-width)/2.0);//Centering, deprecated
2269+ spacing = round((parentWidth-width)/nGaps);
2270+ }
2271+ buttonOcular->setPos(posX, posY);
2272+ posX += buttonOcular->getButtonPixmapWidth() + spacing;
2273+ if (buttonCrosshairs->isVisible())
2274+ {
2275+ buttonCrosshairs->setPos(posX, posY);
2276+ posX += buttonCrosshairs->getButtonPixmapWidth() + spacing;
2277+ }
2278+ buttonCcd->setPos(posX, posY);
2279+ posX += buttonCcd->getButtonPixmapWidth() + spacing;
2280+ buttonTelrad->setPos(posX, posY);
2281+ posX += buttonTelrad->getButtonPixmapWidth() + spacing;
2282+ buttonConfiguration->setPos(posX, posY);
2283+ posX += buttonConfiguration->getButtonPixmapWidth() + spacing;
2284+}
2285+
2286+void OcularsGuiPanel::setControlsColor(const QColor& color)
2287+{
2288+ Q_ASSERT(fieldOcularName);
2289+ Q_ASSERT(fieldOcularFl);
2290+ Q_ASSERT(fieldOcularAfov);
2291+ Q_ASSERT(fieldCcdName);
2292+ Q_ASSERT(fieldCcdDimensions);
2293+ Q_ASSERT(fieldCcdRotation);
2294+ Q_ASSERT(fieldTelescopeName);
2295+ Q_ASSERT(fieldMagnification);
2296+ Q_ASSERT(fieldFov);
2297+
2298+ fieldOcularName->setDefaultTextColor(color);
2299+ fieldOcularFl->setDefaultTextColor(color);
2300+ fieldOcularAfov->setDefaultTextColor(color);
2301+ fieldCcdName->setDefaultTextColor(color);
2302+ fieldCcdDimensions->setDefaultTextColor(color);
2303+ fieldCcdRotation->setDefaultTextColor(color);
2304+ fieldTelescopeName->setDefaultTextColor(color);
2305+ fieldMagnification->setDefaultTextColor(color);
2306+ fieldFov->setDefaultTextColor(color);
2307+}
2308+
2309+void OcularsGuiPanel::setControlsFont(const QFont& font)
2310+{
2311+ Q_ASSERT(fieldOcularName);
2312+ Q_ASSERT(fieldOcularFl);
2313+ Q_ASSERT(fieldOcularAfov);
2314+ Q_ASSERT(fieldCcdName);
2315+ Q_ASSERT(fieldCcdDimensions);
2316+ Q_ASSERT(fieldCcdRotation);
2317+ Q_ASSERT(fieldTelescopeName);
2318+ Q_ASSERT(fieldMagnification);
2319+ Q_ASSERT(fieldFov);
2320+
2321+ fieldOcularName->setFont(font);
2322+ fieldOcularFl->setFont(font);
2323+ fieldOcularAfov->setFont(font);
2324+ fieldCcdName->setFont(font);
2325+ fieldCcdDimensions->setFont(font);
2326+ fieldCcdRotation->setFont(font);
2327+ fieldTelescopeName->setFont(font);
2328+ fieldMagnification->setFont(font);
2329+ fieldFov->setFont(font);
2330+}
2331+
2332+void OcularsGuiPanel::setButtonsNightMode(bool nightMode)
2333+{
2334+ //Reused from SkyGui, with modifications
2335+ foreach (QGraphicsItem *child, QGraphicsItem::children())
2336+ {
2337+ foreach (QGraphicsItem *grandchild, child->children())
2338+ {
2339+ StelButton* button = qgraphicsitem_cast<StelButton*>(grandchild);
2340+ if (button)
2341+ button->setRedMode(nightMode);
2342+ }
2343+ }
2344+}
2345+
2346+void OcularsGuiPanel::setColorScheme(const QString &schemeName)
2347+{
2348+ if (schemeName == "night_color")
2349+ {
2350+ borderPath->setPen(QColor::fromRgbF(0.7,0.2,0.2,0.5));
2351+ borderPath->setBrush(QColor::fromRgbF(0.23, 0.13, 0.03, 0.2));
2352+ setControlsColor(QColor::fromRgbF(0.9, 0.33, 0.33, 0.9));
2353+ setButtonsNightMode(true);
2354+ }
2355+ else
2356+ {
2357+ borderPath->setPen(QColor::fromRgbF(0.7,0.7,0.7,0.5));
2358+ borderPath->setBrush(QColor::fromRgbF(0.15, 0.16, 0.19, 0.2));
2359+ setControlsColor(QColor::fromRgbF(0.9, 0.91, 0.95, 0.9));
2360+ setButtonsNightMode(false);
2361+ }
2362+}
2363+
2364+QPixmap OcularsGuiPanel::createPixmapFromText(const QString& text,
2365+ int width,
2366+ int height,
2367+ const QFont& font,
2368+ const QColor& textColor,
2369+ const QColor& backgroundColor)
2370+{
2371+ if (width <= 0 || height <=0)
2372+ return QPixmap();
2373+
2374+ QPixmap pixmap(width, height);
2375+ pixmap.fill(backgroundColor);
2376+
2377+ if (text.isEmpty())
2378+ return pixmap;
2379+
2380+ QPainter painter(&pixmap);
2381+ painter.setFont(font);
2382+ painter.setPen(QPen(textColor));
2383+ painter.drawText(0, 0, width, height,
2384+ Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextSingleLine,
2385+ text);
2386+
2387+ return pixmap;
2388+}
2389
2390=== added file 'plugins/Oculars/src/gui/OcularsGuiPanel.hpp'
2391--- plugins/Oculars/src/gui/OcularsGuiPanel.hpp 1970-01-01 00:00:00 +0000
2392+++ plugins/Oculars/src/gui/OcularsGuiPanel.hpp 2011-11-24 21:50:30 +0000
2393@@ -0,0 +1,137 @@
2394+/*
2395+Oculars plug-in for Stellarium: graphical user interface widget
2396+Copyright (C) 2011 Bogdan Marinov
2397+
2398+This program is free software; you can redistribute it and/or
2399+modify it under the terms of the GNU General Public License
2400+as published by the Free Software Foundation; either version 2
2401+of the License, or (at your option) any later version.
2402+
2403+This program is distributed in the hope that it will be useful,
2404+but WITHOUT ANY WARRANTY; without even the implied warranty of
2405+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2406+GNU General Public License for more details.
2407+
2408+You should have received a copy of the GNU General Public License
2409+along with this program; if not, write to the Free Software
2410+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
2411+*/
2412+
2413+#ifndef OCULARSGUIPANEL_HPP
2414+#define OCULARSGUIPANEL_HPP
2415+
2416+#include <QGraphicsWidget>
2417+
2418+class Oculars;
2419+class StelButton;
2420+class QGraphicsLinearLayout;
2421+class QGraphicsProxyWidget;
2422+class QLabel;
2423+class QPushButton;
2424+class QWidget;
2425+
2426+//! A screen widget similar to InfoPanel. Contains controls and information.
2427+class OcularsGuiPanel : public QGraphicsWidget
2428+{
2429+ Q_OBJECT
2430+
2431+public:
2432+ OcularsGuiPanel(Oculars* ocularsPlugin,
2433+ QGraphicsWidget * parent = 0,
2434+ Qt::WindowFlags wFlags = 0);
2435+ ~OcularsGuiPanel();
2436+
2437+public slots:
2438+ //! Show only the controls used with an ocular overlay.
2439+ void showOcularGui();
2440+ //! Show only the controls used with a CCD overlay.
2441+ void showCcdGui();
2442+ //! Hide the controls, leaving only the button bar.
2443+ void foldGui();
2444+
2445+private slots:
2446+ //! Update the position of the widget within the parent.
2447+ //! Tied to the parent's geometryChanged() signal.
2448+ void updatePosition();
2449+
2450+ //! Updates the information shown when an ocular overlay is displayed
2451+ void updateOcularControls();
2452+ //! Updates the information shown when a sensor overlay is displayed
2453+ void updateCcdControls();
2454+ //! Updates the information that depends on the current telescope.
2455+ //! Called in both updateOcularControls() and updateCcdControls().
2456+ void updateTelescopeControls();
2457+
2458+ //! Sets the color scheme (day/night mode)
2459+ void setColorScheme(const QString& schemeName);
2460+
2461+private:
2462+ Oculars* ocularsPlugin;
2463+
2464+ //! This is actually SkyGui. Perhaps it should be more specific?
2465+ QGraphicsWidget* parentWidget;
2466+
2467+ QGraphicsLinearLayout* mainLayout;
2468+
2469+ QGraphicsPathItem* borderPath;
2470+
2471+ //! Mini-toolbar holding StelButtons
2472+ QGraphicsWidget* buttonBar;
2473+ QGraphicsWidget* ocularControls;
2474+ QGraphicsWidget* ccdControls;
2475+ QGraphicsWidget* telescopeControls;
2476+
2477+ //Mini-toolbar
2478+ StelButton* buttonOcular;
2479+ StelButton* buttonCrosshairs;
2480+ StelButton* buttonCcd;
2481+ StelButton* buttonTelrad;
2482+ StelButton* buttonConfiguration;
2483+
2484+ //Information display
2485+ StelButton* prevOcularButton;
2486+ StelButton* nextOcularButton;
2487+ StelButton* prevTelescopeButton;
2488+ StelButton* nextTelescopeButton;
2489+ StelButton* prevCcdButton;
2490+ StelButton* nextCcdButton;
2491+ QGraphicsTextItem* fieldOcularName;
2492+ QGraphicsTextItem* fieldOcularFl;
2493+ QGraphicsTextItem* fieldOcularAfov;
2494+ QGraphicsTextItem* fieldCcdName;
2495+ QGraphicsTextItem* fieldCcdDimensions;
2496+ QGraphicsTextItem* fieldCcdRotation;
2497+ QGraphicsTextItem* fieldTelescopeName;
2498+ QGraphicsTextItem* fieldMagnification;
2499+ QGraphicsTextItem* fieldFov;
2500+
2501+ //Sensor frame rotation controls
2502+ StelButton* rotateCcdMinus15Button;
2503+ StelButton* rotateCcdMinus5Button;
2504+ StelButton* rotateCcdMinus1Button;
2505+ StelButton* resetCcdRotationButton;
2506+ StelButton* rotateCcdPlus1Button;
2507+ StelButton* rotateCcdPlus5Button;
2508+ StelButton* rotateCcdPlus15Button;
2509+
2510+ //! Sets the visibility of the ocular name label and the associated buttons.
2511+ void setOcularControlsVisible(bool show);
2512+ void setCcdControlsVisible(bool show);
2513+ void setTelescopeControlsVisible(bool show);
2514+ //! Updates the positions of the buttons inside the button bar.
2515+ void updateMainButtonsPositions();
2516+
2517+ void setControlsColor(const QColor& color);
2518+ void setControlsFont(const QFont& font);
2519+ //! Sets the night mode flag on all StelButton-s.
2520+ void setButtonsNightMode(bool nightMode);
2521+
2522+ static QPixmap createPixmapFromText(const QString& text,
2523+ int width,
2524+ int height,
2525+ const QFont& font,
2526+ const QColor& textColor,
2527+ const QColor& backgroundColor = QColor(0,0,0,0));
2528+};
2529+
2530+#endif // OCULARSGUIPANEL_HPP
2531
2532=== modified file 'plugins/Oculars/src/gui/PropertyBasedTableModel.cpp'
2533--- plugins/Oculars/src/gui/PropertyBasedTableModel.cpp 2011-01-12 21:08:24 +0000
2534+++ plugins/Oculars/src/gui/PropertyBasedTableModel.cpp 2011-11-24 21:50:30 +0000
2535@@ -113,3 +113,29 @@
2536 return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
2537 }
2538
2539+void PropertyBasedTableModel::moveRowUp(int position)
2540+{
2541+ int count = content->count();
2542+ if (count < 2 || position < 1 || position >= count)
2543+ return;
2544+
2545+ beginMoveRows(QModelIndex(), position, position, QModelIndex(), position-1);
2546+
2547+ content->move(position, position - 1);
2548+
2549+ endMoveRows();
2550+}
2551+
2552+void PropertyBasedTableModel::moveRowDown(int position)
2553+{
2554+ int count = content->count();
2555+ if (count < 2 || position < 0 || position > (count - 2))
2556+ return;
2557+
2558+ beginMoveRows(QModelIndex(), position, position, QModelIndex(), position+2);
2559+
2560+ content->move(position, position + 1);
2561+
2562+ endMoveRows();
2563+}
2564+
2565
2566=== modified file 'plugins/Oculars/src/gui/PropertyBasedTableModel.hpp'
2567--- plugins/Oculars/src/gui/PropertyBasedTableModel.hpp 2011-01-12 21:08:24 +0000
2568+++ plugins/Oculars/src/gui/PropertyBasedTableModel.hpp 2011-11-24 21:50:30 +0000
2569@@ -40,6 +40,9 @@
2570 virtual bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole);
2571 virtual bool removeRows(int position, int rows, const QModelIndex &index=QModelIndex());
2572
2573+ void moveRowUp(int position);
2574+ void moveRowDown(int position);
2575+
2576 private:
2577 QList<QObject *>* content;
2578 QMap<int, QString> mappings;
2579
2580=== modified file 'plugins/Oculars/src/gui/ocularDialog.ui'
2581--- plugins/Oculars/src/gui/ocularDialog.ui 2011-03-24 16:25:59 +0000
2582+++ plugins/Oculars/src/gui/ocularDialog.ui 2011-11-24 21:50:30 +0000
2583@@ -22,9 +22,6 @@
2584 <height>320</height>
2585 </size>
2586 </property>
2587- <property name="windowTitle">
2588- <string>Form</string>
2589- </property>
2590 <layout class="QVBoxLayout" name="verticalLayout_2">
2591 <property name="spacing">
2592 <number>0</number>
2593@@ -152,115 +149,149 @@
2594 <property name="currentIndex">
2595 <number>0</number>
2596 </property>
2597- <property name="documentMode">
2598- <bool>false</bool>
2599- </property>
2600 <widget class="QWidget" name="General">
2601 <attribute name="title">
2602 <string>General</string>
2603 </attribute>
2604- <widget class="QCheckBox" name="scaleImageCircleCheckBox">
2605- <property name="geometry">
2606- <rect>
2607- <x>10</x>
2608- <y>10</y>
2609- <width>141</width>
2610- <height>21</height>
2611- </rect>
2612- </property>
2613- <property name="text">
2614- <string>Scale Image Circle</string>
2615- </property>
2616- </widget>
2617- <widget class="QGroupBox" name="groupBox">
2618- <property name="geometry">
2619- <rect>
2620- <x>0</x>
2621- <y>40</y>
2622- <width>503</width>
2623- <height>121</height>
2624- </rect>
2625- </property>
2626- <property name="title">
2627- <string>Key Mappings</string>
2628- </property>
2629- <layout class="QGridLayout" name="gridLayout_2">
2630- <item row="0" column="0">
2631- <widget class="QLabel" name="label_11">
2632- <property name="text">
2633- <string>Toggle Plugin:</string>
2634- </property>
2635- <property name="alignment">
2636- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
2637- </property>
2638- </widget>
2639- </item>
2640- <item row="0" column="1">
2641- <widget class="QLineEdit" name="togglePluginLineEdit">
2642- <property name="sizePolicy">
2643- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
2644- <horstretch>0</horstretch>
2645- <verstretch>0</verstretch>
2646- </sizepolicy>
2647- </property>
2648- <property name="baseSize">
2649- <size>
2650- <width>100</width>
2651- <height>22</height>
2652- </size>
2653- </property>
2654- <property name="text">
2655- <string/>
2656- </property>
2657- <property name="maxLength">
2658- <number>50</number>
2659- </property>
2660- </widget>
2661- </item>
2662- <item row="0" column="2">
2663- <widget class="QLabel" name="label_13">
2664- <property name="text">
2665- <string>Popup Navigator:</string>
2666- </property>
2667- <property name="alignment">
2668- <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
2669- </property>
2670- </widget>
2671- </item>
2672- <item row="0" column="3">
2673- <widget class="QLineEdit" name="togglePopupNavigatorWindowLineEdit">
2674- <property name="sizePolicy">
2675- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
2676- <horstretch>0</horstretch>
2677- <verstretch>0</verstretch>
2678- </sizepolicy>
2679- </property>
2680- <property name="baseSize">
2681- <size>
2682- <width>100</width>
2683- <height>22</height>
2684- </size>
2685- </property>
2686- <property name="maxLength">
2687- <number>50</number>
2688- </property>
2689- </widget>
2690- </item>
2691- </layout>
2692- </widget>
2693- <widget class="QCheckBox" name="requireSelectionCheckBox">
2694- <property name="geometry">
2695- <rect>
2696- <x>260</x>
2697- <y>10</y>
2698- <width>201</width>
2699- <height>21</height>
2700- </rect>
2701- </property>
2702- <property name="text">
2703- <string>Require selection to enable</string>
2704- </property>
2705- </widget>
2706+ <layout class="QVBoxLayout" name="verticalLayoutTabGeneral">
2707+ <property name="spacing">
2708+ <number>0</number>
2709+ </property>
2710+ <property name="margin">
2711+ <number>0</number>
2712+ </property>
2713+ <item>
2714+ <widget class="QGroupBox" name="groupBoxOcularOptions">
2715+ <property name="title">
2716+ <string>Ocular view</string>
2717+ </property>
2718+ <layout class="QVBoxLayout" name="verticalLayout_7">
2719+ <property name="margin">
2720+ <number>0</number>
2721+ </property>
2722+ <item>
2723+ <widget class="QCheckBox" name="requireSelectionCheckBox">
2724+ <property name="text">
2725+ <string>Enable only if an object is selected</string>
2726+ </property>
2727+ </widget>
2728+ </item>
2729+ <item>
2730+ <widget class="QCheckBox" name="scaleImageCircleCheckBox">
2731+ <property name="text">
2732+ <string>Scale image circle</string>
2733+ </property>
2734+ </widget>
2735+ </item>
2736+ </layout>
2737+ </widget>
2738+ </item>
2739+ <item>
2740+ <widget class="QGroupBox" name="groupBox">
2741+ <property name="title">
2742+ <string>Key mappings</string>
2743+ </property>
2744+ <layout class="QFormLayout" name="formLayout_3">
2745+ <property name="margin">
2746+ <number>0</number>
2747+ </property>
2748+ <item row="0" column="0">
2749+ <widget class="QLabel" name="label_11">
2750+ <property name="text">
2751+ <string>Toggle ocular view:</string>
2752+ </property>
2753+ <property name="alignment">
2754+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
2755+ </property>
2756+ </widget>
2757+ </item>
2758+ <item row="0" column="1">
2759+ <widget class="QLineEdit" name="togglePluginLineEdit">
2760+ <property name="maximumSize">
2761+ <size>
2762+ <width>100</width>
2763+ <height>16777215</height>
2764+ </size>
2765+ </property>
2766+ <property name="baseSize">
2767+ <size>
2768+ <width>100</width>
2769+ <height>22</height>
2770+ </size>
2771+ </property>
2772+ <property name="text">
2773+ <string/>
2774+ </property>
2775+ <property name="maxLength">
2776+ <number>50</number>
2777+ </property>
2778+ </widget>
2779+ </item>
2780+ <item row="1" column="0">
2781+ <widget class="QLabel" name="labelPopupMenuShortcut">
2782+ <property name="text">
2783+ <string>Open pop-up navigation menu:</string>
2784+ </property>
2785+ <property name="alignment">
2786+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
2787+ </property>
2788+ </widget>
2789+ </item>
2790+ <item row="1" column="1">
2791+ <widget class="QLineEdit" name="togglePopupNavigatorWindowLineEdit">
2792+ <property name="maximumSize">
2793+ <size>
2794+ <width>100</width>
2795+ <height>16777215</height>
2796+ </size>
2797+ </property>
2798+ <property name="baseSize">
2799+ <size>
2800+ <width>100</width>
2801+ <height>22</height>
2802+ </size>
2803+ </property>
2804+ <property name="maxLength">
2805+ <number>50</number>
2806+ </property>
2807+ </widget>
2808+ </item>
2809+ </layout>
2810+ </widget>
2811+ </item>
2812+ <item>
2813+ <widget class="QGroupBox" name="groupBoxInterface">
2814+ <property name="title">
2815+ <string>Interface</string>
2816+ </property>
2817+ <layout class="QVBoxLayout" name="verticalLayout_8">
2818+ <property name="margin">
2819+ <number>0</number>
2820+ </property>
2821+ <item>
2822+ <widget class="QCheckBox" name="checkBoxControlPanel">
2823+ <property name="text">
2824+ <string>On-screen control panel</string>
2825+ </property>
2826+ </widget>
2827+ </item>
2828+ </layout>
2829+ </widget>
2830+ </item>
2831+ <item>
2832+ <spacer name="verticalSpacer_3">
2833+ <property name="orientation">
2834+ <enum>Qt::Vertical</enum>
2835+ </property>
2836+ <property name="sizeHint" stdset="0">
2837+ <size>
2838+ <width>20</width>
2839+ <height>40</height>
2840+ </size>
2841+ </property>
2842+ </spacer>
2843+ </item>
2844+ </layout>
2845 </widget>
2846 <widget class="QWidget" name="Eyepieces">
2847 <attribute name="title">
2848@@ -335,9 +366,6 @@
2849 <enum>QFrame::Raised</enum>
2850 </property>
2851 <layout class="QHBoxLayout" name="horizontalLayout_2">
2852- <property name="spacing">
2853- <number>0</number>
2854- </property>
2855 <property name="leftMargin">
2856 <number>0</number>
2857 </property>
2858@@ -352,29 +380,65 @@
2859 </property>
2860 <item>
2861 <widget class="QPushButton" name="addOcular">
2862+ <property name="minimumSize">
2863+ <size>
2864+ <width>0</width>
2865+ <height>24</height>
2866+ </size>
2867+ </property>
2868 <property name="text">
2869 <string>Add</string>
2870 </property>
2871 </widget>
2872 </item>
2873 <item>
2874- <spacer name="horizontalSpacer_3">
2875- <property name="orientation">
2876- <enum>Qt::Horizontal</enum>
2877- </property>
2878- <property name="sizeType">
2879- <enum>QSizePolicy::Preferred</enum>
2880- </property>
2881- <property name="sizeHint" stdset="0">
2882- <size>
2883- <width>20</width>
2884- <height>20</height>
2885- </size>
2886- </property>
2887- </spacer>
2888+ <widget class="QPushButton" name="pushButtonMoveOcularUp">
2889+ <property name="sizePolicy">
2890+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
2891+ <horstretch>0</horstretch>
2892+ <verstretch>0</verstretch>
2893+ </sizepolicy>
2894+ </property>
2895+ <property name="minimumSize">
2896+ <size>
2897+ <width>24</width>
2898+ <height>24</height>
2899+ </size>
2900+ </property>
2901+ <property name="icon">
2902+ <iconset resource="../../../../data/gui/guiRes.qrc">
2903+ <normaloff>:/graphicGui/spinup.png</normaloff>:/graphicGui/spinup.png</iconset>
2904+ </property>
2905+ </widget>
2906+ </item>
2907+ <item>
2908+ <widget class="QPushButton" name="pushButtonMoveOcularDown">
2909+ <property name="sizePolicy">
2910+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
2911+ <horstretch>0</horstretch>
2912+ <verstretch>0</verstretch>
2913+ </sizepolicy>
2914+ </property>
2915+ <property name="minimumSize">
2916+ <size>
2917+ <width>24</width>
2918+ <height>24</height>
2919+ </size>
2920+ </property>
2921+ <property name="icon">
2922+ <iconset resource="../../../../data/gui/guiRes.qrc">
2923+ <normaloff>:/graphicGui/spindown.png</normaloff>:/graphicGui/spindown.png</iconset>
2924+ </property>
2925+ </widget>
2926 </item>
2927 <item>
2928 <widget class="QPushButton" name="deleteOcular">
2929+ <property name="minimumSize">
2930+ <size>
2931+ <width>0</width>
2932+ <height>24</height>
2933+ </size>
2934+ </property>
2935 <property name="text">
2936 <string>Delete</string>
2937 </property>
2938@@ -468,7 +532,7 @@
2939 <item row="2" column="0">
2940 <widget class="QLabel" name="label_5">
2941 <property name="text">
2942- <string>Focal Length:</string>
2943+ <string>Focal length:</string>
2944 </property>
2945 </widget>
2946 </item>
2947@@ -488,7 +552,7 @@
2948 <item row="3" column="0">
2949 <widget class="QLabel" name="label_10">
2950 <property name="text">
2951- <string>Field Stop:</string>
2952+ <string>Field stop:</string>
2953 </property>
2954 </widget>
2955 </item>
2956@@ -606,9 +670,6 @@
2957 <enum>QFrame::Raised</enum>
2958 </property>
2959 <layout class="QHBoxLayout" name="CCD_horizontalLayout_2">
2960- <property name="spacing">
2961- <number>0</number>
2962- </property>
2963 <property name="leftMargin">
2964 <number>0</number>
2965 </property>
2966@@ -623,29 +684,65 @@
2967 </property>
2968 <item>
2969 <widget class="QPushButton" name="addCCD">
2970+ <property name="minimumSize">
2971+ <size>
2972+ <width>0</width>
2973+ <height>24</height>
2974+ </size>
2975+ </property>
2976 <property name="text">
2977 <string>Add</string>
2978 </property>
2979 </widget>
2980 </item>
2981 <item>
2982- <spacer name="horizontalSpacer_add_remove">
2983- <property name="orientation">
2984- <enum>Qt::Horizontal</enum>
2985- </property>
2986- <property name="sizeType">
2987- <enum>QSizePolicy::Preferred</enum>
2988- </property>
2989- <property name="sizeHint" stdset="0">
2990- <size>
2991- <width>20</width>
2992- <height>20</height>
2993- </size>
2994- </property>
2995- </spacer>
2996+ <widget class="QPushButton" name="pushButtonMoveSensorUp">
2997+ <property name="sizePolicy">
2998+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
2999+ <horstretch>0</horstretch>
3000+ <verstretch>0</verstretch>
3001+ </sizepolicy>
3002+ </property>
3003+ <property name="minimumSize">
3004+ <size>
3005+ <width>24</width>
3006+ <height>24</height>
3007+ </size>
3008+ </property>
3009+ <property name="icon">
3010+ <iconset resource="../../../../data/gui/guiRes.qrc">
3011+ <normaloff>:/graphicGui/spinup.png</normaloff>:/graphicGui/spinup.png</iconset>
3012+ </property>
3013+ </widget>
3014+ </item>
3015+ <item>
3016+ <widget class="QPushButton" name="pushButtonMoveSensorDown">
3017+ <property name="sizePolicy">
3018+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
3019+ <horstretch>0</horstretch>
3020+ <verstretch>0</verstretch>
3021+ </sizepolicy>
3022+ </property>
3023+ <property name="minimumSize">
3024+ <size>
3025+ <width>24</width>
3026+ <height>24</height>
3027+ </size>
3028+ </property>
3029+ <property name="icon">
3030+ <iconset resource="../../../../data/gui/guiRes.qrc">
3031+ <normaloff>:/graphicGui/spindown.png</normaloff>:/graphicGui/spindown.png</iconset>
3032+ </property>
3033+ </widget>
3034 </item>
3035 <item>
3036 <widget class="QPushButton" name="deleteCCD">
3037+ <property name="minimumSize">
3038+ <size>
3039+ <width>0</width>
3040+ <height>24</height>
3041+ </size>
3042+ </property>
3043 <property name="text">
3044 <string>Delete</string>
3045 </property>
3046@@ -947,38 +1044,80 @@
3047 </item>
3048 <item>
3049 <widget class="QFrame" name="frame_3">
3050- <property name="frameShape">
3051- <enum>QFrame::StyledPanel</enum>
3052- </property>
3053- <property name="frameShadow">
3054- <enum>QFrame::Raised</enum>
3055- </property>
3056 <layout class="QHBoxLayout" name="horizontalLayout">
3057+ <property name="leftMargin">
3058+ <number>0</number>
3059+ </property>
3060+ <property name="topMargin">
3061+ <number>5</number>
3062+ </property>
3063+ <property name="rightMargin">
3064+ <number>0</number>
3065+ </property>
3066+ <property name="bottomMargin">
3067+ <number>0</number>
3068+ </property>
3069 <item>
3070 <widget class="QPushButton" name="addTelescope">
3071+ <property name="minimumSize">
3072+ <size>
3073+ <width>0</width>
3074+ <height>24</height>
3075+ </size>
3076+ </property>
3077 <property name="text">
3078 <string>Add</string>
3079 </property>
3080 </widget>
3081 </item>
3082 <item>
3083- <spacer name="horizontalSpacer">
3084- <property name="orientation">
3085- <enum>Qt::Horizontal</enum>
3086- </property>
3087- <property name="sizeType">
3088- <enum>QSizePolicy::Preferred</enum>
3089- </property>
3090- <property name="sizeHint" stdset="0">
3091- <size>
3092- <width>20</width>
3093- <height>20</height>
3094- </size>
3095- </property>
3096- </spacer>
3097+ <widget class="QPushButton" name="pushButtonMoveTelescopeUp">
3098+ <property name="sizePolicy">
3099+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
3100+ <horstretch>0</horstretch>
3101+ <verstretch>0</verstretch>
3102+ </sizepolicy>
3103+ </property>
3104+ <property name="minimumSize">
3105+ <size>
3106+ <width>24</width>
3107+ <height>24</height>
3108+ </size>
3109+ </property>
3110+ <property name="icon">
3111+ <iconset resource="../../../../data/gui/guiRes.qrc">
3112+ <normaloff>:/graphicGui/spinup.png</normaloff>:/graphicGui/spinup.png</iconset>
3113+ </property>
3114+ </widget>
3115+ </item>
3116+ <item>
3117+ <widget class="QPushButton" name="pushButtonMoveTelescopeDown">
3118+ <property name="sizePolicy">
3119+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
3120+ <horstretch>0</horstretch>
3121+ <verstretch>0</verstretch>
3122+ </sizepolicy>
3123+ </property>
3124+ <property name="minimumSize">
3125+ <size>
3126+ <width>24</width>
3127+ <height>24</height>
3128+ </size>
3129+ </property>
3130+ <property name="icon">
3131+ <iconset resource="../../../../data/gui/guiRes.qrc">
3132+ <normaloff>:/graphicGui/spindown.png</normaloff>:/graphicGui/spindown.png</iconset>
3133+ </property>
3134+ </widget>
3135 </item>
3136 <item>
3137 <widget class="QPushButton" name="deleteTelescope">
3138+ <property name="minimumSize">
3139+ <size>
3140+ <width>0</width>
3141+ <height>24</height>
3142+ </size>
3143+ </property>
3144 <property name="text">
3145 <string>Delete</string>
3146 </property>
3147@@ -1040,7 +1179,7 @@
3148 <item row="1" column="0">
3149 <widget class="QLabel" name="label_9">
3150 <property name="text">
3151- <string>Focal Length:</string>
3152+ <string>Focal length:</string>
3153 </property>
3154 </widget>
3155 </item>
3156@@ -1068,14 +1207,14 @@
3157 <item row="3" column="1">
3158 <widget class="QCheckBox" name="telescopeHFlip">
3159 <property name="text">
3160- <string>Horizontal Flip</string>
3161+ <string>Horizontal flip</string>
3162 </property>
3163 </widget>
3164 </item>
3165 <item row="4" column="1">
3166 <widget class="QCheckBox" name="telescopeVFlip">
3167 <property name="text">
3168- <string>Vertical Flip</string>
3169+ <string>Vertical flip</string>
3170 </property>
3171 </widget>
3172 </item>
3173@@ -1105,42 +1244,13 @@
3174 <string>About</string>
3175 </attribute>
3176 <layout class="QGridLayout" name="gridLayout">
3177- <property name="leftMargin">
3178- <number>12</number>
3179- </property>
3180- <property name="topMargin">
3181+ <property name="margin">
3182 <number>0</number>
3183 </property>
3184- <property name="rightMargin">
3185- <number>12</number>
3186- </property>
3187- <property name="bottomMargin">
3188- <number>12</number>
3189- </property>
3190 <item row="0" column="0">
3191 <widget class="QTextBrowser" name="textBrowser">
3192- <property name="html">
3193- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
3194-&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
3195-p, li { white-space: pre-wrap; }
3196-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
3197-&lt;table border=&quot;0&quot; style=&quot;-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;&quot;&gt;
3198-&lt;tr&gt;
3199-&lt;td style=&quot;border: none;&quot;&gt;
3200-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt;Author: &lt;/span&gt;&lt;a href=&quot;treaves@silverfieldstech.com&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt; text-decoration: underline; color:#0000ff;&quot;&gt;Timothy Reaves&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
3201-&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt;&lt;/p&gt;
3202-&lt;p style=&quot; margin-top:18px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-weight:600;&quot;&gt;Overview&lt;/span&gt;&lt;/p&gt;
3203-&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt;This plugin is intended to simulate what you would see through an eyepiece. This configuration dialog can be used to add, modify, or delete eyepieces and telescopes, as well as CCD Sensors. Your first time running the app will populate some samples to get your started.&lt;/span&gt;&lt;/p&gt;
3204-&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt;You can choose to scale the image you see on the screen. This is intended to show you a better comparison of what one eyepiece/telescope combination will be like as compared to another. The same eyepiece in two different telescopes of differing focal length will produce two different exit circles, changing the view someone. The trade-off of this is that, with the image scaled, a good deal of the screen can be wasted. Therefor I recommend that you leave it off, unless you feel you have a need of it.&lt;/span&gt;&lt;/p&gt;
3205-&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt;You can toggle a crosshair in the view. Ideally, I wanted this to be aligned to North. I've been unable to do so. So currently it aligns to the top of the screen.&lt;/span&gt;&lt;/p&gt;
3206-&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt;You can toggle a Telrad finder; this can only be done when you have not turned on the Ocular view. This feature draws three concentric circles of 0.5°, 2.0°, and 4.0°, helping you see what you would expect to see with the naked eye through the Telrad (or similar) finder.&lt;/span&gt;&lt;/p&gt;
3207-&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt;If you find any issues, please let me know. Enjoy!&lt;/span&gt;&lt;/p&gt;
3208-&lt;p style=&quot; margin-top:18px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-weight:600;&quot;&gt;Hot Keys&lt;/span&gt;&lt;/p&gt;
3209-&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt;These keys are the default, and can be edited in the General Tab. If you are not a Mac user, replace the &lt;/span&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-style:italic;&quot;&gt;Command&lt;/span&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt; key with the &lt;/span&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-style:italic;&quot;&gt;CTRL&lt;/span&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt; key.&lt;/span&gt;&lt;/p&gt;
3210-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-weight:600;&quot;&gt;Command-O&lt;/span&gt;&lt;/p&gt;
3211-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:30px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt;Activate / de-activate the plugin.&lt;/span&gt;&lt;/p&gt;
3212-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt; font-weight:600;&quot;&gt;Alt-O&lt;/span&gt;&lt;/p&gt;
3213-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:30px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Lucida Grande'; font-size:13pt;&quot;&gt;Shows the popup menu.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/body&gt;&lt;/html&gt;</string>
3214+ <property name="openExternalLinks">
3215+ <bool>true</bool>
3216 </property>
3217 </widget>
3218 </item>
3219@@ -1161,6 +1271,48 @@
3220 <container>1</container>
3221 </customwidget>
3222 </customwidgets>
3223- <resources/>
3224+ <tabstops>
3225+ <tabstop>Tabs</tabstop>
3226+ <tabstop>requireSelectionCheckBox</tabstop>
3227+ <tabstop>scaleImageCircleCheckBox</tabstop>
3228+ <tabstop>togglePluginLineEdit</tabstop>
3229+ <tabstop>togglePopupNavigatorWindowLineEdit</tabstop>
3230+ <tabstop>ocularListView</tabstop>
3231+ <tabstop>addOcular</tabstop>
3232+ <tabstop>pushButtonMoveOcularUp</tabstop>
3233+ <tabstop>pushButtonMoveOcularDown</tabstop>
3234+ <tabstop>deleteOcular</tabstop>
3235+ <tabstop>ocularName</tabstop>
3236+ <tabstop>ocularAFov</tabstop>
3237+ <tabstop>ocularFL</tabstop>
3238+ <tabstop>ocularFieldStop</tabstop>
3239+ <tabstop>binocularsCheckBox</tabstop>
3240+ <tabstop>ccdListView</tabstop>
3241+ <tabstop>addCCD</tabstop>
3242+ <tabstop>pushButtonMoveSensorUp</tabstop>
3243+ <tabstop>pushButtonMoveSensorDown</tabstop>
3244+ <tabstop>deleteCCD</tabstop>
3245+ <tabstop>ccdName</tabstop>
3246+ <tabstop>ccdResX</tabstop>
3247+ <tabstop>ccdResY</tabstop>
3248+ <tabstop>ccdChipX</tabstop>
3249+ <tabstop>ccdChipY</tabstop>
3250+ <tabstop>ccdPixelX</tabstop>
3251+ <tabstop>ccdPixelY</tabstop>
3252+ <tabstop>telescopeListView</tabstop>
3253+ <tabstop>addTelescope</tabstop>
3254+ <tabstop>pushButtonMoveTelescopeUp</tabstop>
3255+ <tabstop>pushButtonMoveTelescopeDown</tabstop>
3256+ <tabstop>deleteTelescope</tabstop>
3257+ <tabstop>telescopeName</tabstop>
3258+ <tabstop>telescopeFL</tabstop>
3259+ <tabstop>telescopeDiameter</tabstop>
3260+ <tabstop>telescopeHFlip</tabstop>
3261+ <tabstop>telescopeVFlip</tabstop>
3262+ <tabstop>textBrowser</tabstop>
3263+ </tabstops>
3264+ <resources>
3265+ <include location="../../../../data/gui/guiRes.qrc"/>
3266+ </resources>
3267 <connections/>
3268 </ui>
3269
3270=== modified file 'src/gui/StelGui.cpp'
3271--- src/gui/StelGui.cpp 2011-11-21 10:37:37 +0000
3272+++ src/gui/StelGui.cpp 2011-11-24 21:50:30 +0000
3273@@ -837,6 +837,8 @@
3274
3275 LeftStelBar* StelGui::getWindowsButtonBar() {return skyGui->winBar;}
3276
3277+SkyGui* StelGui::getSkyGui() {return skyGui;}
3278+
3279 bool StelGui::getAutoHideHorizontalButtonBar() const {return skyGui->autoHideHorizontalButtonBar;}
3280
3281 void StelGui::setAutoHideHorizontalButtonBar(bool b) {skyGui->autoHideHorizontalButtonBar=b;}
3282
3283=== modified file 'src/gui/StelGui.hpp'
3284--- src/gui/StelGui.hpp 2011-01-29 18:14:28 +0000
3285+++ src/gui/StelGui.hpp 2011-11-24 21:50:30 +0000
3286@@ -78,6 +78,10 @@
3287
3288 //! Get the button bar of the left of the screen
3289 class LeftStelBar* getWindowsButtonBar();
3290+
3291+ //! Get the SkyGui instance (useful for adding other interface elements).
3292+ //! It will return a valid object only if called after init().
3293+ class SkyGui* getSkyGui();
3294
3295 //! Get whether the buttons toggling image flip are visible
3296 bool getFlagShowFlipButtons() {return flagShowFlipButtons;}
3297
3298=== modified file 'src/gui/StelGuiItems.cpp'
3299--- src/gui/StelGuiItems.cpp 2011-07-21 11:07:44 +0000
3300+++ src/gui/StelGuiItems.cpp 2011-11-24 21:50:30 +0000
3301@@ -45,11 +45,22 @@
3302 #include <QGraphicsLinearLayout>
3303 #include <QSettings>
3304
3305-StelButton::StelButton(QGraphicsItem* parent, const QPixmap& apixOn, const QPixmap& apixOff,
3306- const QPixmap& apixHover, QAction* aaction, bool noBackground) :
3307- QGraphicsPixmapItem(apixOff, parent), pixOn(apixOn), pixOff(apixOff), pixHover(apixHover),
3308- checked(ButtonStateOff), action(aaction), noBckground(noBackground), isTristate_(false),
3309- opacity(1.), hoverOpacity(0.)
3310+StelButton::StelButton(QGraphicsItem* parent,
3311+ const QPixmap& apixOn,
3312+ const QPixmap& apixOff,
3313+ const QPixmap& apixHover,
3314+ QAction* aaction,
3315+ bool noBackground) :
3316+ QGraphicsPixmapItem(apixOff, parent),
3317+ pixOn(apixOn),
3318+ pixOff(apixOff),
3319+ pixHover(apixHover),
3320+ checked(ButtonStateOff),
3321+ action(aaction),
3322+ noBckground(noBackground),
3323+ isTristate_(false),
3324+ opacity(1.),
3325+ hoverOpacity(0.)
3326 {
3327 Q_ASSERT(!pixOn.isNull());
3328 Q_ASSERT(!pixOff.isNull());
3329@@ -70,24 +81,41 @@
3330
3331 if (action!=NULL)
3332 {
3333- QObject::connect(action, SIGNAL(toggled(bool)), this, SLOT(setChecked(bool)));
3334+ QObject::connect(action, SIGNAL(toggled(bool)),
3335+ this, SLOT(setChecked(bool)));
3336 if (action->isCheckable())
3337 {
3338 setChecked(action->isChecked());
3339- QObject::connect(this, SIGNAL(toggled(bool)), action, SLOT(setChecked(bool)));
3340+ QObject::connect(this, SIGNAL(toggled(bool)),
3341+ action, SLOT(setChecked(bool)));
3342 }
3343 else
3344 {
3345- QObject::connect(this, SIGNAL(triggered()), action, SLOT(trigger()));
3346+ QObject::connect(this, SIGNAL(triggered()),
3347+ action, SLOT(trigger()));
3348 }
3349 }
3350 }
3351
3352-StelButton::StelButton(QGraphicsItem* parent, const QPixmap& apixOn, const QPixmap& apixOff, const QPixmap& apixNoChange,
3353- const QPixmap& apixHover, QAction* aaction, bool noBackground, bool isTristate) :
3354- QGraphicsPixmapItem(apixOff, parent), pixOn(apixOn), pixOff(apixOff), pixNoChange(apixNoChange), pixHover(apixHover),
3355- checked(ButtonStateOff), action(aaction), noBckground(noBackground), isTristate_(isTristate),
3356- opacity(1.), hoverOpacity(0.)
3357+StelButton::StelButton(QGraphicsItem* parent,
3358+ const QPixmap& apixOn,
3359+ const QPixmap& apixOff,
3360+ const QPixmap& apixNoChange,
3361+ const QPixmap& apixHover,
3362+ QAction* aaction,
3363+ bool noBackground,
3364+ bool isTristate) :
3365+ QGraphicsPixmapItem(apixOff, parent),
3366+ pixOn(apixOn),
3367+ pixOff(apixOff),
3368+ pixNoChange(apixNoChange),
3369+ pixHover(apixHover),
3370+ checked(ButtonStateOff),
3371+ action(aaction),
3372+ noBckground(noBackground),
3373+ isTristate_(isTristate),
3374+ opacity(1.),
3375+ hoverOpacity(0.)
3376 {
3377 Q_ASSERT(!pixOn.isNull());
3378 Q_ASSERT(!pixOff.isNull());
3379@@ -95,7 +123,8 @@
3380 redMode = StelApp::getInstance().getVisionModeNight();
3381 pixOnRed = StelButton::makeRed(pixOn);
3382 pixOffRed = StelButton::makeRed(pixOff);
3383- if (isTristate_) {
3384+ if (isTristate_)
3385+ {
3386 Q_ASSERT(!pixNoChange.isNull());
3387 pixNoChangeRed = StelButton::makeRed(pixNoChange);
3388 }
3389@@ -108,27 +137,33 @@
3390 setAcceptsHoverEvents(true);
3391 timeLine = new QTimeLine(250, this);
3392 timeLine->setCurveShape(QTimeLine::EaseOutCurve);
3393- connect(timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animValueChanged(qreal)));
3394+ connect(timeLine, SIGNAL(valueChanged(qreal)),
3395+ this, SLOT(animValueChanged(qreal)));
3396
3397 if (action!=NULL)
3398 {
3399- QObject::connect(action, SIGNAL(toggled(bool)), this, SLOT(setChecked(bool)));
3400+ QObject::connect(action, SIGNAL(toggled(bool)),
3401+ this, SLOT(setChecked(bool)));
3402 if (action->isCheckable())
3403 {
3404 setChecked(action->isChecked());
3405- QObject::connect(this, SIGNAL(toggled(bool)), action, SLOT(setChecked(bool)));
3406+ QObject::connect(this, SIGNAL(toggled(bool)),
3407+ action, SLOT(setChecked(bool)));
3408 }
3409 else
3410 {
3411- QObject::connect(this, SIGNAL(triggered()), action, SLOT(trigger()));
3412+ QObject::connect(this, SIGNAL(triggered()),
3413+ action, SLOT(trigger()));
3414 }
3415 }
3416 }
3417
3418-int StelButton::toggleChecked(int checked) {
3419+int StelButton::toggleChecked(int checked)
3420+{
3421 if (!isTristate_)
3422 checked = !!!checked;
3423- else {
3424+ else
3425+ {
3426 if (++checked > ButtonStateNoChange)
3427 checked = ButtonStateOff;
3428 }
3429@@ -169,22 +204,22 @@
3430
3431 void StelButton::updateIcon()
3432 {
3433- if (opacity<0.)
3434- opacity=0;
3435+ if (opacity < 0.)
3436+ opacity = 0;
3437 QPixmap pix(pixOn.size());
3438 pix.fill(QColor(0,0,0,0));
3439 QPainter painter(&pix);
3440 painter.setOpacity(opacity);
3441 if (!pixBackground.isNull() && noBckground==false)
3442- painter.drawPixmap(0,0, redMode ? pixBackgroundRed : pixBackground);
3443+ painter.drawPixmap(0, 0, redMode ? pixBackgroundRed : pixBackground);
3444 painter.drawPixmap(0, 0,
3445 (isTristate_ && checked == ButtonStateNoChange) ? (redMode ? pixNoChangeRed : pixNoChange) :
3446 (checked == ButtonStateOn) ? (redMode ? pixOnRed : pixOn) :
3447 /* (checked == ButtonStateOff) ? */ (redMode ? pixOffRed : pixOff));
3448- if (hoverOpacity>0)
3449+ if (hoverOpacity > 0)
3450 {
3451- painter.setOpacity(hoverOpacity*opacity);
3452- painter.drawPixmap(0,0, redMode ? pixHoverRed : pixHover);
3453+ painter.setOpacity(hoverOpacity * opacity);
3454+ painter.drawPixmap(0, 0, redMode ? pixHoverRed : pixHover);
3455 }
3456 setPixmap(pix);
3457 }
3458@@ -201,6 +236,13 @@
3459 updateIcon();
3460 }
3461
3462+void StelButton::setBackgroundPixmap(const QPixmap &newBackground)
3463+{
3464+ pixBackground = newBackground;
3465+ pixBackgroundRed = makeRed(newBackground);
3466+ updateIcon();
3467+}
3468+
3469 QPixmap StelButton::makeRed(const QPixmap& p)
3470 {
3471 QImage im = p.toImage().convertToFormat(QImage::Format_ARGB32);
3472@@ -314,9 +356,16 @@
3473 }
3474 }
3475
3476-BottomStelBar::BottomStelBar(QGraphicsItem* parent, const QPixmap& pixLeft, const QPixmap& pixRight,
3477- const QPixmap& pixMiddle, const QPixmap& pixSingle) : QGraphicsItem(parent), pixBackgroundLeft(pixLeft), pixBackgroundRight(pixRight),
3478- pixBackgroundMiddle(pixMiddle), pixBackgroundSingle(pixSingle)
3479+BottomStelBar::BottomStelBar(QGraphicsItem* parent,
3480+ const QPixmap& pixLeft,
3481+ const QPixmap& pixRight,
3482+ const QPixmap& pixMiddle,
3483+ const QPixmap& pixSingle) :
3484+ QGraphicsItem(parent),
3485+ pixBackgroundLeft(pixLeft),
3486+ pixBackgroundRight(pixRight),
3487+ pixBackgroundMiddle(pixMiddle),
3488+ pixBackgroundSingle(pixSingle)
3489 {
3490 // The text is dummy just for testing
3491 datetime = new QGraphicsSimpleTextItem("2008-02-06 17:33", this);
3492@@ -359,17 +408,17 @@
3493 void BottomStelBar::addButton(StelButton* button, const QString& groupName, const QString& beforeActionName)
3494 {
3495 QList<StelButton*>& g = buttonGroups[groupName].elems;
3496- bool done=false;
3497- for (int i=0;i<g.size();++i)
3498+ bool done = false;
3499+ for (int i=0; i<g.size(); ++i)
3500 {
3501 if (g[i]->action && g[i]->action->objectName()==beforeActionName)
3502 {
3503 g.insert(i, button);
3504- done=true;
3505+ done = true;
3506 break;
3507 }
3508 }
3509- if (done==false)
3510+ if (done == false)
3511 g.append(button);
3512
3513 button->setVisible(true);
3514@@ -382,7 +431,7 @@
3515 StelButton* BottomStelBar::hideButton(const QString& actionName)
3516 {
3517 QString gName;
3518- StelButton* bToRemove=NULL;
3519+ StelButton* bToRemove = NULL;
3520 for (QMap<QString, ButtonGroup>::iterator iter=buttonGroups.begin();iter!=buttonGroups.end();++iter)
3521 {
3522 int i=0;
3523@@ -390,7 +439,7 @@
3524 {
3525 if (b->action && b->action->objectName()==actionName)
3526 {
3527- gName=iter.key();
3528+ gName = iter.key();
3529 bToRemove = b;
3530 iter.value().elems.removeAt(i);
3531 break;
3532@@ -398,9 +447,9 @@
3533 ++i;
3534 }
3535 }
3536- if (bToRemove==NULL)
3537+ if (bToRemove == NULL)
3538 return NULL;
3539- if (buttonGroups[gName].elems.size()==0)
3540+ if (buttonGroups[gName].elems.size() == 0)
3541 {
3542 buttonGroups.remove(gName);
3543 }
3544@@ -417,15 +466,18 @@
3545 {
3546 if (!buttonGroups.contains(groupName))
3547 return;
3548- buttonGroups[groupName].leftMargin=left;
3549- buttonGroups[groupName].rightMargin=right;
3550+ buttonGroups[groupName].leftMargin = left;
3551+ buttonGroups[groupName].rightMargin = right;
3552 updateButtonsGroups();
3553 }
3554
3555 //! Change the background of a group
3556-void BottomStelBar::setGroupBackground(const QString& groupName, const QPixmap& pixLeft,
3557- const QPixmap& pixRight, const QPixmap& pixMiddle,
3558- const QPixmap& pixSingle){
3559+void BottomStelBar::setGroupBackground(const QString& groupName,
3560+ const QPixmap& pixLeft,
3561+ const QPixmap& pixRight,
3562+ const QPixmap& pixMiddle,
3563+ const QPixmap& pixSingle)
3564+{
3565
3566 if (!buttonGroups.contains(groupName))
3567 return;
3568@@ -435,7 +487,6 @@
3569 buttonGroups[groupName].pixBackgroundMiddle = new QPixmap(pixMiddle);
3570 buttonGroups[groupName].pixBackgroundSingle = new QPixmap(pixSingle);
3571 updateButtonsGroups();
3572-
3573 }
3574
3575 QRectF BottomStelBar::getButtonsBoundingRect() const
3576@@ -461,63 +512,65 @@
3577
3578 void BottomStelBar::updateButtonsGroups()
3579 {
3580- double x=0;
3581- double y = datetime->boundingRect().height()+3;
3582+ double x = 0;
3583+ double y = datetime->boundingRect().height() + 3;
3584 for (QMap<QString, ButtonGroup >::iterator iter=buttonGroups.begin();iter!=buttonGroups.end();++iter)
3585 {
3586- if (iter.value().elems.empty())
3587+ ButtonGroup& group = iter.value();
3588+ QList<StelButton*>& buttons = group.elems;
3589+ if (buttons.empty())
3590 continue;
3591- x+=iter.value().leftMargin;
3592- int n=0;
3593- foreach (StelButton* b, iter.value().elems)
3594+ x += group.leftMargin;
3595+ int n = 0;
3596+ foreach (StelButton* b, buttons)
3597 {
3598 // We check if the group has its own background if not the case
3599 // We apply a default background.
3600- if (n==0)
3601+ if (n == 0)
3602 {
3603- if (iter.value().elems.size()==1)
3604+ if (buttons.size() == 1)
3605 {
3606- if (iter.value().pixBackgroundSingle == NULL)
3607- b->pixBackground = pixBackgroundSingle;
3608+ if (group.pixBackgroundSingle == NULL)
3609+ b->setBackgroundPixmap(pixBackgroundSingle);
3610 else
3611- b->pixBackground = *(iter.value().pixBackgroundSingle);
3612+ b->setBackgroundPixmap(*group.pixBackgroundSingle);
3613 }
3614 else
3615 {
3616- if (iter.value().pixBackgroundLeft == NULL)
3617- b->pixBackground = pixBackgroundLeft;
3618+ if (group.pixBackgroundLeft == NULL)
3619+ b->setBackgroundPixmap(pixBackgroundLeft);
3620 else
3621- b->pixBackground = *(iter.value().pixBackgroundLeft);
3622+ b->setBackgroundPixmap(*group.pixBackgroundLeft);
3623 }
3624 }
3625- else if (n==iter.value().elems.size()-1)
3626+ else if (n == buttons.size()-1)
3627 {
3628- if (iter.value().elems.size()!=1)
3629+ if (buttons.size() != 1)
3630 {
3631- if (iter.value().pixBackgroundSingle == NULL)
3632- b->pixBackground = pixBackgroundSingle;
3633+ if (group.pixBackgroundSingle == NULL)
3634+ b->setBackgroundPixmap(pixBackgroundSingle);
3635 else
3636- b->pixBackground = *(iter.value().pixBackgroundSingle);
3637+ b->setBackgroundPixmap(*group.pixBackgroundSingle);
3638 }
3639- if (iter.value().pixBackgroundRight == NULL)
3640- b->pixBackground = pixBackgroundRight;
3641+ if (group.pixBackgroundRight == NULL)
3642+ b->setBackgroundPixmap(pixBackgroundRight);
3643 else
3644- b->pixBackground = *(iter.value().pixBackgroundRight);
3645+ b->setBackgroundPixmap(*group.pixBackgroundRight);
3646 }
3647 else
3648 {
3649- if (iter.value().pixBackgroundMiddle == NULL)
3650- b->pixBackground = pixBackgroundMiddle;
3651+ if (group.pixBackgroundMiddle == NULL)
3652+ b->setBackgroundPixmap(pixBackgroundMiddle);
3653 else
3654- b->pixBackground = *(iter.value().pixBackgroundMiddle);
3655+ b->setBackgroundPixmap(*group.pixBackgroundMiddle);
3656 }
3657 // Update the button pixmap
3658 b->animValueChanged(0.);
3659 b->setPos(x, y);
3660- x+=b->pixOn.width();
3661+ x += b->getButtonPixmapWidth();
3662 ++n;
3663 }
3664- x+=iter.value().rightMargin;
3665+ x+=group.rightMargin;
3666 }
3667 updateText(true);
3668 }
3669
3670=== modified file 'src/gui/StelGuiItems.hpp'
3671--- src/gui/StelGuiItems.hpp 2010-05-09 20:23:43 +0000
3672+++ src/gui/StelGuiItems.hpp 2011-11-24 21:50:30 +0000
3673@@ -88,12 +88,21 @@
3674 //! Get whether the button is checked
3675 int isChecked() const {return checked;}
3676
3677+ //! Get the width of the button image.
3678+ //! The width is based on pixOn.
3679+ int getButtonPixmapWidth() const {return pixOn.width();}
3680+
3681 //! Set the button opacity
3682 void setOpacity(double v) {opacity=v; updateIcon();}
3683
3684 //! Activate red mode for this button, i.e. will reduce the non red color component of the icon
3685 void setRedMode(bool b) {redMode=b; updateIcon();}
3686
3687+ //! Set the background pixmap of the button.
3688+ //! A variant for night vision mode (pixBackgroundRed) is automatically
3689+ //! generated from the new background.
3690+ void setBackgroundPixmap(const QPixmap& newBackground);
3691+
3692 //! Transform the pixmap so that it look red for night vision mode
3693 static QPixmap makeRed(const QPixmap& p);
3694