2017-08-12 10:40:58 +02:00
|
|
|
/************************************************************************
|
|
|
|
**
|
|
|
|
** @file
|
|
|
|
** @author Roman Telezhynskyi <dismine(at)gmail.com>
|
|
|
|
** @date 12 8, 2017
|
|
|
|
**
|
|
|
|
** @brief
|
|
|
|
** @copyright
|
2017-10-05 11:20:01 +02:00
|
|
|
** This source code is part of the Valentina project, a pattern making
|
2017-08-12 10:40:58 +02:00
|
|
|
** program, whose allow create and modeling patterns of clothing.
|
|
|
|
** Copyright (C) 2017 Valentina project
|
2020-01-31 07:00:05 +01:00
|
|
|
** <https://gitlab.com/smart-pattern/valentina> All Rights Reserved.
|
2017-08-12 10:40:58 +02:00
|
|
|
**
|
|
|
|
** Valentina 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 3 of the License, or
|
|
|
|
** (at your option) any later version.
|
|
|
|
**
|
|
|
|
** Valentina 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.
|
|
|
|
**
|
|
|
|
** You should have received a copy of the GNU General Public License
|
|
|
|
** along with Valentina. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
**
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
#include "vlineedit.h"
|
|
|
|
|
2020-03-24 16:31:32 +01:00
|
|
|
#include <QApplication>
|
|
|
|
#include <QCompleter>
|
|
|
|
#include <QStringListModel>
|
|
|
|
#include <QTimer>
|
|
|
|
#include <QtDebug>
|
2022-09-12 16:00:42 +02:00
|
|
|
#include <chrono>
|
2020-03-24 16:31:32 +01:00
|
|
|
|
2022-09-13 12:10:12 +02:00
|
|
|
#if (defined(Q_CC_GNU) && Q_CC_GNU < 409) && !defined(Q_CC_CLANG)
|
|
|
|
// DO NOT WORK WITH GCC 4.8
|
|
|
|
#else
|
2022-09-08 20:00:14 +02:00
|
|
|
#if __cplusplus >= 201402L
|
|
|
|
using namespace std::chrono_literals;
|
|
|
|
#else
|
|
|
|
#include "../vmisc/bpstd/chrono.hpp"
|
|
|
|
using namespace bpstd::literals::chrono_literals;
|
2022-09-13 12:10:12 +02:00
|
|
|
#endif // __cplusplus >= 201402L
|
|
|
|
#endif //(defined(Q_CC_GNU) && Q_CC_GNU < 409) && !defined(Q_CC_CLANG)
|
2020-03-24 16:31:32 +01:00
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
class MultiSelectCompleter : public QCompleter
|
|
|
|
{
|
|
|
|
public:
|
2020-03-24 16:41:12 +01:00
|
|
|
explicit MultiSelectCompleter(QObject* parent=nullptr);
|
2020-03-24 16:31:32 +01:00
|
|
|
virtual ~MultiSelectCompleter() =default;
|
|
|
|
|
|
|
|
virtual QString pathFromIndex(const QModelIndex& index) const override;
|
|
|
|
virtual QStringList splitPath(const QString& path) const override;
|
|
|
|
|
|
|
|
private:
|
2022-08-12 17:50:13 +02:00
|
|
|
Q_DISABLE_COPY_MOVE(MultiSelectCompleter) // NOLINT
|
2020-03-24 16:31:32 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
//MultiSelectCompleter
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
MultiSelectCompleter::MultiSelectCompleter(QObject *parent)
|
|
|
|
: QCompleter(parent)
|
|
|
|
{}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
QString MultiSelectCompleter::pathFromIndex(const QModelIndex& index) const
|
|
|
|
{
|
|
|
|
QString path = QCompleter::pathFromIndex(index);
|
|
|
|
|
|
|
|
QString text = static_cast<QLineEdit*>(widget())->text();
|
|
|
|
|
|
|
|
int pos = text.lastIndexOf(',');
|
|
|
|
if (pos >= 0)
|
|
|
|
{
|
|
|
|
path = text.left(pos) + ", " + path;
|
|
|
|
}
|
|
|
|
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
QStringList MultiSelectCompleter::splitPath( const QString& path ) const
|
|
|
|
{
|
|
|
|
int pos = path.lastIndexOf(',') + 1;
|
|
|
|
|
|
|
|
while (pos < path.length() && path.at(pos) == QLatin1Char(' '))
|
|
|
|
{
|
|
|
|
pos++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return QStringList(path.mid(pos));
|
|
|
|
}
|
|
|
|
|
|
|
|
//VLineEdit
|
2017-08-12 10:40:58 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
VLineEdit::VLineEdit(QWidget *parent)
|
2017-08-12 10:57:46 +02:00
|
|
|
: QLineEdit(parent),
|
|
|
|
m_selectOnMousePress(false)
|
2017-08-12 10:40:58 +02:00
|
|
|
{}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
VLineEdit::VLineEdit(const QString &contents, QWidget *parent)
|
2017-08-12 10:57:46 +02:00
|
|
|
: QLineEdit(contents, parent),
|
|
|
|
m_selectOnMousePress(false)
|
2017-08-12 10:40:58 +02:00
|
|
|
{}
|
|
|
|
|
2017-08-12 10:57:46 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VLineEdit::focusInEvent(QFocusEvent *e)
|
|
|
|
{
|
|
|
|
QLineEdit::focusInEvent(e);
|
|
|
|
selectAll();
|
|
|
|
m_selectOnMousePress = true;
|
|
|
|
}
|
|
|
|
|
2017-08-12 10:40:58 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VLineEdit::focusOutEvent(QFocusEvent *e)
|
|
|
|
{
|
|
|
|
const int start = selectionStart();
|
2017-08-12 10:57:46 +02:00
|
|
|
const int selectionLength = selectedText().length();
|
2017-08-12 10:40:58 +02:00
|
|
|
const bool wasTextSelected = hasSelectedText();
|
|
|
|
|
|
|
|
QLineEdit::focusOutEvent(e);
|
|
|
|
|
|
|
|
if (wasTextSelected)
|
|
|
|
{
|
|
|
|
setSelection(start, selectionLength);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-12 10:57:46 +02:00
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VLineEdit::mousePressEvent(QMouseEvent *e)
|
|
|
|
{
|
|
|
|
QLineEdit::mousePressEvent(e);
|
|
|
|
if(m_selectOnMousePress)
|
|
|
|
{
|
|
|
|
selectAll();
|
|
|
|
m_selectOnMousePress = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-24 16:31:32 +01:00
|
|
|
// VCompleterLineEdit
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
VCompleterLineEdit::VCompleterLineEdit(QWidget *parent)
|
|
|
|
: VLineEdit(parent),
|
|
|
|
m_model(new QStringListModel(this))
|
|
|
|
{
|
|
|
|
setCompleter(new MultiSelectCompleter());
|
|
|
|
completer()->setModel(m_model);
|
|
|
|
completer()->setCompletionMode(QCompleter::PopupCompletion);
|
|
|
|
completer()->setCaseSensitivity(Qt::CaseInsensitive);
|
|
|
|
connect(this, &VCompleterLineEdit::textEdited, this, &VCompleterLineEdit::ShowCompletion);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VCompleterLineEdit::SetCompletion(const QStringList &list)
|
|
|
|
{
|
|
|
|
m_model->setStringList(list);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VCompleterLineEdit::focusInEvent(QFocusEvent *e)
|
|
|
|
{
|
|
|
|
QLineEdit::focusInEvent(e);
|
|
|
|
// force completion when line edit is focued in
|
|
|
|
completer()->complete();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VCompleterLineEdit::ShowCompletion()
|
|
|
|
{
|
|
|
|
// PrepareCompletion();
|
|
|
|
|
|
|
|
// force to show all items when text is empty
|
|
|
|
completer()->setCompletionMode(text().isEmpty() ? QCompleter::UnfilteredPopupCompletion
|
|
|
|
: QCompleter::PopupCompletion);
|
|
|
|
if (text().isEmpty())
|
|
|
|
{
|
|
|
|
// completion list will be hidden now; we will show it again after a delay
|
2022-09-08 20:00:14 +02:00
|
|
|
QTimer::singleShot(V_MSECONDS(100), this, &VCompleterLineEdit::CompletionPopup);
|
2020-03-24 16:31:32 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VCompleterLineEdit::CompletionPopup()
|
|
|
|
{
|
|
|
|
// apparently, complete() works only in event handler
|
|
|
|
QApplication::postEvent(this, new QEvent(QEvent::User));
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------------------
|
|
|
|
void VCompleterLineEdit::customEvent(QEvent *e)
|
|
|
|
{
|
|
|
|
QLineEdit::customEvent(e);
|
|
|
|
// force completion after text is deleted
|
|
|
|
completer()->complete();
|
|
|
|
}
|