Feathercoin  0.5.0
P2P Digital Currency
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
bitcoin.cpp
Go to the documentation of this file.
1 /*
2  * W.J. van der Laan 2011-2012
3  */
4 
5 #include <QApplication>
6 
7 #include "bitcoingui.h"
8 #include "clientmodel.h"
9 #include "walletmodel.h"
10 #include "optionsmodel.h"
11 #include "guiutil.h"
12 #include "guiconstants.h"
13 #include "init.h"
14 #include "util.h"
15 #include "ui_interface.h"
16 #include "paymentserver.h"
17 #include "splashscreen.h"
18 
19 #include <QMessageBox>
20 #if QT_VERSION < 0x050000
21 #include <QTextCodec>
22 #endif
23 #include <QLocale>
24 #include <QTimer>
25 #include <QTranslator>
26 #include <QLibraryInfo>
27 
28 #ifdef Q_OS_MAC
29 #include "macdockiconhandler.h"
30 #endif
31 
32 #if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED)
33 #define _BITCOIN_QT_PLUGINS_INCLUDED
34 #define __INSURE__
35 #include <QtPlugin>
36 Q_IMPORT_PLUGIN(qcncodecs)
37 Q_IMPORT_PLUGIN(qjpcodecs)
38 Q_IMPORT_PLUGIN(qtwcodecs)
39 Q_IMPORT_PLUGIN(qkrcodecs)
40 Q_IMPORT_PLUGIN(qtaccessiblewidgets)
41 #endif
42 
43 // Declare meta types used for QMetaObject::invokeMethod
44 Q_DECLARE_METATYPE(bool*)
45 
46 // Need a global reference for the notifications to find the GUI
47 static BitcoinGUI *guiref;
48 static SplashScreen *splashref;
49 
50 static bool ThreadSafeMessageBox(const std::string& message, const std::string& caption, unsigned int style)
51 {
52  // Message from network thread
53  if(guiref)
54  {
55  bool modal = (style & CClientUIInterface::MODAL);
56  bool ret = false;
57  // In case of modal message, use blocking connection to wait for user to click a button
58  QMetaObject::invokeMethod(guiref, "message",
59  modal ? GUIUtil::blockingGUIThreadConnection() : Qt::QueuedConnection,
60  Q_ARG(QString, QString::fromStdString(caption)),
61  Q_ARG(QString, QString::fromStdString(message)),
62  Q_ARG(unsigned int, style),
63  Q_ARG(bool*, &ret));
64  return ret;
65  }
66  else
67  {
68  printf("%s: %s\n", caption.c_str(), message.c_str());
69  fprintf(stderr, "%s: %s\n", caption.c_str(), message.c_str());
70  return false;
71  }
72 }
73 
74 static bool ThreadSafeAskFee(int64 nFeeRequired)
75 {
76  if(!guiref)
77  return false;
78  if(nFeeRequired < CTransaction::nMinTxFee || nFeeRequired <= nTransactionFee || fDaemon)
79  return true;
80 
81  bool payFee = false;
82 
83  QMetaObject::invokeMethod(guiref, "askFee", GUIUtil::blockingGUIThreadConnection(),
84  Q_ARG(qint64, nFeeRequired),
85  Q_ARG(bool*, &payFee));
86 
87  return payFee;
88 }
89 
90 static void InitMessage(const std::string &message)
91 {
92  if(splashref)
93  {
94  splashref->showMessage(QString::fromStdString(message), Qt::AlignBottom|Qt::AlignHCenter, QColor(55,55,55));
95  qApp->processEvents();
96  }
97  printf("init message: %s\n", message.c_str());
98 }
99 
100 /*
101  Translate string to current locale using Qt.
102  */
103 static std::string Translate(const char* psz)
104 {
105  return QCoreApplication::translate("bitcoin-core", psz).toStdString();
106 }
107 
108 /* Handle runaway exceptions. Shows a message box with the problem and quits the program.
109  */
110 static void handleRunawayException(std::exception *e)
111 {
112  PrintExceptionContinue(e, "Runaway exception");
113  QMessageBox::critical(0, "Runaway exception", BitcoinGUI::tr("A fatal error occurred. Feathercoin can no longer continue safely and will quit.") + QString("\n\n") + QString::fromStdString(strMiscWarning));
114  exit(1);
115 }
116 
117 #ifndef BITCOIN_QT_TEST
118 int main(int argc, char *argv[])
119 {
120  // Command-line options take precedence:
121  ParseParameters(argc, argv);
122 
123 #if QT_VERSION < 0x050000
124  // Internal string conversion is all UTF-8
125  QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
126  QTextCodec::setCodecForCStrings(QTextCodec::codecForTr());
127 #endif
128 
129  Q_INIT_RESOURCE(bitcoin);
130  QApplication app(argc, argv);
131 
132  // Register meta types used for QMetaObject::invokeMethod
133  qRegisterMetaType< bool* >();
134 
135  // Do this early as we don't want to bother initializing if we are just calling IPC
136  // ... but do it after creating app, so QCoreApplication::arguments is initialized:
138  exit(0);
139  PaymentServer* paymentServer = new PaymentServer(&app);
140 
141  // Install global event filter that makes sure that long tooltips can be word-wrapped
142  app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
143 
144  // ... then bitcoin.conf:
145  if (!boost::filesystem::is_directory(GetDataDir(false)))
146  {
147  // This message can not be translated, as translation is not initialized yet
148  // (which not yet possible because lang=XX can be overridden in bitcoin.conf in the data directory)
149  QMessageBox::critical(0, "Feathercoin",
150  QString("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"])));
151  return 1;
152  }
154 
155  // Application identification (must be set before OptionsModel is initialized,
156  // as it is used to locate QSettings)
157  QApplication::setOrganizationName("Feathercoin");
158  QApplication::setOrganizationDomain("feathercoin.com");
159  if(GetBoolArg("-testnet")) // Separate UI settings for testnet
160  QApplication::setApplicationName("Feathercoin-Qt-testnet");
161  else
162  QApplication::setApplicationName("Feathercoin-Qt");
163 
164  // ... then GUI settings:
165  OptionsModel optionsModel;
166 
167  // Get desired locale (e.g. "de_DE") from command line or use system locale
168  QString lang_territory = QString::fromStdString(GetArg("-lang", QLocale::system().name().toStdString()));
169  QString lang = lang_territory;
170  // Convert to "de" only by truncating "_DE"
171  lang.truncate(lang_territory.lastIndexOf('_'));
172 
173  QTranslator qtTranslatorBase, qtTranslator, translatorBase, translator;
174  // Load language files for configured locale:
175  // - First load the translator for the base language, without territory
176  // - Then load the more specific locale translator
177 
178  // Load e.g. qt_de.qm
179  if (qtTranslatorBase.load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
180  app.installTranslator(&qtTranslatorBase);
181 
182  // Load e.g. qt_de_DE.qm
183  if (qtTranslator.load("qt_" + lang_territory, QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
184  app.installTranslator(&qtTranslator);
185 
186  // Load e.g. bitcoin_de.qm (shortcut "de" needs to be defined in bitcoin.qrc)
187  if (translatorBase.load(lang, ":/translations/"))
188  app.installTranslator(&translatorBase);
189 
190  // Load e.g. bitcoin_de_DE.qm (shortcut "de_DE" needs to be defined in bitcoin.qrc)
191  if (translator.load(lang_territory, ":/translations/"))
192  app.installTranslator(&translator);
193 
194  // Subscribe to global signals from core
195  uiInterface.ThreadSafeMessageBox.connect(ThreadSafeMessageBox);
196  uiInterface.ThreadSafeAskFee.connect(ThreadSafeAskFee);
197  uiInterface.InitMessage.connect(InitMessage);
198  uiInterface.Translate.connect(Translate);
199 
200  // Show help message immediately after parsing command-line options (for "-lang") and setting locale,
201  // but before showing splash screen.
202  if (mapArgs.count("-?") || mapArgs.count("--help"))
203  {
205  help.showOrPrint();
206  return 1;
207  }
208 
209 #ifdef Q_OS_MAC
210  // on mac, also change the icon now because it would look strange to have a testnet splash (green) and a std app icon (orange)
211  if(GetBoolArg("-testnet")) {
212  MacDockIconHandler::instance()->setIcon(QIcon(":icons/bitcoin_testnet"));
213  }
214 #endif
215 
216  SplashScreen splash(QPixmap(), 0);
217  if (GetBoolArg("-splash", true) && !GetBoolArg("-min"))
218  {
219  splash.show();
220  splash.setAutoFillBackground(true);
221  splashref = &splash;
222  }
223 
224  app.processEvents();
225  app.setQuitOnLastWindowClosed(false);
226 
227  try
228  {
229 #ifndef Q_OS_MAC
230  // Regenerate startup link, to fix links to old versions
231  // OSX: makes no sense on mac and might also scan/mount external (and sleeping) volumes (can take up some secs)
234 #endif
235 
236  boost::thread_group threadGroup;
237 
238  BitcoinGUI window;
239  guiref = &window;
240 
241  QTimer* pollShutdownTimer = new QTimer(guiref);
242  QObject::connect(pollShutdownTimer, SIGNAL(timeout()), guiref, SLOT(detectShutdown()));
243  pollShutdownTimer->start(200);
244 
245  if(AppInit2(threadGroup))
246  {
247  {
248  // Put this in a block, so that the Model objects are cleaned up before
249  // calling Shutdown().
250 
251  optionsModel.Upgrade(); // Must be done after AppInit2
252 
253  if (splashref)
254  splash.finish(&window);
255 
256  ClientModel clientModel(&optionsModel);
257  WalletModel *walletModel = 0;
258  if(pwalletMain)
259  walletModel = new WalletModel(pwalletMain, &optionsModel);
260 
261  window.setClientModel(&clientModel);
262  if(walletModel)
263  {
264  window.addWallet("~Default", walletModel);
265  window.setCurrentWallet("~Default");
266  }
267 
268  // If -min option passed, start window minimized.
269  if(GetBoolArg("-min"))
270  {
271  window.showMinimized();
272  }
273  else
274  {
275  window.show();
276  }
277 
278  // Now that initialization/startup is done, process any command-line
279  // bitcoin: URIs
280  QObject::connect(paymentServer, SIGNAL(receivedURI(QString)), &window, SLOT(handleURI(QString)));
281  QTimer::singleShot(100, paymentServer, SLOT(uiReady()));
282 
283  app.exec();
284 
285  window.hide();
286  window.setClientModel(0);
287  window.removeAllWallets();
288  guiref = 0;
289  delete walletModel;
290  }
291  // Shutdown the core and its threads, but don't exit Bitcoin-Qt here
292  threadGroup.interrupt_all();
293  threadGroup.join_all();
294  Shutdown();
295  }
296  else
297  {
298  threadGroup.interrupt_all();
299  threadGroup.join_all();
300  Shutdown();
301  return 1;
302  }
303  } catch (std::exception& e) {
304  handleRunawayException(&e);
305  } catch (...) {
306  handleRunawayException(NULL);
307  }
308  return 0;
309 }
310 #endif // BITCOIN_QT_TEST
const boost::filesystem::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:1060
Value help(const Array &params, bool fHelp)
Definition: bitcoinrpc.cpp:165
string strMiscWarning
Definition: util.cpp:80
class for the splashscreen with information of the running client
Definition: splashscreen.h:8
bool setCurrentWallet(const QString &name)
Definition: bitcoingui.cpp:351
int main(int argc, char *argv[])
Definition: bitcoin.cpp:118
Qt::ConnectionType blockingGUIThreadConnection()
Get connection type to call object slot in GUI thread with invokeMethod.
Definition: guiutil.cpp:240
bool GetStartOnSystemStartup()
Definition: guiutil.cpp:490
Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text repre...
Definition: guiutil.h:84
Bitcoin GUI main class.
Definition: bitcoingui.h:39
int64 nTransactionFee
Definition: main.cpp:84
Force blocking, modal message box dialog (not just OS notification)
Definition: ui_interface.h:62
void setIcon(const QIcon &icon)
static int64 nMinTxFee
Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) ...
Definition: main.h:480
static bool ipcSendCommandLine()
bool fDaemon
Definition: util.cpp:77
void setClientModel(ClientModel *clientModel)
Set the client model.
Definition: bitcoingui.cpp:300
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
Definition: util.cpp:600
static MacDockIconHandler * instance()
boost::signals2::signal< std::string(const char *psz)> Translate
Translate a message to the native language of the user.
Definition: ui_interface.h:83
#define printf
Definition: rpcdump.cpp:12
CClientUIInterface uiInterface
Definition: init.cpp:32
bool AppInit2(boost::thread_group &threadGroup)
Initialize bitcoin.
Definition: init.cpp:455
CWallet * pwalletMain
Definition: init.cpp:31
boost::signals2::signal< bool(int64 nFeeRequired), boost::signals2::last_value< bool > > ThreadSafeAskFee
Ask the user whether they want to pay a fee or not.
Definition: ui_interface.h:74
void Shutdown()
Definition: init.cpp:93
bool addWallet(const QString &name, WalletModel *walletModel)
Set the wallet model.
Definition: bitcoingui.cpp:345
void PrintExceptionContinue(std::exception *pex, const char *pszThread)
Definition: util.cpp:1023
void ParseParameters(int argc, const char *const argv[])
Definition: util.cpp:541
Model for Bitcoin network client.
Definition: clientmodel.h:24
void showOrPrint()
Show message box or print help message to standard output, based on operating system.
Definition: guiutil.cpp:524
void ReadConfigFile(map< string, string > &mapSettingsRet, map< string, vector< string > > &mapMultiSettingsRet)
Definition: util.cpp:1101
Interface from Qt to configuration data structure for Bitcoin client.
Definition: optionsmodel.h:12
Interface to Bitcoin wallet from Qt view code.
Definition: walletmodel.h:36
Help message for Bitcoin-Qt, shown with –help.
Definition: guiutil.h:102
boost::signals2::signal< bool(const std::string &message, const std::string &caption, unsigned int style), boost::signals2::last_value< bool > > ThreadSafeMessageBox
Show message box.
Definition: ui_interface.h:71
bool SetStartOnSystemStartup(bool fAutoStart)
Definition: guiutil.cpp:491
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
Definition: util.cpp:586
map< string, vector< string > > mapMultiArgs
Definition: util.cpp:72
void * arg
Definition: env_posix.cc:716
boost::signals2::signal< void(const std::string &message)> InitMessage
Progress message during initialization.
Definition: ui_interface.h:80
map< string, string > mapArgs
Definition: util.cpp:71
void removeAllWallets()
Definition: bitcoingui.cpp:356
const char * name
Definition: testharness.cc:18
long long int64
Definition: serialize.h:25