Toggle main window hide on tray icon click
[novacoin.git] / src / qt / guiutil.cpp
1 #include "guiutil.h"
2 #include "bitcoinaddressvalidator.h"
3 #include "walletmodel.h"
4 #include "bitcoinunits.h"
5
6 #include "headers.h"
7
8 #include <QString>
9 #include <QDateTime>
10 #include <QDoubleValidator>
11 #include <QFont>
12 #include <QLineEdit>
13 #include <QUrl>
14 #include <QTextDocument> // For Qt::escape
15 #include <QAbstractItemView>
16 #include <QApplication>
17 #include <QClipboard>
18 #include <QFileDialog>
19 #include <QDesktopServices>
20 #include <QThread>
21
22 namespace GUIUtil {
23
24 QString dateTimeStr(const QDateTime &date)
25 {
26     return date.date().toString(Qt::SystemLocaleShortDate) + QString(" ") + date.toString("hh:mm");
27 }
28
29 QString dateTimeStr(qint64 nTime)
30 {
31     return dateTimeStr(QDateTime::fromTime_t((qint32)nTime));
32 }
33
34 QFont bitcoinAddressFont()
35 {
36     QFont font("Monospace");
37     font.setStyleHint(QFont::TypeWriter);
38     return font;
39 }
40
41 void setupAddressWidget(QLineEdit *widget, QWidget *parent)
42 {
43     widget->setMaxLength(BitcoinAddressValidator::MaxAddressLength);
44     widget->setValidator(new BitcoinAddressValidator(parent));
45     widget->setFont(bitcoinAddressFont());
46 }
47
48 void setupAmountWidget(QLineEdit *widget, QWidget *parent)
49 {
50     QDoubleValidator *amountValidator = new QDoubleValidator(parent);
51     amountValidator->setDecimals(8);
52     amountValidator->setBottom(0.0);
53     widget->setValidator(amountValidator);
54     widget->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
55 }
56
57 bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
58 {
59     if(uri.scheme() != QString("bitcoin"))
60         return false;
61
62     SendCoinsRecipient rv;
63     rv.address = uri.path();
64     rv.amount = 0;
65     QList<QPair<QString, QString> > items = uri.queryItems();
66     for (QList<QPair<QString, QString> >::iterator i = items.begin(); i != items.end(); i++)
67     {
68         bool fShouldReturnFalse = false;
69         if (i->first.startsWith("req-"))
70         {
71             i->first.remove(0, 4);
72             fShouldReturnFalse = true;
73         }
74
75         if (i->first == "label")
76         {
77             rv.label = i->second;
78             fShouldReturnFalse = false;
79         }
80         else if (i->first == "amount")
81         {
82             if(!i->second.isEmpty())
83             {
84                 if(!BitcoinUnits::parse(BitcoinUnits::BTC, i->second, &rv.amount))
85                 {
86                     return false;
87                 }
88             }
89             fShouldReturnFalse = false;
90         }
91
92         if (fShouldReturnFalse)
93             return false;
94     }
95     if(out)
96     {
97         *out = rv;
98     }
99     return true;
100 }
101
102 bool parseBitcoinURI(QString uri, SendCoinsRecipient *out)
103 {
104     // Convert bitcoin:// to bitcoin:
105     //
106     //    Cannot handle this later, because bitcoin:// will cause Qt to see the part after // as host,
107     //    which will lowercase it (and thus invalidate the address).
108     if(uri.startsWith("bitcoin://"))
109     {
110         uri.replace(0, 10, "bitcoin:");
111     }
112     QUrl uriInstance(uri);
113     return parseBitcoinURI(uriInstance, out);
114 }
115
116 QString HtmlEscape(const QString& str, bool fMultiLine)
117 {
118     QString escaped = Qt::escape(str);
119     if(fMultiLine)
120     {
121         escaped = escaped.replace("\n", "<br>\n");
122     }
123     return escaped;
124 }
125
126 QString HtmlEscape(const std::string& str, bool fMultiLine)
127 {
128     return HtmlEscape(QString::fromStdString(str), fMultiLine);
129 }
130
131 void copyEntryData(QAbstractItemView *view, int column, int role)
132 {
133     if(!view || !view->selectionModel())
134         return;
135     QModelIndexList selection = view->selectionModel()->selectedRows(column);
136
137     if(!selection.isEmpty())
138     {
139         // Copy first item
140         QApplication::clipboard()->setText(selection.at(0).data(role).toString());
141     }
142 }
143
144 QString getSaveFileName(QWidget *parent, const QString &caption,
145                                  const QString &dir,
146                                  const QString &filter,
147                                  QString *selectedSuffixOut)
148 {
149     QString selectedFilter;
150     QString myDir;
151     if(dir.isEmpty()) // Default to user documents location
152     {
153         myDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
154     }
155     else
156     {
157         myDir = dir;
158     }
159     QString result = QFileDialog::getSaveFileName(parent, caption, myDir, filter, &selectedFilter);
160
161     /* Extract first suffix from filter pattern "Description (*.foo)" or "Description (*.foo *.bar ...) */
162     QRegExp filter_re(".* \\(\\*\\.(.*)[ \\)]");
163     QString selectedSuffix;
164     if(filter_re.exactMatch(selectedFilter))
165     {
166         selectedSuffix = filter_re.cap(1);
167     }
168
169     /* Add suffix if needed */
170     QFileInfo info(result);
171     if(!result.isEmpty())
172     {
173         if(info.suffix().isEmpty() && !selectedSuffix.isEmpty())
174         {
175             /* No suffix specified, add selected suffix */
176             if(!result.endsWith("."))
177                 result.append(".");
178             result.append(selectedSuffix);
179         }
180     }
181
182     /* Return selected suffix if asked to */
183     if(selectedSuffixOut)
184     {
185         *selectedSuffixOut = selectedSuffix;
186     }
187     return result;
188 }
189
190 Qt::ConnectionType blockingGUIThreadConnection()
191 {
192     if(QThread::currentThread() != QCoreApplication::instance()->thread())
193     {
194         return Qt::BlockingQueuedConnection;
195     }
196     else
197     {
198         return Qt::DirectConnection;
199     }
200 }
201
202 bool checkPoint(const QPoint &p, const QWidget *w)
203 {
204   QWidget *atW = qApp->widgetAt(w->mapToGlobal(p));
205   if(!atW) return false;
206   return atW->topLevelWidget() == w;
207 }
208
209 bool isObscured(QWidget *w)
210 {
211
212   return !(checkPoint(QPoint(0, 0), w)
213            && checkPoint(QPoint(w->width() - 1, 0), w)
214            && checkPoint(QPoint(0, w->height() - 1), w)
215            && checkPoint(QPoint(w->width() - 1, w->height() - 1), w)
216            && checkPoint(QPoint(w->width()/2, w->height()/2), w));
217 }
218
219 } // namespace GUIUtil
220