/*************************************************************************** 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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(TQListView * parent, const TQString & text):TQCheckListItem(parent, text, TQCheckListItem::CheckBox),m_checkedChildren(0){ m_sig = new TQSignal; } myCheckListItem::myCheckListItem(TQCheckListItem * parent, const TQString & text):TQCheckListItem(parent, text, TQCheckListItem::CheckBox),m_checkedChildren(0){ m_sig = new TQSignal; } myCheckListItem::~myCheckListItem(){ delete m_sig; } void myCheckListItem::connect( TQObject *receiver, const char *member ){ m_sig->connect( receiver, member ); } void myCheckListItem::activate(){ if(isOn()) TQCheckListItem::activate(); } void myCheckListItem::addCheckedChild() { m_checkedChildren++; } void myCheckListItem::stateChange (bool b){ if(!b) { if(childCount()) { TQListViewItem * child = firstChild(); while( child ) { m_sig->setValue(TQVariant(child->text(0))); m_sig->activate(); static_cast(child)->setOn(false); child = child->nextSibling(); } m_checkedChildren = 0; } else { if(parent()){ myCheckListItem *p = static_cast(parent()); while( p ) { if( p->m_checkedChildren != 1) { p->m_checkedChildren--; m_sig->setValue(TQVariant(text(0))); m_sig->activate(); break; } else { m_sig->setValue(TQVariant(text(0))); m_sig->activate(); p->setOn(false); } p = static_cast(p->parent()); } } else { m_sig->setValue(TQVariant(text(0))); m_sig->activate(); } } } else { if(parent()) static_cast(parent())->addCheckedChild(); } } void CSSEditor::appendSub(TQDomNodeList l, myCheckListItem *cli){ unsigned int i; for(i=0;iconnect(this,TQ_SLOT(removeProperty(const TQVariant&))); if(l.item(i).toElement().attribute("hasSub") == "yes") appendSub(l.item(i).childNodes(),item); } } void CSSEditor::buildListView(TQDomNodeList l, TQListView *lv){ unsigned int i; for(i=0;iconnect(this,TQ_SLOT(removeProperty(const TQVariant&))); if(l.item(i).toElement().attribute("hasSub") == "yes") { TQDomNodeList listSub = l.item(i).childNodes(); appendSub(listSub,item); } } } void CSSEditor::setCurrentPropOn(const TQString& s){ if( (m_currentProp = static_cast(lvVisual->findItem( s,0 )) )) m_currentProp->setOn(true); else if( (m_currentProp = static_cast(lvAll->findItem( s,0 )) )) m_currentProp->setOn(true); else if( (m_currentProp = static_cast(lvAural->findItem( s,0 )) )) m_currentProp->setOn(true); else if( (m_currentProp = static_cast(lvInteractive->findItem( s,0 )) )) m_currentProp->setOn(true); else if( (m_currentProp = static_cast(lvPaged->findItem( s,0 )) )) m_currentProp->setOn(true); if( m_currentProp && m_currentProp->depth() ) { myCheckListItem *p = static_cast(m_currentProp->parent()); while(p) { p->setOn(true); p=static_cast(p->parent()); } } } void CSSEditor::addAndSetPropertyOn(const TQString& property, const TQString& value){ addProperty(property,value); setCurrentPropOn(property); } void CSSEditor::setSidesOfPropertyBorderOn(const TQString& s){ static_cast(lvVisual->findItem( "border-top",0 ))->setOn(true); static_cast(lvVisual->findItem( "border-right",0 ))->setOn(true); static_cast(lvVisual->findItem( "border-bottom",0 ))->setOn(true); static_cast(lvVisual->findItem( "border-left",0 ))->setOn(true); static_cast(lvVisual->findItem( "border-top-"+s,0 ))->setOn(true); static_cast(lvVisual->findItem( "border-right-"+s,0 ))->setOn(true); static_cast(lvVisual->findItem( "border-bottom-"+s,0 ))->setOn(true); static_cast(lvVisual->findItem( "border-left-"+s,0 ))->setOn(true); } void CSSEditor::hidePreviewer(){ fPreview->hide(); } void CSSEditor::initialize(){ m_config = kapp->config(); connect(pbOk, TQ_SIGNAL(clicked()), this, TQ_SLOT(toggleShortendForm())); m_config->setGroup("CSSEditor Options"); SHckb->setChecked(m_config->readBoolEntry("Shorthand form enabled",false)); TQString configFile = locate("appdata", "csseditor/config.xml"); m_myhi = new TQMyHighlighter(display); TQBoxLayout *fPreviewLayout = new TQBoxLayout(fPreview,TQBoxLayout::LeftToRight); m_previewer=new TDEHTMLPart(fPreview); fPreviewLayout->addWidget(m_previewer->view()); TQFile file( configFile ); if ( !file.open( IO_ReadOnly ) ) { return; } if ( !m_doc.setContent( &file ) ) { file.close(); return; } file.close(); TQDomElement docElem = m_doc.documentElement(); TQDomNode n = docElem.firstChild(); while( !n.isNull() ) { TQDomElement 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(); TQBoxLayout *fEditingLayout = new TQBoxLayout(fEditing,TQBoxLayout::LeftToRight); m_ps = new propertySetter(fEditing); fEditingLayout->addWidget(m_ps); connect(m_ps, TQ_SIGNAL(valueChanged(const TQString&)), this, TQ_SLOT(checkProperty(const TQString&))); TQStringList props; TQString temp; bool normalMode = true; if( !m_selectorName.isEmpty() ){ //the cssselector has been called m_initialProperties = m_initialProperties.stripWhiteSpace(); props=TQStringList::split(";",m_initialProperties); temp= m_selectorName + " {\n\t" ; } else { m_InlineStyleContent = m_InlineStyleContent.stripWhiteSpace(); normalMode = false; props=TQStringList::split(";",m_InlineStyleContent); temp="\n\t"; } for ( TQStringList::Iterator it = props.begin(); it != props.end(); ++it ) { const TQString propertyName((*it).section(":",0,0).stripWhiteSpace()); const TQString propertyValue((*it).section(":",1)); if( ShorthandFormer::SHFormList().contains(propertyName)==0 ) { temp+= propertyName + " : " + propertyValue +";\n\t"; addAndSetPropertyOn(propertyName,propertyValue); } else{ ShorthandFormer decompressor; TQMap expandedProperties = decompressor.expand(propertyName, propertyValue ); TQMap::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(TQListViewItem *i, TQWidget *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(TQListViewItem* i){ m_ps->reset(); if(i->childCount()==0) { m_currentProp = static_cast(i); TQDomNodeList valueTypes = m_doc.elementsByTagName(i->text(0)).item(0).childNodes(); unsigned int i; for(i=0; isetComboBox(); TQStringList values = TQStringList::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(TQString()); 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 ){ TQString 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(TQString(),TQString()); m_ps->installMiniEditor(editor); } else if( valueTypeName == "doublePercentage") { doublePercentageEditor *editor = new doublePercentageEditor(m_ps); if(m_properties.contains(m_currentProp->text(0)) !=0 ){ TQString 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(TQString(),TQString()); 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(TQString()); 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(TQString()); 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(TQString()); 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(TQStringList::split(",",curr.firstChild().toElement().attribute("value"))); editor->cbDx()->insertStringList(TQStringList::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(TQString()); m_ps->installMiniEditor(editor); } } m_ps->addButton(); m_ps->Show(); } } void CSSEditor::checkProperty(const TQString& v){ if(!m_currentProp->isOn()) m_currentProp->setOn(true); if( m_currentProp->depth() ){ myCheckListItem *p = static_cast(m_currentProp->parent()); while(p){ p->setOn(true); p=static_cast(p->parent()); } } if(m_currentProp->text(0) =="border-style" ){ setSidesOfPropertyBorderOn("style"); TQStringList values = TQStringList::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"); TQStringList values = TQStringList::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"); TQStringList values = TQStringList::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, TQ_SIGNAL(signalUpdatePreview()), this, TQ_SLOT(updatePreview())); connect(lvVisual,TQ_SIGNAL(selectionChanged ( TQListViewItem * )),this,TQ_SLOT(setMiniEditors ( TQListViewItem * ))); connect(lvAll,TQ_SIGNAL( selectionChanged( TQListViewItem * )),this,TQ_SLOT(setMiniEditors ( TQListViewItem * ))); connect(lvAural,TQ_SIGNAL( selectionChanged( TQListViewItem * )),this,TQ_SLOT(setMiniEditors ( TQListViewItem * ))); connect(lvInteractive,TQ_SIGNAL( selectionChanged( TQListViewItem * )),this,TQ_SLOT(setMiniEditors ( TQListViewItem * ))); connect(lvPaged,TQ_SIGNAL( selectionChanged( TQListViewItem * )),this,TQ_SLOT(setMiniEditors ( TQListViewItem * ))); } void CSSEditor::removeProperty(const TQVariant& v){ m_properties.remove(v.toString()); updatePreview(); } TQString CSSEditor::generateProperties(){ TQString props; TQMap::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){ TQString testHeader, testFooter, testBody; if(!m_selectorName.isEmpty()) { testHeader += m_selectorName + " { \n "; testFooter = "\n}" + m_Selectors; } else { testHeader += " style=\"" ; testFooter = "\"" ; } TQMap::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 { TQString tmp("{"); TQFile file(m_fileToPreview); if ( file.open( IO_ReadOnly ) ) { TQMap::Iterator it; for ( it = m_properties.begin(); it != m_properties.end(); ++it ) tmp+= it.key() + " : " + it.data() + ";"; TQFileInfo 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); TQTextStream 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(){ TQString toDisplay; TQMap::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 block toDisplay.prepend(m_selectorName +" {\n\t"); toDisplay+="}"; } else toDisplay.prepend("\n\t"); display->setText(toDisplay); } #include "csseditor.moc"