summaryrefslogtreecommitdiff
path: root/src/libs/utils/pathchooser.h
blob: 4fb31599a161fc7711fff35f925bac52e2fd56a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0

#pragma once

#include "utils_global.h"

#include "fancylineedit.h"
#include "filepath.h"

#include <QWidget>

QT_BEGIN_NAMESPACE
class QAbstractButton;
class QLineEdit;
QT_END_NAMESPACE

namespace Utils {

class CommandLine;
class MacroExpander;
class Environment;
class EnvironmentChange;
class PathChooserPrivate;

class QTCREATOR_UTILS_EXPORT PathChooser : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(QString path READ path WRITE setPath NOTIFY textChanged DESIGNABLE true)
    Q_PROPERTY(QString promptDialogTitle READ promptDialogTitle WRITE setPromptDialogTitle DESIGNABLE true)
    Q_PROPERTY(QString promptDialogFilter READ promptDialogFilter WRITE setPromptDialogFilter DESIGNABLE true)
    Q_PROPERTY(Kind expectedKind READ expectedKind WRITE setExpectedKind DESIGNABLE true)
    Q_PROPERTY(Utils::FilePath baseDirectory READ baseDirectory WRITE setBaseDirectory DESIGNABLE true)
    Q_PROPERTY(QStringList commandVersionArguments READ commandVersionArguments WRITE setCommandVersionArguments)
    Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly DESIGNABLE true)
    // Designer does not know this type, so force designable to false:
    Q_PROPERTY(Utils::FilePath filePath READ filePath WRITE setFilePath DESIGNABLE false)

public:
    static QString browseButtonLabel();

    explicit PathChooser(QWidget *parent = nullptr);
    ~PathChooser() override;

    enum Kind {
        ExistingDirectory,
        Directory, // A directory, doesn't need to exist
        File,
        SaveFile,
        ExistingCommand, // A command that must exist at the time of selection
        Command, // A command that may or may not exist at the time of selection (e.g. result of a build)
        Any
    };
    Q_ENUM(Kind)

    // Default is <ExistingDirectory>
    void setExpectedKind(Kind expected);
    Kind expectedKind() const;

    void setPromptDialogTitle(const QString &title);
    QString promptDialogTitle() const;

    void setPromptDialogFilter(const QString &filter);
    QString promptDialogFilter() const;

    void setInitialBrowsePathBackup(const FilePath &path);

    bool isValid() const;
    QString errorMessage() const;

    FilePath filePath() const; // Close to what's in the line edit.
    FilePath absoluteFilePath() const; // Relative paths resolved wrt the specified base dir.

    FilePath rawFilePath() const; // The raw unexpanded input as FilePath.

    static QString expandedDirectory(const QString &input, const Environment &env,
                                     const QString &baseDir);

    FilePath baseDirectory() const;
    void setBaseDirectory(const FilePath &base);

    void setEnvironmentChange(const EnvironmentChange &change);

    /** Returns the suggested label title when used in a form layout. */
    static QString label();

    FancyLineEdit::ValidationFunction defaultValidationFunction() const;
    void setValidationFunction(const FancyLineEdit::ValidationFunction &fn);

    /** Return the home directory, which needs some fixing under Windows. */
    static FilePath homePath();

    void addButton(const QString &text, QObject *context, const std::function<void()> &callback);
    void insertButton(int index, const QString &text, QObject *context, const std::function<void()> &callback);
    QAbstractButton *buttonAtIndex(int index) const;

    FancyLineEdit *lineEdit() const;

    // For PathChoosers of 'Command' type, this property specifies the arguments
    // required to obtain the tool version (commonly, '--version'). Setting them
    // causes the version to be displayed as a tooltip.
    QStringList commandVersionArguments() const;
    void setCommandVersionArguments(const QStringList &arguments);

    // Utility to run a tool and return its stdout.
    static QString toolVersion(const CommandLine &cmd);
    // Install a tooltip on lineedits used for binaries showing the version.
    static void installLineEditVersionToolTip(QLineEdit *le, const QStringList &arguments);

    // Enable a history completer with a history of entries.
    void setHistoryCompleter(const QString &historyKey, bool restoreLastItemFromHistory = false);

    // Sets a macro expander that is used when producing path and fileName.
    // By default, the global expander is used.
    // nullptr can be passed to disable macro expansion.
    void setMacroExpander(const MacroExpander *macroExpander);

    bool isReadOnly() const;
    void setReadOnly(bool b);

    void triggerChanged();

    // global handler for adding context menus to ALL pathchooser
    // used by the coreplugin to add "Open in Terminal" and "Open in Explorer" context menu actions
    using AboutToShowContextMenuHandler = std::function<void (PathChooser *, QMenu *)>;
    static void setAboutToShowContextMenuHandler(AboutToShowContextMenuHandler handler);

    void setOpenTerminalHandler(const std::function<void()> &openTerminal);
    std::function<void()> openTerminalHandler() const;

    // this sets the placeHolderText to defaultValue and enables to use this as
    // input value during validation if the real value is empty
    // setting an empty QString will disable this and clear the placeHolderText
    void setDefaultValue(const QString &defaultValue);

    void setAllowPathFromDevice(bool allow);
    bool allowPathFromDevice() const;

public slots:
    void setPath(const QString &);
    void setFilePath(const FilePath &);

signals:
    void validChanged(bool validState);
    void rawPathChanged();
    void textChanged(const QString &text); // Triggered from the line edit's textChanged()
    void editingFinished(); // Triggered from the line edit's editingFinished()
    void beforeBrowsing();
    void browsingFinished();
    void returnPressed();

private:
    // Deprecated, only used in property getter.
    // Use filePath().toString() or better suitable conversions.
    QString path() const { return filePath().toString(); }

    bool validatePath(FancyLineEdit *edit, QString *errorMessage) const;
    // Returns overridden title or the one from <title>
    QString makeDialogTitle(const QString &title);
    void slotBrowse();
    void contextMenuRequested(const QPoint &pos);

    PathChooserPrivate *d = nullptr;
    static AboutToShowContextMenuHandler s_aboutToShowContextMenuHandler;
};

} // namespace Utils