Besser Drucken/HTML qt4 QTextEdit &Browser / XHTML updat

Code-Schnippsel, oder Tipps und Tricks, die einem beim Programmieren mit Qt helfen können.
Antworten
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Besser Drucken/HTML qt4 QTextEdit &Browser / XHTML updat

Beitrag von patrik08 »

XHTML ist weit weg ... was qt4 QTextEdit / Browser html parser und alle 10 classen die verbunden sind ...produziert....

Normaler qt4 html sieht so aus...

Code: Alles auswählen

<html><head><meta name="qrichtext" content="1" /><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /></head><body style=" white-space: pre-wrap; font-family:MS Shell Dlg 2; font-size:8.25pt; font-weight:400; font-style:normal; text-decoration:none;"><p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; font-style:italic; color:#ff0000;">Test page..</span></p></body></html>
ganz zu schweigen mit tabellen mit 1cm rand/border 1

der XHTML Standard ist beschrieben in http://www.w3.org/TR/xhtml1/

mit Tidy (http://tidy.sourceforge.net/ ) kann man den ganzen salat saubern...

einmal die tidy lib compiliert auf mac, window, linux (mit qtidy.h class)

svn co http://ciz.ch/svnciz/_STATIC_LIBS_QT4/lib_tidy_src/ tidylib

hat man eine 350kb libs die ein super job leistet....


einfach im class header
#include "qtidy.h"
## von der libs
im pro file

INCLUDEPATH += ../lib_tidy_src
INCLUDEPATH += ../lib_tidy_src/includ
## extra wurste mit VS MS macht einfach libtidy.lib
win32:LIBS += ../all_os_libs/libtidy.a
unix:LIBS += ../all_os_libs/libtidy.a
mac:LIBS += ../all_os_libs/libtidy.a

dann das configuration-file anpassen nach eigene bedurfnisse...
http://ciz.ch/svnciz/_STATIC_LIBS_QT4/l ... /tidy.conf

und die funktion einsetzen ....

Code: Alles auswählen

QString  HTML_Edit::TidyFile(QString html)
{
    qDebug() << "### html kommt  " << html;
    if (!is_file(TIDY_CONF)) {
        qDebug() << "### config file nicht gefunden... " << TIDY_CONF;
       return html; 
    }
    QString  cleaner ="";
    bool ok;
    ok = file_put_contents(TIDY_IN,html);
    if (ok) {
    QTidy corr;
    corr.SetUp(TIDY_CONF);
    corr.CleanTidy(TIDY_IN,TIDY_OUT);
    cleaner = file_get_contents(TIDY_OUT);
    qDebug() << "### Clean result xhtml " << cleaner;
    return cleaner;
    } else {
    return html;
    }
}
sogar beim source umschalten geht das putzen innert sekunden fraktion.

Code: Alles auswählen


void HTML_Edit::SwitschSource()
{
    if (status_html) {
    actualstream = html_area->document()->toPlainText();
    } else {
    actualstream = html_area->document()->toHtml("UTF-8");
    }
    
    actualstream=TidyFile(actualstream);
    
     if (!status_html) {
    status_html  = true;
    editcache = false;
    } else {
    status_html  = false;  
    editcache = true;        
    }
    html_area->clear(); /*  QTextEdit */
    if (status_html) {
    html_area->insertPlainText(actualstream); 
    html_area->toPlainText();
    } else {
    html_area->insertHtml(actualstream);  
    }
}
  • Und das auge sowie ein cms .... und vorallem den drucker hat etwas besseres zu sehen....
Zuletzt geändert von patrik08 am 23. Juni 2006 18:33, insgesamt 1-mal geändert.
patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Beitrag von patrik08 »

Es gibt ein update....

um somit nicht nur xhtml file zu checken sondern auch xml file...


um nicht 20 file zu machen mit x einstellungen.. habe ich eine variante gemacht welche .. die funktion di config schreibt.... und einliest .... die normal ueber ein struct geht...

einfach in der class diverse methoden machen um was auch immer zu cleanen.... und dass richtige setup aufrufen befor man putzt....

Code: Alles auswählen

/* prepare config tidy config file xml clean */
bool QTidy::SetUp_xml()
{
    status = 0;
    ErrorMSG ="";
	doc = tidyCreate();
    qDebug() << "### load config xml ....  ";
    bool ok;
    tidiconfigfile.clear();
    tidiconfigfile.append("input-xml: yes");
    tidiconfigfile.append("char-encoding: ascii");
    tidiconfigfile.append("output-encoding: ascii");
    tidiconfigfile.append("output-xml: yes");
    tidiconfigfile.append("hide-comments: yes");
    tidiconfigfile.append("numeric-entities: yes");
    tidiconfigfile.append("add-xml-space: no");
    QString configtotsl = tidiconfigfile.join("\n");
    ok = file_set_config(configtotsl);   /* TIDY_CONF */
    if (ok) {
         QByteArray configfileti = TIDY_CONF.toAscii();
         status = tidyLoadConfig( doc, configfileti.data() );  /* http://ch2.php.net/manual/de/function.tidy-load-config.php */
        if ( status != 0 ) {
         ErrorMSG ="Not possibel to load Config File!";
         return false;
        } else {  
        return true;
        } 
    } else {
      ErrorMSG ="Not possibel to load Config File!";
     return false;  
    }  
}
header...

Code: Alles auswählen


#ifndef QTIDY_H
#define QTIDY_H

#include <QString>
#include <QTextStream>
#include <QDebug>
#include <QFile>
#include <QDomText>
#include "tidy.h"
#include "main.h"
#include <QDomDocument>
#include <QDomElement>
#include <QStringList>
#include <QDir>

class QTidy
{
	/*Q_OBJECT*/
	//
public:
	QTidy();
    bool CleanTidy(QString inputfile, QString outfile);
    bool SetUp_xhtml();
    bool SetUp_xml();
    bool SetUp_xhtml_full_page();
    QString  ErrorMSG;
    QStringList  tidiconfigfile;
    int status;
    TidyDoc doc;
    bool file_set_config(QString xml);

};
//
#endif // QTIDY_H




source ....

Code: Alles auswählen


#include "qtidy.h"
#include "tidy.h"


QTidy::QTidy()
{
    status = 0;
}

/* prepare config tidy config file xml clean */
bool QTidy::SetUp_xml()
{
    status = 0;
    ErrorMSG ="";
	doc = tidyCreate();
    qDebug() << "### load config xml ....  ";
    bool ok;
    tidiconfigfile.clear();
    tidiconfigfile.append("input-xml: yes");
    tidiconfigfile.append("char-encoding: ascii");
    tidiconfigfile.append("output-encoding: ascii");
    tidiconfigfile.append("output-xml: yes");
    tidiconfigfile.append("hide-comments: yes");
    tidiconfigfile.append("numeric-entities: yes");
    tidiconfigfile.append("add-xml-space: no");
    QString configtotsl = tidiconfigfile.join("\n");
    ok = file_set_config(configtotsl);   /* TIDY_CONF */
    if (ok) {
         QByteArray configfileti = TIDY_CONF.toAscii();
         status = tidyLoadConfig( doc, configfileti.data() );  /* http://ch2.php.net/manual/de/function.tidy-load-config.php */
        if ( status != 0 ) {
         ErrorMSG ="Not possibel to load Config File!";
         return false;
        } else {  
        return true;
        } 
    } else {
      ErrorMSG ="Not possibel to load Config File!";
     return false;  
    }  
}

/* prepare config tidy config file xhtml clean */
bool QTidy::SetUp_xhtml()
{
    status = 0;
    ErrorMSG ="";
	doc = tidyCreate();
    qDebug() << "### load config. xhtml ...  ";
    bool ok;
    tidiconfigfile.clear();
    tidiconfigfile.append("output-xhtml: yes");
    tidiconfigfile.append("clean: yes");
    tidiconfigfile.append("wrap: 550");
    tidiconfigfile.append("indent-spaces: 1");
    tidiconfigfile.append("char-encoding: ascii");
    tidiconfigfile.append("output-encoding: ascii");
    tidiconfigfile.append("wrap-attributes: yes");
    tidiconfigfile.append("doctype: no");
    tidiconfigfile.append("hide-comments: yes");
    tidiconfigfile.append("numeric-entities: yes");
    tidiconfigfile.append("drop-proprietary-attributes: no");
    tidiconfigfile.append("word-2000: yes");
    //////tidiconfigfile.append("bare: yes");
    tidiconfigfile.append("show-body-only: yes");  /* only body checks */
    QString configtotsl = tidiconfigfile.join("\n");
    ok = file_set_config(configtotsl);   /* TIDY_CONF */
    if (ok) {
         QByteArray configfileti = TIDY_CONF.toAscii();
         status = tidyLoadConfig( doc, configfileti.data() );  /* http://ch2.php.net/manual/de/function.tidy-load-config.php */
        if ( status != 0 ) {
         ErrorMSG ="Not possibel to load Config File!";
         return false;
        } else {  
        return true;
        } 
    } else {
      ErrorMSG ="Not possibel to load Config File!";
     return false;  
    }  
}




/* prepare config tidy config file xhtml clean */
bool QTidy::SetUp_xhtml_full_page()
{
    status = 0;
    ErrorMSG ="";
	doc = tidyCreate();
    /////////qDebug() << "### load config. xhtml ...  ";
    bool ok;
    tidiconfigfile.clear();
    tidiconfigfile.append("output-xhtml: yes");
    tidiconfigfile.append("clean: yes");
    tidiconfigfile.append("wrap: 550");
    tidiconfigfile.append("indent-spaces: 1");
    tidiconfigfile.append("char-encoding: ascii");
    tidiconfigfile.append("output-encoding: ascii");
    tidiconfigfile.append("wrap-attributes: yes");
    tidiconfigfile.append("doctype: yes");
    tidiconfigfile.append("hide-comments: yes");
    tidiconfigfile.append("numeric-entities: yes");
    tidiconfigfile.append("drop-proprietary-attributes: yes");
    tidiconfigfile.append("word-2000: yes");
    tidiconfigfile.append("bare: yes");
    
    
    //////tidiconfigfile.append("show-body-only: yes");  /* only body checks */
    QString configtotsl = tidiconfigfile.join("\n");
    ok = file_set_config(configtotsl);   /* TIDY_CONF */
    if (ok) {
         QByteArray configfileti = TIDY_CONF.toAscii();
         status = tidyLoadConfig( doc, configfileti.data() );  /* http://ch2.php.net/manual/de/function.tidy-load-config.php */
        if ( status != 0 ) {
         ErrorMSG ="Not possibel to load Config File!";
         return false;
        } else {  
        return true;
        } 
    } else {
      ErrorMSG ="Not possibel to load Config File!";
     return false;  
    }  
}








/* QString clean file inputfile and put to outfile */
bool QTidy::CleanTidy(QString inputfile, QString outfile)
{
    /*qDebug() << "### load inputfile....  "  << inputfile;*/
    /*qDebug() << "### load outfile....  "  << outfile;*/
    Bool ok;
    ctmbstr cfgfil = NULL, outputfil = NULL, htmlfil = NULL;
    int rc = 0 - 10;
    int base = 0 - 10;
    int status = 0;
    QByteArray infile = inputfile.toAscii();
    QByteArray outfi = outfile.toAscii();
    htmlfil = infile.data();   /* incomming file entra */
    outputfil = outfi.data(); 
    rc = tidyParseFile( doc, htmlfil );
    
                if ( outputfil ) {
                    status = tidySaveFile( doc, outputfil );
                    ///////////qDebug() << "### save to out file ... ";
                } else {
                    status = tidySaveStdout( doc );
                }
                
    /* check if file exist if not copy in to out */
    QFile f( outfile );
	if (!f.exists()) {
    //////////qDebug() << "### file out not exist copy in to out... ";
       QFile Imaged(inputfile);  
      if (!Imaged.copy(outfile)) {  
       ErrorMSG ="Not possibel to copy!";          
       }
	} else {
    ///////////qDebug() << "### file found SUCCESS!!!!!!!! bravo ... ";
    return true;
    }
    /* check if file exist if not copy in to out */

return false;
}



bool QTidy::file_set_config(QString xml)
{
QString data = xml+"\n";
QFile f( TIDY_CONF );
if ( f.open( QFile::WriteOnly | QFile::Text ) )
{
QTextStream sw( &f );
sw << data;
f.close();
return true;
}
return false;
}



patrik08
Beiträge: 746
Registriert: 27. Februar 2006 10:48
Wohnort: DE Freiburg

Tidy QT4 Update Subversion

Beitrag von patrik08 »

Gewisse performance habe ich verbessert um xhtml file aus qt4 zu cleanen... und vorallem copy aus anderen programmen zu qtextedit .... openoffice 2.2 hat horror html code im export fragment...!

svn co https://qt-webdav.svn.sourceforge.net/s ... _tidy_src/ lib_tidy_src

Die class fuer QT4 ist im ordner QT4_doc....

Um gewisse copy & paste aus word oder openoffice zu putzen habe ich eine radikale html wasche gemacht ... ein paar zeile um style und white aus A4 muster zu beheben.....

tidy sollte dass auch koennen style rausholen .... aber damit gehts auch....

Etwas radikal ... aber das resultat lasst sich sehen ... un somit sind A4 copy mit 800 pixel & mehr sichtbar....

Code: Alles auswählen


QString TidyExternalHtml( QString body )
{
    QString prehtml = TidyCleanhtml(body);  /* base clean to stay on minimal standard xhtml */
    QStringList notneed;
    notneed.clear();
    ///////////////width="456" lang  class
    QRegExp expression( "width=[\"\'](.*)[\"\']", Qt::CaseInsensitive );  /* table td tr width image amen */
    QRegExp expression2( "style=[\"\'](.*)[\"\']", Qt::CaseInsensitive );
    QRegExp expression3( "lang=[\"\'](.*)[\"\']", Qt::CaseInsensitive );
    QRegExp expression4( "class=[\"\'](.*)[\"\']", Qt::CaseInsensitive );
    
    
    expression.setMinimal(true);
    expression2.setMinimal(true);
    expression3.setMinimal(true);
    expression4.setMinimal(true);
    
    int iPosition = 0;
    while( (iPosition = expression.indexIn( prehtml , iPosition )) != -1 ) {
        QString semi1 = expression.cap( 1 );
        notneed.append(QString("width=\"%1\"").arg(semi1));
        notneed.append(QString("width='%1'").arg(semi1));
        iPosition += expression.matchedLength();
    }
    
    iPosition = 0;
       while( (iPosition = expression2.indexIn( prehtml , iPosition )) != -1 ) {
        QString semi2 = expression2.cap( 1 );
        notneed.append(QString("style=\"%1\"").arg(semi2));
        notneed.append(QString("style='%1'").arg(semi2));
        iPosition += expression2.matchedLength();
    }
    
    iPosition = 0;
       while( (iPosition = expression3.indexIn( prehtml , iPosition )) != -1 ) {
        QString semi3 = expression3.cap( 1 );
        notneed.append(QString("lang=\"%1\"").arg(semi3));
        notneed.append(QString("lang='%1'").arg(semi3));
        iPosition += expression3.matchedLength();
    }
    
     iPosition = 0;
       while( (iPosition = expression4.indexIn( prehtml , iPosition )) != -1 ) {
        QString semi4 = expression4.cap( 1 );
        notneed.append(QString("class=\"%1\"").arg(semi4));
        notneed.append(QString("class='%1'").arg(semi4));
        iPosition += expression4.matchedLength();
    }
    
    for (int i = 0; i < notneed.size(); ++i)  {
          const QString fluteremove = notneed.at(i);
          prehtml = prehtml.replace(fluteremove,"", Qt::CaseInsensitive );
    }
    
    return prehtml;
}




Um den paste annehmen zu koennen von andere programmen ....
muss man QTextBrowser erweiter....

Da die bilder auch gut kommen im Paste ( Copy von gimp , firefox, openoffice ..ecc... ) kann man sie auch annehmen....
und dass emit signal gibt dann am oberen widget der command das bild beim cursor zu integrieren.....

Drag & Drop ist den ein level hoher im widget ....

Code: Alles auswählen



#include "qvimedit.h"
//
/*  Save file as qvimedit.cpp  */
/*  incomming class name QVimedit */
//


QVimedit::QVimedit( QWidget* parent )
 : QTextBrowser(parent)
{
	numerobase = 0;
}

QVimedit::~QVimedit()
{
    numerobase = 0;
}


bool QVimedit::canInsertFromMimeData ( const QMimeData * source )
{
    return QTextEdit::canInsertFromMimeData(source);
     qDebug() << "### insertFromMimeData 1  ";
}
    
void QVimedit::insertFromMimeData ( const QMimeData * source )
{
    
    //////qDebug() << "### insertFromMimeData 2  ";
    if ( source->hasImage() ) {
         numerobase++;
         const  QString nuovaim = QString("%2/image_%1.png").arg(numerobase).arg(QDir::homePath());
         QImage images = qvariant_cast<QImage>(source->imageData());
         bool salvato = images.save(nuovaim,"PNG",100);
         //////////////////qDebug() << "### salvato 1/0  " << salvato;
          emit TakeImage(nuovaim);   /* and remove nuovaim  */
         return;
        
    }
    ////////////////QTextEdit::insertFromMimeData(source);
    if ( source->formats().contains("text/html") ) {
        ////////qDebug() << "### incomming paste text/html  ";
        const  QString tidicaches = QString("%2/.qtidy/").arg(QDir::homePath());
        QString draghtml = source->html();
        /* fwriteutf8(QString fullFileName,QString xml) */
        QTidy *tidy = new QTidy();   /* QTidy  *tidy; */
               tidy->Init(tidicaches);  /* tidy cache remove on last event */
        const  QString xhtmlnew = tidy->TidyExternalHtml(draghtml);
        ///////fwriteutf8("copy_in.html",xhtmlnew);
         QTextDocumentFragment fragment = QTextDocumentFragment::fromHtml(xhtmlnew);
         textCursor().insertFragment(fragment);
         emit IncommingHTML();
        return;
    }
}







Code: Alles auswählen


class QVimedit : public QTextBrowser
{
     Q_OBJECT
//
public:	 
    QVimedit( QWidget *parent = 0);
    ~QVimedit();
    bool canInsertFromMimeData ( const QMimeData * source );
    void insertFromMimeData ( const QMimeData * source );
//
protected:
//
private:
    int numerobase;
signals:
     void IncommingHTML();
     void TakeImage( QString nuovaimagine );
public slots:

};

.........................
speack português italiano deutsch english castellà qt
Antworten