aboutsummaryrefslogtreecommitdiff
path: root/src/qt/guiutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qt/guiutil.cpp')
-rw-r--r--src/qt/guiutil.cpp196
1 files changed, 154 insertions, 42 deletions
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index b87498402..7b264d27c 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -6,6 +6,7 @@
#include "bitcoinaddressvalidator.h"
#include "bitcoinunits.h"
+#include "qvalidatedlineedit.h"
#include "walletmodel.h"
#include "core.h"
@@ -32,6 +33,9 @@
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
+#if BOOST_FILESYSTEM_VERSION >= 3
+#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
+#endif
#include <QAbstractItemView>
#include <QApplication>
@@ -53,6 +57,10 @@
#include <QUrlQuery>
#endif
+#if BOOST_FILESYSTEM_VERSION >= 3
+static boost::filesystem::detail::utf8_codecvt_facet utf8;
+#endif
+
namespace GUIUtil {
QString dateTimeStr(const QDateTime &date)
@@ -72,11 +80,16 @@ QFont bitcoinAddressFont()
return font;
}
-void setupAddressWidget(QLineEdit *widget, QWidget *parent)
+void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
{
- widget->setMaxLength(BitcoinAddressValidator::MaxAddressLength);
- widget->setValidator(new BitcoinAddressValidator(parent));
+ parent->setFocusProxy(widget);
+
widget->setFont(bitcoinAddressFont());
+#if QT_VERSION >= 0x040700
+ widget->setPlaceholderText(QObject::tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
+#endif
+ widget->setValidator(new BitcoinAddressEntryValidator(parent));
+ widget->setCheckValidator(new BitcoinAddressCheckValidator(parent));
}
void setupAmountWidget(QLineEdit *widget, QWidget *parent)
@@ -90,7 +103,7 @@ void setupAmountWidget(QLineEdit *widget, QWidget *parent)
bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
{
- // return if URI is not valid or is no bitcoin URI
+ // return if URI is not valid or is no bitcoin: URI
if(!uri.isValid() || uri.scheme() != QString("bitcoin"))
return false;
@@ -346,7 +359,7 @@ void openDebugLogfile()
/* Open debug.log with the associated application */
if (boost::filesystem::exists(pathDebug))
- QDesktopServices::openUrl(QUrl::fromLocalFile(QString::fromStdString(pathDebug.string())));
+ QDesktopServices::openUrl(QUrl::fromLocalFile(boostPathToQString(pathDebug)));
}
ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent) :
@@ -361,11 +374,11 @@ bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt)
{
QWidget *widget = static_cast<QWidget*>(obj);
QString tooltip = widget->toolTip();
- if(tooltip.size() > size_threshold && !tooltip.startsWith("<qt/>") && !Qt::mightBeRichText(tooltip))
+ if(tooltip.size() > size_threshold && !tooltip.startsWith("<qt") && !Qt::mightBeRichText(tooltip))
{
- // Prefix <qt/> to make sure Qt detects this as rich text
+ // Envelop with <qt></qt> to make sure Qt detects this as rich text
// Escape the current message as HTML and replace \n by <br>
- tooltip = "<qt/>" + HtmlEscape(tooltip, true);
+ tooltip = "<qt>" + HtmlEscape(tooltip, true) + "</qt>";
widget->setToolTip(tooltip);
return true;
}
@@ -373,6 +386,123 @@ bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt)
return QObject::eventFilter(obj, evt);
}
+void TableViewLastColumnResizingFixer::connectViewHeadersSignals()
+{
+ connect(tableView->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(on_sectionResized(int,int,int)));
+ connect(tableView->horizontalHeader(), SIGNAL(geometriesChanged()), this, SLOT(on_geometriesChanged()));
+}
+
+// We need to disconnect these while handling the resize events, otherwise we can enter infinite loops.
+void TableViewLastColumnResizingFixer::disconnectViewHeadersSignals()
+{
+ disconnect(tableView->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(on_sectionResized(int,int,int)));
+ disconnect(tableView->horizontalHeader(), SIGNAL(geometriesChanged()), this, SLOT(on_geometriesChanged()));
+}
+
+// Setup the resize mode, handles compatibility for Qt5 and below as the method signatures changed.
+// Refactored here for readability.
+void TableViewLastColumnResizingFixer::setViewHeaderResizeMode(int logicalIndex, QHeaderView::ResizeMode resizeMode)
+{
+#if QT_VERSION < 0x050000
+ tableView->horizontalHeader()->setResizeMode(logicalIndex, resizeMode);
+#else
+ tableView->horizontalHeader()->setSectionResizeMode(logicalIndex, resizeMode);
+#endif
+}
+
+void TableViewLastColumnResizingFixer::resizeColumn(int nColumnIndex, int width)
+{
+ tableView->setColumnWidth(nColumnIndex, width);
+ tableView->horizontalHeader()->resizeSection(nColumnIndex, width);
+}
+
+int TableViewLastColumnResizingFixer::getColumnsWidth()
+{
+ int nColumnsWidthSum = 0;
+ for (int i = 0; i < columnCount; i++)
+ {
+ nColumnsWidthSum += tableView->horizontalHeader()->sectionSize(i);
+ }
+ return nColumnsWidthSum;
+}
+
+int TableViewLastColumnResizingFixer::getAvailableWidthForColumn(int column)
+{
+ int nResult = lastColumnMinimumWidth;
+ int nTableWidth = tableView->horizontalHeader()->width();
+
+ if (nTableWidth > 0)
+ {
+ int nOtherColsWidth = getColumnsWidth() - tableView->horizontalHeader()->sectionSize(column);
+ nResult = std::max(nResult, nTableWidth - nOtherColsWidth);
+ }
+
+ return nResult;
+}
+
+// Make sure we don't make the columns wider than the tables viewport width.
+void TableViewLastColumnResizingFixer::adjustTableColumnsWidth()
+{
+ disconnectViewHeadersSignals();
+ resizeColumn(lastColumnIndex, getAvailableWidthForColumn(lastColumnIndex));
+ connectViewHeadersSignals();
+
+ int nTableWidth = tableView->horizontalHeader()->width();
+ int nColsWidth = getColumnsWidth();
+ if (nColsWidth > nTableWidth)
+ {
+ resizeColumn(secondToLastColumnIndex,getAvailableWidthForColumn(secondToLastColumnIndex));
+ }
+}
+
+// Make column use all the space available, useful during window resizing.
+void TableViewLastColumnResizingFixer::stretchColumnWidth(int column)
+{
+ disconnectViewHeadersSignals();
+ resizeColumn(column, getAvailableWidthForColumn(column));
+ connectViewHeadersSignals();
+}
+
+// When a section is resized this is a slot-proxy for ajustAmountColumnWidth().
+void TableViewLastColumnResizingFixer::on_sectionResized(int logicalIndex, int oldSize, int newSize)
+{
+ adjustTableColumnsWidth();
+ int remainingWidth = getAvailableWidthForColumn(logicalIndex);
+ if (newSize > remainingWidth)
+ {
+ resizeColumn(logicalIndex, remainingWidth);
+ }
+}
+
+// When the tabless geometry is ready, we manually perform the stretch of the "Message" column,
+// as the "Stretch" resize mode does not allow for interactive resizing.
+void TableViewLastColumnResizingFixer::on_geometriesChanged()
+{
+ if ((getColumnsWidth() - this->tableView->horizontalHeader()->width()) != 0)
+ {
+ disconnectViewHeadersSignals();
+ resizeColumn(secondToLastColumnIndex, getAvailableWidthForColumn(secondToLastColumnIndex));
+ connectViewHeadersSignals();
+ }
+}
+
+/**
+ * Initializes all internal variables and prepares the
+ * the resize modes of the last 2 columns of the table and
+ */
+TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* table, int lastColMinimumWidth, int allColsMinimumWidth) :
+ tableView(table),
+ lastColumnMinimumWidth(lastColMinimumWidth),
+ allColumnsMinimumWidth(allColsMinimumWidth)
+{
+ columnCount = tableView->horizontalHeader()->count();
+ lastColumnIndex = columnCount - 1;
+ secondToLastColumnIndex = columnCount - 2;
+ tableView->horizontalHeader()->setMinimumSectionSize(allColumnsMinimumWidth);
+ setViewHeaderResizeMode(secondToLastColumnIndex, QHeaderView::Interactive);
+ setViewHeaderResizeMode(lastColumnIndex, QHeaderView::Interactive);
+}
+
#ifdef WIN32
boost::filesystem::path static StartupShortcutPath()
{
@@ -591,51 +721,33 @@ void restoreWindowGeometry(const QString& strSetting, const QSize& defaultSize,
parent->move(pos);
}
-HelpMessageBox::HelpMessageBox(QWidget *parent) :
- QMessageBox(parent)
+void setClipboard(const QString& str)
{
- header = tr("Bitcoin Core") + " " + tr("version") + " " +
- QString::fromStdString(FormatFullVersion()) + "\n\n" +
- tr("Usage:") + "\n" +
- " bitcoin-qt [" + tr("command-line options") + "] " + "\n";
-
- coreOptions = QString::fromStdString(HelpMessage(HMM_BITCOIN_QT));
-
- uiOptions = tr("UI options") + ":\n" +
- " -lang=<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" +
- " -choosedatadir " + tr("Choose data directory on startup (default: 0)") + "\n";
-
- setWindowTitle(tr("Bitcoin Core"));
- 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);
+ QApplication::clipboard()->setText(str, QClipboard::Clipboard);
+ QApplication::clipboard()->setText(str, QClipboard::Selection);
}
-void HelpMessageBox::printToConsole()
+#if BOOST_FILESYSTEM_VERSION >= 3
+boost::filesystem::path qstringToBoostPath(const QString &path)
{
- // 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());
+ return boost::filesystem::path(path.toStdString(), utf8);
}
-void HelpMessageBox::showOrPrint()
+QString boostPathToQString(const boost::filesystem::path &path)
{
-#if defined(WIN32)
- // On Windows, show a message box, as there is no stderr/stdout in windowed applications
- exec();
+ return QString::fromStdString(path.string(utf8));
+}
#else
- // On other operating systems, print help text to console
- printToConsole();
-#endif
+#warning Conversion between boost path and QString can use invalid character encoding with boost_filesystem v2 and older
+boost::filesystem::path qstringToBoostPath(const QString &path)
+{
+ return boost::filesystem::path(path.toStdString());
}
-void setClipboard(const QString& str)
+QString boostPathToQString(const boost::filesystem::path &path)
{
- QApplication::clipboard()->setText(str, QClipboard::Clipboard);
- QApplication::clipboard()->setText(str, QClipboard::Selection);
+ return QString::fromStdString(path.string());
}
+#endif
} // namespace GUIUtil