Skip to content

Commit

Permalink
リポジトリURL補完機能の改良
Browse files Browse the repository at this point in the history
  • Loading branch information
soramimi committed Apr 14, 2024
1 parent 2babebd commit f956bb1
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 108 deletions.
46 changes: 36 additions & 10 deletions src/DropDownListFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@ DropDownListFrame::DropDownListFrame(QWidget *parent)
{
qApp->installEventFilter(this);
installEventFilter(this);

setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint);
auto *layout = new QVBoxLayout;
layout->setContentsMargins(0, 0, 0, 0);
setLayout(layout);
listw_ = new QListWidget;
layout->addWidget(listw_);

connect(listw_, &QListWidget::itemClicked, [this](QListWidgetItem *item) {
QString s = item->text();
emit itemClicked(item->text());
emit done();
});
}

void DropDownListFrame::addItem(const QString &text)
Expand All @@ -33,7 +39,7 @@ void DropDownListFrame::setItems(const QStringList &list)
}
}

void DropDownListFrame::show()
void DropDownListFrame::show_()
{
QWidget *par = parentWidget();
QPoint pt = par->geometry().bottomLeft();
Expand All @@ -43,31 +49,38 @@ void DropDownListFrame::show()
listw_->setFixedHeight(height);
setFixedHeight(height);
setGeometry(pt.x(), pt.y(), par->geometry().width(), height);
QFrame::show();
QFrame::setVisible(true);
activateWindow();
listw_->setFocus();
listw_->setCurrentRow(0);
}

void DropDownListFrame::setVisible(bool visible)
{
if (visible) {
show_();
} else {
QFrame::setVisible(false);
}
}

void DropDownListFrame::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
case Qt::Key_Escape:
hide();
emit done();
return;
case Qt::Key_Return:
emit itemClicked(listw_->currentItem()->text());
hide();
emit done();
return;
}
QFrame::keyPressEvent(event);
}



void DropDownListFrame::focusOutEvent(QFocusEvent *event)
{
hide();
emit done();
event->accept();
}

Expand All @@ -78,17 +91,30 @@ bool DropDownListFrame::eventFilter(QObject *watched, QEvent *event)
if (isVisible()) {
QKeyEvent *e = static_cast<QKeyEvent *>(event);
if (e->key() == Qt::Key_Tab || e->key() == Qt::Key_Backtab) {
hide();
emit done();
return true;
}
}
break;
case QEvent::WindowDeactivate:
if (watched == this) {
hide();
emit done();
return true;
}
break;
case QEvent::MouseButtonPress:
{
QWidget *w = qobject_cast<QWidget *>(watched);
if (w) {
QPoint p = static_cast<QMouseEvent *>(event)->pos();
p = w->mapToGlobal(p);
if (!geometry().contains(p)) { // clicked outside
emit done();
return true;
}
}
}
break;
}
return QFrame::eventFilter(watched, event);
}
5 changes: 4 additions & 1 deletion src/DropDownListFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@ class DropDownListFrame : public QFrame {
DropDownListFrame(QWidget *parent);
void addItem(QString const &text);
void setItems(QStringList const &list);
void show();
void show_();
protected:
bool eventFilter(QObject *watched, QEvent *event);
void focusOutEvent(QFocusEvent *event);
void keyPressEvent(QKeyEvent *event);
public slots:
void setVisible(bool visible);
signals:
void itemClicked(QString const &text);
void done();
};

