X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fqt%2Fguiutil.cpp;h=53873e57879c7b1d0aaf4d38690b9d824179982b;hb=aff47bd084ec500155c7ce37f831d260dc6fd8e8;hp=cb2473240e0d53ee234448bcce4eb9d0ee0e8ba8;hpb=86d5634941734cbde54e47fc6288f21104acf26e;p=novacoin.git diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index cb24732..53873e5 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -2,16 +2,20 @@ #include "bitcoinaddressvalidator.h" #include "walletmodel.h" #include "bitcoinunits.h" - -#include "headers.h" +#include "util.h" +#include "init.h" #include #include #include #include #include +#if QT_VERSION >= 0x050000 +#include +#else #include -#include // For Qt::escape +#endif +#include // For Qt::mightBeRichText #include #include #include @@ -19,6 +23,27 @@ #include #include +#include +#include + +#ifdef WIN32 +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +#define _WIN32_WINNT 0x0501 +#ifdef _WIN32_IE +#undef _WIN32_IE +#endif +#define _WIN32_IE 0x0501 +#define WIN32_LEAN_AND_MEAN 1 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include "shlwapi.h" +#include "shlobj.h" +#include "shellapi.h" +#endif + namespace GUIUtil { QString dateTimeStr(const QDateTime &date) @@ -56,13 +81,19 @@ void setupAmountWidget(QLineEdit *widget, QWidget *parent) bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out) { - if(uri.scheme() != QString("bitcoin")) + // NovaCoin: check prefix + if(uri.scheme() != QString("novacoin")) return false; SendCoinsRecipient rv; rv.address = uri.path(); rv.amount = 0; +#if QT_VERSION < 0x050000 QList > items = uri.queryItems(); +#else + QUrlQuery uriQuery(uri); + QList > items = uriQuery.queryItems(); +#endif for (QList >::iterator i = items.begin(); i != items.end(); i++) { bool fShouldReturnFalse = false; @@ -101,13 +132,13 @@ bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out) bool parseBitcoinURI(QString uri, SendCoinsRecipient *out) { - // Convert bitcoin:// to bitcoin: + // Convert novacoin:// to novacoin: // // Cannot handle this later, because bitcoin:// will cause Qt to see the part after // as host, - // which will lowercase it (and thus invalidate the address). - if(uri.startsWith("bitcoin://")) + // which will lower-case it (and thus invalidate the address). + if(uri.startsWith("novacoin://")) { - uri.replace(0, 10, "bitcoin:"); + uri.replace(0, 10, "novacoin:"); } QUrl uriInstance(uri); return parseBitcoinURI(uriInstance, out); @@ -115,7 +146,11 @@ bool parseBitcoinURI(QString uri, SendCoinsRecipient *out) QString HtmlEscape(const QString& str, bool fMultiLine) { +#if QT_VERSION < 0x050000 QString escaped = Qt::escape(str); +#else + QString escaped = str.toHtmlEscaped(); +#endif if(fMultiLine) { escaped = escaped.replace("\n", "
\n"); @@ -150,7 +185,11 @@ QString getSaveFileName(QWidget *parent, const QString &caption, QString myDir; if(dir.isEmpty()) // Default to user documents location { +#if QT_VERSION < 0x050000 myDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); +#else + myDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); +#endif } else { @@ -201,19 +240,255 @@ Qt::ConnectionType blockingGUIThreadConnection() bool checkPoint(const QPoint &p, const QWidget *w) { - QWidget *atW = qApp->widgetAt(w->mapToGlobal(p)); - if(!atW) return false; - return atW->topLevelWidget() == w; + QWidget *atW = qApp->widgetAt(w->mapToGlobal(p)); + if (!atW) return false; + return atW->topLevelWidget() == w; } bool isObscured(QWidget *w) { + return !(checkPoint(QPoint(0, 0), w) + && checkPoint(QPoint(w->width() - 1, 0), w) + && checkPoint(QPoint(0, w->height() - 1), w) + && checkPoint(QPoint(w->width() - 1, w->height() - 1), w) + && checkPoint(QPoint(w->width() / 2, w->height() / 2), w)); +} + +void openDebugLogfile() +{ + boost::filesystem::path pathDebug = GetDataDir() / "debug.log"; + + /* Open debug.log with the associated application */ + if (boost::filesystem::exists(pathDebug)) + QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(pathDebug.string()))); +} + +ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent) : + QObject(parent), size_threshold(size_threshold) +{ + +} + +bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt) +{ + if(evt->type() == QEvent::ToolTipChange) + { + QWidget *widget = static_cast(obj); + QString tooltip = widget->toolTip(); + if(tooltip.size() > size_threshold && !tooltip.startsWith("") && !Qt::mightBeRichText(tooltip)) + { + // Prefix to make sure Qt detects this as rich text + // Escape the current message as HTML and replace \n by
+ tooltip = "" + HtmlEscape(tooltip, true) + ""; + widget->setToolTip(tooltip); + return true; + } + } + return QObject::eventFilter(obj, evt); +} + +#ifdef WIN32 +boost::filesystem::path static StartupShortcutPath() +{ + return GetSpecialFolderPath(CSIDL_STARTUP) / "NovaCoin.lnk"; +} + +bool GetStartOnSystemStartup() +{ + // check for Bitcoin.lnk + return boost::filesystem::exists(StartupShortcutPath()); +} + +bool SetStartOnSystemStartup(bool fAutoStart) +{ + // If the shortcut exists already, remove it for updating + boost::filesystem::remove(StartupShortcutPath()); + + if (fAutoStart) + { + CoInitialize(NULL); + + // Get a pointer to the IShellLink interface. + IShellLink* psl = NULL; + HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL, + CLSCTX_INPROC_SERVER, IID_IShellLink, + reinterpret_cast(&psl)); + + if (SUCCEEDED(hres)) + { + // Get the current executable path + TCHAR pszExePath[MAX_PATH]; + GetModuleFileName(NULL, pszExePath, sizeof(pszExePath)); + + TCHAR pszArgs[5] = TEXT("-min"); + + // Set the path to the shortcut target + psl->SetPath(pszExePath); + PathRemoveFileSpec(pszExePath); + psl->SetWorkingDirectory(pszExePath); + psl->SetShowCmd(SW_SHOWMINNOACTIVE); + psl->SetArguments(pszArgs); + + // Query IShellLink for the IPersistFile interface for + // saving the shortcut in persistent storage. + IPersistFile* ppf = NULL; + hres = psl->QueryInterface(IID_IPersistFile, + reinterpret_cast(&ppf)); + if (SUCCEEDED(hres)) + { + WCHAR pwsz[MAX_PATH]; + // Ensure that the string is ANSI. + MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().string().c_str(), -1, pwsz, MAX_PATH); + // Save the link by calling IPersistFile::Save. + hres = ppf->Save(pwsz, TRUE); + ppf->Release(); + psl->Release(); + CoUninitialize(); + return true; + } + psl->Release(); + } + CoUninitialize(); + return false; + } + return true; +} + +#elif defined(LINUX) + +// Follow the Desktop Application Autostart Spec: +// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html + +boost::filesystem::path static GetAutostartDir() +{ + namespace fs = boost::filesystem; + + char* pszConfigHome = getenv("XDG_CONFIG_HOME"); + if (pszConfigHome) return fs::path(pszConfigHome) / "autostart"; + char* pszHome = getenv("HOME"); + if (pszHome) return fs::path(pszHome) / ".config" / "autostart"; + return fs::path(); +} + +boost::filesystem::path static GetAutostartFilePath() +{ + return GetAutostartDir() / "novacoin.desktop"; +} + +bool GetStartOnSystemStartup() +{ + boost::filesystem::ifstream optionFile(GetAutostartFilePath()); + if (!optionFile.good()) + return false; + // Scan through file for "Hidden=true": + std::string line; + while (!optionFile.eof()) + { + getline(optionFile, line); + if (line.find("Hidden") != std::string::npos && + line.find("true") != std::string::npos) + return false; + } + optionFile.close(); + + return true; +} + +bool SetStartOnSystemStartup(bool fAutoStart) +{ + if (!fAutoStart) + boost::filesystem::remove(GetAutostartFilePath()); + else + { + char pszExePath[MAX_PATH+1]; + memset(pszExePath, 0, sizeof(pszExePath)); + if (readlink("/proc/self/exe", pszExePath, sizeof(pszExePath)-1) == -1) + return false; + + boost::filesystem::create_directories(GetAutostartDir()); + + boost::filesystem::ofstream optionFile(GetAutostartFilePath(), std::ios_base::out|std::ios_base::trunc); + if (!optionFile.good()) + return false; + // Write a bitcoin.desktop file to the autostart directory: + optionFile << "[Desktop Entry]\n"; + optionFile << "Type=Application\n"; + optionFile << "Name=NovaCoin\n"; + optionFile << "Exec=" << pszExePath << " -min\n"; + optionFile << "Terminal=false\n"; + optionFile << "Hidden=false\n"; + optionFile.close(); + } + return true; +} +#else + +// TODO: OSX startup stuff; see: +// https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPSystemStartup/Articles/CustomLogin.html + +bool GetStartOnSystemStartup() { return false; } +bool SetStartOnSystemStartup(bool fAutoStart) { return false; } + +#endif + +HelpMessageBox::HelpMessageBox(QWidget *parent) : + QMessageBox(parent) +{ + header = tr("NovaCoin-Qt") + " " + tr("version") + " " + + QString::fromStdString(FormatFullVersion()) + "\n\n" + + tr("Usage:") + "\n" + + " novacoin-qt [" + tr("command-line options") + "] " + "\n"; + + coreOptions = QString::fromStdString(HelpMessage()); + + uiOptions = tr("UI options") + ":\n" + + " -lang= " + tr("Set language, for example \"de_DE\" (default: system locale)") + "\n" + + " -min " + tr("Start minimized") + "\n" + + " -splash " + tr("Show splash screen on startup (default: 1)") + "\n"; + + setWindowTitle(tr("NovaCoin-Qt")); + setTextFormat(Qt::PlainText); + // setMinimumWidth is ignored for QMessageBox so put in non-breaking spaces to make it wider. + setText(header + QString(QChar(0x2003)).repeated(50)); + setDetailedText(coreOptions + "\n" + uiOptions); +} + +void HelpMessageBox::printToConsole() +{ + // On other operating systems, the expected action is to print the message to the console. + QString strUsage = header + "\n" + coreOptions + "\n" + uiOptions; + fprintf(stdout, "%s", strUsage.toStdString().c_str()); +} + +void HelpMessageBox::showOrPrint() +{ +#if defined(WIN32) + // On Windows, show a message box, as there is no stderr/stdout in windowed applications + exec(); +#else + // On other operating systems, print help text to console + printToConsole(); +#endif +} + +QString formatDurationStr(int secs) +{ + QStringList strList; + int days = secs / 86400; + int hours = (secs % 86400) / 3600; + int mins = (secs % 3600) / 60; + int seconds = secs % 60; + + if (days) + strList.append(QString(QObject::tr("%1 d")).arg(days)); + if (hours) + strList.append(QString(QObject::tr("%1 h")).arg(hours)); + if (mins) + strList.append(QString(QObject::tr("%1 m")).arg(mins)); + if (seconds || (!days && !hours && !mins)) + strList.append(QString(QObject::tr("%1 s")).arg(seconds)); - return !(checkPoint(QPoint(0, 0), w) - && checkPoint(QPoint(w->width() - 1, 0), w) - && checkPoint(QPoint(0, w->height() - 1), w) - && checkPoint(QPoint(w->width() - 1, w->height() - 1), w) - && checkPoint(QPoint(w->width()/2, w->height()/2), w)); + return strList.join(" "); } } // namespace GUIUtil