1 /*
2 # PostgreSQL Database Modeler (pgModeler)
3 #
4 # Copyright 2006-2020 - Raphael Araújo e Silva <raphael@pgmodeler.io>
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 version 3.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # The complete text of GPLv3 is at LICENSE file on source code root directory.
16 # Also, you can get the complete GNU General Public License at <http://www.gnu.org/licenses/>
17 */
18
19 #include "fileselectorwidget.h"
20 #include "pgmodeleruins.h"
21
FileSelectorWidget(QWidget * parent)22 FileSelectorWidget::FileSelectorWidget(QWidget *parent) : QWidget(parent)
23 {
24 setupUi(this);
25 allow_filename_input = read_only = false;
26
27 file_dlg.setWindowIcon(QPixmap(PgModelerUiNs::getIconPath("pgsqlModeler48x48")));
28
29 filename_edt->setReadOnly(true);
30 filename_edt->installEventFilter(this);
31
32 warn_ico_lbl = new QLabel(this);
33 warn_ico_lbl->setVisible(false);
34 warn_ico_lbl->setMinimumSize(filename_edt->height(), filename_edt->height());
35 warn_ico_lbl->setMaximumSize(warn_ico_lbl->minimumSize());
36 warn_ico_lbl->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
37 warn_ico_lbl->setScaledContents(true);
38 warn_ico_lbl->setPixmap(QPixmap(PgModelerUiNs::getIconPath("msgbox_alerta")));
39 warn_ico_lbl->setToolTip(tr("No such file or directory!"));
40
41 connect(sel_file_tb, SIGNAL(clicked(bool)), this, SLOT(openFileDialog()));
42 connect(rem_file_tb, SIGNAL(clicked(bool)), this, SLOT(clearSelector()));
43 connect(filename_edt, &QLineEdit::textChanged, [&](const QString &text){
44 rem_file_tb->setEnabled(!text.isEmpty());
45 validateSelectedFile();
46 emit s_selectorChanged(!text.isEmpty());
47 });
48 }
49
eventFilter(QObject * obj,QEvent * evnt)50 bool FileSelectorWidget::eventFilter(QObject *obj, QEvent *evnt)
51 {
52 if(isEnabled() && evnt->type() == QEvent::FocusIn &&
53 QApplication::mouseButtons() == Qt::LeftButton && obj == filename_edt)
54 {
55 QFocusEvent *focus_evnt = dynamic_cast<QFocusEvent *>(evnt);
56
57 if(!allow_filename_input && !read_only && focus_evnt->reason() == Qt::MouseFocusReason)
58 {
59 openFileDialog();
60 return true;
61 }
62 }
63
64 return QWidget::eventFilter(obj, evnt);
65 }
66
resizeEvent(QResizeEvent *)67 void FileSelectorWidget::resizeEvent(QResizeEvent *)
68 {
69 warn_ico_lbl->move(filename_edt->width() - warn_ico_lbl->width(),
70 (filename_edt->height() - warn_ico_lbl->height())/2);
71 }
72
setAllowFilenameInput(bool allow_fl_input)73 void FileSelectorWidget::setAllowFilenameInput(bool allow_fl_input)
74 {
75 allow_filename_input = allow_fl_input && !read_only;
76 filename_edt->setReadOnly(!allow_filename_input);
77 }
78
setFileMode(QFileDialog::FileMode file_mode)79 void FileSelectorWidget::setFileMode(QFileDialog::FileMode file_mode)
80 {
81 // Forcing the ExistingFile (single file selection) if multiple file selection is provided
82 if(file_mode == QFileDialog::ExistingFiles)
83 file_mode = QFileDialog::ExistingFile;
84 else if(file_mode == QFileDialog::Directory)
85 file_mode = QFileDialog::DirectoryOnly;
86
87 file_dlg.setFileMode(file_mode);
88 validateSelectedFile();
89 }
90
setAcceptMode(QFileDialog::AcceptMode accept_mode)91 void FileSelectorWidget::setAcceptMode(QFileDialog::AcceptMode accept_mode)
92 {
93 file_dlg.setAcceptMode(accept_mode);
94 }
95
setNameFilters(const QStringList & filters)96 void FileSelectorWidget::setNameFilters(const QStringList &filters)
97 {
98 file_dlg.setNameFilters(filters);
99 }
100
setFileDialogTitle(const QString & title)101 void FileSelectorWidget::setFileDialogTitle(const QString &title)
102 {
103 file_dlg.setWindowTitle(title);
104 }
105
setSelectedFile(const QString & file)106 void FileSelectorWidget::setSelectedFile(const QString &file)
107 {
108 filename_edt->setText(file);
109 }
110
setMimeTypeFilters(const QStringList & filters)111 void FileSelectorWidget::setMimeTypeFilters(const QStringList &filters)
112 {
113 file_dlg.setMimeTypeFilters(filters);
114 }
115
setDefaultSuffix(const QString & suffix)116 void FileSelectorWidget::setDefaultSuffix(const QString &suffix)
117 {
118 file_dlg.setDefaultSuffix(suffix);
119 }
120
hasWarning()121 bool FileSelectorWidget::hasWarning()
122 {
123 QString str = warn_ico_lbl->toolTip();
124 return !warn_ico_lbl->toolTip().isEmpty();
125 }
126
getSelectedFile()127 QString FileSelectorWidget::getSelectedFile()
128 {
129 return filename_edt->text();
130 }
131
clearCustomWarning()132 void FileSelectorWidget::clearCustomWarning()
133 {
134 warn_ico_lbl->setToolTip("");
135 showWarning();
136 }
137
setReadOnly(bool value)138 void FileSelectorWidget::setReadOnly(bool value)
139 {
140 read_only = value;
141 filename_edt->setReadOnly(value);
142 allow_filename_input = false;
143
144 sel_file_tb->setToolTip(value ? tr("Open in file manager") : tr("Select file"));
145 rem_file_tb->setVisible(!value);
146
147 if(value)
148 {
149 disconnect(sel_file_tb, SIGNAL(clicked(bool)), this, SLOT(openFileDialog()));
150 connect(sel_file_tb, SIGNAL(clicked(bool)), this, SLOT(openFileExternally()));
151 }
152 else
153 {
154 connect(sel_file_tb, SIGNAL(clicked(bool)), this, SLOT(openFileDialog()));
155 disconnect(sel_file_tb, SIGNAL(clicked(bool)), this, SLOT(openFileExternally()));
156 }
157 }
158
setToolTip(const QString & tooltip)159 void FileSelectorWidget::setToolTip(const QString &tooltip)
160 {
161 filename_edt->setToolTip(tooltip);
162 }
163
setCustomWarning(const QString & warn_msg)164 void FileSelectorWidget::setCustomWarning(const QString &warn_msg)
165 {
166 warn_ico_lbl->setToolTip(warn_msg);
167 showWarning();
168 }
169
openFileDialog()170 void FileSelectorWidget::openFileDialog()
171 {
172 filename_edt->clearFocus();
173 file_dlg.selectFile(filename_edt->text());
174 file_dlg.exec();
175
176 if(file_dlg.result() == QDialog::Accepted && !file_dlg.selectedFiles().isEmpty())
177 {
178 filename_edt->setText(file_dlg.selectedFiles().at(0));
179 emit s_fileSelected(file_dlg.selectedFiles().at(0));
180 }
181 }
182
openFileExternally()183 void FileSelectorWidget::openFileExternally()
184 {
185 QDesktopServices::openUrl(QUrl(QString("file://") + filename_edt->text()));
186 }
187
showWarning()188 void FileSelectorWidget::showWarning()
189 {
190 QPalette pal;
191 int padding = 0;
192 bool has_warn = !warn_ico_lbl->toolTip().isEmpty();
193
194 warn_ico_lbl->setVisible(has_warn);
195
196 if(has_warn)
197 {
198 pal.setColor(QPalette::Text, QColor(255, 0, 0));
199 padding = warn_ico_lbl->width();
200 }
201 else
202 pal = qApp->palette();
203
204 filename_edt->setStyleSheet(QString("padding: 2px %1px 2px 1px").arg(padding));
205 filename_edt->setPalette(pal);
206 }
207
validateSelectedFile()208 void FileSelectorWidget::validateSelectedFile()
209 {
210 QFileInfo fi(filename_edt->text());
211 warn_ico_lbl->setToolTip("");
212
213 if(!filename_edt->text().isEmpty())
214 {
215 if(fi.exists() && fi.isDir() && file_dlg.fileMode() != QFileDialog::DirectoryOnly)
216 warn_ico_lbl->setToolTip(tr("The provided path is not a file!"));
217 else if(fi.exists() && fi.isFile() && file_dlg.fileMode() == QFileDialog::DirectoryOnly)
218 warn_ico_lbl->setToolTip(tr("The provided path is not a directory!"));
219 else if(!fi.exists() && file_dlg.fileMode() != QFileDialog::AnyFile)
220 {
221 if(file_dlg.fileMode() == QFileDialog::DirectoryOnly)
222 warn_ico_lbl->setToolTip(tr("No such directory!"));
223 else
224 warn_ico_lbl->setToolTip(tr("No such file!"));
225 }
226 }
227
228 showWarning();
229 }
230
clearSelector()231 void FileSelectorWidget::clearSelector()
232 {
233 filename_edt->clear();
234 filename_edt->clearFocus();
235 rem_file_tb->setEnabled(false);
236
237 emit s_selectorCleared();
238 emit s_selectorChanged(false);
239 }
240