Solving the creation of an additional tab for a deleted file.

BUG: 412978
BUG: 412979
This commit is contained in:
Andi Sardina Ramos 2020-02-10 23:22:06 +00:00 committed by Albert Astals Cid
parent cb3426d024
commit c549d28f7f
12 changed files with 220 additions and 82 deletions

View File

@ -9,7 +9,7 @@ ecm_add_test(shelltest.cpp ../shell/shellutils.cpp
if(Poppler_Qt5_FOUND)
if (BUILD_DESKTOP)
ecm_add_test(parttest.cpp
ecm_add_test(parttest.cpp closedialoghelper.cpp
TEST_NAME "parttest"
LINK_LIBRARIES Qt5::Widgets Qt5::Test Qt5::Xml okularcore okularpart
)
@ -82,7 +82,7 @@ ecm_add_test(calculatetexttest.cpp
)
if(KF5Activities_FOUND AND BUILD_DESKTOP)
ecm_add_test(mainshelltest.cpp ../shell/okular_main.cpp ../shell/shellutils.cpp ../shell/shell.cpp
ecm_add_test(mainshelltest.cpp ../shell/okular_main.cpp ../shell/shellutils.cpp ../shell/shell.cpp closedialoghelper.cpp
TEST_NAME "mainshelltest"
LINK_LIBRARIES Qt5::Test KF5::Activities okularpart okularcore
)

View File

@ -0,0 +1,41 @@
#include "closedialoghelper.h"
#include <QApplication>
#include <QDialog>
#include <QPushButton>
#include <QTest>
namespace TestingUtils
{
CloseDialogHelper::CloseDialogHelper(Okular::Part *p, QDialogButtonBox::StandardButton b) : m_widget(p->widget()), m_button(b), m_clicked(false)
{
QTimer::singleShot(0, this, &CloseDialogHelper::closeDialog);
}
CloseDialogHelper::CloseDialogHelper(QWidget *w, QDialogButtonBox::StandardButton b) : m_widget(w), m_button(b), m_clicked(false)
{
QTimer::singleShot(0, this, &CloseDialogHelper::closeDialog);
}
CloseDialogHelper::CloseDialogHelper(QDialogButtonBox::StandardButton b) : m_widget(nullptr), m_button(b), m_clicked(false)
{
QTimer::singleShot(0, this, &CloseDialogHelper::closeDialog);
}
CloseDialogHelper::~CloseDialogHelper()
{
QVERIFY(m_clicked);
}
void CloseDialogHelper::closeDialog()
{
QWidget *dialog = ( m_widget ) ? m_widget->findChild<QDialog*>() : qApp->activeModalWidget();
if (!dialog) {
QTimer::singleShot(0, this, &CloseDialogHelper::closeDialog);
return;
}
QDialogButtonBox *buttonBox = dialog->findChild<QDialogButtonBox*>();
buttonBox->button(m_button)->click();
m_clicked = true;
}
}

View File

@ -0,0 +1,39 @@
#ifndef CLOSEDIALOGHELPER_H
#define CLOSEDIALOGHELPER_H
#include <QDialogButtonBox>
#include <QObject>
#include <../part.h>
namespace TestingUtils
{
/*
* The CloseDialogHelper class is a helper to auto close modals opened in tests.
*/
class CloseDialogHelper : public QObject
{
public:
CloseDialogHelper(Okular::Part *p, QDialogButtonBox::StandardButton b);
CloseDialogHelper(QWidget *w, QDialogButtonBox::StandardButton b);
// Close a modal dialog, which may not be associated to any other widget
CloseDialogHelper(QDialogButtonBox::StandardButton b);
~CloseDialogHelper() override;
private slots:
void closeDialog();
private:
QWidget *m_widget;
QDialogButtonBox::StandardButton m_button;
bool m_clicked;
};
}
#endif // CLOSEDIALOGHELPER_H

View File

@ -16,6 +16,7 @@
#include <QStandardPaths>
#include <kconfiggroup.h>
#include <klineedit.h>
#include <krecentfilesaction.h>
#include "../shell/okular_main.h"
#include "../shell/shell.h"
@ -25,6 +26,7 @@
#include "../ui/presentationwidget.h"
#include "../part.h"
#include "../settings.h"
#include "closedialoghelper.h"
#include <sys/types.h>
#ifndef Q_OS_WIN
@ -89,6 +91,8 @@ private slots:
void testMiddleButtonCloseUndo();
void testSessionRestore_data();
void testSessionRestore();
void testOpenInvalidFiles_data();
void testOpenInvalidFiles();
private:
};
@ -243,7 +247,7 @@ void MainShellTest::testShell()
Okular::Settings::self()->setShellOpenFileInTabs(useTabs);
if (expectPrintDialog || externalProcessExpectPrintDialog) {
const int expectedTab = externalProcessExpectPrintDialog && !unique ? 1 : 0;
const int expectedTab = 0;
helper.reset(new ClosePrintDialogHelper(expectedTab));
QTimer::singleShot(0, helper.data(), SLOT(closePrintDialog()));
}
@ -601,6 +605,62 @@ void MainShellTest::testSessionRestore()
QCOMPARE( shells.size(), useTabsRestore ? numWindows : paths.size() );
}
void MainShellTest::testOpenInvalidFiles_data()
{
QTest::addColumn<QList<QUrl>>("files");
QTest::addColumn<QString>("options");
QString options = ShellUtils::serializeOptions( false, false, false, false, false, QString(), QString() );
QUrl validFile = ShellUtils::urlFromArg( QStringLiteral( KDESRCDIR "data/file2.pdf" ), ShellUtils::qfileExistFunc(), QString() );
QUrl invalidFile = ShellUtils::urlFromArg( QStringLiteral( KDESRCDIR "data/non-existing-doc.pdf" ), ShellUtils::qfileExistFunc(), QString() );
QList<QUrl> firstCase { invalidFile, validFile };
QList<QUrl> secondCase { validFile, invalidFile };
QTest::newRow( "opening the invalid file first" ) << firstCase << options;
QTest::newRow( "opening the valid file first" ) << secondCase << options;
}
void MainShellTest::testOpenInvalidFiles()
{
QFETCH( QList<QUrl>, files );
QFETCH( QString, options );
/*
* The purpose of this test is to verify that when we open an invalid file, no tab is created in the
* shell.
*
*/
Okular::Settings::self()->setShellOpenFileInTabs( true );
Okular::Status status = Okular::main( QStringList(), options );
QCOMPARE( status, Okular::Success );
Shell *shell = findShell();
QVERIFY( shell );
/*
* We need to make sure that the KrecentFilesAction is empty before starting, because we will also test that
* the file gets removed from the recent documents
*
*/
shell->m_recent->clear();
QScopedPointer<TestingUtils::CloseDialogHelper> closeDialogHelper { new TestingUtils::CloseDialogHelper( QDialogButtonBox::StandardButton::Ok ) };
for (const QUrl& file: files)
{
shell->openUrl( file );
}
QList<QUrl> recentFiles = shell->m_recent->urls();
QVERIFY( shell->m_tabs.size() == 1 );
QVERIFY( recentFiles.size() == 1 );
QVERIFY( recentFiles.first().toString().contains( QStringLiteral( "data/file2.pdf" ) ) );
}
void MainShellTest::testMiddleButtonCloseUndo()
{
const QStringList paths = { QStringLiteral(KDESRCDIR "data/file1.pdf"), QStringLiteral(KDESRCDIR "data/file2.pdf") };

View File

@ -21,6 +21,7 @@
#include "../ui/pageview.h"
#include "../ui/presentationwidget.h"
#include "../settings.h"
#include "closedialoghelper.h"
#include "../generators/poppler/config-okular-poppler.h"
@ -41,51 +42,6 @@
#include <QDesktopServices>
#include <QMenu>
class CloseDialogHelper : public QObject
{
Q_OBJECT
public:
CloseDialogHelper(Okular::Part *p, QDialogButtonBox::StandardButton b) : m_widget(p->widget()), m_button(b), m_clicked(false)
{
QTimer::singleShot(0, this, &CloseDialogHelper::closeDialog);
}
CloseDialogHelper(QWidget *w, QDialogButtonBox::StandardButton b) : m_widget(w), m_button(b), m_clicked(false)
{
QTimer::singleShot(0, this, &CloseDialogHelper::closeDialog);
}
// Close a modal dialog, which may not be associated to any other widget
CloseDialogHelper(QDialogButtonBox::StandardButton b) : m_widget(nullptr), m_button(b), m_clicked(false)
{
QTimer::singleShot(0, this, &CloseDialogHelper::closeDialog);
}
~CloseDialogHelper() override
{
QVERIFY(m_clicked);
}
private slots:
void closeDialog()
{
QWidget *dialog = ( m_widget ) ? m_widget->findChild<QDialog*>() : qApp->activeModalWidget();
if (!dialog) {
QTimer::singleShot(0, this, &CloseDialogHelper::closeDialog);
return;
}
QDialogButtonBox *buttonBox = dialog->findChild<QDialogButtonBox*>();
buttonBox->button(m_button)->click();
m_clicked = true;
}
private:
QWidget *m_widget;
QDialogButtonBox::StandardButton m_button;
bool m_clicked;
};
namespace Okular
{
class PartTest
@ -927,7 +883,7 @@ void PartTest::testSaveAs()
QFETCH(bool, nativelySupportsAnnotations);
QFETCH(bool, canSwapBackingFile);
QScopedPointer<CloseDialogHelper> closeDialogHelper;
QScopedPointer<TestingUtils::CloseDialogHelper> closeDialogHelper;
QString annotName;
QTemporaryFile archiveSave( QStringLiteral( "%1/okrXXXXXX.okular" ).arg( QDir::tempPath() ) );
@ -958,7 +914,7 @@ void PartTest::testSaveAs()
{
if ( !nativelySupportsAnnotations )
{
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
}
QVERIFY( part.saveAs( QUrl::fromLocalFile( nativeDirectSave.fileName() ), Part::NoSaveAsFlags ) );
// For backends that don't support annotations natively we mark the part as still modified
@ -971,12 +927,12 @@ void PartTest::testSaveAs()
{
// We need to save to archive first otherwise we lose the annotation
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::Yes )); // this is the "you're going to lose the undo/redo stack" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::Yes )); // this is the "you're going to lose the undo/redo stack" dialog
QVERIFY( part.saveAs( QUrl::fromLocalFile( archiveSave.fileName() ), Part::SaveAsOkularArchive ) );
if ( !nativelySupportsAnnotations )
{
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
}
QVERIFY( part.saveAs( QUrl::fromLocalFile( nativeDirectSave.fileName() ), Part::NoSaveAsFlags ) );
}
@ -996,7 +952,7 @@ void PartTest::testSaveAs()
if ( !nativelySupportsAnnotations )
{
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
}
QVERIFY( part.saveAs( QUrl::fromLocalFile( nativeFromArchiveFile.fileName() ), Part::NoSaveAsFlags ) );
@ -1005,7 +961,7 @@ void PartTest::testSaveAs()
// For backends that don't support annotations natively we mark the part as still modified
// after a save because we keep the annotation around but it will get lost if the user closes the app
// so we want to give her a last chance to save on close with the "you have changes dialog"
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "do you want to save or discard" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "do you want to save or discard" dialog
}
QCOMPARE( part.m_document->documentInfo().get( Okular::DocumentInfo::FilePath ), part.m_document->currentDocument().toDisplayString() );
@ -1109,7 +1065,7 @@ void PartTest::testSaveAsUndoStackAnnotations()
const Part::SaveAsFlag saveFlags = saveToArchive ? Part::SaveAsOkularArchive : Part::NoSaveAsFlags;
QScopedPointer<CloseDialogHelper> closeDialogHelper;
QScopedPointer<TestingUtils::CloseDialogHelper> closeDialogHelper;
// closeDialogHelper relies on the availability of the "Continue" button to drop changes
// when saving to a file format not supporting those. However, this button is only sensible
@ -1134,7 +1090,7 @@ void PartTest::testSaveAsUndoStackAnnotations()
QString annotName = annot->uniqueName();
if ( !nativelySupportsAnnotations && !saveToArchive ) {
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
}
QVERIFY( part.saveAs( QUrl::fromLocalFile( saveFile1.fileName() ), saveFlags ) );
@ -1181,7 +1137,7 @@ void PartTest::testSaveAsUndoStackAnnotations()
// Check we can still undo the annot add after save
if ( !nativelySupportsAnnotations && !saveToArchive ) {
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
}
QVERIFY( part.saveAs( QUrl::fromLocalFile( saveFile2.fileName() ), saveFlags ) );
QVERIFY( part.m_document->canUndo() );
@ -1212,7 +1168,7 @@ void PartTest::testSaveAsUndoStackAnnotations()
// Now check we can still undo/redo/save at all the intermediate states and things still work
if ( !nativelySupportsAnnotations && !saveToArchive ) {
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
}
QVERIFY( part.saveAs( QUrl::fromLocalFile( saveFile2.fileName() ), saveFlags ) );
QVERIFY( part.m_document->canUndo() );
@ -1220,7 +1176,7 @@ void PartTest::testSaveAsUndoStackAnnotations()
QVERIFY( part.m_document->canUndo() );
if ( !nativelySupportsAnnotations && !saveToArchive ) {
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
}
QVERIFY( part.saveAs( QUrl::fromLocalFile( saveFile1.fileName() ), saveFlags ) );
QVERIFY( part.m_document->canUndo() );
@ -1228,7 +1184,7 @@ void PartTest::testSaveAsUndoStackAnnotations()
QVERIFY( part.m_document->canUndo() );
if ( !nativelySupportsAnnotations && !saveToArchive ) {
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
}
QVERIFY( part.saveAs( QUrl::fromLocalFile( saveFile2.fileName() ), saveFlags ) );
QVERIFY( part.m_document->canUndo() );
@ -1236,7 +1192,7 @@ void PartTest::testSaveAsUndoStackAnnotations()
QVERIFY( part.m_document->canUndo() );
if ( !nativelySupportsAnnotations && !saveToArchive ) {
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
}
QVERIFY( part.saveAs( QUrl::fromLocalFile( saveFile1.fileName() ), saveFlags ) );
QVERIFY( part.m_document->canUndo() );
@ -1251,7 +1207,7 @@ void PartTest::testSaveAsUndoStackAnnotations()
QVERIFY( part.m_document->canRedo() );
if ( !nativelySupportsAnnotations && !saveToArchive ) {
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
}
QVERIFY( part.saveAs( QUrl::fromLocalFile( saveFile2.fileName() ), saveFlags ) );
QVERIFY( part.m_document->canRedo() );
@ -1259,7 +1215,7 @@ void PartTest::testSaveAsUndoStackAnnotations()
QVERIFY( part.m_document->canRedo() );
if ( !nativelySupportsAnnotations && !saveToArchive ) {
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
}
QVERIFY( part.saveAs( QUrl::fromLocalFile( saveFile1.fileName() ), saveFlags ) );
QVERIFY( part.m_document->canRedo() );
@ -1267,14 +1223,14 @@ void PartTest::testSaveAsUndoStackAnnotations()
QVERIFY( part.m_document->canRedo() );
if ( !nativelySupportsAnnotations && !saveToArchive ) {
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "you're going to lose the annotations" dialog
}
QVERIFY( part.saveAs( QUrl::fromLocalFile( saveFile2.fileName() ), saveFlags ) );
QVERIFY( part.m_document->canRedo() );
part.m_document->redo();
QVERIFY( !part.m_document->canRedo() );
closeDialogHelper.reset(new CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "do you want to save or discard" dialog
closeDialogHelper.reset(new TestingUtils::CloseDialogHelper( &part, QDialogButtonBox::No )); // this is the "do you want to save or discard" dialog
part.closeUrl();
}
@ -1841,7 +1797,7 @@ void PartTest::testTypewriterAnnotTool()
typewriterButton->click();
QTest::qWait(1000); // Wait for the "add new note" dialog to appear
CloseDialogHelper closeDialogHelper( QDialogButtonBox::Ok );
TestingUtils::CloseDialogHelper closeDialogHelper( QDialogButtonBox::Ok );
QTest::mouseClick(part.m_pageView->viewport(), Qt::LeftButton, Qt::NoModifier, QPoint(width * 0.5, height * 0.2));
@ -1923,7 +1879,7 @@ void PartTest::testTabletProximityBehavior()
part.widget()->show();
// close the KMessageBox "There are two ways of exiting[...]"
CloseDialogHelper closeDialogHelper( w, QDialogButtonBox::Ok ); // confirm the "To leave, press ESC"
TestingUtils::CloseDialogHelper closeDialogHelper( w, QDialogButtonBox::Ok ); // confirm the "To leave, press ESC"
QTabletEvent enterProximityEvent{ QEvent::TabletEnterProximity,
QPoint( 10, 10 ), QPoint( 10, 10 ),
@ -1989,7 +1945,7 @@ void PartTest::testOpenPrintPreview()
QVERIFY( openDocument( &part, QStringLiteral( KDESRCDIR "data/file1.pdf" ) ) );
part.widget()->show();
QVERIFY(QTest::qWaitForWindowExposed(part.widget()));
CloseDialogHelper closeDialogHelper( QDialogButtonBox::Close );
TestingUtils::CloseDialogHelper closeDialogHelper( QDialogButtonBox::Close );
part.slotPrintPreview();
}

View File

@ -9,7 +9,6 @@
#include "testingutils.h"
#include "core/annotations.h"
#include <qtest.h>
namespace TestingUtils
{
@ -51,4 +50,5 @@ namespace TestingUtils
{
m_disposedAnnotationName = ann->uniqueName();
}
}

View File

@ -46,6 +46,7 @@ namespace TestingUtils
static void resetDisposedAnnotationName();
static void disposeAnnotation( const Okular::Annotation *ann );
};
}
#endif

