1 /***************************************************************************
2                           getfilenamewidget  -  description
3                              -------------------
4     begin                : Tue Aug 24 2004
5     copyright            : (C) 2004, 2007, 2009, 2010, 2012, 2015 by Thomas Friedrichsmeier
6     email                : thomas.friedrichsmeier@kdemail.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 #include "getfilenamewidget.h"
18 
19 #include <qlabel.h>
20 #include <QVBoxLayout>
21 #include <QFileDialog>
22 
23 #include <KLocalizedString>
24 #include <kurlrequester.h>
25 #include <KLineEdit>
26 
27 #include "../settings/rksettingsmodulegeneral.h"
28 
29 #include "../debug.h"
30 
GetFileNameWidget(QWidget * parent,FileType mode,bool only_local,const QString & label,const QString & caption,const QString & initial)31 GetFileNameWidget::GetFileNameWidget (QWidget *parent, FileType mode, bool only_local, const QString &label, const QString &caption, const QString &initial) : QWidget (parent) {
32 	RK_TRACE (MISC);
33 	QVBoxLayout *vbox = new QVBoxLayout (this);
34 	vbox->setContentsMargins (0, 0, 0, 0);
35 	vbox->setSizeConstraint (QLayout::SetMinimumSize);
36 
37 	if (!label.isEmpty ()) vbox->addWidget (new QLabel (label, this));
38 
39 	edit = new KUrlRequester (this);
40 	vbox->addWidget (edit);
41 
42 	_mode = mode;
43 	KFile::Modes mode_flags;
44 	if (mode == ExistingDirectory) {
45 		mode_flags = KFile::Directory | KFile::ExistingOnly;
46 #ifdef Q_OS_WIN
47 		// KF5 TODO: Still needed?
48 		// TODO: Hang on Windows when trying to select any dir (also in KFileDialog::getExistingDirectory ()). KDE 4.10
49 		// this hack works around this, by using QFileDialog::getExistingDirectory ().
50 		edit->button ()->disconnect (SIGNAL (clicked())); // Use old and new syntax, as we don't know, which way it was connected
51 		disconnect (edit->button (), &QPushButton::clicked, 0, 0);
52 		connect (edit->button (), &QPushButton::clicked, this, &GetFileNameWidget::hackOverrideDirDialog);
53 #endif
54 	} else if (mode == ExistingFile) {
55 		mode_flags = KFile::File | KFile::ExistingOnly;
56 	} else if (mode == SaveFile) {
57 		mode_flags = KFile::File;
58 	} else {
59 		RK_ASSERT (false);
60 	}
61 	if (only_local) mode_flags |= KFile::LocalOnly;
62 	edit->setMode (mode_flags);
63 
64 	QString append = initial;
65 	if (initial.startsWith ('<')) {
66 		storage_key = initial.section ('>', 0, 0).mid (1);
67 		append = initial.section ('>', 1);
68 	}
69 	QUrl initial_url = RKSettingsModuleGeneral::lastUsedUrlFor (storage_key);  // storage_key == QString () in the default case is intended
70 	if (!append.isEmpty ()) {
71 		if (initial_url.isLocalFile ()) {
72 			initial_url = QUrl::fromUserInput (append, initial_url.toLocalFile (), QUrl::AssumeLocalFile);
73 		} else {
74 			initial_url.setPath (initial_url.path () + '/' + append);
75 		}
76 		initial_url = initial_url.adjusted (QUrl::NormalizePathSegments);
77 	}
78 	if (initial_url.isLocalFile () || !only_local) {
79 		if (!initial.isEmpty ()) edit->setUrl (initial_url);
80 		else edit->setStartDir (initial_url);
81 	}
82 
83 	connect (edit, &KUrlRequester::textChanged, this, &GetFileNameWidget::locationEditChanged);
84 	connect (edit, &KUrlRequester::urlSelected, this, &GetFileNameWidget::updateLastUsedUrl);
85 
86 	if (caption.isEmpty ()) edit->setWindowTitle (label);
87 	else edit->setWindowTitle (caption);
88 }
89 
~GetFileNameWidget()90 GetFileNameWidget::~GetFileNameWidget () {
91 	RK_TRACE (MISC);
92 }
93 
setFilter(const QString & filter)94 void GetFileNameWidget::setFilter (const QString &filter) {
95 	RK_TRACE (MISC);
96 
97 	RK_ASSERT (edit);
98 	edit->setFilter (filter);
99 }
100 
updateLastUsedUrl(const QUrl & url)101 void GetFileNameWidget::updateLastUsedUrl (const QUrl& url) {
102 	RK_TRACE (MISC);
103 
104 	if (!url.isValid ()) return;
105 	if (edit->mode () & KFile::Directory) RKSettingsModuleGeneral::updateLastUsedUrl (storage_key, url);
106 	else RKSettingsModuleGeneral::updateLastUsedUrl (storage_key, url.adjusted (QUrl::RemoveFilename));
107 }
108 
setLocation(const QString & new_location)109 void GetFileNameWidget::setLocation (const QString &new_location) {
110 	RK_TRACE (MISC);
111 
112 	if (edit->text () != new_location) edit->setUrl (QUrl::fromUserInput (new_location, QString (), QUrl::AssumeLocalFile));
113 }
114 
115 #ifdef Q_OS_WIN
hackOverrideDirDialog()116 void GetFileNameWidget::hackOverrideDirDialog () {
117 	RK_TRACE (MISC);
118 
119 	// TODO: Hang on Windows when trying to select any dir using (K|Q)FileDialog::getExistingDirectory (). KDE 4.10
120 	QFileDialog dummy (this, edit->windowTitle (), edit->startDir ().toLocalFile ());
121 	dummy.setFileMode (QFileDialog::Directory);
122 	dummy.setOptions (QFileDialog::ShowDirsOnly);
123 	if (dummy.exec ()) {
124 		edit->setUrl (QUrl::fromLocalFile (dummy.selectedFiles ().value (0)));
125 		emit (locationChanged ());
126 	}
127 }
128 #endif
129 
locationEditChanged(const QString &)130 void GetFileNameWidget::locationEditChanged (const QString &) {
131 	RK_TRACE (MISC);
132 	emit (locationChanged ());
133 }
134 
getLocation()135 QString GetFileNameWidget::getLocation () {
136 	if (edit->url ().isLocalFile ()) return (edit->url ().toLocalFile ());
137 	return (edit->url ().url ());
138 }
139 
setBackgroundColor(const QColor & color)140 void GetFileNameWidget::setBackgroundColor (const QColor & color) {
141 	RK_TRACE (MISC);
142 
143 	QPalette palette = edit->lineEdit ()->palette ();
144 	palette.setColor (edit->lineEdit ()->backgroundRole (), color);
145 	edit->lineEdit ()->setPalette (palette);
146 }
147 
148