22 #define _WIN32_WINNT 0x0501
26 #define _WIN32_IE 0x0501
27 #define WIN32_LEAN_AND_MEAN 1
36 #include <boost/filesystem.hpp>
37 #include <boost/filesystem/fstream.hpp>
38 #if BOOST_FILESYSTEM_VERSION >= 3
39 #include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
42 #include <QAbstractItemView>
43 #include <QApplication>
46 #include <QDesktopServices>
47 #include <QDesktopWidget>
48 #include <QDoubleValidator>
49 #include <QFileDialog>
53 #include <QTextDocument>
56 #if QT_VERSION < 0x050000
62 #if BOOST_FILESYSTEM_VERSION >= 3
63 static boost::filesystem::detail::utf8_codecvt_facet utf8;
67 extern double NSAppKitVersionNumber;
68 #if !defined(NSAppKitVersionNumber10_9)
69 #define NSAppKitVersionNumber10_9 1265
77 return date.date().toString(Qt::SystemLocaleShortDate) + QString(
" ") + date.toString(
"hh:mm");
82 return dateTimeStr(QDateTime::fromTime_t((qint32)nTime));
87 QFont font(
"Monospace");
88 #if QT_VERSION >= 0x040800
89 font.setStyleHint(QFont::Monospace);
91 font.setStyleHint(QFont::TypeWriter);
98 parent->setFocusProxy(widget);
101 #if QT_VERSION >= 0x040700
102 widget->setPlaceholderText(QObject::tr(
"Enter a Anoncoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
110 QDoubleValidator *amountValidator =
new QDoubleValidator(parent);
111 amountValidator->setDecimals(8);
112 amountValidator->setBottom(0.0);
113 widget->setValidator(amountValidator);
114 widget->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
120 if(!uri.isValid() || uri.scheme() != QString(
"anoncoin"))
126 if (rv.
address.endsWith(
"/")) {
131 #if QT_VERSION < 0x050000
132 QList<QPair<QString, QString> > items = uri.queryItems();
134 QUrlQuery uriQuery(uri);
135 QList<QPair<QString, QString> > items = uriQuery.queryItems();
137 for (QList<QPair<QString, QString> >::iterator i = items.begin(); i != items.end(); i++)
139 bool fShouldReturnFalse =
false;
140 if (i->first.startsWith(
"req-"))
142 i->first.remove(0, 4);
143 fShouldReturnFalse =
true;
146 if (i->first ==
"label")
148 rv.
label = i->second;
149 fShouldReturnFalse =
false;
151 if (i->first ==
"message")
154 fShouldReturnFalse =
false;
156 else if (i->first ==
"amount")
158 if(!i->second.isEmpty())
165 fShouldReturnFalse =
false;
168 if (fShouldReturnFalse)
184 if(uri.startsWith(
"anoncoin://", Qt::CaseInsensitive))
186 uri.replace(0, 10,
"anoncoin:");
188 QUrl uriInstance(uri);
194 QString ret = QString(
"anoncoin:%1").arg(info.
address);
203 if (!info.
label.isEmpty())
205 QString lbl(QUrl::toPercentEncoding(info.
label));
206 ret += QString(
"%1label=%2").arg(paramCount == 0 ?
"?" :
"&").arg(lbl);
212 QString msg(QUrl::toPercentEncoding(info.
message));;
213 ret += QString(
"%1message=%2").arg(paramCount == 0 ?
"?" :
"&").arg(msg);
220 bool isDust(
const QString& address, qint64 amount)
224 CTxOut txOut(amount, script);
230 #if QT_VERSION < 0x050000
231 QString escaped = Qt::escape(str);
233 QString escaped = str.toHtmlEscaped();
237 escaped = escaped.replace(
"\n",
"<br>\n");
244 return HtmlEscape(QString::fromStdString(str), fMultiLine);
249 if(!view || !view->selectionModel())
251 QModelIndexList selection = view->selectionModel()->selectedRows(column);
253 if(!selection.isEmpty())
261 const QString &filter,
262 QString *selectedSuffixOut)
264 QString selectedFilter;
268 #if QT_VERSION < 0x050000
269 myDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
271 myDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
282 QRegExp filter_re(
".* \\(\\*\\.(.*)[ \\)]");
283 QString selectedSuffix;
284 if(filter_re.exactMatch(selectedFilter))
286 selectedSuffix = filter_re.cap(1);
290 QFileInfo info(result);
291 if(!result.isEmpty())
293 if(info.suffix().isEmpty() && !selectedSuffix.isEmpty())
296 if(!result.endsWith(
"."))
298 result.append(selectedSuffix);
303 if(selectedSuffixOut)
305 *selectedSuffixOut = selectedSuffix;
311 const QString &filter,
312 QString *selectedSuffixOut)
314 QString selectedFilter;
318 #if QT_VERSION < 0x050000
319 myDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
321 myDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
331 if(selectedSuffixOut)
334 QRegExp filter_re(
".* \\(\\*\\.(.*)[ \\)]");
335 QString selectedSuffix;
336 if(filter_re.exactMatch(selectedFilter))
338 selectedSuffix = filter_re.cap(1);
340 *selectedSuffixOut = selectedSuffix;
347 if(QThread::currentThread() != qApp->thread())
349 return Qt::BlockingQueuedConnection;
353 return Qt::DirectConnection;
359 QWidget *atW = QApplication::widgetAt(w->mapToGlobal(p));
360 if (!atW)
return false;
361 return atW->topLevelWidget() == w;
369 &&
checkPoint(QPoint(w->width() - 1, w->height() - 1), w)
370 &&
checkPoint(QPoint(w->width() / 2, w->height() / 2), w));
375 boost::filesystem::path pathDebug =
GetDataDir() /
"debug.log";
378 if (boost::filesystem::exists(pathDebug))
383 QObject(parent), size_threshold(size_threshold)
390 #if defined(Q_OS_MAC)
401 #if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8
402 if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_9)
403 QFont::insertSubstitution(
".Lucida Grande UI",
"Lucida Grande");
410 if(evt->type() == QEvent::ToolTipChange)
412 QWidget *widget =
static_cast<QWidget*
>(obj);
413 QString tooltip = widget->toolTip();
414 if(tooltip.size() >
size_threshold && !tooltip.startsWith(
"<qt") && !Qt::mightBeRichText(tooltip))
418 tooltip =
"<qt>" +
HtmlEscape(tooltip,
true) +
"</qt>";
419 widget->setToolTip(tooltip);
423 return QObject::eventFilter(obj, evt);
443 #if QT_VERSION < 0x050000
444 tableView->horizontalHeader()->setResizeMode(logicalIndex, resizeMode);
446 tableView->horizontalHeader()->setSectionResizeMode(logicalIndex, resizeMode);
452 tableView->setColumnWidth(nColumnIndex, width);
453 tableView->horizontalHeader()->resizeSection(nColumnIndex, width);
458 int nColumnsWidthSum = 0;
461 nColumnsWidthSum +=
tableView->horizontalHeader()->sectionSize(i);
463 return nColumnsWidthSum;
469 int nTableWidth =
tableView->horizontalHeader()->width();
474 nResult = std::max(nResult, nTableWidth - nOtherColsWidth);
487 int nTableWidth =
tableView->horizontalHeader()->width();
489 if (nColsWidth > nTableWidth)
508 if (newSize > remainingWidth)
532 lastColumnMinimumWidth(lastColMinimumWidth),
533 allColumnsMinimumWidth(allColsMinimumWidth)
544 boost::filesystem::path
static StartupShortcutPath()
546 return GetSpecialFolderPath(CSIDL_STARTUP) /
"Anoncoin.lnk";
552 return boost::filesystem::exists(StartupShortcutPath());
558 boost::filesystem::remove(StartupShortcutPath());
565 IShellLink* psl = NULL;
566 HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
567 CLSCTX_INPROC_SERVER, IID_IShellLink,
568 reinterpret_cast<void**>(&psl));
574 GetModuleFileName(NULL, pszExePath,
sizeof(pszExePath));
576 TCHAR pszArgs[5] = TEXT(
"-min");
579 psl->SetPath(pszExePath);
580 PathRemoveFileSpec(pszExePath);
581 psl->SetWorkingDirectory(pszExePath);
582 psl->SetShowCmd(SW_SHOWMINNOACTIVE);
583 psl->SetArguments(pszArgs);
587 IPersistFile* ppf = NULL;
588 hres = psl->QueryInterface(IID_IPersistFile,
589 reinterpret_cast<void**>(&ppf));
594 MultiByteToWideChar(CP_ACP, 0, StartupShortcutPath().
string().c_str(), -1, pwsz,
MAX_PATH);
596 hres = ppf->Save(pwsz, TRUE);
610 #elif defined(Q_OS_LINUX)
615 boost::filesystem::path
static GetAutostartDir()
617 namespace fs = boost::filesystem;
619 char* pszConfigHome = getenv(
"XDG_CONFIG_HOME");
620 if (pszConfigHome)
return fs::path(pszConfigHome) /
"autostart";
621 char* pszHome = getenv(
"HOME");
622 if (pszHome)
return fs::path(pszHome) /
".config" /
"autostart";
626 boost::filesystem::path
static GetAutostartFilePath()
628 return GetAutostartDir() /
"anoncoin.desktop";
633 boost::filesystem::ifstream optionFile(GetAutostartFilePath());
634 if (!optionFile.good())
638 while (!optionFile.eof())
640 getline(optionFile, line);
641 if (line.find(
"Hidden") != std::string::npos &&
642 line.find(
"true") != std::string::npos)
653 boost::filesystem::remove(GetAutostartFilePath());
657 memset(pszExePath, 0,
sizeof(pszExePath));
658 if (readlink(
"/proc/self/exe", pszExePath,
sizeof(pszExePath)-1) == -1)
661 boost::filesystem::create_directories(GetAutostartDir());
663 boost::filesystem::ofstream optionFile(GetAutostartFilePath(), std::ios_base::out|std::ios_base::trunc);
664 if (!optionFile.good())
667 optionFile <<
"[Desktop Entry]\n";
668 optionFile <<
"Type=Application\n";
669 optionFile <<
"Name=Anoncoin\n";
670 optionFile <<
"Exec=" << pszExePath <<
" -min\n";
671 optionFile <<
"Terminal=false\n";
672 optionFile <<
"Hidden=false\n";
679 #elif defined(Q_OS_MAC)
682 #include <CoreFoundation/CoreFoundation.h>
683 #include <CoreServices/CoreServices.h>
685 LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef findUrl);
686 LSSharedFileListItemRef findStartupItemInList(LSSharedFileListRef list, CFURLRef findUrl)
689 CFArrayRef listSnapshot = LSSharedFileListCopySnapshot(list, NULL);
690 for(
int i = 0; i < CFArrayGetCount(listSnapshot); i++) {
691 LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(listSnapshot, i);
692 UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes;
693 CFURLRef currentItemURL = NULL;
694 LSSharedFileListItemResolve(item, resolutionFlags, ¤tItemURL, NULL);
695 if(currentItemURL && CFEqual(currentItemURL, findUrl)) {
697 CFRelease(currentItemURL);
701 CFRelease(currentItemURL);
709 CFURLRef anoncoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
710 LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
711 LSSharedFileListItemRef foundItem = findStartupItemInList(loginItems, anoncoinAppUrl);
717 CFURLRef anoncoinAppUrl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
718 LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
719 LSSharedFileListItemRef foundItem = findStartupItemInList(loginItems, anoncoinAppUrl);
721 if(fAutoStart && !foundItem) {
723 LSSharedFileListInsertItemURL(loginItems, kLSSharedFileListItemBeforeFirst, NULL, NULL, anoncoinAppUrl, NULL, NULL);
725 else if(!fAutoStart && foundItem) {
727 LSSharedFileListItemRemove(loginItems, foundItem);
741 settings.setValue(strSetting +
"Pos", parent->pos());
742 settings.setValue(strSetting +
"Size", parent->size());
748 QPoint pos = settings.value(strSetting +
"Pos").toPoint();
749 QSize size = settings.value(strSetting +
"Size", defaultSize).toSize();
751 if (!pos.x() && !pos.y()) {
752 QRect screen = QApplication::desktop()->screenGeometry();
753 pos.setX((screen.width() - size.width()) / 2);
754 pos.setY((screen.height() - size.height()) / 2);
757 parent->resize(size);
763 QApplication::clipboard()->setText(str, QClipboard::Clipboard);
764 QApplication::clipboard()->setText(str, QClipboard::Selection);
767 #if BOOST_FILESYSTEM_VERSION >= 3
770 return boost::filesystem::path(path.toStdString(), utf8);
775 return QString::fromStdString(path.string(utf8));
778 #warning Conversion between boost path and QString can use invalid character encoding with boost_filesystem v2 and older
781 return boost::filesystem::path(path.toStdString());
786 return QString::fromStdString(path.string());
793 int days = secs / 86400;
794 int hours = (secs % 86400) / 3600;
795 int mins = (secs % 3600) / 60;
796 int seconds = secs % 60;
799 strList.append(QString(QObject::tr(
"%1 d")).arg(days));
801 strList.append(QString(QObject::tr(
"%1 h")).arg(hours));
803 strList.append(QString(QObject::tr(
"%1 m")).arg(mins));
804 if (seconds || (!days && !hours && !mins))
805 strList.append(QString(QObject::tr(
"%1 s")).arg(seconds));
807 return strList.join(
" ");
815 for (
int i = 0; i < 8; i++) {
816 uint64_t check = 1 << i;
822 strList.append(QObject::tr(
"NETWORK"));
825 strList.append(QString(
"%1[%2]").arg(QObject::tr(
"UNKNOWN")).arg(check));
831 return strList.join(
" & ");
833 return QObject::tr(
"None");
838 return dPingTime == 0 ? QObject::tr(
"N/A") : QString(QObject::tr(
"%1 ms")).arg(QString::number((
int)(dPingTime * 1000), 10));
const boost::filesystem::path & GetDataDir(bool fNetSpecific)
void stretchColumnWidth(int column)
bool IsDust(int64_t nMinRelayTxFee) const
Utility functions used by the Anoncoin Qt UI.
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedSuffixOut)
Get open filename, convenience wrapper for QFileDialog::getOpenFileName.
void setupAmountWidget(QLineEdit *widget, QWidget *parent)
void setViewHeaderResizeMode(int logicalIndex, QHeaderView::ResizeMode resizeMode)
TableViewLastColumnResizingFixer(QTableView *table, int lastColMinimumWidth, int allColsMinimumWidth)
Initializes all internal variables and prepares the the resize modes of the last 2 columns of the tab...
void on_geometriesChanged()
Base58 entry widget validator, checks for valid characters and removes some whitespace.
int secondToLastColumnIndex
QString dateTimeStr(const QDateTime &date)
bool parseAnoncoinURI(const QUrl &uri, SendCoinsRecipient *out)
Qt::ConnectionType blockingGUIThreadConnection()
Get connection type to call object slot in GUI thread with invokeMethod.
bool GetStartOnSystemStartup()
ToolTipToRichTextFilter(int size_threshold, QObject *parent=0)
QString HtmlEscape(const QString &str, bool fMultiLine)
boost::filesystem::path qstringToBoostPath(const QString &path)
void connectViewHeadersSignals()
Line edit that can be marked as "invalid" to show input validation feedback.
static bool parse(int unit, const QString &value, qint64 *val_out)
Parse string to coin amount.
int getAvailableWidthForColumn(int column)
void saveWindowGeometry(const QString &strSetting, QWidget *parent)
Save window size and position.
void SetDestination(const CTxDestination &address)
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
void SubstituteFonts()
Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text repre...
bool isObscured(QWidget *w)
bool eventFilter(QObject *obj, QEvent *evt)
static QString format(int unit, qint64 amount, bool plussign=false)
Format as string.
QString formatDurationStr(int secs)
void setClipboard(const QString &str)
int lastColumnMinimumWidth
bool isDust(const QString &address, qint64 amount)
base58-encoded Anoncoin addresses.
An output of a transaction.
QFont anoncoinAddressFont()
void restoreWindowGeometry(const QString &strSetting, const QSize &defaultSize, QWidget *parent)
Restore window size and position.
QString formatPingTime(double dPingTime)
void on_sectionResized(int logicalIndex, int oldSize, int newSize)
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
void disconnectViewHeadersSignals()
int allColumnsMinimumWidth
Serialized script, used inside transaction inputs and outputs.
QString formatServicesStr(quint64 mask)
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedSuffixOut)
Get save filename, mimics QFileDialog::getSaveFileName, except that it appends a default suffix when ...
Anoncoin address widget validator, checks for a valid anoncoin address.
void adjustTableColumnsWidth()
bool checkPoint(const QPoint &p, const QWidget *w)
void setCheckValidator(const QValidator *v)
static int64_t nMinRelayTxFee
Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) ...
bool SetStartOnSystemStartup(bool fAutoStart)
QString boostPathToQString(const boost::filesystem::path &path)
QString formatAnoncoinURI(const SendCoinsRecipient &info)
void copyEntryData(QAbstractItemView *view, int column, int role)
Copy a field of the currently selected entry of a view to the clipboard.
void resizeColumn(int nColumnIndex, int width)