1 /**************************************************************************
2 * This file is part of the Fraqtive program
3 * Copyright (C) 2004-2012 Michał Męciński
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 **************************************************************************/
18 
19 #include "fraqtiveapplication.h"
20 
21 #include <QTimer>
22 #include <QDateTime>
23 #include <QPushButton>
24 #include <QDesktopServices>
25 #include <QUrl>
26 
27 #if defined( Q_OS_WIN )
28 #include <shlobj.h>
29 #endif
30 
31 #include "jobscheduler.h"
32 #include "configurationdata.h"
33 #include "fraqtivemainwindow.h"
34 #include "datastructures.h"
35 #include "aboutbox.h"
36 #include "guidedialog.h"
37 #include "iconloader.h"
38 
39 #if defined( Q_OS_WIN )
40 #include "xmlui/windowsstyle.h"
41 #elif defined( Q_OS_MAC )
42 #include "xmlui/macstyle.h"
43 #endif
44 
FraqtiveApplication(int & argc,char ** argv)45 FraqtiveApplication::FraqtiveApplication( int& argc, char** argv ) : QApplication( argc, argv )
46 {
47 #if defined( Q_OS_WIN ) && !defined( XMLUI_NO_STYLE_WINDOWS )
48     setStyle( new XmlUi::WindowsStyle() );
49 #elif defined( Q_OS_MAC ) && !defined( XMLUI_NO_STYLE_MAC )
50     setStyle( new XmlUi::MacStyle() );
51 #endif
52 
53     setWindowIcon( IconLoader::icon( "fraqtive" ) );
54 
55     registerDataStructures();
56 
57     m_jobScheduler = new JobScheduler();
58 
59     m_configuration = new ConfigurationData();
60     m_configuration->readConfiguration();
61 
62     m_mainWindow = new FraqtiveMainWindow();
63     m_mainWindow->show();
64 
65     if ( m_configuration->value( "LastVersion" ).toString() != version() ) {
66         m_configuration->setValue( "LastVersion", version() );
67         QTimer::singleShot( 100, this, SLOT( about() ) );
68     }
69 }
70 
~FraqtiveApplication()71 FraqtiveApplication::~FraqtiveApplication()
72 {
73     delete m_mainWindow;
74     m_mainWindow = NULL;
75 
76     delete m_jobScheduler;
77     m_jobScheduler = NULL;
78 
79     m_configuration->writeConfiguration();
80 
81     delete m_configuration;
82     m_configuration = NULL;
83 }
84 
version() const85 QString FraqtiveApplication::version() const
86 {
87     return "0.4.8";
88 }
89 
90 #if defined( Q_OS_WIN )
91 #if defined( Q_CC_GNU )
92 #define __ImageBase _image_base__
93 #endif
94 extern "C" IMAGE_DOS_HEADER __ImageBase;
95 #endif
96 
technicalInformation()97 QString FraqtiveApplication::technicalInformation()
98 {
99 #if defined( Q_OS_WIN )
100 #if defined( Q_OS_WIN64 )
101     QString configBits = "64";
102 #else
103     QString configBits = "32";
104 #endif
105 #endif
106 #if defined ( QT_DEBUG )
107     QString configMode = "debug";
108 #else
109     QString configMode = "release";
110 #endif
111 #if defined( QT_SHARED )
112     QString configLink = "dynamic";
113 #else
114     QString configLink = "static";
115 #endif
116 
117     QString qtVersion = qVersion();
118 
119     QString infoMessage;
120     infoMessage += "<h4>" + tr( "Technical Information" ) + "</h4>";
121     infoMessage += "<p>";
122 
123 #if defined( Q_OS_WIN )
124     const IMAGE_NT_HEADERS* header = (const IMAGE_NT_HEADERS*)( (char*)&__ImageBase + __ImageBase.e_lfanew );
125     QDateTime compiled = QDateTime::fromTime_t( header->FileHeader.TimeDateStamp );
126 
127     infoMessage += tr( "Built on %1 in %2-bit %3 mode." ).arg( compiled.toString( "yyyy-MM-dd HH:mm" ), configBits, configMode ) + " ";
128 #else
129     infoMessage += tr( "Built in %1 mode." ).arg( configMode ) + " ";
130 #endif
131 
132     infoMessage += tr( "Using Qt %1 (%2 linking)." ).arg( qtVersion, configLink ) + "</p>";
133 
134     return infoMessage;
135 }
136 
about()137 void FraqtiveApplication::about()
138 {
139     if ( !m_aboutBox ) {
140         QString message;
141         message += "<h3>" + tr( "Fraqtive %1" ).arg( version() ) + "</h3>";
142         message += "<p>" + tr( "Mandelbrot family fractal generator." ) + "</p>";
143         message += "<p>" + tr( "This program is free software: you can redistribute it and/or modify"
144             " it under the terms of the GNU General Public License as published by"
145             " the Free Software Foundation, either version 3 of the License, or"
146             " (at your option) any later version." ) + "</p>";
147         message += "<p>" + trUtf8( "Copyright &copy; 2004-2015 Michał Męciński" ) + "</p>";
148 
149         QString link = "<a href=\"http://fraqtive.mimec.org\">fraqtive.mimec.org</a>";
150 
151         QString helpMessage;
152         helpMessage += "<h4>" + tr( "Help" ) + "</h4>";
153         helpMessage += "<p>" + tr( "Open the Fraqtive Quick Guide for help." ) + "</p>";
154 
155         QString webMessage;
156         webMessage += "<h4>" + tr( "Website" ) + "</h4>";
157         webMessage += "<p>" + tr( "Visit %1 for more information about Fraqtive." ).arg( link ) + "</p>";
158 
159         QString donateMessage;
160         donateMessage += "<h4>" + tr( "Donations" ) + "</h4>";
161         donateMessage += "<p>" + tr( "If you like this program, your donation will help me dedicate more time for it, support it and implement new features." ) + "</p>";
162 
163         QString infoMessage = technicalInformation();
164 
165         m_aboutBox = new AboutBox( tr( "About Fraqtive" ), message, m_mainWindow );
166 
167         AboutBoxSection* helpSection = m_aboutBox->addSection( IconLoader::pixmap( "help" ), helpMessage );
168 
169         QPushButton* helpButton = helpSection->addButton( tr( "&Quick Guide" ) );
170         connect( helpButton, SIGNAL( clicked() ), this, SLOT( showQuickGuide() ) );
171 
172         m_aboutBox->addSection( IconLoader::pixmap( "web" ), webMessage );
173 
174         AboutBoxSection* donateSection = m_aboutBox->addSection( IconLoader::pixmap( "donate" ), donateMessage );
175 
176         QPushButton* donateButton = donateSection->addButton( tr( "&Donate" ) );
177         connect( donateButton, SIGNAL( clicked() ), this, SLOT( openDonations() ) );
178 
179         m_aboutBox->addSection( IconLoader::pixmap( "info" ), infoMessage );
180     }
181 
182     m_aboutBox->show();
183     m_aboutBox->activateWindow();
184 }
185 
showQuickGuide()186 void FraqtiveApplication::showQuickGuide()
187 {
188     m_aboutBox->close();
189 
190     if ( !m_guideDialog ) {
191         m_guideDialog = new GuideDialog( m_mainWindow );
192 
193         m_guideDialog->resize( m_mainWindow->width() / 2, m_mainWindow->height() - 100 );
194         m_guideDialog->move( m_mainWindow->pos().x() + m_mainWindow->width() / 2 - 50, m_mainWindow->pos().y() + 50 );
195     }
196 
197     m_guideDialog->show();
198     m_guideDialog->activateWindow();
199 }
200 
openDonations()201 void FraqtiveApplication::openDonations()
202 {
203     QDesktopServices::openUrl( QUrl( "http://fraqtive.mimec.org/donations" ) );
204 }
205