KIO

kurlrequester.cpp
1/*
2 This file is part of the KDE libraries
3 SPDX-FileCopyrightText: 1999, 2000, 2001 Carsten Pfeiffer <pfeiffer@kde.org>
4 SPDX-FileCopyrightText: 2013 Teo Mrnjavac <teo@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-only
7*/
8
9#include "kurlrequester.h"
10#include "../utils_p.h"
11#include "kio_widgets_debug.h"
12
13#include <KComboBox>
14#include <KDragWidgetDecorator>
15#include <KLineEdit>
16#include <KLocalizedString>
17#include <kprotocolmanager.h>
18#include <kurlcompletion.h>
19
20#include <QAction>
21#include <QApplication>
22#include <QDrag>
23#include <QEvent>
24#include <QHBoxLayout>
25#include <QKeySequence>
26#include <QMenu>
27#include <QMimeData>
28
29#include <private/qguiapplication_p.h>
30#include <qpa/qplatformtheme.h>
31
32class KUrlDragPushButton : public QPushButton
33{
35public:
36 explicit KUrlDragPushButton(QWidget *parent)
38 {
39 new DragDecorator(this);
40 }
41 ~KUrlDragPushButton() override
42 {
43 }
44
45 void setURL(const QUrl &url)
46 {
47 m_urls.clear();
48 m_urls.append(url);
49 }
50
51private:
52 class DragDecorator : public KDragWidgetDecoratorBase
53 {
54 public:
55 explicit DragDecorator(KUrlDragPushButton *button)
57 , m_button(button)
58 {
59 }
60
61 protected:
62 QDrag *dragObject() override
63 {
64 if (m_button->m_urls.isEmpty()) {
65 return nullptr;
66 }
67
68 QDrag *drag = new QDrag(m_button);
69 QMimeData *mimeData = new QMimeData;
70 mimeData->setUrls(m_button->m_urls);
71 drag->setMimeData(mimeData);
72 return drag;
73 }
74
75 private:
76 KUrlDragPushButton *m_button;
77 };
78
79 QList<QUrl> m_urls;
80};
81
82class Q_DECL_HIDDEN KUrlRequester::KUrlRequesterPrivate
83{
84public:
85 explicit KUrlRequesterPrivate(KUrlRequester *parent)
86 : m_fileDialogModeWasDirAndFile(false)
87 , m_parent(parent)
88 , edit(nullptr)
89 , combo(nullptr)
90 , fileDialogMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly)
91 , fileDialogAcceptMode(QFileDialog::AcceptOpen)
92 {
93 }
94
95 ~KUrlRequesterPrivate()
96 {
97 delete myCompletion;
98 delete myFileDialog;
99 }
100
101 void init();
102
103 void setText(const QString &text)
104 {
105 if (combo) {
106 if (combo->isEditable()) {
107 combo->setEditText(text);
108 } else {
109 int i = combo->findText(text);
110 if (i == -1) {
111 combo->addItem(text);
112 combo->setCurrentIndex(combo->count() - 1);
113 } else {
114 combo->setCurrentIndex(i);
115 }
116 }
117 } else {
118 edit->setText(text);
119 }
120 }
121
122 void connectSignals(KUrlRequester *receiver)
123 {
124 if (combo) {
127
129 } else if (edit) {
132
133 connect(edit, qOverload<>(&QLineEdit::returnPressed), receiver, [this]() {
134 m_parent->Q_EMIT returnPressed(QString{});
135 });
136
137 if (auto kline = qobject_cast<KLineEdit *>(edit)) {
139 }
140 }
141 }
142
143 void setCompletionObject(KCompletion *comp)
144 {
145 if (combo) {
146 combo->setCompletionObject(comp);
147 } else {
148 edit->setCompletionObject(comp);
149 }
150 }
151
152 void updateCompletionStartDir(const QUrl &newStartDir)
153 {
154 myCompletion->setDir(newStartDir);
155 }
156
157 QString text() const
158 {
159 return combo ? combo->currentText() : edit->text();
160 }
161
162 /**
163 * replaces ~user or $FOO, if necessary
164 * if text() is a relative path, make it absolute using startDir()
165 */
166 QUrl url() const
167 {
168 const QString txt = text();
169 KUrlCompletion *comp;
170 if (combo) {
171 comp = qobject_cast<KUrlCompletion *>(combo->completionObject());
172 } else {
173 comp = qobject_cast<KUrlCompletion *>(edit->completionObject());
174 }
175
176 QString enteredPath;
177 if (comp) {
178 enteredPath = comp->replacedPath(txt);
179 } else {
180 enteredPath = txt;
181 }
182
183 if (Utils::isAbsoluteLocalPath(enteredPath)) {
184 return QUrl::fromLocalFile(enteredPath);
185 }
186
187 const QUrl enteredUrl = QUrl(enteredPath); // absolute or relative
188 if (enteredUrl.isRelative() && !txt.isEmpty()) {
189 QUrl finalUrl(m_startDir);
190 finalUrl.setPath(Utils::concatPaths(finalUrl.path(), enteredPath));
191 return finalUrl;
192 } else {
193 return enteredUrl;
194 }
195 }
196
197 static void applyFileMode(QFileDialog *dlg, KFile::Modes m, QFileDialog::AcceptMode acceptMode)
198 {
199 QFileDialog::FileMode fileMode;
200 bool dirsOnly = false;
201 if (m & KFile::Directory) {
202 fileMode = QFileDialog::Directory;
203 if ((m & KFile::File) == 0 && (m & KFile::Files) == 0) {
204 dirsOnly = true;
205 }
206 } else if (m & KFile::Files && m & KFile::ExistingOnly) {
208 } else if (m & KFile::File && m & KFile::ExistingOnly) {
209 fileMode = QFileDialog::ExistingFile;
210 } else {
211 fileMode = QFileDialog::AnyFile;
212 }
213
214 dlg->setFileMode(fileMode);
215 dlg->setAcceptMode(acceptMode);
216 dlg->setOption(QFileDialog::ShowDirsOnly, dirsOnly);
217 }
218
219 QUrl getDirFromFileDialog(const QUrl &openUrl) const
220 {
221 return QFileDialog::getExistingDirectoryUrl(m_parent, QString(), openUrl, QFileDialog::ShowDirsOnly);
222 }
223
224 void createFileDialog()
225 {
226 // Creates the fileDialog if it doesn't exist yet
227 QFileDialog *dlg = m_parent->fileDialog();
228
229 if (!url().isEmpty() && !url().isRelative()) {
230 QUrl u(url());
231 // If we won't be able to list it (e.g. http), then don't try :)
233 dlg->selectUrl(u);
234 }
235 } else {
236 dlg->setDirectoryUrl(m_startDir);
237 }
238
239 dlg->setAcceptMode(fileDialogAcceptMode);
240
241 // Update the file dialog window modality
242 if (dlg->windowModality() != fileDialogModality) {
243 dlg->setWindowModality(fileDialogModality);
244 }
245
246 if (fileDialogModality == Qt::NonModal) {
247 dlg->show();
248 } else {
249 dlg->exec();
250 }
251 }
252
253 // slots
254 void slotUpdateUrl();
255 void slotOpenDialog();
256 void slotFileDialogAccepted();
257
258 QUrl m_startDir;
259 bool m_startDirCustomized;
260 bool m_fileDialogModeWasDirAndFile;
261 KUrlRequester *const m_parent; // TODO: rename to 'q'
262 KLineEdit *edit;
263 KComboBox *combo;
264 KFile::Modes fileDialogMode;
265 QFileDialog::AcceptMode fileDialogAcceptMode;
266 QStringList nameFilters;
267 QStringList mimeTypeFilters;
268 KEditListWidget::CustomEditor editor;
269 KUrlDragPushButton *myButton;
270 QFileDialog *myFileDialog;
271 KUrlCompletion *myCompletion;
272 Qt::WindowModality fileDialogModality;
273};
274
276 : QWidget(parent)
277 , d(new KUrlRequesterPrivate(this))
278{
279 // must have this as parent
280 editWidget->setParent(this);
281 d->combo = qobject_cast<KComboBox *>(editWidget);
282 d->edit = qobject_cast<KLineEdit *>(editWidget);
283 if (d->edit) {
284 d->edit->setClearButtonEnabled(true);
285 }
286
287 d->init();
288}
289
291 : QWidget(parent)
292 , d(new KUrlRequesterPrivate(this))
293{
294 d->init();
295}
296
298 : QWidget(parent)
299 , d(new KUrlRequesterPrivate(this))
300{
301 d->init();
302 setUrl(url);
303}
304
306{
307 QWidget *widget = d->combo ? static_cast<QWidget *>(d->combo) : static_cast<QWidget *>(d->edit);
308 widget->removeEventFilter(this);
309}
310
311void KUrlRequester::KUrlRequesterPrivate::init()
312{
313 myFileDialog = nullptr;
314 fileDialogModality = Qt::ApplicationModal;
315
316 if (!combo && !edit) {
317 edit = new KLineEdit(m_parent);
318 edit->setClearButtonEnabled(true);
319 }
320
321 QWidget *widget = combo ? static_cast<QWidget *>(combo) : static_cast<QWidget *>(edit);
322
323 QHBoxLayout *topLayout = new QHBoxLayout(m_parent);
324 topLayout->setContentsMargins(0, 0, 0, 0);
325 topLayout->setSpacing(-1); // use default spacing
326 topLayout->addWidget(widget);
327
328 myButton = new KUrlDragPushButton(m_parent);
329 myButton->setIcon(QIcon::fromTheme(QStringLiteral("document-open")));
330 int buttonSize = myButton->sizeHint().expandedTo(widget->sizeHint()).height();
331 myButton->setFixedSize(buttonSize, buttonSize);
332 myButton->setToolTip(i18n("Open file dialog"));
333
334 connect(myButton, &KUrlDragPushButton::pressed, m_parent, [this]() {
335 slotUpdateUrl();
336 });
337
338 widget->installEventFilter(m_parent);
339 m_parent->setFocusProxy(widget);
340 m_parent->setFocusPolicy(Qt::StrongFocus);
341 topLayout->addWidget(myButton);
342
343 connectSignals(m_parent);
344 connect(myButton, &KUrlDragPushButton::clicked, m_parent, [this]() {
345 slotOpenDialog();
346 });
347
349 m_startDirCustomized = false;
350
351 myCompletion = new KUrlCompletion();
352 updateCompletionStartDir(m_startDir);
353
354 setCompletionObject(myCompletion);
355
356 QAction *openAction = new QAction(m_parent);
357 openAction->setShortcut(QKeySequence::Open);
358 m_parent->connect(openAction, &QAction::triggered, m_parent, [this]() {
359 slotOpenDialog();
360 });
361}
362
364{
365 d->setText(url.toDisplayString(QUrl::PreferLocalFile));
366}
367
369{
370 d->setText(text);
371}
372
374{
375 d->m_startDir = startDir;
376 d->m_startDirCustomized = true;
377 d->updateCompletionStartDir(startDir);
378}
379
380void KUrlRequester::changeEvent(QEvent *e)
381{
382 if (e->type() == QEvent::WindowTitleChange) {
383 if (d->myFileDialog) {
384 d->myFileDialog->setWindowTitle(windowTitle());
385 }
386 }
388}
389
390QUrl KUrlRequester::url() const
391{
392 return d->url();
393}
394
396{
397 return d->m_startDir;
398}
399
400QString KUrlRequester::text() const
401{
402 return d->text();
403}
404
405void KUrlRequester::KUrlRequesterPrivate::slotOpenDialog()
406{
407 if (myFileDialog) {
408 if (myFileDialog->isVisible()) {
409 // The file dialog is already being shown, raise it and exit
410 myFileDialog->raise();
411 myFileDialog->activateWindow();
412 return;
413 }
414 }
415
416 if (!m_fileDialogModeWasDirAndFile
417 && (((fileDialogMode & KFile::Directory) && !(fileDialogMode & KFile::File)) ||
418 /* catch possible fileDialog()->setMode( KFile::Directory ) changes */
419 (myFileDialog && (myFileDialog->fileMode() == QFileDialog::Directory && myFileDialog->testOption(QFileDialog::ShowDirsOnly))))) {
420 const QUrl openUrl = (!m_parent->url().isEmpty() && !m_parent->url().isRelative()) ? m_parent->url() : m_startDir;
421
422 /* FIXME We need a new abstract interface for using KDirSelectDialog in a non-modal way */
423
424 QUrl newUrl;
425 if (fileDialogMode & KFile::LocalOnly) {
426 newUrl = QFileDialog::getExistingDirectoryUrl(m_parent, QString(), openUrl, QFileDialog::ShowDirsOnly, QStringList() << QStringLiteral("file"));
427 } else {
428 newUrl = getDirFromFileDialog(openUrl);
429 }
430
431 if (newUrl.isValid()) {
432 m_parent->setUrl(newUrl);
433 Q_EMIT m_parent->urlSelected(url());
434 }
435 } else {
436 Q_EMIT m_parent->openFileDialog(m_parent);
437
438 if (((fileDialogMode & KFile::Directory) && (fileDialogMode & KFile::File)) || m_fileDialogModeWasDirAndFile) {
439 QMenu *dirOrFileMenu = new QMenu();
440 QAction *fileAction = new QAction(QIcon::fromTheme(QStringLiteral("document-new")), i18n("File"));
441 QAction *dirAction = new QAction(QIcon::fromTheme(QStringLiteral("folder-new")), i18n("Directory"));
442 dirOrFileMenu->addAction(fileAction);
443 dirOrFileMenu->addAction(dirAction);
444
445 connect(fileAction, &QAction::triggered, [this]() {
446 fileDialogMode = KFile::File;
447 applyFileMode(m_parent->fileDialog(), fileDialogMode, fileDialogAcceptMode);
448 m_fileDialogModeWasDirAndFile = true;
449 createFileDialog();
450 });
451
452 connect(dirAction, &QAction::triggered, [this]() {
453 fileDialogMode = KFile::Directory;
454 applyFileMode(m_parent->fileDialog(), fileDialogMode, fileDialogAcceptMode);
455 m_fileDialogModeWasDirAndFile = true;
456 createFileDialog();
457 });
458
459 dirOrFileMenu->exec(m_parent->mapToGlobal(QPoint(m_parent->width(), m_parent->height())));
460
461 return;
462 }
463
464 createFileDialog();
465 }
466}
467
468void KUrlRequester::KUrlRequesterPrivate::slotFileDialogAccepted()
469{
470 if (!myFileDialog) {
471 return;
472 }
473
474 const QUrl newUrl = myFileDialog->selectedUrls().constFirst();
475 if (newUrl.isValid()) {
476 m_parent->setUrl(newUrl);
477 Q_EMIT m_parent->urlSelected(url());
478 // remember url as defaultStartDir and update startdir for autocompletion
479 if (newUrl.isLocalFile() && !m_startDirCustomized) {
480 m_startDir = newUrl.adjusted(QUrl::RemoveFilename);
481 updateCompletionStartDir(m_startDir);
482 }
483 }
484}
485
487{
488 Q_ASSERT((mode & KFile::Files) == 0);
489 d->fileDialogMode = mode;
490 if ((mode & KFile::Directory) && !(mode & KFile::File)) {
491 d->myCompletion->setMode(KUrlCompletion::DirCompletion);
492 }
493
494 if (d->myFileDialog) {
495 d->applyFileMode(d->myFileDialog, mode, d->fileDialogAcceptMode);
496 }
497}
498
499KFile::Modes KUrlRequester::mode() const
500{
501 return d->fileDialogMode;
502}
503
505{
506 d->fileDialogAcceptMode = mode;
507
508 if (d->myFileDialog) {
509 d->applyFileMode(d->myFileDialog, d->fileDialogMode, mode);
510 }
511}
512
513QFileDialog::AcceptMode KUrlRequester::acceptMode() const
514{
515 return d->fileDialogAcceptMode;
516}
517
519{
520 return d->nameFilters;
521}
522
524{
525 d->nameFilters = filters;
526
527 if (d->myFileDialog) {
528 d->myFileDialog->setNameFilters(d->nameFilters);
529 }
530}
531
533{
534 if (filter.isEmpty()) {
536 return;
537 }
538
539 // by default use ";;" as separator
540 // if not present, support alternatively "\n" (matching QFileDialog behaviour)
541 // if also not present split() will simply return the string passed in
542 QString separator = QStringLiteral(";;");
543 if (!filter.contains(separator)) {
544 separator = QStringLiteral("\n");
545 }
546 setNameFilters(filter.split(separator));
547}
548
550{
551 d->mimeTypeFilters = mimeTypes;
552
553 if (d->myFileDialog) {
554 d->myFileDialog->setMimeTypeFilters(d->mimeTypeFilters);
555 }
556 d->myCompletion->setMimeTypeFilters(d->mimeTypeFilters);
557}
558
560{
561 return d->mimeTypeFilters;
562}
563
565{
566 if (d->myFileDialog
567 && ((d->myFileDialog->fileMode() == QFileDialog::Directory && !(d->fileDialogMode & KFile::Directory))
568 || (d->myFileDialog->fileMode() != QFileDialog::Directory && (d->fileDialogMode & KFile::Directory)))) {
569 delete d->myFileDialog;
570 d->myFileDialog = nullptr;
571 }
572
573 if (!d->myFileDialog) {
574 d->myFileDialog = new QFileDialog(window(), windowTitle());
575 if (!d->mimeTypeFilters.isEmpty()) {
576 QStringList mimeTypeFilters = d->mimeTypeFilters;
577 // The non plasma file dialogs don't have the "All Supported types" feature, so add the "All Files" type for them if more than one
578 // file type type is possible
579 if (mimeTypeFilters.count() > 1 && !mimeTypeFilters.contains(QStringLiteral("application/octet-stream"))
580 && QGuiApplicationPrivate::platformTheme()->name() != QStringLiteral("kde")) {
581 mimeTypeFilters.prepend(QStringLiteral("application/octet-stream"));
582 }
583 d->myFileDialog->setMimeTypeFilters(mimeTypeFilters);
584 } else {
585 d->myFileDialog->setNameFilters(d->nameFilters);
586 }
587
588 d->applyFileMode(d->myFileDialog, d->fileDialogMode, d->fileDialogAcceptMode);
589
590 d->myFileDialog->setWindowModality(d->fileDialogModality);
591 connect(d->myFileDialog, &QFileDialog::accepted, this, [this]() {
592 d->slotFileDialogAccepted();
593 });
594 }
595
596 return d->myFileDialog;
597}
598
600{
601 d->setText(QString());
602}
603
605{
606 return d->edit;
607}
608
610{
611 return d->combo;
612}
613
614void KUrlRequester::KUrlRequesterPrivate::slotUpdateUrl()
615{
616 const QUrl visibleUrl = url();
617 QUrl u = visibleUrl;
618 if (visibleUrl.isRelative()) {
620 }
621 myButton->setURL(u);
622}
623
624bool KUrlRequester::eventFilter(QObject *obj, QEvent *ev)
625{
626 if ((d->edit == obj) || (d->combo == obj)) {
627 if ((ev->type() == QEvent::FocusIn) || (ev->type() == QEvent::FocusOut))
628 // Forward focusin/focusout events to the urlrequester; needed by file form element in khtml
629 {
630 QApplication::sendEvent(this, ev);
631 }
632 }
633 return QWidget::eventFilter(obj, ev);
634}
635
637{
638 return d->myButton;
639}
640
642{
643 return d->myCompletion;
644}
645
647{
648 if (d->edit) {
649 d->edit->setPlaceholderText(msg);
650 }
651}
652
653QString KUrlRequester::placeholderText() const
654{
655 if (d->edit) {
656 return d->edit->placeholderText();
657 } else {
658 return QString();
659 }
660}
661
662Qt::WindowModality KUrlRequester::fileDialogModality() const
663{
664 return d->fileDialogModality;
665}
666
668{
669 d->fileDialogModality = modality;
670}
671
673{
675
676 KLineEdit *edit = d->edit;
677 if (!edit && d->combo) {
678 edit = qobject_cast<KLineEdit *>(d->combo->lineEdit());
679 }
680
681#ifndef NDEBUG
682 if (!edit) {
683 qCWarning(KIO_WIDGETS) << "KUrlRequester's lineedit is not a KLineEdit!??\n";
684 }
685#endif
686
687 d->editor.setRepresentationWidget(this);
688 d->editor.setLineEdit(edit);
689 return d->editor;
690}
691
692KUrlComboRequester::KUrlComboRequester(QWidget *parent)
693 : KUrlRequester(new KComboBox(false), parent)
694 , d(nullptr)
695{
696}
697
698#include "kurlrequester.moc"
699#include "moc_kurlrequester.cpp"
void returnPressed(const QString &text)
KDragWidgetDecoratorBase(QWidget *parent=nullptr)
QFlags< Mode > Modes
Stores a combination of Mode values.
Definition kfile.h:47
void returnKeyPressed(const QString &text)
static bool supportsListing(const QUrl &url)
Returns whether the protocol can list files/objects.
This class does completion of URLs including user directories (~user) and environment variables.
QString replacedPath(const QString &text) const
Replaces username and/or environment variables, depending on the current settings and returns the fil...
This class is a widget showing a lineedit and a button, which invokes a filedialog.
void setFileDialogModality(Qt::WindowModality modality)
Set the window modality for the file dialog to modality Directory selection dialogs are always modal.
void setUrl(const QUrl &url)
Sets the url in the lineedit to url.
void setStartDir(const QUrl &startDir)
Sets the start dir startDir.
QPushButton * button() const
void setNameFilter(const QString &filter)
Sets the filters for the file dialog.
QStringList nameFilters
void clear()
Clears the lineedit/combobox.
~KUrlRequester() override
Destructs the KUrlRequester.
const KEditListWidget::CustomEditor & customEditor()
virtual QFileDialog * fileDialog() const
void setMode(KFile::Modes mode)
Sets the mode of the file dialog.
KLineEdit * lineEdit() const
KUrlCompletion * completionObject() const
void setText(const QString &text)
Sets the current text in the lineedit or combobox.
void setMimeTypeFilters(const QStringList &mimeTypes)
Sets the MIME type filters for the file dialog.
QUrl startDir() const
void textChanged(const QString &)
Emitted when the text in the lineedit changes.
void returnPressed(const QString &text)
Emitted when return or enter was pressed in the lineedit.
void setAcceptMode(QFileDialog::AcceptMode m)
Sets the open / save mode of the file dialog.
KUrlRequester(QWidget *parent=nullptr)
Constructs a KUrlRequester widget.
KComboBox * comboBox() const
void textEdited(const QString &)
Emitted when the text in the lineedit was modified by the user.
void setNameFilters(const QStringList &filters)
Sets the filters for the file dialog.
void setPlaceholderText(const QString &msg)
This makes the KUrlRequester line edit display a grayed-out hinting text as long as the user didn't e...
QStringList mimeTypeFilters() const
Returns the MIME type filters for the file dialog.
QString i18n(const char *text, const TYPE &arg...)
void init(KXmlGuiWindow *window, KGameDifficulty *difficulty=nullptr)
void clicked(bool checked)
void setShortcut(const QKeySequence &shortcut)
void triggered(bool checked)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
virtual void setSpacing(int spacing) override
void currentTextChanged(const QString &text)
void editTextChanged(const QString &text)
bool sendEvent(QObject *receiver, QEvent *event)
void accepted()
virtual int exec()
QString currentPath()
void setMimeData(QMimeData *data)
WindowTitleChange
Type type() const const
void setAcceptMode(AcceptMode mode)
void setFileMode(FileMode mode)
QUrl getExistingDirectoryUrl(QWidget *parent, const QString &caption, const QUrl &dir, Options options, const QStringList &supportedSchemes)
void selectUrl(const QUrl &url)
void setDirectoryUrl(const QUrl &directory)
void setOption(Option option, bool on)
QIcon fromTheme(const QString &name)
void setContentsMargins(const QMargins &margins)
void setClearButtonEnabled(bool enable)
void returnPressed()
void textChanged(const QString &text)
void textEdited(const QString &text)
QAction * addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut)
QAction * exec()
void setUrls(const QList< QUrl > &urls)
QObject(QObject *parent)
Q_EMITQ_EMIT
Q_OBJECTQ_OBJECT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
virtual bool eventFilter(QObject *watched, QEvent *event)
void installEventFilter(QObject *filterObj)
QObject * parent() const const
T qobject_cast(QObject *object)
void removeEventFilter(QObject *obj)
QPushButton(QWidget *parent)
bool isEmpty() const const
StrongFocus
NonModal
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
PreferLocalFile
QUrl adjusted(FormattingOptions options) const const
QUrl fromLocalFile(const QString &localFile)
bool isLocalFile() const const
bool isRelative() const const
bool isValid() const const
QUrl resolved(const QUrl &relative) const const
QString url(FormattingOptions options) const const
QWidget(QWidget *parent, Qt::WindowFlags f)
virtual void changeEvent(QEvent *event)
void setParent(QWidget *parent)
void show()
void setSizePolicy(QSizePolicy)
QWidget * window() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Feb 28 2025 11:52:09 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.