1/*
2 This file is part of the KDE project
3 SPDX-FileCopyrightText: 1999 Simon Hausmann <hausmann@kde.org>
4 SPDX-FileCopyrightText: 1999 David Faure <faure@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-or-later
7*/
8
9#ifndef _KPARTS_READONLYPART_H
10#define _KPARTS_READONLYPART_H
11
12#include <kparts/part.h>
13
14#include <QUrl>
15
16class KJob;
17namespace KIO
18{
19class Job;
20}
21
22namespace KParts
23{
24class ReadOnlyPartPrivate;
25class NavigationExtension;
26class OpenUrlArguments;
27
28/**
29 * @class ReadOnlyPart readonlypart.h <KParts/ReadOnlyPart>
30 *
31 * @short Base class for any "viewer" part.
32 *
33 * This class takes care of network transparency for you,
34 * in the simplest way (downloading to a temporary file, then letting the part
35 * load from the temporary file).
36 * To use the built-in network transparency, you only need to implement
37 * openFile(), not openUrl().
38 *
39 * To implement network transparency differently (e.g. for progressive loading,
40 * like a web browser does for instance), or to prevent network transparency
41 * (but why would you do that?), you can override openUrl().
42 *
43 * An application using KParts can use the signals to show feedback while
44 * the URL is being loaded.
45 *
46 * ReadOnlyPart handles the window caption by setting it to the current URL
47 * (set in openUrl(), and each time the part is activated).
48 * If you want another caption, set it in openFile() and,
49 * if the part might ever be used with a part manager, in guiActivateEvent().
50 */
51class KPARTS_EXPORT ReadOnlyPart : public Part
52{
53 Q_OBJECT
54
55 Q_PROPERTY(QUrl url READ url)
56
57 KPARTS_DECLARE_PRIVATE(ReadOnlyPart)
58
59public:
60 /**
61 * Constructor.
62 * See also Part for the setXXX methods to call.
63 */
64 explicit ReadOnlyPart(QObject *parent = nullptr, const KPluginMetaData &data = {});
65
66 /**
67 * Destructor.
68 */
69 ~ReadOnlyPart() override;
70
71 /**
72 * Call this to turn off the progress info dialog used by
73 * the internal KIO job. Use this if you provide another way
74 * of displaying progress info (e.g. a statusbar), using the
75 * signals emitted by this class, and/or those emitted by
76 * the job given by started().
77 */
78 void setProgressInfoEnabled(bool show);
79
80 /**
81 * Returns whether the part shows the progress info dialog used by the internal
82 * KIO job.
83 */
84 bool isProgressInfoEnabled() const;
85
86public Q_SLOTS:
87 /**
88 * Only reimplement this if you don't want the network transparency support
89 * to download from the URL into a temporary file (when the URL isn't local).
90 * Otherwise, reimplement openFile() only.
91 *
92 * If you reimplement it, don't forget to set the caption, usually with
93 * @code
94 * Q_EMIT setWindowCaption( url.toDisplayString() );
95 * @endcode
96 * and also, if the URL refers to a local file, resolve it to a
97 * local path and call setLocalFilePath().
98 */
99 virtual bool openUrl(const QUrl &url);
100
101public:
102 /**
103 * Returns the URL currently opened in (or being opened by) this part.
104 * @note The URL is not cleared if openUrl() fails to load the URL.
105 * Call closeUrl() if you need to explicitly reset it.
106 *
107 * @return The current URL.
108 */
109 QUrl url() const;
110
111 /**
112 * Called when closing the current URL (for example, a document), for instance
113 * when switching to another URL (note that openUrl() calls it
114 * automatically in this case).
115 * If the current URL is not fully loaded yet, aborts loading.
116 * Deletes the temporary file used when the URL is remote.
117 * Resets the current url() to QUrl().
118 * @return always true, but the return value exists for reimplementations
119 */
120 virtual bool closeUrl();
121
122 /**
123 * This convenience method returns the NavigationExtension for this part,
124 * or @c nullptr if there isn't one.
125 */
126 NavigationExtension *navigationExtension() const;
127
128 /**
129 * Sets the arguments to use for the next openUrl() call.
130 */
131 void setArguments(const OpenUrlArguments &arguments);
132 // TODO to avoid problems with the case where the loading fails, this could also be a openUrl() argument (heavy porting!).
133 // However we need to have setArguments in any case for updated made by the part, see e.g. KHTMLPart::openUrl.
134 // Well, maybe we should have setArguments (affects next openurl call) and updateArguments?
135
136 /**
137 * @return the arguments that were used to open this URL.
138 */
139 OpenUrlArguments arguments() const;
140
141public:
142 /**
143 * Initiate sending data to this part.
144 * This is an alternative to openUrl(), which allows the user of the part
145 * to load the data itself, and send it progressively to the part.
146 *
147 * @param mimeType the type of data that is going to be sent to this part.
148 * @param url the URL representing this data. Although not directly used,
149 * every ReadOnlyPart has a URL (see url()), so this simply sets it.
150 * @return true if the part supports progressive loading and accepts data, false otherwise.
151 */
152 bool openStream(const QString &mimeType, const QUrl &url);
153
154 /**
155 * Send some data to the part. openStream must have been called previously,
156 * and must have returned true.
157 * @return true if the data was accepted by the part. If false is returned,
158 * the application should stop sending data, and doesn't have to call closeStream.
159 */
160 bool writeStream(const QByteArray &data);
161
162 /**
163 * Terminate the sending of data to the part.
164 * With some data types (text, html...) closeStream might never actually be called,
165 * in the case of continuous streams, for instance plain text or HTML data.
166 */
167 bool closeStream();
168
169#ifdef K_DOXYGEN
170protected: // are parsed by doxygen (kapidox/ecm_add_qch): unhide for doxygen configured to skip private methods
171#else
172private: // Makes no sense for inherited classes to call those. But make it protected there.
173#endif // K_DOXYGEN
174
175 /**
176 * Called by openStream to initiate sending of data.
177 * Parts which implement progress loading should check the @p mimeType
178 * parameter, and return true if they can accept a data stream of that type.
179 */
180 virtual bool doOpenStream(const QString &mimeType)
181 {
182 Q_UNUSED(mimeType);
183 return false;
184 }
185 /**
186 * Receive some data from the hosting application.
187 * In this method the part should attempt to display the data progressively.
188 * With some data types (text, html...) closeStream might never actually be called,
189 * in the case of continuous streams. This can't happen with e.g. images.
190 */
191 virtual bool doWriteStream(const QByteArray &data)
192 {
193 Q_UNUSED(data);
194 return false;
195 }
196 /**
197 * This is called by closeStream(), to indicate that all the data has been sent.
198 * Parts should ensure that all of the data is displayed at this point.
199 * @return whether the data could be displayed correctly.
200 */
201 virtual bool doCloseStream()
202 {
203 return false;
204 }
205
206Q_SIGNALS:
207 /**
208 * The part emits this when starting to load data.
209 * If using a KIO::Job, it provides the @p job so that
210 * progress information can be shown. Otherwise, @p job is @c nullptr.
211 **/
212 void started(KIO::Job *job);
213
214 /**
215 * Emit this when you have completed loading data.
216 * Hosting applications will want to know when the process of loading the data
217 * is finished, so that they can access the data when everything is loaded.
218 **/
219 void completed();
220
221 /**
222 * This signal is similar to the @c KParts::ReadOnlyPart::completed() signal
223 * except it is only emitted if there is still a pending action to be executed
224 * on a delayed timer.
225 *
226 * An example of this is the meta-refresh tags on web pages used to reload/redirect
227 * after a certain period of time. This signal is useful if you want to give the
228 * user the ability to cancel such pending actions.
229 *
230 * @since 5.81
231 */
232 void completedWithPendingAction();
233
234 /**
235 * Emit this if loading is canceled by the user or by an error.
236 * @param errMsg the error message, empty if the user canceled the loading voluntarily.
237 */
238 void canceled(const QString &errMsg);
239
240 /**
241 * Emitted by the part when url() changes
242 * @since 4.10
243 */
244 void urlChanged(const QUrl &url);
245
246protected:
247 /**
248 * If the part uses the standard implementation of openUrl(),
249 * it must reimplement this to open the local file.
250 * The default implementation simply returns false.
251 *
252 * If this method returns true the part emits completed(),
253 * otherwise it emits canceled().
254 *
255 * @see completed(), canceled()
256 */
257 virtual bool openFile();
258
259 /**
260 * @internal
261 */
262 void abortLoad();
263
264 /**
265 * Reimplemented from Part, so that the window caption is set to
266 * the current URL (decoded) when the part is activated.
267 * This is the usual behavior in 99% of applications.
268 * Reimplement if you don't like it - test for event->activated()!
269 *
270 * @note This is done with GUIActivateEvent and not with
271 * PartActivateEvent because it's handled by the main window
272 * (which gets the event after the PartActivateEvent events have been sent).
273 */
274 void guiActivateEvent(GUIActivateEvent *event) override;
275
276 /**
277 * Sets the URL associated with this part.
278 */
279 void setUrl(const QUrl &url);
280
281 /**
282 * Returns the local file path associated with this part.
283 *
284 * @note The result will only be valid if openUrl() or
285 * setLocalFilePath() has previously been called.
286 */
287 QString localFilePath() const;
288
289 /**
290 * Sets the local file path associated with this part.
291 */
292 void setLocalFilePath(const QString &localFilePath);
293
294protected:
295 KPARTS_NO_EXPORT ReadOnlyPart(ReadOnlyPartPrivate &dd, QObject *parent);
296
297private:
298 Q_DISABLE_COPY(ReadOnlyPart)
299};
300
301} // namespace
302
303#endif
304

source code of kparts/src/readonlypart.h