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