View File

@ -930,7 +930,7 @@ Document::OpenResult DocumentPrivate::openDocumentInternal( const KPluginMetaDat
m_generator->d_func()->m_document = this;
// connect error reporting signals
QObject::connect( m_generator, &Generator::error, m_parent, &Document::error );
QObject::connect( m_generator, &Generator::error, m_parent, &Document::setOpenError );
QObject::connect( m_generator, &Generator::warning, m_parent, &Document::warning );
QObject::connect( m_generator, &Generator::notice, m_parent, &Document::notice );
@ -990,6 +990,14 @@ Document::OpenResult DocumentPrivate::openDocumentInternal( const KPluginMetaDat
// TODO: emit a message telling the document is empty
if ( openResult == Document::OpenSuccess )
openResult = Document::OpenError;
} else {
/*
* Now that the documen is opened, the tab (if using tabs) is visible, which mean that
* we can now connect the error reporting signal directly to the parent
*/
QObject::disconnect( m_generator, &Generator::error, m_parent, &Document::setOpenError );
QObject::connect( m_generator, &Generator::error, m_parent, &Document::error );
}
return openResult;
@ -2551,7 +2559,8 @@ Document::OpenResult Document::openDocument(const QString & docFile, const QUrl
}
if (!offer.isValid())
{
emit error( i18n( "Can not find a plugin which is able to handle the document being passed." ), -1 );
d->m_openError = i18n( "Can not find a plugin which is able to handle the document being passed." );
emit error( d->m_openError, -1 );
qCWarning(OkularCoreDebug).nospace() << "No plugin for mimetype '" << mime.name() << "'.";
return OpenError;
}
@ -5328,6 +5337,11 @@ QAbstractItemModel * Document::layersModel() const
return d->m_generator ? d->m_generator->layersModel() : nullptr;
}
QString Document::openError() const
{
return d->m_openError;
}
QByteArray Document::requestSignedRevisionData( const Okular::SignatureInfo &info )
{
QFile f( d->m_docFileName );
@ -5352,6 +5366,11 @@ void Document::refreshPixmaps( int pageNumber )
d->refreshPixmaps( pageNumber );
}
void Document::setOpenError( const QString &message, int /*interval*/ )
{
d->m_openError = message;
}
void DocumentPrivate::executeScript( const QString &function )
{
if( !m_scripter )

View File

@ -976,6 +976,11 @@ class OKULARCORE_EXPORT Document : public QObject
*/
QAbstractItemModel * layersModel() const;
/**
* Returns the reason why the file opening failed, if any.
*/
QString openError() const;
public Q_SLOTS:
/**
* This slot is called whenever the user changes the @p rotation of
@ -1073,6 +1078,9 @@ class OKULARCORE_EXPORT Document : public QObject
*/
void refreshPixmaps( int pageNumber );
private Q_SLOTS:
void setOpenError( const QString& message, int /*interval*/ );
Q_SIGNALS:
/**
* This signal is emitted whenever the document is about to close.

View File

@ -339,6 +339,8 @@ class DocumentPrivate
synctex_scanner_p m_synctex_scanner;
QString m_openError;
// generator selection
static QVector<KPluginMetaData> availableGenerators();
static QVector<KPluginMetaData> configurableGenerators();

View File

@ -1785,7 +1785,9 @@ bool Part::openUrl( const QUrl &_url, bool swapInsteadOfOpening )
else
{
resetStartArguments();
KMessageBox::error( widget(), i18n("Could not open %1", url.toDisplayString() ) );
/* TRANSLATORS: Adding the reason (%2) why the opening failed (if any). */
QString errorMessage = i18n("Could not open %1. %2", url.toDisplayString(), QString("\n%1").arg(m_document->openError()) );
KMessageBox::error( widget(), errorMessage );
}
return openOk;

