1 | /* This file is part of the KDE project |
2 | Copyright (C) 1999 Simon Hausmann <hausmann@kde.org> |
3 | (C) 1999 David Faure <faure@kde.org> |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2 of the License, or (at your option) any later version. |
9 | |
10 | This library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Library General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Library General Public License |
16 | along with this library; see the file COPYING.LIB. If not, write to |
17 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 | Boston, MA 02110-1301, USA. |
19 | */ |
20 | #ifndef _KPART_H |
21 | #define _KPART_H |
22 | |
23 | #include <QtCore/QPointer> |
24 | #include <QtCore/QEvent> |
25 | #include <QtCore/QSharedDataPointer> |
26 | #include <QtXml/QDomElement> // KDE5: remove |
27 | |
28 | #include <kurl.h> |
29 | #include <kxmlguiclient.h> |
30 | |
31 | #include <kparts/kparts_export.h> |
32 | |
33 | #define KPARTS_DECLARE_PRIVATE(Class) \ |
34 | inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(PartBase::d_ptr); } \ |
35 | inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(PartBase::d_ptr); } \ |
36 | friend class Class##Private; |
37 | |
38 | class KIconLoader; |
39 | class KComponentData; |
40 | class QWidget; |
41 | class QEvent; |
42 | class QPoint; |
43 | struct QUnknownInterface; |
44 | |
45 | class KJob; |
46 | namespace KIO { |
47 | class Job; |
48 | } |
49 | |
50 | namespace KParts |
51 | { |
52 | |
53 | class PartManager; |
54 | class Plugin; |
55 | class PartPrivate; |
56 | class PartActivateEvent; |
57 | class PartSelectEvent; |
58 | class GUIActivateEvent; |
59 | class PartBasePrivate; |
60 | |
61 | /** |
62 | * @short Base class for all parts. |
63 | */ |
64 | class KPARTS_EXPORT PartBase : virtual public KXMLGUIClient |
65 | { |
66 | KPARTS_DECLARE_PRIVATE(PartBase) |
67 | |
68 | public: |
69 | |
70 | /** |
71 | * Constructor. |
72 | */ |
73 | PartBase(); |
74 | |
75 | /** |
76 | * Destructor. |
77 | */ |
78 | virtual ~PartBase(); |
79 | |
80 | /** |
81 | * Internal method. Called by KParts::Part to specify the parent object for plugin objects. |
82 | * |
83 | * @internal |
84 | */ |
85 | void setPartObject( QObject *object ); |
86 | QObject *partObject() const; |
87 | |
88 | protected: |
89 | /** |
90 | * Set the componentData(KComponentData) for this part. |
91 | * |
92 | * Call this *first* in the inherited class constructor, |
93 | * because it loads the i18n catalogs. |
94 | */ |
95 | virtual void setComponentData(const KComponentData &componentData); |
96 | |
97 | /** |
98 | * Set the componentData(KComponentData) for this part. |
99 | * |
100 | * Call this *first* in the inherited class constructor, |
101 | * because it loads the i18n catalogs. |
102 | * |
103 | * It is recommended to call setComponentData with loadPlugins set to false, |
104 | * and to load plugins at the end of your part constructor (in the case of |
105 | * KParts::MainWindow, plugins are automatically loaded in createGUI anyway, |
106 | * so set loadPlugins to false for KParts::MainWindow as well). |
107 | */ |
108 | virtual void setComponentData(const KComponentData &componentData, bool loadPlugins); |
109 | // TODO KDE5: merge the above two methods, using loadPlugins=true. Or better, remove loadPlugins |
110 | // altogether and change plugins to call loadPlugins() manually at the end of their ctor. |
111 | // In the case of KParts MainWindows, plugins are automatically loaded in createGUI anyway, |
112 | // so setComponentData() should really not load the plugins. |
113 | |
114 | /** |
115 | * We have three different policies, whether to load new plugins or not. The |
116 | * value in the KConfig object of the KComponentData object always overrides |
117 | * LoadPlugins and LoadPluginsIfEnabled. |
118 | */ |
119 | enum PluginLoadingMode { |
120 | /** |
121 | * Don't load any plugins at all. |
122 | */ |
123 | DoNotLoadPlugins = 0, |
124 | /** |
125 | * Load new plugins automatically. Can be |
126 | * overridden by the plugin if it sets |
127 | * EnabledByDefault=false in the corresponding |
128 | * .desktop file. |
129 | */ |
130 | LoadPlugins = 1, |
131 | /** |
132 | * New plugins are disabled by default. Can be |
133 | * overridden by the plugin if it sets |
134 | * EnabledByDefault=true in the corresponding |
135 | * .desktop file. |
136 | */ |
137 | LoadPluginsIfEnabled = 2 |
138 | }; |
139 | |
140 | /** |
141 | * Load the Plugins honoring the PluginLoadingMode. |
142 | * |
143 | * If you call this method in an already constructed GUI (like when the user |
144 | * has changed which plugins are enabled) you need to add the new plugins to |
145 | * the KXMLGUIFactory: |
146 | * \code |
147 | * if( factory() ) |
148 | * { |
149 | * QList<KParts::Plugin *> plugins = KParts::Plugin::pluginObjects( this ); |
150 | * for(int i = 0; i != plugins.size(); ++i) { |
151 | * factory()->addClient( plugins[i] ); |
152 | * } |
153 | * } |
154 | * \endcode |
155 | */ |
156 | void loadPlugins(QObject *parent, KXMLGUIClient *parentGUIClient, const KComponentData &componentData); |
157 | |
158 | /** |
159 | * Set how plugins should be loaded |
160 | * @param loadingMode see PluginLoadingMode |
161 | * |
162 | * For a KParts::Part: call this before setComponentData. |
163 | * For a KParts::MainWindow: call this before createGUI. |
164 | */ |
165 | void setPluginLoadingMode( PluginLoadingMode loadingMode ); |
166 | |
167 | /** |
168 | * If you change the binary interface offered by your part, you can avoid crashes |
169 | * from old plugins lying around by setting X-KDE-InterfaceVersion=2 in the |
170 | * .desktop files of the plugins, and calling setPluginInterfaceVersion( 2 ), so that |
171 | * the old plugins are not loaded. Increase both numbers every time a |
172 | * binary incompatible change in the application's plugin interface is made. |
173 | * |
174 | * @param version the interface version that plugins must have in order to be loaded. |
175 | * |
176 | * For a KParts::Part: call this before setComponentData. |
177 | * For a KParts::MainWindow: call this before createGUI. |
178 | */ |
179 | void setPluginInterfaceVersion( int version ); |
180 | |
181 | protected: |
182 | PartBase(PartBasePrivate &dd); |
183 | |
184 | PartBasePrivate *d_ptr; |
185 | |
186 | private: |
187 | Q_DISABLE_COPY(PartBase) |
188 | }; |
189 | |
190 | /** |
191 | * Base class for parts. |
192 | * |
193 | * A "part" is a GUI component, featuring: |
194 | * @li A widget embeddedable in any application. |
195 | * @li GUI elements that will be merged in the "host" user interface |
196 | * (menubars, toolbars... ). |
197 | * |
198 | * <b>About the widget:</b>\n |
199 | * |
200 | * Note that KParts::Part does not inherit QWidget. |
201 | * This is due to the fact that the "visual representation" |
202 | * will probably not be a mere QWidget, but an elaborate one. |
203 | * That's why when implementing your KParts::Part (or derived) |
204 | * you should call KParts::Part::setWidget() in your constructor. |
205 | * |
206 | * <b>About the GUI elements:</b>\n |
207 | * |
208 | * Those elements trigger actions, defined by the part ( action()). |
209 | * The layout of the actions in the GUI is defined by an XML file ( setXMLFile()). |
210 | * |
211 | * See also ReadOnlyPart and ReadWritePart, which define the |
212 | * framework for a "viewer" part and for an "editor"-like part. |
213 | * Use Part directly only if your part doesn't fit into those. |
214 | */ |
215 | class KPARTS_EXPORT Part : public QObject, public PartBase |
216 | { |
217 | Q_OBJECT |
218 | |
219 | KPARTS_DECLARE_PRIVATE(Part) |
220 | |
221 | public: |
222 | |
223 | /** |
224 | * Constructor. |
225 | * |
226 | * @param parent Parent object of the part. |
227 | */ |
228 | explicit Part( QObject *parent = 0 ); |
229 | |
230 | /** |
231 | * Destructor. |
232 | */ |
233 | virtual ~Part(); |
234 | |
235 | /** |
236 | * Embed this part into a host widget. |
237 | * |
238 | * You don't need to do this if you created the widget with the |
239 | * correct parent widget - this is just a QWidget::reparent(). |
240 | * Note that the Part is still the holder |
241 | * of the QWidget, meaning that if you delete the Part, |
242 | * then the widget gets destroyed as well, and vice-versa. |
243 | * This method is not recommended since creating the widget with the correct |
244 | * parent is simpler anyway. |
245 | */ |
246 | virtual void embed( QWidget * parentWidget ); |
247 | |
248 | /** |
249 | * @return The widget defined by this part, set by setWidget(). |
250 | */ |
251 | virtual QWidget *widget(); |
252 | |
253 | /** |
254 | * @internal |
255 | * Used by the part manager. |
256 | */ |
257 | virtual void setManager( PartManager * manager ); |
258 | |
259 | /** |
260 | * Returns the part manager handling this part, if any (0L otherwise). |
261 | */ |
262 | PartManager * manager() const; |
263 | |
264 | /** |
265 | * By default, the widget is deleted by the part when the part is deleted. |
266 | * The hosting application can call setAutoDeleteWidget(false) to |
267 | * disable this behavior, given that the widget is usually deleted by |
268 | * its parent widget anyway. |
269 | * This is a method for the hosting application only, Part subclasses |
270 | * should never call this. |
271 | */ |
272 | void setAutoDeleteWidget(bool autoDeleteWidget); |
273 | |
274 | /** |
275 | * By default, the part deletes itself when its widget is deleted. |
276 | * The hosting application can call setAutoDeletePart(false) to |
277 | * disable this behavior, to be able to delete the widget and then the part, |
278 | * independently. |
279 | * This is a method for the hosting application only, Part subclasses |
280 | * should never call this. |
281 | */ |
282 | void setAutoDeletePart(bool autoDeletePart); |
283 | |
284 | /** |
285 | * Returns the part (this, or a child part) at the given global position. |
286 | * This is called by the part manager to ask whether a part should be activated |
287 | * when clicking somewhere. In most cases the default implementation is enough. |
288 | * Reimplement this if your part has child parts in some areas (like in khtml or koffice) |
289 | * @param widget the part widget being clicked - usually the same as widget(), except in koffice. |
290 | * @param globalPos the mouse coordinates in global coordinates |
291 | */ |
292 | virtual Part *hitTest( QWidget *widget, const QPoint &globalPos ); |
293 | |
294 | /** |
295 | * @param selectable Indicates whether the part is selectable or not. |
296 | */ |
297 | virtual void setSelectable( bool selectable ); |
298 | |
299 | /** |
300 | * Returns whether the part is selectable or not. |
301 | */ |
302 | bool isSelectable() const; |
303 | |
304 | /** |
305 | * Use this icon loader to load any icons that are specific to this part, |
306 | * i.e. icons installed into this part's own directories as opposed to standard |
307 | * kde icons. Use KIcon("myicon", iconLoader()). |
308 | * |
309 | * Make sure to call setComponentData before calling iconLoader. |
310 | */ |
311 | KIconLoader* iconLoader(); |
312 | |
313 | Q_SIGNALS: |
314 | /** |
315 | * Emitted by the part, to set the caption of the window(s) |
316 | * hosting this part |
317 | */ |
318 | void setWindowCaption( const QString & caption ); |
319 | /** |
320 | * Emitted by the part, to set a text in the statusbar of the window(s) |
321 | * hosting this part |
322 | */ |
323 | void setStatusBarText( const QString & text ); |
324 | |
325 | protected: |
326 | /** |
327 | * Set the main widget. |
328 | * |
329 | * Call this in the Part-inherited class constructor. |
330 | */ |
331 | virtual void setWidget( QWidget * widget ); |
332 | |
333 | /** |
334 | * @internal |
335 | */ |
336 | virtual void customEvent( QEvent *event ); |
337 | |
338 | /** |
339 | * Convenience method which is called when the Part received a PartActivateEvent . |
340 | * Reimplement this if you don't want to reimplement event and test for the event yourself |
341 | * or even install an event filter. |
342 | */ |
343 | virtual void partActivateEvent( PartActivateEvent *event ); |
344 | |
345 | /** |
346 | * Convenience method which is called when the Part received a |
347 | * PartSelectEvent . |
348 | * Reimplement this if you don't want to reimplement event and |
349 | * test for the event yourself or even install an event filter. |
350 | */ |
351 | virtual void partSelectEvent( PartSelectEvent *event ); |
352 | |
353 | /** |
354 | * Convenience method which is called when the Part received a |
355 | * GUIActivateEvent . |
356 | * Reimplement this if you don't want to reimplement event and |
357 | * test for the event yourself or even install an event filter. |
358 | */ |
359 | virtual void guiActivateEvent( GUIActivateEvent *event ); |
360 | |
361 | /** |
362 | * Convenience method for KXMLGUIFactory::container. |
363 | * @return a container widget owned by the Part's GUI. |
364 | */ |
365 | QWidget *hostContainer( const QString &containerName ); |
366 | |
367 | /** |
368 | * Load this part's plugins now. |
369 | * Normally you want to call this at the end of the part constructor, |
370 | * if you used setComponentData(componentData, false) |
371 | * @since 4.1 |
372 | */ |
373 | void loadPlugins(); |
374 | using PartBase::loadPlugins; |
375 | |
376 | protected Q_SLOTS: |
377 | /** |
378 | * @internal |
379 | */ |
380 | void slotWidgetDestroyed(); |
381 | |
382 | protected: |
383 | Part(PartPrivate &dd, QObject *parent); |
384 | |
385 | private: |
386 | Q_DISABLE_COPY(Part) |
387 | }; |
388 | |
389 | class ReadWritePart; |
390 | class ReadOnlyPartPrivate; |
391 | class BrowserExtension; |
392 | class OpenUrlArgumentsPrivate; |
393 | |
394 | /** |
395 | * OpenUrlArguments is the set of arguments that specify |
396 | * how a URL should be opened by KParts::ReadOnlyPart::openUrl(). |
397 | * |
398 | * For instance reload() indicates that the url should be loaded |
399 | * from the network even if it matches the current url of the part. |
400 | * |
401 | * All setter methods in this class are for the class that calls openUrl |
402 | * (usually the hosting application), all the getter methods are for the part. |
403 | */ |
404 | class KPARTS_EXPORT OpenUrlArguments |
405 | { |
406 | public: |
407 | OpenUrlArguments(); |
408 | OpenUrlArguments(const OpenUrlArguments &other); |
409 | OpenUrlArguments &operator=( const OpenUrlArguments &other); |
410 | ~OpenUrlArguments(); |
411 | |
412 | /** |
413 | * @return true to indicate that the part should reload the URL, |
414 | * i.e. the cache shouldn't be used (forced reload). |
415 | */ |
416 | bool reload() const; |
417 | /** |
418 | * Indicates that the url should be loaded |
419 | * from the network even if it matches the current url of the part. |
420 | */ |
421 | void setReload(bool b); |
422 | |
423 | /** |
424 | * xOffset is the horizontal scrolling of the part's widget |
425 | * (in case it's a scrollview). This is saved into the history |
426 | * and restored when going back in the history. |
427 | */ |
428 | int xOffset() const; |
429 | void setXOffset(int x); |
430 | |
431 | /** |
432 | * yOffset is the vertical scrolling of the part's widget |
433 | * (in case it's a scrollview). This is saved into the history |
434 | * and restored when going back in the history. |
435 | */ |
436 | int yOffset() const; |
437 | void setYOffset(int y); |
438 | |
439 | /** |
440 | * The mimetype to use when opening the url, when known by the calling application. |
441 | */ |
442 | QString mimeType() const; |
443 | void setMimeType(const QString& mime); |
444 | |
445 | /** |
446 | * True if the user requested that the URL be opened. |
447 | * False if the URL should be opened due to an external event, like javascript popups |
448 | * or automatic redirections. |
449 | * This is true by default |
450 | * @since 4.1 |
451 | */ |
452 | bool actionRequestedByUser() const; |
453 | void setActionRequestedByUser(bool userRequested); |
454 | |
455 | /** |
456 | * Meta-data to associate with the KIO operation that will be used to open the URL. |
457 | * This method can be used to add or retrieve metadata. |
458 | * @see KIO::TransferJob etc. |
459 | */ |
460 | QMap<QString, QString> &metaData(); |
461 | const QMap<QString, QString> &metaData() const; |
462 | |
463 | private: |
464 | QSharedDataPointer<OpenUrlArgumentsPrivate> d; |
465 | }; |
466 | |
467 | |
468 | /** |
469 | * Base class for any "viewer" part. |
470 | * |
471 | * This class takes care of network transparency for you, |
472 | * in the simplest way (downloading to a temporary file, then letting the part |
473 | * load from the temporary file). |
474 | * To use the built-in network transparency, you only need to implement |
475 | * openFile(), not openUrl(). |
476 | * |
477 | * To implement network transparency differently (e.g. for progressive loading, |
478 | * like a web browser does for instance), or to prevent network transparency |
479 | * (but why would you do that?), you can override openUrl(). |
480 | * |
481 | * KParts Application can use the signals to show feedback while the URL is being loaded. |
482 | * |
483 | * ReadOnlyPart handles the window caption by setting it to the current URL |
484 | * (set in openUrl(), and each time the part is activated). |
485 | * If you want another caption, set it in openFile() and |
486 | * (if the part might ever be used with a part manager) in guiActivateEvent() |
487 | */ |
488 | class KPARTS_EXPORT ReadOnlyPart : public Part |
489 | { |
490 | Q_OBJECT |
491 | |
492 | Q_PROPERTY( KUrl url READ url ) |
493 | |
494 | KPARTS_DECLARE_PRIVATE(ReadOnlyPart) |
495 | |
496 | public: |
497 | /** |
498 | * Constructor |
499 | * See also Part for the setXXX methods to call. |
500 | */ |
501 | explicit ReadOnlyPart( QObject *parent = 0 ); |
502 | |
503 | /** |
504 | * Destructor |
505 | */ |
506 | virtual ~ReadOnlyPart(); |
507 | |
508 | /** |
509 | * Call this to turn off the progress info dialog used by |
510 | * the internal KIO job. Use this if you provide another way |
511 | * of displaying progress info (e.g. a statusbar), using the |
512 | * signals emitted by this class, and/or those emitted by |
513 | * the Job given by started. |
514 | */ |
515 | void setProgressInfoEnabled( bool show ); |
516 | |
517 | /** |
518 | * Returns whether the part shows the progress info dialog used by internal |
519 | * KIO job. |
520 | */ |
521 | bool isProgressInfoEnabled() const; |
522 | |
523 | #ifndef KDE_NO_COMPAT |
524 | void showProgressInfo( bool show ); |
525 | #endif |
526 | |
527 | public Q_SLOTS: |
528 | /** |
529 | * Only reimplement openUrl if you don't want the network transparency support |
530 | * to download from the url into a temporary file (when the url isn't local). |
531 | * Otherwise, reimplement openFile() only . |
532 | * |
533 | * If you reimplement it, don't forget to set the caption, usually with |
534 | * emit setWindowCaption( url.prettyUrl() ); |
535 | */ |
536 | virtual bool openUrl( const KUrl &url ); |
537 | |
538 | public: |
539 | /** |
540 | * Returns the URL currently opened in this part. |
541 | * |
542 | * @return The current URL. |
543 | */ |
544 | KUrl url() const; |
545 | |
546 | /** |
547 | * Called when closing the current url (e.g. document), for instance |
548 | * when switching to another url (note that openUrl() calls it |
549 | * automatically in this case). |
550 | * If the current URL is not fully loaded yet, aborts loading. |
551 | * Deletes the temporary file used when the url is remote. |
552 | * @return always true, but the return value exists for reimplementations |
553 | */ |
554 | virtual bool closeUrl(); |
555 | |
556 | /** |
557 | * This convenience method returns the browserExtension for this part, |
558 | * or 0 if there isn't any. |
559 | */ |
560 | BrowserExtension* browserExtension() const; |
561 | |
562 | /** |
563 | * Sets the arguments to use for the next openUrl call. |
564 | */ |
565 | void setArguments(const OpenUrlArguments& arguments); |
566 | // TODO to avoid problems with the case where the loading fails, this could also be a openUrl() argument (heavy porting!). |
567 | // However we need to have setArguments in any case for updated made by the part, see e.g. KHTMLPart::openUrl. |
568 | // Well, maybe we should have setArguments (affects next openurl call) and updateArguments? |
569 | |
570 | |
571 | /** |
572 | * @return the arguments that were used to open this URL. |
573 | */ |
574 | OpenUrlArguments arguments() const; |
575 | |
576 | public: |
577 | /** |
578 | * Initiate sending data to this part. |
579 | * This is an alternative to openUrl, which allows the user of the part |
580 | * to load the data itself, and send it progressively to the part. |
581 | * |
582 | * @param mimeType the type of data that is going to be sent to this part. |
583 | * @param url the URL representing this data. Although not directly used, |
584 | * every ReadOnlyPart has a URL (see url()), so this simply sets it. |
585 | * @return true if the part supports progressive loading and accepts data, false otherwise. |
586 | */ |
587 | bool openStream( const QString& mimeType, const KUrl& url ); |
588 | |
589 | /** |
590 | * Send some data to the part. openStream must have been called previously, |
591 | * and must have returned true. |
592 | * @return true if the data was accepted by the part. If false is returned, |
593 | * the application should stop sending data, and doesn't have to call closeStream. |
594 | */ |
595 | bool writeStream( const QByteArray& data ); |
596 | |
597 | /** |
598 | * Terminate the sending of data to the part. |
599 | * With some data types (text, html...) closeStream might never actually be called, |
600 | * in the case of continuous streams, for instance plain text or HTML data. |
601 | */ |
602 | bool closeStream(); |
603 | |
604 | private: // Makes no sense for inherited classes to call those. But make it protected there. |
605 | |
606 | /** |
607 | * Called by openStream to initiate sending of data. |
608 | * Parts which implement progress loading should check the @p mimeType |
609 | * parameter, and return true if they can accept a data stream of that type. |
610 | */ |
611 | virtual bool doOpenStream( const QString& /*mimeType*/ ) { return false; } |
612 | /** |
613 | * Receive some data from the hosting application. |
614 | * In this method the part should attempt to display the data progressively. |
615 | * With some data types (text, html...) closeStream might never actually be called, |
616 | * in the case of continuous streams. This can't happen with e.g. images. |
617 | */ |
618 | virtual bool doWriteStream( const QByteArray& /*data*/ ) { return false; } |
619 | /** |
620 | * This is called by closeStream(), to indicate that all the data has been sent. |
621 | * Parts should ensure that all of the data is displayed at this point. |
622 | * @return whether the data could be displayed correctly. |
623 | */ |
624 | virtual bool doCloseStream() { return false; } |
625 | |
626 | Q_SIGNALS: |
627 | /** |
628 | * The part emits this when starting data. |
629 | * If using a KIO::Job, it sets the job in the signal, so that |
630 | * progress information can be shown. Otherwise, job is 0. |
631 | **/ |
632 | void started( KIO::Job * ); |
633 | |
634 | /** |
635 | * Emit this when you have completed loading data. |
636 | * Hosting apps will want to know when the process of loading the data |
637 | * is finished, so that they can access the data when everything is loaded. |
638 | **/ |
639 | void completed(); |
640 | |
641 | /** |
642 | * Same as the above signal except it indicates whether there is |
643 | * a pending action to be executed on a delay timer. An example of |
644 | * this is the meta-refresh tags on web pages used to reload/redirect |
645 | * after a certain period of time. This signal is useful if you want |
646 | * to give the user the ability to cancel such pending actions. |
647 | * |
648 | * @p pendingAction true if a pending action exists, false otherwise. |
649 | */ |
650 | void completed( bool pendingAction ); |
651 | |
652 | /** |
653 | * Emit this if loading is canceled by the user or by an error. |
654 | * @param errMsg the error message, empty if the user canceled the loading voluntarily. |
655 | */ |
656 | void canceled( const QString &errMsg ); |
657 | |
658 | /** |
659 | * Emitted by the part when url() changes |
660 | * @since 4.10 |
661 | */ |
662 | void urlChanged( const KUrl & url ); |
663 | |
664 | protected: |
665 | /** |
666 | * If the part uses the standard implementation of openUrl(), |
667 | * it must reimplement this, to open the local file. |
668 | * The default implementation is simply { return false; } |
669 | */ |
670 | virtual bool openFile(); |
671 | |
672 | /** |
673 | * @internal |
674 | */ |
675 | void abortLoad(); |
676 | |
677 | /** |
678 | * Reimplemented from Part, so that the window caption is set to |
679 | * the current url (decoded) when the part is activated |
680 | * This is the usual behavior in 99% of the apps |
681 | * Reimplement if you don't like it - test for event->activated() ! |
682 | * |
683 | * Technical note : this is done with GUIActivateEvent and not with |
684 | * PartActivateEvent because it's handled by the mainwindow |
685 | * (which gets the even after the PartActivateEvent events have been sent) |
686 | */ |
687 | virtual void guiActivateEvent( GUIActivateEvent *event ); |
688 | |
689 | /** |
690 | * @internal |
691 | */ |
692 | #ifndef KDE_NO_DEPRECATED |
693 | KDE_DEPRECATED bool isLocalFileTemporary() const; |
694 | #endif |
695 | |
696 | /** |
697 | * @internal |
698 | */ |
699 | #ifndef KDE_NO_DEPRECATED |
700 | KDE_DEPRECATED void setLocalFileTemporary( bool temp ); |
701 | #endif |
702 | |
703 | /** |
704 | * Sets the url associated with this part. |
705 | */ |
706 | void setUrl(const KUrl &url); |
707 | |
708 | /** |
709 | * Returns the local file path associated with this part. |
710 | */ |
711 | QString localFilePath() const; |
712 | |
713 | /** |
714 | * Sets the local file path associated with this part. |
715 | */ |
716 | void setLocalFilePath( const QString &localFilePath ); |
717 | |
718 | protected: |
719 | ReadOnlyPart(ReadOnlyPartPrivate &dd, QObject *parent); |
720 | |
721 | private: |
722 | Q_PRIVATE_SLOT(d_func(), void _k_slotJobFinished( KJob * job )) |
723 | Q_PRIVATE_SLOT(d_func(), void _k_slotStatJobFinished(KJob*)) |
724 | Q_PRIVATE_SLOT(d_func(), void _k_slotGotMimeType(KIO::Job *job, const QString &mime)) |
725 | |
726 | Q_DISABLE_COPY(ReadOnlyPart) |
727 | }; |
728 | class ReadWritePartPrivate; |
729 | |
730 | /** |
731 | * Base class for an "editor" part. |
732 | * |
733 | * This class handles network transparency for you. |
734 | * Anything that can open a URL, allow modifications, and save |
735 | * (to the same URL or a different one). |
736 | * |
737 | * A read-write part can be set to read-only mode, using setReadWrite(). |
738 | * |
739 | * Part writers : |
740 | * Any part inheriting ReadWritePart should check isReadWrite |
741 | * before allowing any action that modifies the part. |
742 | * The part probably wants to reimplement setReadWrite, disable those |
743 | * actions. Don't forget to call the parent setReadWrite. |
744 | */ |
745 | class KPARTS_EXPORT ReadWritePart : public ReadOnlyPart |
746 | { |
747 | Q_OBJECT |
748 | |
749 | KPARTS_DECLARE_PRIVATE(ReadWritePart) |
750 | |
751 | public: |
752 | /** |
753 | * Constructor |
754 | * See parent constructor for instructions. |
755 | */ |
756 | explicit ReadWritePart( QObject *parent = 0 ); |
757 | /** |
758 | * Destructor |
759 | * Applications using a ReadWritePart should make sure, before |
760 | * destroying it, to call closeUrl(). |
761 | * In KMainWindow::queryClose(), for instance, they should allow |
762 | * closing only if the return value of closeUrl() was true. |
763 | * This allows to cancel. |
764 | */ |
765 | virtual ~ReadWritePart(); |
766 | |
767 | /** |
768 | * @return true if the part is in read-write mode |
769 | */ |
770 | bool isReadWrite() const; |
771 | |
772 | /** |
773 | * Changes the behavior of this part to readonly or readwrite. |
774 | * @param readwrite set to true to enable readwrite mode |
775 | */ |
776 | virtual void setReadWrite ( bool readwrite = true ); |
777 | |
778 | /** |
779 | * @return true if the document has been modified. |
780 | */ |
781 | bool isModified() const; |
782 | |
783 | /** |
784 | * If the document has been modified, ask the user to save changes. |
785 | * This method is meant to be called from KMainWindow::queryClose(). |
786 | * It will also be called from closeUrl(). |
787 | * |
788 | * @return true if closeUrl() can be called without the user losing |
789 | * important data, false if the user chooses to cancel. |
790 | */ |
791 | virtual bool queryClose(); |
792 | |
793 | /** |
794 | * Called when closing the current url (e.g. document), for instance |
795 | * when switching to another url (note that openUrl() calls it |
796 | * automatically in this case). |
797 | * |
798 | * If the current URL is not fully loaded yet, aborts loading. |
799 | * |
800 | * If isModified(), queryClose() will be called. |
801 | * |
802 | * @return false on cancel |
803 | */ |
804 | virtual bool closeUrl(); |
805 | |
806 | /** |
807 | * Call this method instead of the above if you need control if |
808 | * the save prompt is shown. For example, if you call queryClose() |
809 | * from KMainWindow::queryClose(), you would not want to prompt |
810 | * again when closing the url. |
811 | * |
812 | * Equivalent to promptToSave ? closeUrl() : ReadOnlyPart::closeUrl() |
813 | */ |
814 | virtual bool closeUrl( bool promptToSave ); |
815 | |
816 | /** |
817 | * Save the file to a new location. |
818 | * |
819 | * Calls save(), no need to reimplement |
820 | */ |
821 | virtual bool saveAs( const KUrl &url ); |
822 | |
823 | /** |
824 | * Sets the modified flag of the part. |
825 | */ |
826 | virtual void setModified( bool modified ); |
827 | |
828 | Q_SIGNALS: |
829 | /** |
830 | * set handled to true, if you don't want the default handling |
831 | * set abortClosing to true, if you handled the request, |
832 | * but for any reason don't want to allow closing the document |
833 | */ |
834 | void sigQueryClose(bool *handled, bool* abortClosing); |
835 | |
836 | public Q_SLOTS: |
837 | /** |
838 | * Call setModified() whenever the contents get modified. |
839 | * This is a slot for convenience, since it simply calls setModified(true), |
840 | * so that you can connect it to a signal, like textChanged(). |
841 | */ |
842 | void setModified(); |
843 | |
844 | /** |
845 | * Save the file in the location from which it was opened. |
846 | * You can connect this to the "save" action. |
847 | * Calls saveFile() and saveToUrl(), no need to reimplement. |
848 | */ |
849 | virtual bool save(); |
850 | |
851 | /** |
852 | * Waits for any pending upload job to finish and returns whether the |
853 | * last save() action was successful. |
854 | */ |
855 | bool waitSaveComplete(); |
856 | |
857 | protected: |
858 | /** |
859 | * Save to a local file. |
860 | * You need to implement it, to save to the local file. |
861 | * The framework takes care of re-uploading afterwards. |
862 | * |
863 | * @return true on success, false on failure. |
864 | * On failure the function should inform the user about the |
865 | * problem with an appropriate message box. Standard error |
866 | * messages can be constructed using KIO::buildErrorString() |
867 | * in combination with the error codes defined in kio/global.h |
868 | */ |
869 | virtual bool saveFile() = 0; |
870 | |
871 | /** |
872 | * Save the file. |
873 | * |
874 | * Uploads the file, if @p url is remote. |
875 | * This will emit started(), and either completed() or canceled(), |
876 | * in case you want to provide feedback. |
877 | * @return true on success, false on failure. |
878 | */ |
879 | virtual bool saveToUrl(); |
880 | |
881 | private: |
882 | Q_PRIVATE_SLOT(d_func(), void _k_slotUploadFinished( KJob * job )) |
883 | |
884 | Q_DISABLE_COPY(ReadWritePart) |
885 | }; |
886 | |
887 | } // namespace |
888 | |
889 | |
890 | #undef KPARTS_DECLARE_PRIVATE |
891 | |
892 | #endif |
893 | |