#endif // DROPDOWNLISTFRAME_H
4 changes: 2 additions & 2 deletions src/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ bool MainWindow::event(QEvent *event)
return true;
}
}
} else if (et == (QEvent::Type)UserEvent::UserFunction) {
} else if (et == UserEvent(UserFunction)) {
if (auto *e = (UserFunctionEvent *)event) {
e->func(e->var, e->ptr);
return true;
Expand All @@ -660,7 +660,7 @@ bool MainWindow::event(QEvent *event)

void MainWindow::customEvent(QEvent *e)
{
if (e->type() == (QEvent::Type)UserEvent::Start) {
if (e->type() == UserEvent(Start)) {
onStartEvent();
return;
}
Expand Down
119 changes: 33 additions & 86 deletions src/RepositoryUrlLineEdit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,38 @@
#include <QStyle>
#include <QStyleOption>

class CtrlSpaceEvent : public QEvent {
namespace {

class MyEvent : public QEvent {
public:
bool forward_ = true;
CtrlSpaceEvent(bool forward)
int key = 0;
MyEvent(int key)
: QEvent(QEvent::User)
, forward_(forward)
, key(key)
{
}
};

} // namespace

struct RepositoryUrlLineEdit::Private {
QStringList url_candidates;
DropDownListFrame *drop_down_frame = nullptr;
QRect drop_down_botton_rect;
DropDownListFrame *drop_down_list = nullptr;
};

RepositoryUrlLineEdit::RepositoryUrlLineEdit(QWidget *parent)
: QLineEdit{parent}
, m{new Private}
{
m->drop_down_frame = new DropDownListFrame(this);

installEventFilter(this);

connect(m->drop_down_frame, &DropDownListFrame::itemClicked, [this](QString const &text) {
setText(text);
m->drop_down_frame->hide();
m->drop_down_list = new DropDownListFrame(this);
connect(m->drop_down_list, &DropDownListFrame::itemClicked, [this](const QString &item) {
setText(item);
});

connect(this, &QLineEdit::textChanged, [this](const QString &text) {
setText(text);
connect(m->drop_down_list, &DropDownListFrame::done, [this]() {
m->drop_down_list->close();
qApp->postEvent(this, new QFocusEvent(QEvent::FocusIn));
});
}

Expand Down Expand Up @@ -142,78 +143,21 @@ void RepositoryUrlLineEdit::setNextRepositoryUrlCandidate(bool forward)
}
}

/**
* @brief RepositoryUrlLineEdit::showDropDown
*
* ドロップダウンリストを表示する
*/
void RepositoryUrlLineEdit::showDropDown()
{
updateRepositoryUrlCandidates();
m->drop_down_frame->setItems(m->url_candidates);
m->drop_down_frame->show();
}

void RepositoryUrlLineEdit::paintEvent(QPaintEvent *event)
{
const int w = width();
const int h = height();
m->drop_down_botton_rect = QRect(w - h, 0, h, h);

QLineEdit::paintEvent(event);
QPainter pr(this);
QStyleOption opt;
opt.initFrom(this);
opt.rect = m->drop_down_botton_rect;
qApp->style()->drawPrimitive(QStyle::PE_IndicatorButtonDropDown, &opt, &pr, this);
}

void RepositoryUrlLineEdit::mouseMoveEvent(QMouseEvent *event)
{
QPoint p = event->pos();
if (m->drop_down_botton_rect.contains(p)) {
setCursor(Qt::ArrowCursor);
event->accept();
return;
}
QLineEdit::mouseMoveEvent(event);
}

void RepositoryUrlLineEdit::mousePressEvent(QMouseEvent *event)
{
QPoint p = event->pos();
if (m->drop_down_botton_rect.contains(p)) {
showDropDown();
event->accept();
return;
}
QLineEdit::mousePressEvent(event);
}

void RepositoryUrlLineEdit::mouseDoubleClickEvent(QMouseEvent *event)
{
QPoint p = event->pos();
if (m->drop_down_botton_rect.contains(p)) {
showDropDown();
event->accept();
return;
}
QLineEdit::mouseDoubleClickEvent(event);
}

void RepositoryUrlLineEdit::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Down) {
showDropDown();
}
QLineEdit::keyPressEvent(event);
}

void RepositoryUrlLineEdit::customEvent(QEvent *event)
{
if (event->type() == QEvent::User) {
CtrlSpaceEvent *e = static_cast<CtrlSpaceEvent *>(event);
setNextRepositoryUrlCandidate(e->forward_);
MyEvent *e = static_cast<MyEvent *>(event);
if (e->key == Qt::Key_Space) {
setNextRepositoryUrlCandidate(true);
return;
}
if (e->key == Qt::Key_Down) {
updateRepositoryUrlCandidates();
m->drop_down_list->setItems(m->url_candidates);
m->drop_down_list->show();
return;
}
return;
}
}

Expand All @@ -222,8 +166,11 @@ bool RepositoryUrlLineEdit::eventFilter(QObject *watched, QEvent *event)
if (event->type() == QEvent::KeyPress) {
QKeyEvent *e = static_cast<QKeyEvent *>(event);
if (e->key() == Qt::Key_Space && (e->modifiers() & Qt::ControlModifier)) {
bool forward = !(e->modifiers() & Qt::ShiftModifier);
QApplication::postEvent(this, new CtrlSpaceEvent(forward));
QApplication::postEvent(this, new MyEvent(e->key()));
return true;
}
if (e->key() == Qt::Key_Down) {
QApplication::postEvent(this, new MyEvent(e->key()));
return true;
}
}
Expand Down
6 changes: 0 additions & 6 deletions src/RepositoryUrlLineEdit.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,7 @@ class RepositoryUrlLineEdit : public QLineEdit {
struct Private;
Private *m;
void updateRepositoryUrlCandidates();
void showDropDown();
protected:
void keyPressEvent(QKeyEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
void paintEvent(QPaintEvent *event);
void customEvent(QEvent *event);
bool eventFilter(QObject *watched, QEvent *event);
public:
Expand Down
7 changes: 4 additions & 3 deletions src/UserEvent.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@
#include <QVariant>
#include <functional>

enum class UserEvent {
enum class UserEventEnum {
Start = QEvent::User,
UserFunction,
};
#define UserEvent(e) QEvent::Type(UserEventEnum::e)

class StartEvent : public QEvent {
public:
StartEvent()
: QEvent((QEvent::Type)UserEvent::Start)
: QEvent(UserEvent(Start))
{
}
};
Expand All @@ -25,7 +26,7 @@ class UserFunctionEvent : public QEvent {
void *ptr = nullptr;

explicit UserFunctionEvent(std::function<void(QVariant const &, void *ptr)> func, QVariant const &var, void *ptr = nullptr)
: QEvent((QEvent::Type)UserEvent::UserFunction)
: QEvent(UserEvent(UserFunction))
, func(func)
, var(var)
, ptr(ptr)
Expand Down

0 comments on commit f956bb1

Please sign in to comment.