1 /**************************************************************************
2 * Otter Browser: Web browser controlled by the user, not vice-versa.
3 * Copyright (C) 2013 - 2017 Michal Dutkiewicz aka Emdek <michal@emdek.pl>
4 * Copyright (C) 2016 Piotr Wójcik <chocimier@tlen.pl>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 **************************************************************************/
20 
21 #include "FilePathWidget.h"
22 #include "LineEditWidget.h"
23 #include "../core/Utils.h"
24 
25 #include <QtCore/QEvent>
26 #include <QtCore/QStandardPaths>
27 #include <QtWidgets/QHBoxLayout>
28 
29 namespace Otter
30 {
31 
FileSystemCompleterModel(QObject * parent)32 FileSystemCompleterModel::FileSystemCompleterModel(QObject *parent) : QFileSystemModel(parent)
33 {
34 	setFilter(QDir::NoDotAndDotDot | QDir::AllDirs);
35 	setRootPath(QString());
36 }
37 
data(const QModelIndex & index,int role) const38 QVariant FileSystemCompleterModel::data(const QModelIndex &index, int role) const
39 {
40 	if (role == Qt::DisplayRole && index.column() == 0)
41 	{
42 		return QDir::toNativeSeparators(filePath(index));
43 	}
44 
45 	return QFileSystemModel::data(index, role);
46 }
47 
FilePathWidget(QWidget * parent)48 FilePathWidget::FilePathWidget(QWidget *parent) : QWidget(parent),
49 	m_browseButton(new QPushButton(tr("Browse…"), this)),
50 	m_lineEditWidget(new LineEditWidget(this)),
51 	m_completer(nullptr),
52 	m_selectFile(true)
53 {
54 	QHBoxLayout *layout(new QHBoxLayout(this));
55 	layout->addWidget(m_lineEditWidget);
56 	layout->addWidget(m_browseButton);
57 	layout->setContentsMargins(0, 0, 0, 0);
58 
59 	setLayout(layout);
60 	setFocusPolicy(Qt::StrongFocus);
61 	setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
62 
63 	connect(m_lineEditWidget, &LineEditWidget::textEdited, this, &FilePathWidget::updateCompleter);
64 	connect(m_lineEditWidget, &LineEditWidget::textChanged, this, &FilePathWidget::pathChanged);
65 	connect(m_browseButton, &QPushButton::clicked, this, &FilePathWidget::selectPath);
66 }
67 
changeEvent(QEvent * event)68 void FilePathWidget::changeEvent(QEvent *event)
69 {
70 	QWidget::changeEvent(event);
71 
72 	if (event->type() == QEvent::LanguageChange)
73 	{
74 		m_browseButton->setText(tr("Browse…"));
75 	}
76 }
77 
focusInEvent(QFocusEvent * event)78 void FilePathWidget::focusInEvent(QFocusEvent *event)
79 {
80 	QWidget::focusInEvent(event);
81 
82 	m_lineEditWidget->setFocus();
83 }
84 
selectPath()85 void FilePathWidget::selectPath()
86 {
87 	QString path(m_lineEditWidget->text().isEmpty() ? QStandardPaths::standardLocations(QStandardPaths::HomeLocation).value(0) : m_lineEditWidget->text());
88 	path = (m_selectFile ? QFileDialog::getOpenFileName(this, tr("Select File"), path, m_filter) : QFileDialog::getExistingDirectory(this, tr("Select Directory"), path));
89 
90 	if (!path.isEmpty())
91 	{
92 		m_lineEditWidget->setText(QDir::toNativeSeparators(path));
93 	}
94 }
95 
updateCompleter()96 void FilePathWidget::updateCompleter()
97 {
98 	if (!m_completer)
99 	{
100 		m_completer = new QCompleter(this);
101 
102 		FileSystemCompleterModel *model(new FileSystemCompleterModel(m_completer));
103 		model->setFilter(m_selectFile ? (QDir::AllDirs | QDir::Files) : QDir::AllDirs);
104 
105 		m_completer->setModel(model);
106 
107 		m_lineEditWidget->setCompleter(m_completer);
108 
109 		m_completer->complete();
110 
111 		disconnect(m_lineEditWidget, &LineEditWidget::textEdited, this, &FilePathWidget::updateCompleter);
112 	}
113 }
114 
setFilters(const QStringList & filters)115 void FilePathWidget::setFilters(const QStringList &filters)
116 {
117 	m_filter = Utils::formatFileTypes(filters);
118 }
119 
setSelectFile(bool mode)120 void FilePathWidget::setSelectFile(bool mode)
121 {
122 	m_selectFile = mode;
123 }
124 
setPath(const QString & path)125 void FilePathWidget::setPath(const QString &path)
126 {
127 	m_lineEditWidget->setText(path);
128 }
129 
getPath() const130 QString FilePathWidget::getPath() const
131 {
132 	return m_lineEditWidget->text();
133 }
134 
135 }
136