mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-26 23:28:14 +03:00
Merge pull request #4580 from owncloud/implement_ep_1136
Implement EP 1136
This commit is contained in:
commit
7730e826b0
11 changed files with 275 additions and 486 deletions
353
src/3rdparty/fancylineedit/fancylineedit.cpp
vendored
353
src/3rdparty/fancylineedit/fancylineedit.cpp
vendored
|
@ -1,353 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "fancylineedit.h"
|
||||
|
||||
#include <QEvent>
|
||||
#include <QDebug>
|
||||
#include <QString>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QApplication>
|
||||
#include <QMenu>
|
||||
#include <QMouseEvent>
|
||||
#include <QLabel>
|
||||
#include <QAbstractButton>
|
||||
#include <QPainter>
|
||||
#include <QStyle>
|
||||
#include <QPaintEvent>
|
||||
#include <QDesktopWidget>
|
||||
|
||||
/*! Opens a menu at the specified widget position.
|
||||
* This functions computes the position where to show the menu, and opens it with
|
||||
* QMenu::exec().
|
||||
* \param menu The menu to open
|
||||
* \param widget The widget next to which to open the menu
|
||||
*/
|
||||
static void execMenuAtWidget(QMenu *menu, QWidget *widget)
|
||||
{
|
||||
QPoint p;
|
||||
QRect screen = qApp->desktop()->availableGeometry(widget);
|
||||
QSize sh = menu->sizeHint();
|
||||
QRect rect = widget->rect();
|
||||
if (widget->isRightToLeft()) {
|
||||
if (widget->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.height())
|
||||
p = widget->mapToGlobal(rect.bottomRight());
|
||||
else
|
||||
p = widget->mapToGlobal(rect.topRight() - QPoint(0, sh.height()));
|
||||
p.rx() -= sh.width();
|
||||
} else {
|
||||
if (widget->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.height())
|
||||
p = widget->mapToGlobal(rect.bottomLeft());
|
||||
else
|
||||
p = widget->mapToGlobal(rect.topLeft() - QPoint(0, sh.height()));
|
||||
}
|
||||
p.rx() = qMax(screen.left(), qMin(p.x(), screen.right() - sh.width()));
|
||||
p.ry() += 1;
|
||||
|
||||
menu->exec(p);
|
||||
}
|
||||
|
||||
/*!
|
||||
\class Utils::FancyLineEdit
|
||||
|
||||
\brief A line edit with an embedded pixmap on one side that is connected to
|
||||
a menu.
|
||||
|
||||
Additionally, it can display a grayed hintText (like "Type Here to")
|
||||
when not focused and empty. When connecting to the changed signals and
|
||||
querying text, one has to be aware that the text is set to that hint
|
||||
text if isShowingHintText() returns true (that is, does not contain
|
||||
valid user input).
|
||||
*/
|
||||
|
||||
enum { margin = 6 };
|
||||
|
||||
#define ICONBUTTON_HEIGHT 18
|
||||
#define FADE_TIME 160
|
||||
|
||||
namespace Utils {
|
||||
|
||||
// --------- FancyLineEditPrivate
|
||||
class FancyLineEditPrivate : public QObject
|
||||
{
|
||||
public:
|
||||
explicit FancyLineEditPrivate(FancyLineEdit *parent);
|
||||
|
||||
virtual bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
FancyLineEdit *m_lineEdit;
|
||||
QPixmap m_pixmap[2];
|
||||
QMenu *m_menu[2];
|
||||
bool m_menuTabFocusTrigger[2];
|
||||
IconButton *m_iconbutton[2];
|
||||
bool m_iconEnabled[2];
|
||||
};
|
||||
|
||||
|
||||
FancyLineEditPrivate::FancyLineEditPrivate(FancyLineEdit *parent) :
|
||||
QObject(parent), m_lineEdit(parent)
|
||||
{
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
m_menu[i] = 0;
|
||||
m_menuTabFocusTrigger[i] = false;
|
||||
m_iconbutton[i] = new IconButton(parent);
|
||||
m_iconbutton[i]->installEventFilter(this);
|
||||
m_iconbutton[i]->hide();
|
||||
m_iconbutton[i]->setAutoHide(false);
|
||||
m_iconEnabled[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool FancyLineEditPrivate::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
int buttonIndex = -1;
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (obj == m_iconbutton[i]) {
|
||||
buttonIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (buttonIndex == -1)
|
||||
return QObject::eventFilter(obj, event);
|
||||
switch (event->type()) {
|
||||
case QEvent::FocusIn:
|
||||
if (m_menuTabFocusTrigger[buttonIndex] && m_menu[buttonIndex]) {
|
||||
m_lineEdit->setFocus();
|
||||
execMenuAtWidget(m_menu[buttonIndex], m_iconbutton[buttonIndex]);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
|
||||
// --------- FancyLineEdit
|
||||
FancyLineEdit::FancyLineEdit(QWidget *parent) :
|
||||
QLineEdit(parent),
|
||||
d(new FancyLineEditPrivate(this))
|
||||
{
|
||||
ensurePolished();
|
||||
updateMargins();
|
||||
|
||||
connect(this, SIGNAL(textChanged(QString)), this, SLOT(checkButtons(QString)));
|
||||
connect(d->m_iconbutton[Left], SIGNAL(clicked()), this, SLOT(iconClicked()));
|
||||
connect(d->m_iconbutton[Right], SIGNAL(clicked()), this, SLOT(iconClicked()));
|
||||
}
|
||||
|
||||
void FancyLineEdit::checkButtons(const QString &text)
|
||||
{
|
||||
if (m_oldText.isEmpty() || text.isEmpty()) {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (d->m_iconbutton[i]->hasAutoHide())
|
||||
d->m_iconbutton[i]->animateShow(!text.isEmpty());
|
||||
}
|
||||
m_oldText = text;
|
||||
}
|
||||
}
|
||||
|
||||
FancyLineEdit::~FancyLineEdit()
|
||||
{
|
||||
}
|
||||
|
||||
void FancyLineEdit::setButtonVisible(Side side, bool visible)
|
||||
{
|
||||
d->m_iconbutton[side]->setVisible(visible);
|
||||
d->m_iconEnabled[side] = visible;
|
||||
updateMargins();
|
||||
}
|
||||
|
||||
bool FancyLineEdit::isButtonVisible(Side side) const
|
||||
{
|
||||
return d->m_iconEnabled[side];
|
||||
}
|
||||
|
||||
void FancyLineEdit::iconClicked()
|
||||
{
|
||||
IconButton *button = qobject_cast<IconButton *>(sender());
|
||||
int index = -1;
|
||||
for (int i = 0; i < 2; ++i)
|
||||
if (d->m_iconbutton[i] == button)
|
||||
index = i;
|
||||
if (index == -1)
|
||||
return;
|
||||
if (d->m_menu[index]) {
|
||||
execMenuAtWidget(d->m_menu[index], button);
|
||||
} else {
|
||||
emit buttonClicked((Side)index);
|
||||
if (index == Left)
|
||||
emit leftButtonClicked();
|
||||
else if (index == Right)
|
||||
emit rightButtonClicked();
|
||||
}
|
||||
}
|
||||
|
||||
void FancyLineEdit::updateMargins()
|
||||
{
|
||||
bool leftToRight = (layoutDirection() == Qt::LeftToRight);
|
||||
Side realLeft = (leftToRight ? Left : Right);
|
||||
Side realRight = (leftToRight ? Right : Left);
|
||||
|
||||
int leftMargin = d->m_iconbutton[realLeft]->pixmap().width() + 8;
|
||||
int rightMargin = d->m_iconbutton[realRight]->pixmap().width() + 8;
|
||||
// Note KDE does not reserve space for the highlight color
|
||||
if (style()->inherits("OxygenStyle")) {
|
||||
leftMargin = qMax(24, leftMargin);
|
||||
rightMargin = qMax(24, rightMargin);
|
||||
}
|
||||
|
||||
QMargins margins((d->m_iconEnabled[realLeft] ? leftMargin : 0), 0,
|
||||
(d->m_iconEnabled[realRight] ? rightMargin : 0), 0);
|
||||
|
||||
setTextMargins(margins);
|
||||
}
|
||||
|
||||
void FancyLineEdit::updateButtonPositions()
|
||||
{
|
||||
QRect contentRect = rect();
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
Side iconpos = (Side)i;
|
||||
if (layoutDirection() == Qt::RightToLeft)
|
||||
iconpos = (iconpos == Left ? Right : Left);
|
||||
|
||||
if (iconpos == FancyLineEdit::Right) {
|
||||
const int iconoffset = textMargins().right() + 4;
|
||||
d->m_iconbutton[i]->setGeometry(contentRect.adjusted(width() - iconoffset, 0, 0, 0));
|
||||
} else {
|
||||
const int iconoffset = textMargins().left() + 4;
|
||||
d->m_iconbutton[i]->setGeometry(contentRect.adjusted(0, 0, -width() + iconoffset, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FancyLineEdit::resizeEvent(QResizeEvent *)
|
||||
{
|
||||
updateButtonPositions();
|
||||
}
|
||||
|
||||
void FancyLineEdit::setButtonPixmap(Side side, const QPixmap &buttonPixmap)
|
||||
{
|
||||
d->m_iconbutton[side]->setPixmap(buttonPixmap);
|
||||
updateMargins();
|
||||
updateButtonPositions();
|
||||
update();
|
||||
}
|
||||
|
||||
QPixmap FancyLineEdit::buttonPixmap(Side side) const
|
||||
{
|
||||
return d->m_pixmap[side];
|
||||
}
|
||||
|
||||
void FancyLineEdit::setButtonMenu(Side side, QMenu *buttonMenu)
|
||||
{
|
||||
d->m_menu[side] = buttonMenu;
|
||||
d->m_iconbutton[side]->setIconOpacity(1.0);
|
||||
}
|
||||
|
||||
QMenu *FancyLineEdit::buttonMenu(Side side) const
|
||||
{
|
||||
return d->m_menu[side];
|
||||
}
|
||||
|
||||
bool FancyLineEdit::hasMenuTabFocusTrigger(Side side) const
|
||||
{
|
||||
return d->m_menuTabFocusTrigger[side];
|
||||
}
|
||||
|
||||
void FancyLineEdit::setMenuTabFocusTrigger(Side side, bool v)
|
||||
{
|
||||
if (d->m_menuTabFocusTrigger[side] == v)
|
||||
return;
|
||||
|
||||
d->m_menuTabFocusTrigger[side] = v;
|
||||
d->m_iconbutton[side]->setFocusPolicy(v ? Qt::TabFocus : Qt::NoFocus);
|
||||
}
|
||||
|
||||
bool FancyLineEdit::hasAutoHideButton(Side side) const
|
||||
{
|
||||
return d->m_iconbutton[side]->hasAutoHide();
|
||||
}
|
||||
|
||||
void FancyLineEdit::setAutoHideButton(Side side, bool h)
|
||||
{
|
||||
d->m_iconbutton[side]->setAutoHide(h);
|
||||
if (h)
|
||||
d->m_iconbutton[side]->setIconOpacity(text().isEmpty() ? 0.0 : 1.0);
|
||||
else
|
||||
d->m_iconbutton[side]->setIconOpacity(1.0);
|
||||
}
|
||||
|
||||
void FancyLineEdit::setButtonToolTip(Side side, const QString &tip)
|
||||
{
|
||||
d->m_iconbutton[side]->setToolTip(tip);
|
||||
}
|
||||
|
||||
void FancyLineEdit::setButtonFocusPolicy(Side side, Qt::FocusPolicy policy)
|
||||
{
|
||||
d->m_iconbutton[side]->setFocusPolicy(policy);
|
||||
}
|
||||
|
||||
// IconButton - helper class to represent a clickable icon
|
||||
|
||||
IconButton::IconButton(QWidget *parent)
|
||||
: QAbstractButton(parent), m_iconOpacity(0), m_autoHide(false)
|
||||
{
|
||||
setCursor(Qt::ArrowCursor);
|
||||
setFocusPolicy(Qt::NoFocus);
|
||||
}
|
||||
|
||||
void IconButton::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QPainter painter(this);
|
||||
QRect pixmapRect = QRect(0, 0, m_pixmap.width(), m_pixmap.height());
|
||||
pixmapRect.moveCenter(rect().center());
|
||||
|
||||
if (m_autoHide)
|
||||
painter.setOpacity(m_iconOpacity);
|
||||
|
||||
painter.drawPixmap(pixmapRect, m_pixmap);
|
||||
}
|
||||
|
||||
void IconButton::animateShow(bool visible)
|
||||
{
|
||||
if (visible) {
|
||||
QPropertyAnimation *animation = new QPropertyAnimation(this, "iconOpacity");
|
||||
animation->setDuration(FADE_TIME);
|
||||
animation->setEndValue(1.0);
|
||||
animation->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
} else {
|
||||
QPropertyAnimation *animation = new QPropertyAnimation(this, "iconOpacity");
|
||||
animation->setDuration(FADE_TIME);
|
||||
animation->setEndValue(0.0);
|
||||
animation->start(QAbstractAnimation::DeleteWhenStopped);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Utils
|
121
src/3rdparty/fancylineedit/fancylineedit.h
vendored
121
src/3rdparty/fancylineedit/fancylineedit.h
vendored
|
@ -1,121 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef FANCYLINEEDIT_H
|
||||
#define FANCYLINEEDIT_H
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QAbstractButton>
|
||||
|
||||
namespace Utils {
|
||||
|
||||
class FancyLineEditPrivate;
|
||||
|
||||
class IconButton: public QAbstractButton
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float iconOpacity READ iconOpacity WRITE setIconOpacity)
|
||||
Q_PROPERTY(bool autoHide READ hasAutoHide WRITE setAutoHide)
|
||||
Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap)
|
||||
public:
|
||||
explicit IconButton(QWidget *parent = 0);
|
||||
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
|
||||
void setPixmap(const QPixmap &pixmap) { m_pixmap = pixmap; update(); }
|
||||
QPixmap pixmap() const { return m_pixmap; }
|
||||
float iconOpacity() { return m_iconOpacity; }
|
||||
void setIconOpacity(float value) { m_iconOpacity = value; update(); }
|
||||
void animateShow(bool visible);
|
||||
|
||||
void setAutoHide(bool hide) { m_autoHide = hide; }
|
||||
bool hasAutoHide() const { return m_autoHide; }
|
||||
|
||||
private:
|
||||
float m_iconOpacity;
|
||||
bool m_autoHide;
|
||||
QPixmap m_pixmap;
|
||||
};
|
||||
|
||||
class FancyLineEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_ENUMS(Side)
|
||||
|
||||
public:
|
||||
enum Side {Left = 0, Right = 1};
|
||||
|
||||
explicit FancyLineEdit(QWidget *parent = 0);
|
||||
~FancyLineEdit();
|
||||
|
||||
QPixmap buttonPixmap(Side side) const;
|
||||
void setButtonPixmap(Side side, const QPixmap &pixmap);
|
||||
|
||||
QMenu *buttonMenu(Side side) const;
|
||||
void setButtonMenu(Side side, QMenu *menu);
|
||||
|
||||
void setButtonVisible(Side side, bool visible);
|
||||
bool isButtonVisible(Side side) const;
|
||||
|
||||
void setButtonToolTip(Side side, const QString &);
|
||||
void setButtonFocusPolicy(Side side, Qt::FocusPolicy policy);
|
||||
|
||||
// Set whether tabbing in will trigger the menu.
|
||||
void setMenuTabFocusTrigger(Side side, bool v);
|
||||
bool hasMenuTabFocusTrigger(Side side) const;
|
||||
|
||||
// Set if icon should be hidden when text is empty
|
||||
void setAutoHideButton(Side side, bool h);
|
||||
bool hasAutoHideButton(Side side) const;
|
||||
#if QT_VERSION <= 0x040700
|
||||
void setPlaceholderText( const QString& ) { }
|
||||
#endif
|
||||
|
||||
signals:
|
||||
void buttonClicked(Utils::FancyLineEdit::Side side);
|
||||
void leftButtonClicked();
|
||||
void rightButtonClicked();
|
||||
|
||||
private slots:
|
||||
void checkButtons(const QString &);
|
||||
void iconClicked();
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
void updateMargins();
|
||||
void updateButtonPositions();
|
||||
friend class Utils::FancyLineEditPrivate;
|
||||
|
||||
FancyLineEditPrivate *d;
|
||||
QString m_oldText;
|
||||
};
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
#endif // FANCYLINEEDIT_H
|
|
@ -89,6 +89,7 @@ set(client_SRCS
|
|||
creds/shibbolethcredentials.cpp
|
||||
creds/shibboleth/shibbolethwebview.cpp
|
||||
creds/shibboleth/shibbolethuserjob.cpp
|
||||
wizard/postfixlineedit.cpp
|
||||
wizard/abstractcredswizardpage.cpp
|
||||
wizard/owncloudadvancedsetuppage.cpp
|
||||
wizard/owncloudconnectionmethoddialog.cpp
|
||||
|
@ -133,7 +134,6 @@ list(APPEND client_SRCS folderwatcher_mac.cpp)
|
|||
ENDIF()
|
||||
|
||||
set(3rdparty_SRC
|
||||
../3rdparty/fancylineedit/fancylineedit.cpp
|
||||
../3rdparty/QProgressIndicator/QProgressIndicator.cpp
|
||||
../3rdparty/qtlockedfile/qtlockedfile.cpp
|
||||
../3rdparty/qtsingleapplication/qtlocalpeer.cpp
|
||||
|
@ -157,7 +157,6 @@ else()
|
|||
endif()
|
||||
|
||||
set(3rdparty_INC
|
||||
${CMAKE_SOURCE_DIR}/src/3rdparty/fancylineedit
|
||||
${CMAKE_SOURCE_DIR}/src/3rdparty/qjson
|
||||
${CMAKE_SOURCE_DIR}/src/3rdparty/QProgressIndicator
|
||||
${CMAKE_SOURCE_DIR}/src/3rdparty/qtlockedfile
|
||||
|
|
|
@ -42,6 +42,22 @@ OwncloudHttpCredsPage::OwncloudHttpCredsPage(QWidget* parent)
|
|||
registerField( QLatin1String("OCUser*"), _ui.leUsername);
|
||||
registerField( QLatin1String("OCPasswd*"), _ui.lePassword);
|
||||
|
||||
Theme *theme = Theme::instance();
|
||||
switch(theme->userIDType()) {
|
||||
case Theme::UserIDUserName:
|
||||
// default, handled in ui file
|
||||
break;
|
||||
case Theme::UserIDEmail:
|
||||
_ui.usernameLabel->setText(tr("&E-mail address"));
|
||||
break;
|
||||
case Theme::UserIDCustom:
|
||||
_ui.usernameLabel->setText(theme->customUserID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_ui.leUsername->setPlaceholderText(theme->userIDHint());
|
||||
|
||||
setTitle(WizardCommon::titleTemplate().arg(tr("Connect to %1").arg(Theme::instance()->appNameGUI())));
|
||||
setSubTitle(WizardCommon::subTitleTemplate().arg(tr("Enter user credentials")));
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
<item row="1" column="1">
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<widget class="QLabel" name="usernameLabel">
|
||||
<property name="text">
|
||||
<string>&Username</string>
|
||||
</property>
|
||||
|
@ -127,8 +127,6 @@
|
|||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>topLabel</zorder>
|
||||
<zorder>bottomLabel</zorder>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Utils::FancyLineEdit" name="leUrl">
|
||||
<widget class="OCC::PostfixLineEdit" name="leUrl">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
|
@ -189,15 +189,12 @@
|
|||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>topLabel</zorder>
|
||||
<zorder>errorLabel</zorder>
|
||||
<zorder>bottomLabel</zorder>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Utils::FancyLineEdit</class>
|
||||
<class>OCC::PostfixLineEdit</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header location="global">fancylineedit.h</header>
|
||||
<header>wizard/postfixlineedit.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
|
|
|
@ -51,7 +51,9 @@ OwncloudSetupPage::OwncloudSetupPage(QWidget *parent)
|
|||
setTitle(WizardCommon::titleTemplate().arg(tr("Connect to %1").arg(theme->appNameGUI())));
|
||||
setSubTitle(WizardCommon::subTitleTemplate().arg(tr("Setup %1 server").arg(theme->appNameGUI())));
|
||||
|
||||
if (!theme->overrideServerUrl().isEmpty()) {
|
||||
if (theme->overrideServerUrl().isEmpty()) {
|
||||
_ui.leUrl->setPostfix(theme->wizardUrlPostfix());
|
||||
} else {
|
||||
_ui.leUrl->setEnabled(false);
|
||||
}
|
||||
|
||||
|
|
133
src/gui/wizard/postfixlineedit.cpp
Normal file
133
src/gui/wizard/postfixlineedit.cpp
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (C) 2016 by Daniel Molkentin <danimo@owncloud.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include <QRegExpValidator>
|
||||
#include <QRegExp>
|
||||
#include <QDebug>
|
||||
|
||||
#include "postfixlineedit.h"
|
||||
|
||||
namespace OCC {
|
||||
|
||||
// Helper class
|
||||
|
||||
/**
|
||||
* @brief A QRegExValidator with no Intermediate validation state.
|
||||
*
|
||||
* Along with a pre-set text in a lineedit, this enforces a certain text
|
||||
* to always be present.
|
||||
*/
|
||||
class StrictRegExpValidator : public QRegExpValidator
|
||||
{
|
||||
public:
|
||||
explicit StrictRegExpValidator(const QRegExp& rx, QObject *parent = Q_NULLPTR) :
|
||||
QRegExpValidator(rx, parent) {}
|
||||
|
||||
virtual QValidator::State validate(QString& input, int& pos) const Q_DECL_OVERRIDE;
|
||||
};
|
||||
|
||||
|
||||
QValidator::State StrictRegExpValidator::validate(QString &input, int &pos) const
|
||||
{
|
||||
QValidator::State state = QRegExpValidator::validate(input, pos);
|
||||
if (state == QValidator::Intermediate)
|
||||
state = QValidator::Invalid;
|
||||
return state;
|
||||
}
|
||||
|
||||
// Begin of URLLineEdit impl
|
||||
|
||||
PostfixLineEdit::PostfixLineEdit(QWidget *parent)
|
||||
: QLineEdit(parent)
|
||||
{
|
||||
connect(this, SIGNAL(textChanged(const QString&)), SLOT(slotTextChanged(const QString&)));
|
||||
}
|
||||
|
||||
void PostfixLineEdit::setPostfix(const QString &postfix)
|
||||
{
|
||||
_postfix = postfix;
|
||||
}
|
||||
|
||||
QString PostfixLineEdit::postfix() const
|
||||
{
|
||||
return _postfix;
|
||||
}
|
||||
|
||||
void PostfixLineEdit::focusInEvent(QFocusEvent *ev)
|
||||
{
|
||||
QLineEdit::focusInEvent(ev);
|
||||
ensureValidationEngaged();
|
||||
setSelection(0 , maxUserInputLength());
|
||||
}
|
||||
|
||||
void PostfixLineEdit::focusOutEvent(QFocusEvent *ev)
|
||||
{
|
||||
QLineEdit::focusOutEvent(ev);
|
||||
showPlaceholder();
|
||||
}
|
||||
|
||||
void PostfixLineEdit::slotTextChanged(const QString &)
|
||||
{
|
||||
ensureValidationEngaged();
|
||||
}
|
||||
|
||||
void PostfixLineEdit::mouseReleaseEvent(QMouseEvent *ev)
|
||||
{
|
||||
QLineEdit::mouseReleaseEvent(ev);
|
||||
// ensure selections still work
|
||||
if (selectedText().isEmpty()) {
|
||||
limitCursorPlacement();
|
||||
}
|
||||
}
|
||||
|
||||
void PostfixLineEdit::ensureValidationEngaged()
|
||||
{
|
||||
if (_postfix.isEmpty())
|
||||
return;
|
||||
|
||||
if (text().isEmpty()) {
|
||||
// also called from setText via slotTextChanged
|
||||
bool old = blockSignals(true);
|
||||
setText(_postfix);
|
||||
blockSignals(old);
|
||||
}
|
||||
if (!validator()) {
|
||||
QRegExp rx(QString("*%1").arg(_postfix));
|
||||
rx.setPatternSyntax(QRegExp::Wildcard);
|
||||
QRegExpValidator *val = new StrictRegExpValidator(rx);
|
||||
setValidator(val);
|
||||
}
|
||||
}
|
||||
|
||||
void PostfixLineEdit::showPlaceholder()
|
||||
{
|
||||
if (text() == _postfix && !placeholderText().isNull()) {
|
||||
setValidator(0);
|
||||
setText(QString());
|
||||
}
|
||||
}
|
||||
|
||||
int PostfixLineEdit::maxUserInputLength() const
|
||||
{
|
||||
return text().length() - _postfix.length();
|
||||
}
|
||||
|
||||
void PostfixLineEdit::limitCursorPlacement()
|
||||
{
|
||||
if (cursorPosition() > maxUserInputLength()) {
|
||||
setCursorPosition(maxUserInputLength());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OCC
|
55
src/gui/wizard/postfixlineedit.h
Normal file
55
src/gui/wizard/postfixlineedit.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (C) 2016 by Daniel Molkentin <danimo@owncloud.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCC_POSTFIXLINEEDIT_H
|
||||
#define OCC_POSTFIXLINEEDIT_H
|
||||
|
||||
#include <QLineEdit>
|
||||
|
||||
namespace OCC {
|
||||
|
||||
/**
|
||||
* @brief A class with a non-removable postfix string.
|
||||
*
|
||||
* Useful e.g. for setting a fixed domain name.
|
||||
*/
|
||||
class PostfixLineEdit : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PostfixLineEdit(QWidget *parent = 0);
|
||||
/// Sets a non-removeable postfix string
|
||||
void setPostfix(const QString &postfix);
|
||||
/// @return the currently set postfix. Use @ref text() to retrieve the full text.
|
||||
QString postfix() const;
|
||||
|
||||
protected:
|
||||
void mouseReleaseEvent(QMouseEvent*) Q_DECL_OVERRIDE;
|
||||
void focusInEvent(QFocusEvent *) Q_DECL_OVERRIDE;
|
||||
void focusOutEvent(QFocusEvent *) Q_DECL_OVERRIDE;
|
||||
|
||||
private slots:
|
||||
void slotTextChanged(const QString&);
|
||||
|
||||
private:
|
||||
void ensureValidationEngaged();
|
||||
void showPlaceholder();
|
||||
int maxUserInputLength() const;
|
||||
void limitCursorPlacement();
|
||||
QString _postfix;
|
||||
};
|
||||
|
||||
} // namespace OCC
|
||||
|
||||
#endif // OCC_POSTFIXLINEEDIT_H
|
|
@ -432,6 +432,27 @@ bool Theme::forceSystemNetworkProxy() const
|
|||
return false;
|
||||
}
|
||||
|
||||
Theme::UserIDType Theme::userIDType() const
|
||||
{
|
||||
return UserIDType::UserIDUserName;
|
||||
}
|
||||
|
||||
QString Theme::customUserID() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString Theme::userIDHint() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
QString Theme::wizardUrlPostfix() const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // end namespace client
|
||||
|
|
|
@ -239,6 +239,48 @@ public:
|
|||
|
||||
virtual bool forceSystemNetworkProxy() const;
|
||||
|
||||
/**
|
||||
* @brief How to handle the userID
|
||||
*
|
||||
* @value UserIDUserName Wizard asks for user name as ID
|
||||
* @value UserIDEmail Wizard asks for an email as ID
|
||||
* @value UserIDCustom Specify string in \ref customUserID
|
||||
*/
|
||||
enum UserIDType { UserIDUserName = 0, UserIDEmail, UserIDCustom };
|
||||
|
||||
/** @brief What to display as the userID (e.g. in the wizards)
|
||||
*
|
||||
* @return UserIDType::UserIDUserName, unless reimplemented
|
||||
*/
|
||||
virtual UserIDType userIDType() const;
|
||||
|
||||
/**
|
||||
* @brief Allows to customize the type of user ID (e.g. user name, email)
|
||||
*
|
||||
* @note This string cannot be translated, but is still useful for
|
||||
* referencing brand name IDs (e.g. "ACME ID", when using ACME.)
|
||||
*
|
||||
* @return An empty string, unless reimplemented
|
||||
*/
|
||||
virtual QString customUserID() const;
|
||||
|
||||
/**
|
||||
* @brief Demo string to be displayed when no text has been
|
||||
* entered for the user id (e.g. mylogin@company.com)
|
||||
*
|
||||
* @return An empty string, unless reimplemented
|
||||
*/
|
||||
virtual QString userIDHint() const;
|
||||
|
||||
/**
|
||||
* @brief Postfix that will be enforced in a URL. e.g.
|
||||
* ".myhosting.com".
|
||||
*
|
||||
* @return An empty string, unless reimplemented
|
||||
*/
|
||||
virtual QString wizardUrlPostfix() const;
|
||||
|
||||
|
||||
protected:
|
||||
#ifndef TOKEN_AUTH_ONLY
|
||||
QIcon themeIcon(const QString& name, bool sysTray = false) const;
|
||||
|
|
Loading…
Reference in a new issue