diff options
Diffstat (limited to 'quanta/components/csseditor/csseditor.cpp')
-rw-r--r-- | quanta/components/csseditor/csseditor.cpp | 697 |
1 files changed, 697 insertions, 0 deletions
diff --git a/quanta/components/csseditor/csseditor.cpp b/quanta/components/csseditor/csseditor.cpp new file mode 100644 index 00000000..692a8edf --- /dev/null +++ b/quanta/components/csseditor/csseditor.cpp @@ -0,0 +1,697 @@ +/*************************************************************************** + csseditor.cpp - description + ------------------- + begin : mer lug 23 11:20:17 CEST 2003 + copyright : (C) 2003 by gulmini luciano + email : gulmini.luciano@student.unife.it + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "csseditor.h" +#include <qlayout.h> +#include <qtabwidget.h> +#include <qpushbutton.h> +#include <qcheckbox.h> +#include <qtextedit.h> +#include <qtextstream.h> +#include <qfileinfo.h> + +#include <kapplication.h> +#include <klocale.h> +#include <khtml_part.h> +#include <khtmlview.h> +#include <kstandarddirs.h> +#include <klineedit.h> +#include <kdebug.h> +#include <kconfig.h> +#include <kparts/browserextension.h> + +#include "propertysetter.h" +#include "qmyhighlighter.h" +#include "cssshpropertyparser.h" +#include "shorthandformer.h" +#include "percentageeditor.h" +#include "colorslider.h" +#include "tlpeditors.h" +#include "doubleeditors.h" +#include "specialsb.h" +#include "colorrequester.h" + + + +myCheckListItem::myCheckListItem(QListView * parent, const QString & text):QCheckListItem(parent, text, QCheckListItem::CheckBox),m_checkedChildren(0){ + m_sig = new QSignal; +} + +myCheckListItem::myCheckListItem(QCheckListItem * parent, const QString & text):QCheckListItem(parent, text, QCheckListItem::CheckBox),m_checkedChildren(0){ + m_sig = new QSignal; +} + +myCheckListItem::~myCheckListItem(){ + delete m_sig; +} + +void myCheckListItem::connect( QObject *receiver, const char *member ){ + m_sig->connect( receiver, member ); +} + +void myCheckListItem::activate(){ + if(isOn()) QCheckListItem::activate(); +} + +void myCheckListItem::addCheckedChild() { + m_checkedChildren++; +} + +void myCheckListItem::stateChange (bool b){ + + if(!b) { + if(childCount()) { + QListViewItem * child = firstChild(); + while( child ) { + m_sig->setValue(QVariant(child->text(0))); + m_sig->activate(); + static_cast<myCheckListItem*>(child)->setOn(false); + child = child->nextSibling(); + } + m_checkedChildren = 0; + } + else { + if(parent()){ + myCheckListItem *p = static_cast<myCheckListItem*>(parent()); + while( p ) { + if( p->m_checkedChildren != 1) { + p->m_checkedChildren--; + m_sig->setValue(QVariant(text(0))); + m_sig->activate(); + break; + } + else { + m_sig->setValue(QVariant(text(0))); + m_sig->activate(); + p->setOn(false); + } + p = static_cast<myCheckListItem*>(p->parent()); + } + } + else { + m_sig->setValue(QVariant(text(0))); + m_sig->activate(); + } + } + } + else { + if(parent()) static_cast<myCheckListItem*>(parent())->addCheckedChild(); + } +} + +void CSSEditor::appendSub(QDomNodeList l, myCheckListItem *cli){ + unsigned int i; + for(i=0;i<l.length();i++) { + myCheckListItem *item = new myCheckListItem(cli,l.item(i).toElement().tagName()); + item->connect(this,SLOT(removeProperty(const QVariant&))); + if(l.item(i).toElement().attribute("hasSub") == "yes") + appendSub(l.item(i).childNodes(),item); + } +} + +void CSSEditor::buildListView(QDomNodeList l, QListView *lv){ + unsigned int i; + for(i=0;i<l.length();i++) { + myCheckListItem *item = new myCheckListItem(lv,l.item(i).toElement().tagName()); + item->connect(this,SLOT(removeProperty(const QVariant&))); + if(l.item(i).toElement().attribute("hasSub") == "yes") { + QDomNodeList listSub = l.item(i).childNodes(); + appendSub(listSub,item); + } + } +} + +void CSSEditor::setCurrentPropOn(const QString& s){ + if( (m_currentProp = static_cast<myCheckListItem*>(lvVisual->findItem( s,0 )) )) + m_currentProp->setOn(true); + else + if( (m_currentProp = static_cast<myCheckListItem*>(lvAll->findItem( s,0 )) )) + m_currentProp->setOn(true); + else + if( (m_currentProp = static_cast<myCheckListItem*>(lvAural->findItem( s,0 )) )) + m_currentProp->setOn(true); + else + if( (m_currentProp = static_cast<myCheckListItem*>(lvInteractive->findItem( s,0 )) )) + m_currentProp->setOn(true); + else + if( (m_currentProp = static_cast<myCheckListItem*>(lvPaged->findItem( s,0 )) )) + m_currentProp->setOn(true); + + if( m_currentProp && m_currentProp->depth() ) { + myCheckListItem *p = static_cast<myCheckListItem*>(m_currentProp->parent()); + while(p) { + p->setOn(true); + p=static_cast<myCheckListItem*>(p->parent()); + } + } +} + + + void CSSEditor::addAndSetPropertyOn(const QString& property, const QString& value){ + addProperty(property,value); + setCurrentPropOn(property); + } + + void CSSEditor::setSidesOfPropertyBorderOn(const QString& s){ + static_cast<myCheckListItem*>(lvVisual->findItem( "border-top",0 ))->setOn(true); + static_cast<myCheckListItem*>(lvVisual->findItem( "border-right",0 ))->setOn(true); + static_cast<myCheckListItem*>(lvVisual->findItem( "border-bottom",0 ))->setOn(true); + static_cast<myCheckListItem*>(lvVisual->findItem( "border-left",0 ))->setOn(true); + static_cast<myCheckListItem*>(lvVisual->findItem( "border-top-"+s,0 ))->setOn(true); + static_cast<myCheckListItem*>(lvVisual->findItem( "border-right-"+s,0 ))->setOn(true); + static_cast<myCheckListItem*>(lvVisual->findItem( "border-bottom-"+s,0 ))->setOn(true); + static_cast<myCheckListItem*>(lvVisual->findItem( "border-left-"+s,0 ))->setOn(true); + } + +void CSSEditor::hidePreviewer(){ + fPreview->hide(); + } + +void CSSEditor::initialize(){ + + m_config = kapp->config(); + connect(pbOk, SIGNAL(clicked()), this, SLOT(toggleShortendForm())); + m_config->setGroup("CSSEditor Options"); + SHckb->setChecked(m_config->readBoolEntry("Shorthand form enabled",false)); + + QString configFile = locate("appdata", "csseditor/config.xml"); + + m_myhi = new QMyHighlighter(display); + + QBoxLayout *fPreviewLayout = new QBoxLayout(fPreview,QBoxLayout::LeftToRight); + m_previewer=new KHTMLPart(fPreview); + + fPreviewLayout->addWidget(m_previewer->view()); + + QFile file( configFile ); + if ( !file.open( IO_ReadOnly ) ) { + return; + } + if ( !m_doc.setContent( &file ) ) { + file.close(); + return; + } + file.close(); + + QDomElement docElem = m_doc.documentElement(); + + QDomNode n = docElem.firstChild(); + while( !n.isNull() ) { + QDomElement e = n.toElement(); + if( !e.isNull() ) { + if( e.attribute("type") == "visual") { + lvVisual->setRootIsDecorated(true); + buildListView(e.childNodes(), lvVisual); + } + if( e.attribute("type") == "paged") { + lvPaged->setRootIsDecorated(true); + buildListView(e.childNodes(), lvPaged); + } + if( e.attribute("type") == "interactive") { + lvInteractive->setRootIsDecorated(true); + buildListView(e.childNodes(), lvInteractive); + } + if( e.attribute("type") == "aural") { + lvAural->setRootIsDecorated(true); + buildListView(e.childNodes(), lvAural); + } + if( e.attribute("type") == "all"){ + lvAll->setRootIsDecorated(true); + buildListView(e.childNodes(), lvAll); + } + } + n = n.nextSibling(); + } // end while + + Connect(); + + QBoxLayout *fEditingLayout = new QBoxLayout(fEditing,QBoxLayout::LeftToRight); + + m_ps = new propertySetter(fEditing); + fEditingLayout->addWidget(m_ps); + connect(m_ps, SIGNAL(valueChanged(const QString&)), this, SLOT(checkProperty(const QString&))); + + QStringList props; + QString temp; + bool normalMode = true; + + if( !m_selectorName.isEmpty() ){ //the cssselector has been called + m_initialProperties = m_initialProperties.stripWhiteSpace(); + props=QStringList::split(";",m_initialProperties); + temp= m_selectorName + " {\n\t" ; + } + + else { + m_InlineStyleContent = m_InlineStyleContent.stripWhiteSpace(); + normalMode = false; + props=QStringList::split(";",m_InlineStyleContent); + temp="\n\t"; + } + + for ( QStringList::Iterator it = props.begin(); it != props.end(); ++it ) { + const QString propertyName((*it).section(":",0,0).stripWhiteSpace()); + const QString propertyValue((*it).section(":",1)); + + if( ShorthandFormer::SHFormList().contains(propertyName)==0 ) { + temp+= propertyName + " : " + propertyValue +";\n\t"; + addAndSetPropertyOn(propertyName,propertyValue); + } + else{ + ShorthandFormer decompressor; + QMap<QString,QString> expandedProperties = decompressor.expand(propertyName, propertyValue ); + QMap<QString,QString>::Iterator it; + + for ( it = expandedProperties.begin(); it != expandedProperties.end(); ++it ) { + addAndSetPropertyOn( it.key(), it.data() ); + temp += ( it.key() + " : " + it.data() + ";\n\t"); + } + } + } + temp.truncate(temp.length()-1); + //temp.chop(1); + if(normalMode)//normal mode editing + temp+="}"; + display->setText(temp); + activatePreview(); +} + +void CSSEditor::toggleShortendForm() +{ + m_config->setGroup("CSSEditor Options"); + m_config->writeEntry("Shorthand form enabled", SHckb->isChecked()); + m_config->sync(); +} + +CSSEditor::CSSEditor(QListViewItem *i, QWidget *parent, const char *name) : CSSEditorS(parent, name){ + m_selectorName = i->text(0); + m_initialProperties = i->text(1); +} + +CSSEditor::~CSSEditor() { + delete m_myhi; + delete m_ps; + delete m_previewer; +} + +void CSSEditor::setMiniEditors(QListViewItem* i){ + + m_ps->reset(); + + if(i->childCount()==0) { + m_currentProp = static_cast<myCheckListItem*>(i); + QDomNodeList valueTypes = m_doc.elementsByTagName(i->text(0)).item(0).childNodes(); + unsigned int i; + for(i=0; i<valueTypes.length(); i++) { + QDomElement curr =valueTypes.item(i).toElement(); + QString valueTypeName(curr.tagName()); + + if(valueTypeName =="list") { + m_ps->setComboBox(); + QStringList values = QStringList::split(",",curr.attribute("value")); + m_ps->ComboBox()->insertStringList(values); + if(m_properties.contains(m_currentProp->text(0)) !=0 ) + if( values.contains(m_currentProp->text(0))) + m_ps->ComboBox()->setCurrentText(m_properties[m_currentProp->text(0)]); + if(curr.attribute("editable") == "yes"){ + m_ps->ComboBox()->setEditable(true); + /*if(m_properties.contains(m_currentProp->text(0)) !=0 ) + m_ps->ComboBox()->setEditText(m_properties[m_currentProp->text(0)]); */ + } + } + else + + /*if( typeName == "spinbox") { + m_ps->setSpinBox("0", values.item(k).toElement().attribute("minValue"), + values.item(k).toElement().attribute("maxValue"), + values.item(k).toElement().attribute("suffix")); + } + + else*/ + if( valueTypeName == "number") m_ps->setLineEdit(); + else + if( valueTypeName == "integer") { + if(m_properties.contains(m_currentProp->text(0)) !=0 ) { + if(!curr.attribute("minValue").isNull()) + m_ps->setSpinBox(m_properties[m_currentProp->text(0)],curr.attribute("minValue")); + else + m_ps->setSpinBox(m_properties[m_currentProp->text(0)]); + } + else + if(!curr.attribute("minValue").isNull()) + m_ps->setSpinBox("0",curr.attribute("minValue")); + else + m_ps->setSpinBox(); + } + else + if( valueTypeName == "length") { + lengthEditor *editor = new lengthEditor(m_ps); + if(m_properties.contains(m_currentProp->text(0)) !=0 ) + editor->setInitialValue(m_properties[m_currentProp->text(0)]); + else + editor->setInitialValue(QString::null); + m_ps->installMiniEditor(editor); + } + else + if( valueTypeName == "percentage") { + if(m_properties.contains(m_currentProp->text(0)) !=0 ){ + percentageEditor *editor = new percentageEditor(m_properties[m_currentProp->text(0)],m_ps); + m_ps->installMiniEditor(editor); + } + else { + percentageEditor *editor = new percentageEditor("0",m_ps); + m_ps->installMiniEditor(editor); + } + } + else + if( valueTypeName == "doubleLength") { + doubleLengthEditor *editor = new doubleLengthEditor(m_ps); + + if(m_properties.contains(m_currentProp->text(0)) !=0 ){ + QString temp(m_properties[m_currentProp->text(0)].simplifyWhiteSpace()), + sx(temp.section(" ",0,0)), + dx(temp.section(" ",1,1)); + + editor->setInitialValue(sx,dx); + } + else editor->setInitialValue(QString::null,QString::null); + m_ps->installMiniEditor(editor); + } + else + if( valueTypeName == "doublePercentage") { + doublePercentageEditor *editor = new doublePercentageEditor(m_ps); + + if(m_properties.contains(m_currentProp->text(0)) !=0 ){ + QString temp(m_properties[m_currentProp->text(0)].simplifyWhiteSpace()), + sx(temp.section(" ",0,0)), + dx(temp.section(" ",1,1)); + + editor->setInitialValue(sx,dx); + } + else editor->setInitialValue(QString::null,QString::null); + m_ps->installMiniEditor(editor); + } + else + if( valueTypeName == "frequency") { + frequencyEditor *editor = new frequencyEditor(m_ps); + if(m_properties.contains(m_currentProp->text(0)) !=0 ) + editor->setInitialValue(m_properties[m_currentProp->text(0)]); + else + editor->setInitialValue(QString::null); + m_ps->installMiniEditor(editor); + } + else + if( valueTypeName == "time") { + timeEditor *editor = new timeEditor(m_ps); + if(m_properties.contains(m_currentProp->text(0)) !=0 ) + editor->setInitialValue(m_properties[m_currentProp->text(0)]); + else + editor->setInitialValue(QString::null); + m_ps->installMiniEditor(editor); + } + else + if( valueTypeName == "angle") { + angleEditor *editor = new angleEditor(m_ps); + if(m_properties.contains(m_currentProp->text(0)) !=0 ) + editor->setInitialValue(m_properties[m_currentProp->text(0)]); + else + editor->setInitialValue(QString::null); + m_ps->installMiniEditor(editor); + } + else + if( valueTypeName == "freeedit") { + m_ps->setLineEdit(); + } + else + if( valueTypeName == "uri") { + URIEditor *editor = new URIEditor(m_ps); + + if(curr.attribute("mode") == "multi") editor->setMode(URIEditor::Multi); + else editor->setMode(URIEditor::Single); + + if( curr.attribute("resourceType") == "audio") editor->setResourceType(URIEditor::audio); + else + if( curr.attribute("resourceType") == "image") editor->setResourceType(URIEditor::image); + else + if( curr.attribute("resourceType") == "mousePointer") editor->setResourceType(URIEditor::mousePointer); + + m_ps->installMiniEditor(editor); + } + else + if( valueTypeName == "colors") { + RGBcolorSlider *RGBeditor = new RGBcolorSlider(m_ps); + colorRequester *CReditor = new colorRequester(m_ps); + if(m_properties.contains(m_currentProp->text(0)) !=0 ){ + CReditor->lineEdit()->setText(m_properties[m_currentProp->text(0)]); + CReditor->setInitialValue(); + + } + + m_ps->installMiniEditor(CReditor); + m_ps->setPredefinedColorListEditor(); + m_ps->installMiniEditor(RGBeditor); + } + else + if( valueTypeName =="doubleList") { + doubleComboBoxEditor *editor = new doubleComboBoxEditor(m_ps); + editor->cbSx()->insertStringList(QStringList::split(",",curr.firstChild().toElement().attribute("value"))); + editor->cbDx()->insertStringList(QStringList::split(",",curr.lastChild().toElement().attribute("value"))); + m_ps->installMiniEditor(editor); + } + else + if( valueTypeName == "fontDialog" ){ + fontEditor *editor = new fontEditor(m_ps); + if(m_properties.contains(m_currentProp->text(0)) !=0 ){ + editor->setInitialValue(m_properties[m_currentProp->text(0)]); + } + else editor->setInitialValue(QString::null); + m_ps->installMiniEditor(editor); + } + } + m_ps->addButton(); + m_ps->Show(); + } +} + +void CSSEditor::checkProperty(const QString& v){ + if(!m_currentProp->isOn()) + m_currentProp->setOn(true); + + if( m_currentProp->depth() ){ + myCheckListItem *p = static_cast<myCheckListItem*>(m_currentProp->parent()); + while(p){ + p->setOn(true); + p=static_cast<myCheckListItem*>(p->parent()); + } + } + + if(m_currentProp->text(0) =="border-style" ){ + setSidesOfPropertyBorderOn("style"); + QStringList values = QStringList::split(" ",v.stripWhiteSpace()); + addProperty("border-top-style",values[0]); + switch(values.count()) { + case 1: + addProperty("border-right-style",values[0]); + addProperty("border-bottom-style",values[0]); + addProperty("border-left-style",values[0]); + break; + + case 2: + addProperty("border-right-style",values[1]); + addProperty("border-bottom-style",values[0]); + addProperty("border-left-style",values[1]); + break; + + case 3: + addProperty("border-right-style",values[1]); + addProperty("border-bottom-style",values[2]); + addProperty("border-left-style",values[1]); + break; + + case 4: + addProperty("border-right-style",values[1]); + addProperty("border-bottom-style",values[2]); + addProperty("border-left-style",values[3]);break; + } + } + else + if(m_currentProp->text(0) =="border-width" ){ + setSidesOfPropertyBorderOn("width"); + QStringList values = QStringList::split(" ",v.stripWhiteSpace()); + addProperty("border-top-width",values[0]); + switch(values.count()) { + case 1: + addProperty("border-right-width",values[0]); + addProperty("border-bottom-width",values[0]); + addProperty("border-left-width",values[0]); + break; + + case 2: + addProperty("border-right-width",values[1]); + addProperty("border-bottom-width",values[0]); + addProperty("border-left-width",values[1]); + break; + + case 3: + addProperty("border-right-width",values[1]); + addProperty("border-bottom-width",values[2]); + addProperty("border-left-width",values[1]); + break; + + case 4: + addProperty("border-right-width",values[1]); + addProperty("border-bottom-width",values[2]); + addProperty("border-left-width",values[3]);break; + } + } + else + if(m_currentProp->text(0) =="border-color" ){ + setSidesOfPropertyBorderOn("color"); + QStringList values = QStringList::split(" ",v.stripWhiteSpace()); + addProperty("border-top-color",values[0]); + switch(values.count()) { + case 1: + addProperty("border-right-color",values[0]); + addProperty("border-bottom-color",values[0]); + addProperty("border-left-color",values[0]); + break; + + case 2: + addProperty("border-right-color",values[1]); + addProperty("border-bottom-color",values[0]); + addProperty("border-left-color",values[1]); + break; + + case 3: + addProperty("border-right-color",values[1]); + addProperty("border-bottom-color",values[2]); + addProperty("border-left-color",values[1]); + break; + + case 4: + addProperty("border-right-style",values[1]); + addProperty("border-bottom-style",values[2]); + addProperty("border-left-style",values[3]);break; + } + } + else addProperty(m_currentProp->text(0),v); + emit signalUpdatePreview(); +} + +void CSSEditor::Connect(){ + connect(this, SIGNAL(signalUpdatePreview()), this, SLOT(updatePreview())); + connect(lvVisual,SIGNAL(selectionChanged ( QListViewItem * )),this,SLOT(setMiniEditors ( QListViewItem * ))); + connect(lvAll,SIGNAL( selectionChanged( QListViewItem * )),this,SLOT(setMiniEditors ( QListViewItem * ))); + connect(lvAural,SIGNAL( selectionChanged( QListViewItem * )),this,SLOT(setMiniEditors ( QListViewItem * ))); + connect(lvInteractive,SIGNAL( selectionChanged( QListViewItem * )),this,SLOT(setMiniEditors ( QListViewItem * ))); + connect(lvPaged,SIGNAL( selectionChanged( QListViewItem * )),this,SLOT(setMiniEditors ( QListViewItem * ))); +} + +void CSSEditor::removeProperty(const QVariant& v){ + m_properties.remove(v.toString()); + updatePreview(); +} + +QString CSSEditor::generateProperties(){ + QString props; + QMap<QString,QString>::Iterator it; + if(!SHckb->isChecked()) { + for ( it = m_properties.begin(); it != m_properties.end(); ++it ) + props+= it.key() + " : " + it.data().stripWhiteSpace() + "; " ; + props.truncate(props.length()-1);//the last white space creates some problems: better remove it + //props.chop(1); + return props; + } + else { + ShorthandFormer sf(m_properties); + return sf.compress(); + } +} + +void CSSEditor::updatePreview(){ + updateDisplay(); + activatePreview(); +} + +void CSSEditor::activatePreview() { + if(!m_isFileToPreviewExternal){ + QString testHeader, + testFooter, + testBody; + + if(!m_selectorName.isEmpty()) { + testHeader += m_selectorName + " { \n "; + testFooter = "\n}" + m_Selectors; + } + else { + testHeader += " style=\"" ; + testFooter = "\"" ; + } + + QMap<QString,QString>::Iterator it; + for ( it = m_properties.begin(); it != m_properties.end(); ++it ) + testBody+= it.key() + " : " + it.data() + ";"; + + m_previewer->begin( KURL(m_fileToPreview) ); + m_previewer->write( m_Header + testHeader + testBody+ testFooter+ m_Footer); + m_previewer->end(); + + + } + else { + QString tmp("{"); + QFile file(m_fileToPreview); + if ( file.open( IO_ReadOnly ) ) { + QMap<QString,QString>::Iterator it; + for ( it = m_properties.begin(); it != m_properties.end(); ++it ) + tmp+= it.key() + " : " + it.data() + ";"; + + + QFileInfo fi(m_fileToPreview); + KParts::URLArgs a; + if(fi.extension().lower() == "xml" || fi.extension().lower() == "xhtml") + a.serviceType="text/xml"; + if(fi.extension().lower() == "html" || fi.extension().lower() == "html") + a.serviceType="text/xml"; + m_previewer->browserExtension()->setURLArgs(a); + QTextStream stream( &file ); + + m_previewer->begin(KURL(m_fileToPreview)); + m_previewer->write(stream.read()); + m_previewer->end(); + m_previewer->setUserStyleSheet(m_externalStyleSheetDefinition + " " + m_selectorName+" "+ tmp +"}"); + file.close(); + } + //else KMessageBox::sorry(this,i18n("The css file you want to edit can't be opened")); + } +} + +void CSSEditor::updateDisplay(){ + QString toDisplay; + QMap<QString,QString>::Iterator it; + for ( it = m_properties.begin(); it != m_properties.end(); ++it ) + toDisplay += it.key() + " : " + it.data() + ";\n\t"; + + if(!m_selectorName.isEmpty()){// we're working on <style></style> block + toDisplay.prepend(m_selectorName +" {\n\t"); + toDisplay+="}"; + } + else toDisplay.prepend("\n\t"); + + display->setText(toDisplay); +} + +#include "csseditor.moc" |