View File

@ -304,7 +304,10 @@ void Shell::openUrl( const QUrl & url, const QString &serializedOptions )
m_recent->addUrl( url );
}
else
{
m_recent->removeUrl( url );
closeTab( activeTab );
}
}
}
}
@ -670,13 +673,6 @@ void Shell::closeTab( int tab )
void Shell::openNewTab( const QUrl& url, const QString &serializedOptions )
{
// Tabs are hidden when there's only one, so show it
if( m_tabs.size() == 1 )
{
m_tabWidget->tabBar()->show();
m_nextTabAction->setEnabled( true );
m_prevTabAction->setEnabled( true );
}
const int newIndex = m_tabs.size();
@ -684,19 +680,33 @@ void Shell::openNewTab( const QUrl& url, const QString &serializedOptions )
m_tabs.append( m_partFactory->create<KParts::ReadWritePart>(this) );
connectPart( m_tabs[newIndex].part );
// Update GUI
KParts::ReadWritePart* const part = m_tabs[newIndex].part;
m_tabWidget->addTab( part->widget(), url.fileName() );
applyOptionsToPart(part, serializedOptions);
int previousActiveTab = m_tabWidget->currentIndex();
setActiveTab( m_tabs.size() - 1 );
if( part->openUrl(url) )
{
// Update GUI
m_tabWidget->addTab( part->widget(), url.fileName() );
// Tabs are hidden when there's only one, so show it
if( m_tabs.size() == 1 )
{
m_tabWidget->tabBar()->show();
m_nextTabAction->setEnabled( true );
m_prevTabAction->setEnabled( true );
}
m_recent->addUrl( url );
}
else
{
setActiveTab( previousActiveTab );
closeTab( m_tabs.size() - 1 );
m_recent->removeUrl( url );
}
}
void Shell::applyOptionsToPart( QObject* part, const QString &serializedOptions )