From db134d69c4e2448db024a2707f66849713c8e145 Mon Sep 17 00:00:00 2001 From: "Nox P@sNox" Date: Sun, 16 Sep 2012 14:33:19 +0200 Subject: [PATCH 1/3] Fix a bug that does not set the document highlighter correctly. --- src/syntax/Highlighter.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/syntax/Highlighter.cpp b/src/syntax/Highlighter.cpp index 92cf155..c21c7ce 100644 --- a/src/syntax/Highlighter.cpp +++ b/src/syntax/Highlighter.cpp @@ -29,15 +29,19 @@ class Syntax::HighlighterPrivate { : highlighter( _highlighter ) { Q_ASSERT( highlighter ); + + if ( highlighter->textDocument() ) { + highlighter->textDocument()->setSyntaxHighlighter( highlighter ); + } } - TextBlockUserData* testBlockUserData( const QTextBlock& block ) const { + /*TextBlockUserData* testBlockUserData( const QTextBlock& block ) const { return highlighter->textDocument()->testUserData( block ); } TextBlockUserData* blockUserData( QTextBlock& block ) const { return highlighter->textDocument()->userData( block ); - } + }*/ private: Syntax::Highlighter* highlighter; From bafa238679a8fc15cf0f1eed900141040480d26f Mon Sep 17 00:00:00 2001 From: "Nox P@sNox" Date: Sun, 16 Sep 2012 14:33:52 +0200 Subject: [PATCH 2/3] Introduce futured api for file opening to avoid gui freeze. --- src/Manager.cpp | 9 +++------ src/Threading.cpp | 5 +++++ src/Threading.h | 1 + src/Tools.cpp | 39 +++++++++++++++++++++++++++++++++++++++ src/Tools.h | 8 ++++---- 5 files changed, 52 insertions(+), 10 deletions(-) diff --git a/src/Manager.cpp b/src/Manager.cpp index 295b474..80d263d 100644 --- a/src/Manager.cpp +++ b/src/Manager.cpp @@ -41,15 +41,12 @@ class QodeEdit::ManagerData : public QObject { // update syntaxes syntaxesFilesWatcher = new QFutureWatcher >( this ); connect( syntaxesFilesWatcher, SIGNAL( finished() ), this, SLOT( syntaxesFilesParsed() ) ); - syntaxesFilesWatcher->setFuture( QodeEdit::Threading::parseSyntaxesFiles( manager->syntaxDefinitionFilePaths() ) ); // update schemas /*schemasFilesWatcher = new QFutureWatcher( this ); connect( syntaxesFilesWatcher, SIGNAL( finished() ), this, SLOT( syntaxesFilesParsed() ) ); - - const QFuture future = QodeEdit::Threading::listFilesInPaths( manager->syntaxDefinitionFilePaths(), QStringList( "*.xml" ), true ); - syntaxesFilesWatcher->setFuture( future );*/ + schemasFilesWatcher->setFuture( QodeEdit::Threading::listFilesInPaths( manager->syntaxDefinitionFilePaths(), QStringList( "*.xml" ), true ) ); } public slots: @@ -226,7 +223,7 @@ Syntax::Highlighter* QodeEdit::Manager::highlighterForFilePath( const QString& f } if ( documents.isEmpty() ) { - return 0; + return QodeEdit::Manager::highlighter( QString::null, QString::null, textDocument ); } return QodeEdit::Manager::highlighter( ( documents.end() -1 ).value()->name(), QString::null, textDocument ); @@ -245,7 +242,7 @@ Syntax::Highlighter* QodeEdit::Manager::highlighterForMimeType( const QString& m } if ( documents.isEmpty() ) { - return 0; + return QodeEdit::Manager::highlighter( QString::null, QString::null, textDocument ); } return QodeEdit::Manager::highlighter( ( documents.end() -1 ).value()->name(), QString::null, textDocument ); diff --git a/src/Threading.cpp b/src/Threading.cpp index f18afb3..35e2710 100644 --- a/src/Threading.cpp +++ b/src/Threading.cpp @@ -18,3 +18,8 @@ QFuture > QodeEdit::Threading::bestMatchingMimeTypesIcon { return QtConcurrent::run( QodeEdit::Tools::bestMatchingMimeTypesIcons, mimeTypes, defaultMimeType, false ); } + +QFuture > > QodeEdit::Threading::getFilesContentWithTextCodec( const QStringList& filePaths, const QByteArray& textCodec ) +{ + return QtConcurrent::run( QodeEdit::Tools::getFilesContentWithTextCodec, filePaths, textCodec, false ); +} diff --git a/src/Threading.h b/src/Threading.h index f09f3a0..e9494c3 100644 --- a/src/Threading.h +++ b/src/Threading.h @@ -15,6 +15,7 @@ namespace Threading QFuture listFilesInPaths( const QStringList& paths, const QStringList& filters, bool recursive, bool sort = true ); QFuture > parseSyntaxesFiles( const QStringList& paths ); QFuture > bestMatchingMimeTypesIcons( const QHash& mimeTypes, const QString& defaultMimeType ); + QFuture > > getFilesContentWithTextCodec( const QStringList& filePaths, const QByteArray& textCodec ); }; // Threading }; // QodeEdit diff --git a/src/Tools.cpp b/src/Tools.cpp index 05b5778..e074d70 100644 --- a/src/Tools.cpp +++ b/src/Tools.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include namespace QodeEdit { @@ -175,6 +176,21 @@ bool QodeEdit::Tools::versionStringLessThan( const QString& left, const QString& return leftParts.value( 4 ) < rightParts.value( 4 ); // not the best but afaik ;) } +QTextCodec* QodeEdit::Tools::textCodec( const QByteArray& name, const QByteArray& data ) +{ + QTextCodec* codec = QTextCodec::codecForName( name ); + + if ( !codec ) { + codec = QTextCodec::codecForUtfText( data ); + } + + if ( !codec ) { + codec = QTextCodec::codecForLocale(); + } + + return codec; +} + QStringList QodeEdit::Tools::listFilesInPath( const QString& path, const QStringList& filters, bool recursive, bool sort ) { QDir dir( path ); @@ -283,3 +299,26 @@ QHash QodeEdit::Tools::bestMatchingMimeTypesIcons( const QHash return hash; } + +QHash > QodeEdit::Tools::getFilesContentWithTextCodec( const QStringList& filePaths, const QByteArray& textCodec, bool processEvents ) +{ + const QTextCodec* codec = QodeEdit::Tools::textCodec( textCodec ); + QHash > contents; + + foreach ( const QString& filePath, filePaths ) { + QFile file( filePath ); + + if ( file.open( QIODevice::ReadOnly ) ) { + contents[ filePath ] = qMakePair( codec->toUnicode( file.readAll() ), QString() ); + } + else { + contents[ filePath ] = qMakePair( QString(), file.errorString() ); + } + + if ( processEvents ) { + QApplication::processEvents(); + } + } + + return contents; +} diff --git a/src/Tools.h b/src/Tools.h index 6997a11..0abdb38 100644 --- a/src/Tools.h +++ b/src/Tools.h @@ -19,10 +19,8 @@ #include "QodeEdit.h" #include - -class QString; -template class QHash; -class QStringList; +#include +#include namespace Syntax { class Document; @@ -48,11 +46,13 @@ namespace Tools { bool localeAwareStringEquals( const QString& left, const QString& right ); bool localeAwareStringLessThan( const QString& left, const QString& right ); bool versionStringLessThan( const QString& left, const QString& right ); + QTextCodec* textCodec( const QByteArray& name, const QByteArray& data = QByteArray() ); QStringList listFilesInPath( const QString& path, const QStringList& filters, bool recursive, bool sort = false ); QStringList listFilesInPaths( const QStringList& paths, const QStringList& filters, bool recursive, bool sort = false ); QHash parseSyntaxesFiles( const QStringList& paths ); QHash bestMatchingMimeTypesIcons( const QHash& mimeTypes, const QString& defaultMimeType, bool processEvents ); + QHash > getFilesContentWithTextCodec( const QStringList& filePaths, const QByteArray& textCodec, bool processEvents ); }; // Tools }; // QodeEdit From 217e31eba61eab162bdd42acf9768b8ec989a091 Mon Sep 17 00:00:00 2001 From: "Nox P@sNox" Date: Sun, 16 Sep 2012 14:34:09 +0200 Subject: [PATCH 3/3] Use recently introduced futured file opening api --- example/UIMain.cpp | 84 +++++++++++++++++++++++++--------------------- example/UIMain.h | 4 +++ 2 files changed, 50 insertions(+), 38 deletions(-) diff --git a/example/UIMain.cpp b/example/UIMain.cpp index 928a575..83fce4f 100644 --- a/example/UIMain.cpp +++ b/example/UIMain.cpp @@ -24,8 +24,7 @@ #include "QodeEdit.h" #include "Manager.h" #include "Tools.h" - -#include +#include "Threading.h" static QMutex qMutex; static UIMain* qMain = 0; @@ -48,27 +47,6 @@ QodeEditor::QodeEditor( QWidget* parent ) new QShortcut( QKeySequence::Save, this, SLOT( save() ) ); } -QString QodeEditor::fileContent( const QString& filePath, const QByteArray& textCodec ) -{ - QFile file( filePath ); - - if ( !file.exists() ) { - return QString::null; - } - - if ( !file.open( QIODevice::ReadOnly ) ) { - return QString::null; - } - - QTextCodec* codec = QTextCodec::codecForName( textCodec ); - - if ( !codec ) { - codec = QTextCodec::codecForLocale(); - } - - return codec->toUnicode( file.readAll() ); -} - void QodeEditor::save() { document()->setModified( false ); @@ -109,6 +87,10 @@ UIMain::UIMain( QWidget* parent ) connect( mManager, SIGNAL( updated() ), this, SLOT( manager_updated() ) ); mManager->initialize(); + +#if !defined( QT_NO_DEBUG ) + //debug(); +#endif } UIMain::~UIMain() @@ -171,6 +153,8 @@ QodeEditor* UIMain::editor( int row ) const void UIMain::debug() { + qWarning() << mManager->availableSyntaxes(); + qWarning() << mManager->mimeTypeForFile( "toto.h" ); qWarning() << mManager->mimeTypeForFile( "toto.c" ); qWarning() << mManager->mimeTypeForFile( "toto.cpp" ); @@ -212,14 +196,20 @@ void UIMain::on_swEditors_currentChanged( int row ) ui->cbSyntax->setCurrentSyntax( editor( row )->textDocument()->syntaxHighlighter()->syntaxDocument().name() ); } -void UIMain::manager_updated() +void UIMain::listFilesFinished() { -#if !defined( QT_NO_DEBUG ) - //debug(); -#endif - - //qWarning() << Syntax::Factory::availableSyntaxes(); + const QStringList files = mListFilesWatcher->result(); + mListFilesWatcher->deleteLater(); + if ( !mOpenFilesWatcher ) { + mOpenFilesWatcher = new QFutureWatcher > >( this ); + connect( mOpenFilesWatcher, SIGNAL( finished() ), this, SLOT( openFilesFinished() ) ); + mOpenFilesWatcher->setFuture( QodeEdit::Threading::getFilesContentWithTextCodec( files, "UTF-8" ) ); + } +} + +void UIMain::openFilesFinished() +{ /*".desktop", "4GL", "4GL-PER", "ABAP", "ABC", "ActionScript 2.0", "Ada", -- "AHDL", "Alerts", "Alerts_indent", "AMPLE", "ANS-Forth94", "ANSI C89", "Ansys", "Apache Configuration", "Asm6502", "ASN.1", "ASP", "Asterisk", "AVR Assembler", @@ -245,16 +235,18 @@ void UIMain::manager_updated() "Vera", "Verilog", "VHDL", "VRML", "Wesnoth Markup Language", "WINE Config", "x.org Configuration", "xHarbour", "XML", "XML (Debug)", "xslt", "XUL", "yacas", "Yacc/Bison", "YAML", "Zonnon", "Zsh"*/ - const QString path = mManager->sharedDataFilePath( "/samples" ); - const QStringList filePaths = QodeEdit::Tools::listFilesInPath( path, QStringList(), true ); + const QHash > contents = mOpenFilesWatcher->result(); + mOpenFilesWatcher->deleteLater(); - foreach ( const QString& filePath, filePaths ) { - Syntax::Highlighter* highlighter = mManager->highlighterForFilePath( filePath ); + foreach ( const QString& filePath, contents.keys() ) { + const QPair& pair = contents[ filePath ]; - if ( highlighter ) { + // File opened + if ( pair.second.isEmpty() ) { QodeEditor* editor = new QodeEditor( this ); - #warning Create a QodeEdit threaded/futured api for file loading - editor->setInitialText( QodeEditor::fileContent( filePath ) ); + Syntax::Highlighter* highlighter = mManager->highlighterForFilePath( filePath ); + + editor->setInitialText( pair.first ); editor->textDocument()->setSyntaxHighlighter( highlighter ); QListWidgetItem* item = new QListWidgetItem( ui->lwEditors ); @@ -262,10 +254,26 @@ void UIMain::manager_updated() item->setData( Qt::UserRole, QVariant::fromValue( editor ) ); ui->swEditors->addWidget( editor ); } + // An error occurs else { - qWarning( "%s: Can't create highlighter for '%s'", Q_FUNC_INFO, qPrintable( filePath ) ); + qWarning() << pair.second; } } - +} + +void UIMain::manager_updated() +{ statusBar()->showMessage( tr( "QodeEdit ready." ) ); + + if ( ui->swEditors->count() > 0 ) { + return; + } + + if ( !mListFilesWatcher ) { + const QString path = mManager->sharedDataFilePath( "/samples" ); + + mListFilesWatcher = new QFutureWatcher( this ); + connect( mListFilesWatcher, SIGNAL( finished() ), this, SLOT( listFilesFinished() ) ); + mListFilesWatcher->setFuture( QodeEdit::Threading::listFilesInPaths( QStringList( path ), QStringList(), true ) ); + } } diff --git a/example/UIMain.h b/example/UIMain.h index 742b1f3..ec124f7 100644 --- a/example/UIMain.h +++ b/example/UIMain.h @@ -53,11 +53,15 @@ class UIMain : public QMainWindow public slots: void appendDebugMessage( const QString& message ); + void listFilesFinished(); + void openFilesFinished(); protected: Ui_UIMain* ui; QodeEdit::Manager* mManager; QHash mEditors; + QPointer > mListFilesWatcher; + QPointer > > > mOpenFilesWatcher; QodeEditor* editor( int row ) const;