fix tricky regression noticed by Vyacheslav Tokarev on Google Reader.
[kdelibs.git] / kparts / part.cpp
blobb93bbb4fcde7c4cc6e9d66eaeff38f9eb7fcf86a
1 /* This file is part of the KDE project
2 Copyright (C) 1999 Simon Hausmann <hausmann@kde.org>
3 (C) 1999-2005 David Faure <faure@kde.org>
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.
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.
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.
21 #include "part.h"
22 #include "event.h"
23 #include "plugin.h"
24 #include "mainwindow.h"
25 #include "partmanager.h"
26 #include "browserextension.h"
28 #include <QtGui/QApplication>
29 #include <QtCore/QFile>
30 #include <QtCore/QFileInfo>
31 #include <QtGui/QPainter>
32 #include <QtCore/QPoint>
34 #include <kdirnotify.h>
35 #include <kfiledialog.h>
36 #include <kcomponentdata.h>
37 #include <kio/job.h>
38 #include <kio/jobuidelegate.h>
39 #include <klocale.h>
40 #include <kmessagebox.h>
41 #include <kstandarddirs.h>
42 #include <ktemporaryfile.h>
43 #include <kxmlguifactory.h>
45 #include <stdio.h>
46 #include <unistd.h>
47 #include <assert.h>
48 #include <kdebug.h>
49 #include <kiconloader.h>
51 using namespace KParts;
53 namespace KParts
56 class PartBasePrivate
58 public:
59 Q_DECLARE_PUBLIC(PartBase)
61 PartBasePrivate(PartBase *q): q_ptr(q)
63 m_pluginLoadingMode = PartBase::LoadPlugins;
64 m_pluginInterfaceVersion = 0;
65 m_obj = 0;
68 virtual ~PartBasePrivate()
72 PartBase *q_ptr;
73 PartBase::PluginLoadingMode m_pluginLoadingMode;
74 int m_pluginInterfaceVersion;
75 QObject *m_obj;
78 class PartPrivate: public PartBasePrivate
80 public:
81 Q_DECLARE_PUBLIC(Part)
83 PartPrivate(Part *q)
84 : PartBasePrivate(q),
85 m_iconLoader(0),
86 m_bSelectable(true),
87 m_autoDeleteWidget(true),
88 m_autoDeletePart(true),
89 m_manager(0)
93 ~PartPrivate()
97 KIconLoader* m_iconLoader;
98 bool m_bSelectable;
99 bool m_autoDeleteWidget;
100 bool m_autoDeletePart;
101 PartManager * m_manager;
102 QPointer<QWidget> m_widget;
107 PartBase::PartBase()
108 : d_ptr(new PartBasePrivate(this))
112 PartBase::PartBase(PartBasePrivate &dd)
113 : d_ptr(&dd)
117 PartBase::~PartBase()
119 delete d_ptr;
122 void PartBase::setPartObject( QObject *obj )
124 Q_D(PartBase);
126 d->m_obj = obj;
129 QObject *PartBase::partObject() const
131 Q_D(const PartBase);
133 return d->m_obj;
136 void PartBase::setComponentData(const KComponentData &componentData)
138 setComponentData(componentData, true);
141 void PartBase::setComponentData(const KComponentData &componentData, bool bLoadPlugins)
143 Q_D(PartBase);
145 KXMLGUIClient::setComponentData(componentData);
146 KGlobal::locale()->insertCatalog(componentData.catalogName());
147 // install 'instancename'data resource type
148 KGlobal::dirs()->addResourceType((componentData.componentName() + "data").toUtf8(),
149 "data", componentData.componentName());
150 if (bLoadPlugins) {
151 loadPlugins(d->m_obj, this, componentData);
155 void PartBase::loadPlugins(QObject *parent, KXMLGUIClient *parentGUIClient, const KComponentData &instance)
157 Q_D(PartBase);
159 if( d->m_pluginLoadingMode != DoNotLoadPlugins )
160 Plugin::loadPlugins( parent, parentGUIClient, instance, d->m_pluginLoadingMode == LoadPlugins, d->m_pluginInterfaceVersion );
163 void PartBase::setPluginLoadingMode( PluginLoadingMode loadingMode )
165 Q_D(PartBase);
167 d->m_pluginLoadingMode = loadingMode;
170 void KParts::PartBase::setPluginInterfaceVersion( int version )
172 Q_D(PartBase);
174 d->m_pluginInterfaceVersion = version;
177 Part::Part( QObject *parent )
178 : QObject( parent ), PartBase( *new PartPrivate(this) )
180 PartBase::setPartObject( this );
183 Part::Part(PartPrivate &dd, QObject *parent)
184 : QObject( parent ), PartBase( dd )
186 PartBase::setPartObject( this );
189 Part::~Part()
191 Q_D(Part);
193 //kDebug(1000) << "Part::~Part " << this;
195 if ( d->m_widget )
197 // We need to disconnect first, to avoid calling it !
198 disconnect( d->m_widget, SIGNAL( destroyed() ),
199 this, SLOT( slotWidgetDestroyed() ) );
202 if ( d->m_manager )
203 d->m_manager->removePart(this);
205 if ( d->m_widget && d->m_autoDeleteWidget )
207 kDebug(1000) << "deleting widget " << d->m_widget << " " << d->m_widget->objectName();
208 delete static_cast<QWidget*>(d->m_widget);
211 delete d->m_iconLoader;
214 void Part::embed( QWidget * parentWidget )
216 if ( widget() )
218 widget()->setParent( parentWidget, 0 );
219 widget()->setGeometry( 0, 0, widget()->width(), widget()->height() );
220 widget()->show();
224 QWidget *Part::widget()
226 Q_D(Part);
228 return d->m_widget;
231 void Part::setAutoDeleteWidget(bool autoDeleteWidget)
233 Q_D(Part);
234 d->m_autoDeleteWidget = autoDeleteWidget;
237 void Part::setAutoDeletePart(bool autoDeletePart)
239 Q_D(Part);
240 d->m_autoDeletePart = autoDeletePart;
245 KIconLoader* Part::iconLoader()
247 Q_D(Part);
249 if (!d->m_iconLoader) {
250 Q_ASSERT(componentData().isValid());
251 d->m_iconLoader = new KIconLoader( componentData() );
253 return d->m_iconLoader;
256 void Part::setManager( PartManager *manager )
258 Q_D(Part);
260 d->m_manager = manager;
263 PartManager *Part::manager() const
265 Q_D(const Part);
267 return d->m_manager;
270 Part *Part::hitTest( QWidget *widget, const QPoint & )
272 Q_D(Part);
274 if ( (QWidget *)d->m_widget != widget )
275 return 0;
277 return this;
280 void Part::setWidget( QWidget *widget )
282 Q_D(Part);
284 assert ( !d->m_widget ); // otherwise we get two connects
285 d->m_widget = widget;
286 connect( d->m_widget, SIGNAL( destroyed() ),
287 this, SLOT( slotWidgetDestroyed() ) );
290 void Part::setSelectable( bool selectable )
292 Q_D(Part);
294 d->m_bSelectable = selectable;
297 bool Part::isSelectable() const
299 Q_D(const Part);
301 return d->m_bSelectable;
304 void Part::customEvent( QEvent *ev )
306 if ( PartActivateEvent::test( ev ) )
308 partActivateEvent( static_cast<PartActivateEvent *>(ev) );
309 return;
312 if ( PartSelectEvent::test( ev ) )
314 partSelectEvent( static_cast<PartSelectEvent *>(ev) );
315 return;
318 if ( GUIActivateEvent::test( ev ) )
320 guiActivateEvent( static_cast<GUIActivateEvent *>(ev) );
321 return;
324 QObject::customEvent( ev );
327 void Part::partActivateEvent( PartActivateEvent * )
331 void Part::partSelectEvent( PartSelectEvent * )
335 void Part::guiActivateEvent( GUIActivateEvent * )
339 QWidget *Part::hostContainer( const QString &containerName )
341 if ( !factory() )
342 return 0;
344 return factory()->container( containerName, this );
347 void Part::slotWidgetDestroyed()
349 Q_D(Part);
351 d->m_widget = 0;
352 if (d->m_autoDeletePart) {
353 kDebug(1000) << "KPart::slotWidgetDestroyed(), deleting part " << objectName();
354 delete this; // ouch, this should probably be deleteLater()
358 void Part::loadPlugins()
360 PartBase::loadPlugins(this, this, componentData());
363 //////////////////////////////////////////////////
365 namespace KParts
368 class ReadOnlyPartPrivate: public PartPrivate
370 public:
371 Q_DECLARE_PUBLIC(ReadOnlyPart)
373 ReadOnlyPartPrivate(ReadOnlyPart *q): PartPrivate(q)
375 m_job = 0;
376 m_uploadJob = 0;
377 m_showProgressInfo = true;
378 m_saveOk = false;
379 m_waitForSave = false;
380 m_duringSaveAs = false;
381 m_bTemp = false;
382 m_bAutoDetectedMime = false;
385 ~ReadOnlyPartPrivate()
389 void _k_slotJobFinished( KJob * job );
390 void _k_slotGotMimeType(KIO::Job *job, const QString &mime);
392 KIO::FileCopyJob * m_job;
393 KIO::FileCopyJob * m_uploadJob;
394 KUrl m_originalURL; // for saveAs
395 QString m_originalFilePath; // for saveAs
396 bool m_showProgressInfo : 1;
397 bool m_saveOk : 1;
398 bool m_waitForSave : 1;
399 bool m_duringSaveAs : 1;
402 * If @p true, @p m_file is a temporary file that needs to be deleted later.
404 bool m_bTemp: 1;
406 // whether the mimetype in the arguments was detected by the part itself
407 bool m_bAutoDetectedMime : 1;
410 * Remote (or local) url - the one displayed to the user.
412 KUrl m_url;
415 * Local file - the only one the part implementation should deal with.
417 QString m_file;
419 OpenUrlArguments m_arguments;
422 class ReadWritePartPrivate: public ReadOnlyPartPrivate
424 public:
425 Q_DECLARE_PUBLIC(ReadWritePart)
427 ReadWritePartPrivate(ReadWritePart *q): ReadOnlyPartPrivate(q)
429 m_bModified = false;
430 m_bReadWrite = true;
431 m_bClosing = false;
434 void _k_slotUploadFinished( KJob * job );
436 void prepareSaving();
438 bool m_bModified;
439 bool m_bReadWrite;
440 bool m_bClosing;
441 QEventLoop m_eventLoop;
446 ReadOnlyPart::ReadOnlyPart( QObject *parent )
447 : Part( *new ReadOnlyPartPrivate(this), parent )
451 ReadOnlyPart::ReadOnlyPart( ReadOnlyPartPrivate &dd, QObject *parent )
452 : Part( dd, parent )
456 ReadOnlyPart::~ReadOnlyPart()
458 ReadOnlyPart::closeUrl();
461 KUrl ReadOnlyPart::url() const
463 Q_D(const ReadOnlyPart);
465 return d->m_url;
468 void ReadOnlyPart::setUrl(const KUrl &url)
470 Q_D(ReadOnlyPart);
472 d->m_url = url;
475 QString ReadOnlyPart::localFilePath() const
477 Q_D(const ReadOnlyPart);
479 return d->m_file;
482 void ReadOnlyPart::setLocalFilePath( const QString &localFilePath )
484 Q_D(ReadOnlyPart);
486 d->m_file = localFilePath;
489 bool ReadOnlyPart::isLocalFileTemporary() const
491 Q_D(const ReadOnlyPart);
493 return d->m_bTemp;
496 void ReadOnlyPart::setLocalFileTemporary( bool temp )
498 Q_D(ReadOnlyPart);
500 d->m_bTemp = temp;
503 void ReadOnlyPart::setProgressInfoEnabled( bool show )
505 Q_D(ReadOnlyPart);
507 d->m_showProgressInfo = show;
510 bool ReadOnlyPart::isProgressInfoEnabled() const
512 Q_D(const ReadOnlyPart);
514 return d->m_showProgressInfo;
517 #ifndef KDE_NO_COMPAT
518 void ReadOnlyPart::showProgressInfo( bool show )
520 Q_D(ReadOnlyPart);
522 d->m_showProgressInfo = show;
524 #endif
526 bool ReadOnlyPart::openUrl( const KUrl &url )
528 Q_D(ReadOnlyPart);
530 if ( !url.isValid() )
531 return false;
532 if (d->m_bAutoDetectedMime) {
533 d->m_arguments.setMimeType(QString());
534 d->m_bAutoDetectedMime = false;
536 OpenUrlArguments args = d->m_arguments;
537 if ( !closeUrl() )
538 return false;
539 d->m_arguments = args;
540 d->m_url = url;
541 if ( d->m_url.isLocalFile() )
543 emit started( 0 );
544 d->m_file = d->m_url.toLocalFile();
545 d->m_bTemp = false;
546 // set the mimetype only if it was not already set (for example, by the host application)
547 if (d->m_arguments.mimeType().isEmpty())
549 // get the mimetype of the file
550 // using findByUrl() to avoid another string -> url conversion
551 KMimeType::Ptr mime = KMimeType::findByUrl(d->m_url, 0, true /* local file*/);
552 if (mime) {
553 d->m_arguments.setMimeType(mime->name());
554 d->m_bAutoDetectedMime = true;
557 bool ret = openFile();
558 if (ret) {
559 emit setWindowCaption( d->m_url.prettyUrl() );
560 emit completed();
561 } else emit canceled(QString());
562 return ret;
564 else
566 d->m_bTemp = true;
567 // Use same extension as remote file. This is important for mimetype-determination (e.g. koffice)
568 QString fileName = url.fileName();
569 QFileInfo fileInfo(fileName);
570 QString ext = fileInfo.completeSuffix();
571 QString extension;
572 if ( !ext.isEmpty() && url.query().isNull() ) // not if the URL has a query, e.g. cgi.pl?something
573 extension = '.'+ext; // keep the '.'
574 KTemporaryFile tempFile;
575 tempFile.setSuffix(extension);
576 tempFile.setAutoRemove(false);
577 tempFile.open();
578 d->m_file = tempFile.fileName();
580 KUrl destURL;
581 destURL.setPath( d->m_file );
582 KIO::JobFlags flags = d->m_showProgressInfo ? KIO::DefaultFlags : KIO::HideProgressInfo;
583 flags |= KIO::Overwrite;
584 d->m_job = KIO::file_copy( d->m_url, destURL, 0600, flags );
585 d->m_job->ui()->setWindow( widget() ? widget()->topLevelWidget() : 0 );
586 emit started( d->m_job );
587 connect( d->m_job, SIGNAL( result( KJob * ) ), this, SLOT( _k_slotJobFinished ( KJob * ) ) );
588 connect(d->m_job, SIGNAL(mimetype(KIO::Job *, const QString &)),
589 this, SLOT(_k_slotGotMimeType(KIO::Job *, const QString&)));
590 return true;
594 void ReadOnlyPart::abortLoad()
596 Q_D(ReadOnlyPart);
598 if ( d->m_job )
600 //kDebug(1000) << "Aborting job " << d->m_job;
601 d->m_job->kill();
602 d->m_job = 0;
606 bool ReadOnlyPart::closeUrl()
608 Q_D(ReadOnlyPart);
610 abortLoad(); //just in case
612 d->m_arguments = KParts::OpenUrlArguments();
614 if ( d->m_bTemp )
616 QFile::remove( d->m_file );
617 d->m_bTemp = false;
619 // It always succeeds for a read-only part,
620 // but the return value exists for reimplementations
621 // (e.g. pressing cancel for a modified read-write part)
622 return true;
625 void ReadOnlyPartPrivate::_k_slotJobFinished( KJob * job )
627 Q_Q(ReadOnlyPart);
629 kDebug(1000) << "ReadOnlyPart::slotJobFinished";
630 assert( job == m_job );
631 m_job = 0;
632 if (job->error())
633 emit q->canceled( job->errorString() );
634 else
636 if ( q->openFile() ) {
637 emit q->setWindowCaption( m_url.prettyUrl() );
638 emit q->completed();
639 } else emit q->canceled(QString());
643 void ReadOnlyPartPrivate::_k_slotGotMimeType(KIO::Job *job, const QString &mime)
645 kDebug(1000) << "ReadOnlyPart::slotJobFinished:" << mime;
646 Q_ASSERT(job == m_job);
647 // set the mimetype only if it was not already set (for example, by the host application)
648 if (m_arguments.mimeType().isEmpty()) {
649 m_arguments.setMimeType(mime);
650 m_bAutoDetectedMime = true;
654 void ReadOnlyPart::guiActivateEvent( GUIActivateEvent * event )
656 Q_D(ReadOnlyPart);
658 if (event->activated())
660 if (!d->m_url.isEmpty())
662 kDebug(1000) << "ReadOnlyPart::guiActivateEvent -> " << d->m_url.prettyUrl();
663 emit setWindowCaption( d->m_url.prettyUrl() );
664 } else emit setWindowCaption( "" );
668 bool ReadOnlyPart::openStream( const QString& mimeType, const KUrl& url )
670 Q_D(ReadOnlyPart);
672 OpenUrlArguments args = d->m_arguments;
673 if ( !closeUrl() )
674 return false;
675 d->m_arguments = args;
676 d->m_url = url;
677 return doOpenStream( mimeType );
680 bool ReadOnlyPart::writeStream( const QByteArray& data )
682 return doWriteStream( data );
685 bool ReadOnlyPart::closeStream()
687 return doCloseStream();
690 BrowserExtension* ReadOnlyPart::browserExtension() const
692 return findChild<KParts::BrowserExtension *>();
695 void KParts::ReadOnlyPart::setArguments(const OpenUrlArguments& arguments)
697 Q_D(ReadOnlyPart);
698 d->m_arguments = arguments;
699 d->m_bAutoDetectedMime = arguments.mimeType().isEmpty();
702 OpenUrlArguments KParts::ReadOnlyPart::arguments() const
704 Q_D(const ReadOnlyPart);
705 return d->m_arguments;
708 //////////////////////////////////////////////////
711 ReadWritePart::ReadWritePart( QObject *parent )
712 : ReadOnlyPart( *new ReadWritePartPrivate(this), parent )
716 ReadWritePart::~ReadWritePart()
718 // parent destructor will delete temp file
719 // we can't call our own closeUrl() here, because
720 // "cancel" wouldn't cancel anything. We have to assume
721 // the app called closeUrl() before destroying us.
724 void ReadWritePart::setReadWrite( bool readwrite )
726 Q_D(ReadWritePart);
728 // Perhaps we should check isModified here and issue a warning if true
729 d->m_bReadWrite = readwrite;
732 void ReadWritePart::setModified( bool modified )
734 Q_D(ReadWritePart);
736 kDebug(1000) << "ReadWritePart::setModified( " << (modified ? "true" : "false") << ")";
737 if ( !d->m_bReadWrite && modified )
739 kError(1000) << "Can't set a read-only document to 'modified' !" << endl;
740 return;
742 d->m_bModified = modified;
745 void ReadWritePart::setModified()
747 setModified( true );
750 bool ReadWritePart::queryClose()
752 Q_D(ReadWritePart);
754 if ( !isReadWrite() || !isModified() )
755 return true;
757 QString docName = url().fileName();
758 if (docName.isEmpty()) docName = i18n( "Untitled" );
760 QWidget *parentWidget=widget();
761 if(!parentWidget) parentWidget=QApplication::activeWindow();
763 int res = KMessageBox::warningYesNoCancel( parentWidget,
764 i18n( "The document \"%1\" has been modified.\n"
765 "Do you want to save your changes or discard them?" , docName ),
766 i18n( "Close Document" ), KStandardGuiItem::save(), KStandardGuiItem::discard() );
768 bool abortClose=false;
769 bool handled=false;
771 switch(res) {
772 case KMessageBox::Yes :
773 sigQueryClose(&handled,&abortClose);
774 if (!handled)
776 if (d->m_url.isEmpty())
778 KUrl url = KFileDialog::getSaveUrl(KUrl(), QString(), parentWidget);
779 if (url.isEmpty())
780 return false;
782 saveAs( url );
784 else
786 save();
788 } else if (abortClose) return false;
789 return waitSaveComplete();
790 case KMessageBox::No :
791 return true;
792 default : // case KMessageBox::Cancel :
793 return false;
797 bool ReadWritePart::closeUrl()
799 abortLoad(); //just in case
800 if ( isReadWrite() && isModified() )
802 if (!queryClose())
803 return false;
805 // Not modified => ok and delete temp file.
806 return ReadOnlyPart::closeUrl();
809 bool ReadWritePart::closeUrl( bool promptToSave )
811 return promptToSave ? closeUrl() : ReadOnlyPart::closeUrl();
814 bool ReadWritePart::save()
816 Q_D(ReadWritePart);
818 d->m_saveOk = false;
819 if ( d->m_file.isEmpty() ) // document was created empty
820 d->prepareSaving();
821 if( saveFile() )
822 return saveToUrl();
823 else
824 emit canceled(QString());
825 return false;
828 bool ReadWritePart::saveAs( const KUrl & kurl )
830 Q_D(ReadWritePart);
832 if (!kurl.isValid())
834 kError(1000) << "saveAs: Malformed URL " << kurl.url() << endl;
835 return false;
837 d->m_duringSaveAs = true;
838 d->m_originalURL = d->m_url;
839 d->m_originalFilePath = d->m_file;
840 d->m_url = kurl; // Store where to upload in saveToURL
841 d->prepareSaving();
842 bool result = save(); // Save local file and upload local file
843 if (result) {
844 emit setWindowCaption( d->m_url.prettyUrl() );
845 } else {
846 d->m_url = d->m_originalURL;
847 d->m_file = d->m_originalFilePath;
848 d->m_duringSaveAs = false;
849 d->m_originalURL = KUrl();
850 d->m_originalFilePath.clear();
853 return result;
856 // Set m_file correctly for m_url
857 void ReadWritePartPrivate::prepareSaving()
859 // Local file
860 if ( m_url.isLocalFile() )
862 if ( m_bTemp ) // get rid of a possible temp file first
863 { // (happens if previous url was remote)
864 QFile::remove( m_file );
865 m_bTemp = false;
867 m_file = m_url.toLocalFile();
869 else
870 { // Remote file
871 // We haven't saved yet, or we did but locally - provide a temp file
872 if ( m_file.isEmpty() || !m_bTemp )
874 KTemporaryFile tempFile;
875 tempFile.setAutoRemove(false);
876 tempFile.open();
877 m_file = tempFile.fileName();
878 m_bTemp = true;
880 // otherwise, we already had a temp file
884 bool ReadWritePart::saveToUrl()
886 Q_D(ReadWritePart);
888 if ( d->m_url.isLocalFile() )
890 setModified( false );
891 emit completed();
892 // if m_url is a local file there won't be a temp file -> nothing to remove
893 assert( !d->m_bTemp );
894 d->m_saveOk = true;
895 d->m_duringSaveAs = false;
896 d->m_originalURL = KUrl();
897 d->m_originalFilePath.clear();
898 return true; // Nothing to do
900 else
902 if (d->m_uploadJob)
904 QFile::remove(d->m_uploadJob->srcUrl().toLocalFile());
905 d->m_uploadJob->kill();
906 d->m_uploadJob = 0;
908 KTemporaryFile *tempFile = new KTemporaryFile();
909 tempFile->open();
910 QString uploadFile = tempFile->fileName();
911 delete tempFile;
912 KUrl uploadUrl;
913 uploadUrl.setPath( uploadFile );
914 // Create hardlink
915 if (::link(QFile::encodeName(d->m_file), QFile::encodeName(uploadFile)) != 0)
917 // Uh oh, some error happened.
918 return false;
920 d->m_uploadJob = KIO::file_move( uploadUrl, d->m_url, -1, KIO::Overwrite );
921 d->m_uploadJob->ui()->setWindow( widget() ? widget()->topLevelWidget() : 0 );
922 connect( d->m_uploadJob, SIGNAL( result( KJob * ) ), this, SLOT( _k_slotUploadFinished (KJob *) ) );
923 return true;
927 void ReadWritePartPrivate::_k_slotUploadFinished( KJob * )
929 Q_Q(ReadWritePart);
931 if (m_uploadJob->error())
933 QFile::remove(m_uploadJob->srcUrl().toLocalFile());
934 QString error = m_uploadJob->errorString();
935 m_uploadJob = 0;
936 if (m_duringSaveAs) {
937 m_url = m_originalURL;
938 m_file = m_originalFilePath;
940 emit q->canceled( error );
942 else
944 KUrl dirUrl( m_url );
945 dirUrl.setPath( dirUrl.directory() );
946 ::org::kde::KDirNotify::emitFilesAdded( dirUrl.url() );
948 m_uploadJob = 0;
949 q->setModified( false );
950 emit q->completed();
951 m_saveOk = true;
953 m_duringSaveAs = false;
954 m_originalURL = KUrl();
955 m_originalFilePath.clear();
956 if (m_waitForSave) {
957 m_eventLoop.quit();
961 bool ReadWritePart::isReadWrite() const
963 Q_D(const ReadWritePart);
965 return d->m_bReadWrite;
968 bool ReadWritePart::isModified() const
970 Q_D(const ReadWritePart);
972 return d->m_bModified;
975 bool ReadWritePart::waitSaveComplete()
977 Q_D(ReadWritePart);
979 if (!d->m_uploadJob)
980 return d->m_saveOk;
982 d->m_waitForSave = true;
984 d->m_eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
986 d->m_waitForSave = false;
988 return d->m_saveOk;
991 ////
993 class KParts::OpenUrlArgumentsPrivate : public QSharedData
995 public:
996 OpenUrlArgumentsPrivate()
997 : reload(false),
998 actionRequestedByUser(true),
999 xOffset(0),
1000 yOffset(0),
1001 mimeType(),
1002 metaData()
1004 bool reload;
1005 bool actionRequestedByUser;
1006 int xOffset;
1007 int yOffset;
1008 QString mimeType;
1009 QMap<QString, QString> metaData;
1012 KParts::OpenUrlArguments::OpenUrlArguments()
1013 : d(new OpenUrlArgumentsPrivate)
1017 KParts::OpenUrlArguments::OpenUrlArguments(const OpenUrlArguments &other)
1018 : d(other.d)
1022 KParts::OpenUrlArguments & KParts::OpenUrlArguments::operator=( const OpenUrlArguments &other)
1024 d = other.d;
1025 return *this;
1028 KParts::OpenUrlArguments::~OpenUrlArguments()
1032 bool KParts::OpenUrlArguments::reload() const
1034 return d->reload;
1037 void KParts::OpenUrlArguments::setReload(bool b)
1039 d->reload = b;
1042 int KParts::OpenUrlArguments::xOffset() const
1044 return d->xOffset;
1047 void KParts::OpenUrlArguments::setXOffset(int x)
1049 d->xOffset = x;
1052 int KParts::OpenUrlArguments::yOffset() const
1054 return d->yOffset;
1057 void KParts::OpenUrlArguments::setYOffset(int y)
1059 d->yOffset = y;
1062 QString KParts::OpenUrlArguments::mimeType() const
1064 return d->mimeType;
1067 void KParts::OpenUrlArguments::setMimeType(const QString& mime)
1069 d->mimeType = mime;
1072 QMap<QString, QString> & KParts::OpenUrlArguments::metaData()
1074 return d->metaData;
1077 const QMap<QString, QString> & KParts::OpenUrlArguments::metaData() const
1079 return d->metaData;
1082 bool KParts::OpenUrlArguments::actionRequestedByUser() const
1084 return d->actionRequestedByUser;
1087 void KParts::OpenUrlArguments::setActionRequestedByUser(bool userRequested)
1089 d->actionRequestedByUser = userRequested;
1092 #include "part.moc"