1 /*
2     This file is part of the KDE libraries
3     SPDX-FileCopyrightText: 2020 Ahmad Samir <a.samirh78@gmail.com>
4 
5     SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6 */
7 
8 #ifndef ASKUSERACTIONINTERFACE_H
9 #define ASKUSERACTIONINTERFACE_H
10 
11 #include <kio/jobuidelegateextension.h> // RenameDialog_Result, SkipDialog_Result
12 #include <kiocore_export.h>
13 
14 #include <QObject>
15 
16 #include <memory>
17 
18 class KJob;
19 
20 namespace KIO
21 {
22 class AskUserActionInterfacePrivate;
23 
24 /**
25  * @class KIO::AskUserActionInterface askuseractioninterface.h <KIO/AskUserActionInterface>
26  *
27  * @brief The AskUserActionInterface class allows a KIO::Job to prompt the user
28  * for a decision when e.g. copying directories/files and there is a conflict
29  * (e.g. a file with the same name already exists at the destination).
30  *
31  * The methods in this interface are similar to their counterparts in
32  * KIO::JobUiDelegateExtension, the main difference is that AskUserActionInterface
33  * shows the dialogs using show() or open(), rather than exec(), the latter creates
34  * a nested event loop which could lead to crashes.
35  *
36  * @sa KIO::JobUiDelegateExtension
37  *
38  * @since 5.78
39  */
40 class KIOCORE_EXPORT AskUserActionInterface : public QObject
41 {
42     Q_OBJECT
43 
44 protected:
45     /**
46      * Constructor
47      */
48     explicit AskUserActionInterface(QObject *parent = nullptr);
49 
50 public:
51     /**
52      * Destructor
53      */
54     ~AskUserActionInterface() override;
55 
56     /**
57      * @relates KIO::RenameDialog
58      *
59      * Constructs a modal, parent-less "rename" dialog, to prompt the user for a decision
60      * in case of conflicts, while copying/moving files. The dialog is shown using open(),
61      * rather than exec() (the latter creates a nested eventloop which could lead to crashes).
62      * You will need to connect to the askUserRenameResult() signal to get the dialog's result
63      * (exit code). The exit code is one of KIO::RenameDialog_Result.
64      *
65      * @see KIO::RenameDialog_Result enum.
66      *
67      * @param job the job that called this method
68      * @param caption the title for the dialog box
69      * @param src the URL of the file/dir being copied/moved
70      * @param dest the URL of the destination file/dir, i.e. the one that already exists
71      * @param options parameters for the dialog (which buttons to show... etc), OR'ed values
72      *            from the KIO::RenameDialog_Options enum
73      * @param sizeSrc size of the source file
74      * @param sizeDest size of the destination file
75      * @param ctimeSrc creation time of the source file
76      * @param ctimeDest creation time of the destination file
77      * @param mtimeSrc modification time of the source file
78      * @param mtimeDest modification time of the destination file
79      */
80     virtual void askUserRename(KJob *job,
81                                const QString &caption,
82                                const QUrl &src,
83                                const QUrl &dest,
84                                KIO::RenameDialog_Options options,
85                                KIO::filesize_t sizeSrc,
86                                KIO::filesize_t sizeDest,
87                                const QDateTime &ctimeSrc = {},
88                                const QDateTime &ctimeDest = {},
89                                const QDateTime &mtimeSrc = {},
90                                const QDateTime &mtimeDest = {}) = 0;
91 
92     /**
93      * @relates KIO::SkipDialog
94      *
95      * You need to connect to the askUserSkipResult signal to get the dialog's
96      * result.
97      *
98      * @param job the job that called this method
99      * @param options parameters for the dialog (which buttons to show... etc), OR'ed
100      *            values from the KIO::SkipDialog_Options enum
101      * @param error_text the error text to show to the user (usually the string returned
102      *               by KJob::errorText())
103      */
104     virtual void askUserSkip(KJob *job, KIO::SkipDialog_Options options, const QString &errorText) = 0;
105 
106     /**
107      * The type of deletion.
108      *
109      * Used by askUserDelete().
110      */
111     enum DeletionType {
112         Delete, /// Delete the files/directories directly, i.e. without moving them to Trash
113         Trash, /// Move the files/directories to Trash
114         EmptyTrash, /// Empty the Trash
115     };
116 
117     /**
118      * Deletion confirmation type.
119      *
120      * Used by askUserDelete().
121      */
122     enum ConfirmationType {
123         DefaultConfirmation, ///< Do not ask if the user has previously set the "Do not ask again"
124                              ///< checkbox (which is is shown in the message dialog invoked by askUserDelete())
125         ForceConfirmation, ///< Always ask the user for confirmation
126     };
127 
128     /**
129      * Ask for confirmation before moving @p urls (files/directories) to the Trash,
130      * emptying the Trash, or directly deleting files (i.e. without moving to Trash).
131      *
132      * Note that this method is not called automatically by KIO jobs. It's the
133      * application's responsibility to ask the user for confirmation before calling
134      * KIO::del() or KIO::trash().
135      *
136      * You need to connect to the askUserDeleteResult signal to get the dialog's result
137      * (exit code).
138      *
139      * @param urls the urls about to be moved to the Trash or deleted directly
140      * @param deletionType the type of deletion (Delete for real deletion, Trash otherwise),
141      *                 see the DeletionType enum
142      * @param confirmationType The type of deletion confirmation, see the ConfirmationType enum.
143      *                     Normally set to DefaultConfirmation
144      * @param parent the parent widget of the message box
145      */
146     virtual void askUserDelete(const QList<QUrl> &urls,
147                                DeletionType deletionType,
148                                ConfirmationType confirmationType,
149                                QWidget *parent = nullptr) = 0; // TODO KF6: replace QWidget* with QObject*
150 
151     enum MessageDialogType {
152         QuestionYesNo = 1,
153         QuestionYesNoCancel = 2,
154         WarningYesNo = 3,
155         WarningYesNoCancel = 4,
156         WarningContinueCancel = 5,
157         SSLMessageBox = 6,
158         Information = 7,
159         Sorry = 8,
160         Error = 9,
161     };
162 
163     /**
164      * This function allows for the delegation of user prompts from the ioslaves.
165      *
166      * @param type the desired type of message box, see the MessageDialogType enum
167      * @param text the message to show to the user
168      * @param caption the title of the message dialog box
169      * @param buttonYes the text for the YES button
170      * @param buttonNo the text for the NO button
171      * @param iconYes the icon to show on the YES button
172      * @param iconNo the icon to show on the NO button
173      * @param dontAskAgainName the config key name used to store the result from
174      *                     'Do not ask again' checkbox
175      * @param details more details about the message shown to the user
176      * @param sslMetaData SSL information primarily used by the SSLMessageBox dialog
177      * @param parent the parent widget of the dialog
178      */
179     virtual void requestUserMessageBox(MessageDialogType type,
180                                        const QString &text,
181                                        const QString &caption,
182                                        const QString &buttonYes,
183                                        const QString &buttonNo,
184                                        const QString &iconYes = {},
185                                        const QString &iconNo = {},
186                                        const QString &dontAskAgainName = {},
187                                        const QString &details = {},
188                                        const KIO::MetaData &sslMetaData = {},
189                                        QWidget *parent = nullptr) = 0; // TODO KF6: replace QWidget* with QObject*, document "widget or window"
190 
191 Q_SIGNALS:
192     /**
193      * Implementations of this interface must emit this signal when the rename dialog
194      * finishes, to notify the caller of the dialog's result.
195      *
196      * @param result the exit code from the rename dialog, one of the KIO::RenameDialog_Result
197      *           enum
198      * @param newUrl the new destination URL set by the user
199      * @param parentJob the job that invoked the dialog
200      */
201     void askUserRenameResult(KIO::RenameDialog_Result result, const QUrl &newUrl, KJob *parentJob);
202 
203     /**
204      * Implementations of this interface must emit this signal when the skip dialog
205      * finishes, to notify the caller of the dialog's result.
206      *
207      * @param result the exit code from the skip dialog, one of the KIO::SkipDialog_Result enum
208      * @param parentJob the job that invoked the dialog
209      */
210     void askUserSkipResult(KIO::SkipDialog_Result result, KJob *parentJob);
211 
212     /**
213      * Implementations of this interface must emit this signal when the dialog invoked
214      * by askUserDelete() finishes, to notify the caller of the user's decision.
215      *
216      * @param allowDelete set to true if the user confirmed the delete operation, otherwise
217      * set to false
218      * @param urls a list of urls to delete/trash
219      * @param deletionType the deletion type to use, one of KIO::AskUserActionInterface::DeletionType
220      * @param parent the parent widget passed to askUserDelete(), for request identification
221      */
222     void askUserDeleteResult(bool allowDelete,
223                              const QList<QUrl> &urls,
224                              KIO::AskUserActionInterface::DeletionType deletionType,
225                              QWidget *parent); // TODO KF6: replace QWidget* with QObject*
226 
227     /**
228      * Implementations of this interface must emit this signal when the dialog invoked
229      * by requestUserMessageBox() finishes, to notify the caller of the dialog's result
230      * (exit code).
231      *
232      * @param result the exit code of the dialog, one of KIO::SlaveBase::ButtonCode enum
233      */
234     void messageBoxResult(int result); // TODO KF6: add a QObject* to identify requests? Or return an int from the request method and pass it back here?
235 
236 private:
237     std::unique_ptr<AskUserActionInterfacePrivate> d;
238 };
239 
240 } // namespace KIO
241 
242 #endif // ASKUSERACTIONINTERFACE_H
243