From e19c4cdec525e07caaac4f6c61c9862c7859d57c Mon Sep 17 00:00:00 2001 From: Edric Milaret <edric.ladent-milaret@savoirfairelinux.com> Date: Fri, 12 Feb 2016 10:19:44 -0500 Subject: [PATCH] share: refactor share menu to show a qrcode - Share menu gives now the choice to share by mail and to show a QRCode of the RingID * This add a dependency to libqrencode Change-Id: I148d06c3ea1c807cd8119807ca743b08c96341de Tuleap: #499 --- .gitmodules | 3 +++ RingWinClient.pro | 4 +-- callwidget.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++- callwidget.h | 4 +++ callwidget.ui | 9 ++++++- libqrencode | 1 + stylesheet.css | 10 +++++--- 7 files changed, 89 insertions(+), 7 deletions(-) create mode 160000 libqrencode diff --git a/.gitmodules b/.gitmodules index fa045e1..087d51c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "winsparkle"] path = winsparkle url = git://github.com/vslavik/winsparkle.git +[submodule "libqrencode"] + path = libqrencode + url = https://github.com/EckoEdc/libqrencode.git diff --git a/RingWinClient.pro b/RingWinClient.pro index 34a6fe0..33490aa 100644 --- a/RingWinClient.pro +++ b/RingWinClient.pro @@ -124,7 +124,7 @@ FORMS += mainwindow.ui \ qualitydialog.ui \ ringbutton.ui -win32: LIBS += -lole32 -luuid -lshlwapi +win32: LIBS += -lole32 -luuid -lshlwapi -lqrencode INCLUDEPATH += $${RING}/include/libringclient INCLUDEPATH += $${RING}/include @@ -187,7 +187,7 @@ win32 { RUNTIMEDIR=$$[QT_INSTALL_BINS] - RUNTIME.files = $${RING}/bin/libring.dll $${RING}/bin/libringclient.dll + RUNTIME.files = $${RING}/bin/libring.dll $${RING}/bin/libringclient.dll $${RING}/bin/libqrencode.dll RUNTIME.path = $$OUT_PWD/release LRC_TRANSLATION.files = $${RING}/share/libringclient/translations diff --git a/callwidget.cpp b/callwidget.cpp index 8f8e603..c2d6793 100644 --- a/callwidget.cpp +++ b/callwidget.cpp @@ -23,6 +23,8 @@ #include <memory> +#include "qrencode.h" + //ERROR is defined in windows.h #include "utils.h" #undef ERROR @@ -74,6 +76,8 @@ CallWidget::CallWidget(QWidget* parent) : ui->ringLogo->setPixmap(logo.scaledToHeight(100, Qt::SmoothTransformation)); ui->ringLogo->setAlignment(Qt::AlignHCenter); + setupShareMenu(); + GlobalInstances::setPixmapManipulator(std::unique_ptr<Interfaces::PixbufManipulator>(new Interfaces::PixbufManipulator())); try { @@ -186,6 +190,25 @@ CallWidget::~CallWidget() delete imDelegate_; delete pageAnim_; delete smartListDelegate_; + delete shareMenu_; +} + +void +CallWidget::setupShareMenu() +{ + ui->shareButton->setPopupMode(QToolButton::ToolButtonPopupMode::MenuButtonPopup); + shareMenu_ = new QMenu(ui->shareButton); + auto emailShare = new QAction(tr("Share by email"), this); + connect(emailShare, &QAction::triggered, [=]() { + Utils::InvokeMailto(tr("Contact me on Ring"), tr("My RingId is : ") + ui->ringIdLabel->text()); + }); + shareMenu_->addAction(emailShare); + auto qrcodeAction = new QAction(tr("Show QRCode"), this); + qrcodeAction->setCheckable(true); + ui->qrLabel->hide(); + connect(qrcodeAction, &QAction::toggled, ui->qrLabel, &QLabel::setVisible); + shareMenu_->addAction(qrcodeAction); + ui->shareButton->setMenu(shareMenu_); } void @@ -309,6 +332,7 @@ CallWidget::findRingAccount(QModelIndex idx1, QModelIndex idx2, QVector<int> vec auto username = idx.data(static_cast<int>(Account::Role::Username)); ui->ringIdLabel->setText(username.toString()); found = true; + setupQRCode(); return; } } @@ -317,6 +341,43 @@ CallWidget::findRingAccount(QModelIndex idx1, QModelIndex idx2, QVector<int> vec } } +void CallWidget::setupQRCode() +{ + auto rcode = QRcode_encodeString(ui->ringIdLabel->text().toStdString().c_str(), + 8, + QR_ECLEVEL_H, // Highest level of error correction + QR_MODE_8, // 8-bit data mode + 1); + if (not rcode) { + qWarning() << "Failed to generate QR code: " << strerror(errno); + return; + } + + auto margin = 5; + int qrwidth = rcode->width + margin * 2; + QImage result(QSize(qrwidth, qrwidth), QImage::Format_Mono); + QPainter painter; + painter.begin(&result); + painter.setClipRect(QRect(0, 0, qrwidth, qrwidth)); + painter.setPen(QPen(Qt::black, 0.1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin)); + painter.setBrush(Qt::black); + painter.fillRect(QRect(0, 0, qrwidth, qrwidth), Qt::white); + unsigned char *row, *p; + p = rcode->data; + for(int y = 0; y < rcode->width; y++) { + row = (p + (y * rcode->width)); + for(int x = 0; x < rcode->width; x++) { + if(*(row + x) & 0x1) { + painter.drawRect(margin + x, margin + y, 1, 1); + } + } + + } + painter.end(); + QRcode_free(rcode); + ui->qrLabel->setPixmap(QPixmap::fromImage(result.scaled(QSize(qrSize_, qrSize_)))); +} + void CallWidget::findRingAccount() { @@ -331,6 +392,8 @@ CallWidget::findRingAccount() account->displayName() = account->alias(); auto username = account->username(); ui->ringIdLabel->setText(username); + setupQRCode(); + found = true; return; } @@ -726,5 +789,5 @@ CallWidget::on_copyCMButton_clicked() void CallWidget::on_shareButton_clicked() { - Utils::InvokeMailto("Contact me on Ring", QStringLiteral("My RingId is : ") + ui->ringIdLabel->text()); + ui->shareButton->showMenu(); } diff --git a/callwidget.h b/callwidget.h index 96722bf..085a2ae 100644 --- a/callwidget.h +++ b/callwidget.h @@ -108,8 +108,10 @@ private: QMetaObject::Connection imConnection_; QMetaObject::Connection imVisibleConnection_; QPropertyAnimation* pageAnim_; + QMenu* shareMenu_; constexpr static int animDuration_ = 200; //msecs + constexpr static int qrSize_ = 100; private: void findRingAccount(); @@ -119,5 +121,7 @@ private: void setupSmartListMenu(); void slidePage(QWidget* widget, bool toRight = false); void callStateToView(Call* value); + void setupShareMenu(); + void setupQRCode(); }; diff --git a/callwidget.ui b/callwidget.ui index dec9194..630ebf9 100644 --- a/callwidget.ui +++ b/callwidget.ui @@ -751,7 +751,7 @@ </spacer> </item> <item> - <widget class="QPushButton" name="shareButton"> + <widget class="QToolButton" name="shareButton"> <property name="sizePolicy"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <horstretch>0</horstretch> @@ -836,6 +836,13 @@ </property> </widget> </item> + <item alignment="Qt::AlignHCenter"> + <widget class="QLabel" name="qrLabel"> + <property name="text"> + <string>Error while generating QR Code</string> + </property> + </widget> + </item> <item> <spacer name="verticalSpacer_2"> <property name="orientation"> diff --git a/libqrencode b/libqrencode new file mode 160000 index 0000000..bad61a1 --- /dev/null +++ b/libqrencode @@ -0,0 +1 @@ +Subproject commit bad61a11b5bd78a1d52b9314fb06e8bfbcd361e5 diff --git a/stylesheet.css b/stylesheet.css index fc3e707..8531d96 100644 --- a/stylesheet.css +++ b/stylesheet.css @@ -184,19 +184,19 @@ QPushButton#hangupButton:pressed{ } QPushButton#exitSettingsButton, QPushButton#settingsButton, QPushButton#addToContactButton, -QPushButton#imBackButton, QPushButton#copyCMButton, QPushButton#shareButton{ +QPushButton#imBackButton, QPushButton#copyCMButton, QToolButton#shareButton{ background-color: #414141; border-radius: 15px; border:solid 1px; } QPushButton#exitSettingsButton:hover, QPushButton#settingsButton:hover, QPushButton#imBackButton:hover, -QPushButton#copyCMButton:hover, QPushButton#shareButton:hover{ +QPushButton#copyCMButton:hover, QToolButton#shareButton:hover{ background-color: #515151; } QPushButton#exitSettingsButton:pressed, QPushButton#settingsButton:pressed, QToolButton#imBackButton:pressed, -QPushButton#copyCMButton:pressed, QPushButton#shareButton:pressed{ +QPushButton#copyCMButton:pressed, QToolButton#shareButton:pressed{ background-color: #313131; } @@ -531,3 +531,7 @@ QSlider::sub-page:vertical{ QSlider::add-page:vertical{ background: #3AC0D2; } + +QToolButton::menu-button {image:none;} + +QToolButton::menu-arrow {image:none;} -- GitLab