/*************************************************************************** cssselector.cpp - description ------------------- begin : mer ago 6 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 "cssselector.h" #include "csseditor.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "project.h" #include "stylesheetparser.h" CSSSelector::CSSSelector(TQWidget *parent, const char* name) : CSSSelectorS (parent,name),m_orderNumber(0),m_stopProcessingStylesheet(false) { m_currentItem = 0L; Connect(); kurApplyToFile->fileDialog()->setURL(Project::ref()->projectBaseURL().url()); kurApplyToFile->fileDialog()->setFilter( "*.html *.htm |" + i18n("HTML Files") +" (*.html *.htm)\n*.xhtml |" + i18n("XHTML Files")+" (*.xhtml)\n*.xml |" + i18n("XML Files")+" (*.xml)\n*.*|" + i18n("All Files")+" (*.*)" ); TQWhatsThis::add((TQLineEdit*)(kurApplyToFile->lineEdit()),"With this line edit you can insert the URL of the file you want to use to preview the style sheet you are editing"); /*TQString configDir = locate("appdata", "csseditor/config.xml"); configDir = TQFileInfo(configDir).dirPath() + "/";*/ TQString configDir = TQFileInfo( locate("appdata", "csseditor/config.xml") ).dirPath() + "/"; TQDomDocument doc; TQFile file( configDir+"pseudo.xml" ); if ( !file.open( IO_ReadOnly ) ) return; if ( !doc.setContent( &file ) ) { file.close(); return; } file.close(); TQDomElement docElem = doc.documentElement(); TQDomNode n = docElem.firstChild(); while( !n.isNull() ) { TQDomElement e = n.toElement(); if( !e.isNull() ) { cbPseudo->insertItem(e.attribute("name")); } n = n.nextSibling(); } file.setName( configDir+"dtdTags.xml" ); if ( !file.open( IO_ReadOnly ) ) return; if ( !doc.setContent( &file ) ) { file.close(); return; } file.close(); TQStringList dtdNames, dtdNickNames; docElem = doc.documentElement(); n = docElem.firstChild(); while( !n.isNull() ) { TQDomElement e = n.toElement(); if( !e.isNull() ) { dtdNames.append(e.attribute("name")); dtdNickNames.append(e.attribute("nickName")); if(e.attribute("default") == "yes") { TQStringList tagList = TQStringList::split( ',',e.text() ); tagList.sort(); cbTag->insertStringList( tagList ); cbTag->setAutoCompletion(true); } } n = n.nextSibling(); } cbDTD->insertStringList( dtdNickNames ); } CSSSelector::~CSSSelector(){ } void CSSSelector::Connect(){ connect(cbDTD,TQT_SIGNAL(activated(const TQString&)),this,TQT_SLOT(setDTDTags(const TQString&))); connect(pbAddTag,TQT_SIGNAL(clicked()), this ,TQT_SLOT(addTag())); connect(pbAddClass,TQT_SIGNAL(clicked()), this ,TQT_SLOT(addClass())); connect(pbAddID,TQT_SIGNAL(clicked()), this ,TQT_SLOT(addID())); connect(pbAddPseudo,TQT_SIGNAL(clicked()), this ,TQT_SLOT(addPseudo())); connect(lvTags, TQT_SIGNAL(doubleClicked( TQListViewItem * )), this, TQT_SLOT(openCSSEditor(TQListViewItem *))); connect(lvClasses, TQT_SIGNAL(doubleClicked( TQListViewItem * )), this, TQT_SLOT(openCSSEditor(TQListViewItem *))); connect(lvIDs, TQT_SIGNAL(doubleClicked( TQListViewItem * )), this, TQT_SLOT(openCSSEditor(TQListViewItem *))); connect(lvPseudo, TQT_SIGNAL(doubleClicked( TQListViewItem * )), this, TQT_SLOT(openCSSEditor(TQListViewItem *))); connect(lvTags, TQT_SIGNAL(selectionChanged( TQListViewItem * )), this, TQT_SLOT(setCurrentItem(TQListViewItem *))); connect(lvClasses, TQT_SIGNAL(selectionChanged( TQListViewItem * )), this, TQT_SLOT(setCurrentItem(TQListViewItem *))); connect(lvIDs, TQT_SIGNAL(selectionChanged( TQListViewItem * )), this, TQT_SLOT(setCurrentItem(TQListViewItem *))); connect(lvPseudo, TQT_SIGNAL( selectionChanged( TQListViewItem * )), this, TQT_SLOT(setCurrentItem(TQListViewItem *))); connect(pbRemoveSelectedTag,TQT_SIGNAL(clicked()), this ,TQT_SLOT(removeSelected())); connect(pbRemoveSelectedClass,TQT_SIGNAL(clicked()), this ,TQT_SLOT(removeSelected())); connect(pbRemoveSelectedID,TQT_SIGNAL(clicked()), this ,TQT_SLOT(removeSelected())); connect(pbRemoveSelectedPseudo,TQT_SIGNAL(clicked()), this ,TQT_SLOT(removeSelected())); connect(twSelectors,TQT_SIGNAL(currentChanged ( TQWidget * )), this ,TQT_SLOT(setCurrentListView( TQWidget * ))); connect(pbRemoveAllTags,TQT_SIGNAL(clicked()), this ,TQT_SLOT(removeAll())); connect(pbRemoveAllClasses,TQT_SIGNAL(clicked()), this ,TQT_SLOT(removeAll())); connect(pbRemoveAllIDs,TQT_SIGNAL(clicked()), this ,TQT_SLOT(removeAll())); connect(pbRemoveAllPseudo,TQT_SIGNAL(clicked()), this ,TQT_SLOT(removeAll())); } void CSSSelector::setDTDTags(const TQString& s){ TQString configDir = TQFileInfo( locate("appdata", "csseditor/config.xml") ).dirPath() + "/"; TQDomDocument doc; TQFile file( configDir+"dtdTags.xml" ); if ( !file.open( IO_ReadOnly ) ) return; if ( !doc.setContent( &file ) ) { file.close(); return; } file.close(); TQStringList dtdNames; TQDomElement docElem = doc.documentElement(); TQDomNode n = docElem.firstChild(); while( !n.isNull() ) { if( n.toElement().attribute("nickName") == s ) break; n = n.nextSibling(); } TQStringList tagList = TQStringList::split( ',',n.toElement().text() ); tagList.sort(); cbTag->clear(); cbTag->insertStringList( tagList ); cbTag->setAutoCompletion(true); } void CSSSelector::addTag(){ TQListViewItem *item = new TQListViewItem(lvTags); if(!cbTag->currentText().isEmpty()){ item->setText(0,cbTag->currentText()); TQPair tmp(TQString(),++m_orderNumber); m_currentStylesheetStructure[item->text(0)]=tmp; } } void CSSSelector::addClass(){ TQListViewItem *item = new TQListViewItem(lvClasses); if(!leClass->text().isEmpty()){ item->setText(0,leClass->text()); TQPair tmp(TQString(),++m_orderNumber); m_currentStylesheetStructure[item->text(0)]=tmp; } } void CSSSelector::addID(){ TQListViewItem *item = new TQListViewItem(lvIDs); if(!leID->text().isEmpty()){ item->setText(0,leID->text()); TQPair tmp(TQString(),++m_orderNumber); m_currentStylesheetStructure[item->text(0)]=tmp; } } void CSSSelector::addPseudo(){ TQListViewItem *item = new TQListViewItem(lvPseudo); item->setText(0,(lePseudoSelector->text()+":"+cbPseudo->currentText()).stripWhiteSpace()); TQPair tmp(TQString(),++m_orderNumber); m_currentStylesheetStructure[item->text(0)]=tmp; } void CSSSelector::openCSSEditor(TQListViewItem * i){ if(!m_stopProcessingStylesheet){ TQListView *lv = i->listView(); TQListViewItem *temp; TQString s; TQObjectList *l = queryList( "TQListView" ); TQObjectListIt it( *l ); // iterate over the listviews TQObject *obj; while ( (obj = it.current()) != 0 ) { TQListView *lvTemp = (TQListView*)obj; if( lv != lvTemp){ temp = lvTemp->firstChild(); while(temp){ s+=(temp->text(0)+" { "+temp->text(1)+" } "); temp = temp->nextSibling(); } } ++it; } delete l; // delete the list, not the objects temp = lv->firstChild(); while(temp){ if(temp != i) s+=(temp->text(0)+" { "+temp->text(1)+" } "); temp = temp->nextSibling(); } CSSEditor dlg(i); if(m_callingFrom == "XHTML"){ dlg.setHeader(m_header); dlg.setSelectors(s); dlg.setFooter(m_footer); dlg.setFileToPreview(m_fileToPreview,false); } else if(m_callingFrom == "CSS"){ if(kurApplyToFile->url().isEmpty()) dlg.hidePreviewer(); else { dlg.setFileToPreview(kurApplyToFile->url(),true); TQString tmp; TQListViewItem *item = lvTags->firstChild(); while( item ) { if(i->text(0).stripWhiteSpace() != item->text(0).stripWhiteSpace()) tmp += item->text(0) + " {" + item->text(1) + "}"; item = item->nextSibling(); } item = lvClasses->firstChild(); while( item ) { if(i->text(0).stripWhiteSpace() != item->text(0).stripWhiteSpace()) tmp += item->text(0) + " {" + item->text(1) + "}"; item = item->nextSibling(); } item = lvIDs->firstChild(); while( item ) { if(i->text(0).stripWhiteSpace() != item->text(0).stripWhiteSpace()) tmp += item->text(0) + " {" + item->text(1) + "}"; item = item->nextSibling(); } item = lvPseudo->firstChild(); while( item ) { if(i->text(0).stripWhiteSpace() != item->text(0).stripWhiteSpace()) tmp += item->text(0) + " {" + item->text(1) + "}"; item = item->nextSibling(); } dlg.setExternalStyleSheetDefinition(tmp); } } dlg.initialize(); if(dlg.exec()) { i->setText(1,dlg.generateProperties()); TQPair tmp(m_currentStylesheetStructure[i->text(0)]); tmp.first = dlg.generateProperties(); m_currentStylesheetStructure[i->text(0)] = tmp; } } } void CSSSelector::setCurrentListView(TQWidget* w){ TQObjectList *l = w->queryList( "TQListView" ); m_currentListView = static_cast(TQT_TQWIDGET(l->first())); } void CSSSelector::removeAll(){ TQListViewItemIterator it( m_currentListView ); while ( it.current() ) { TQListViewItem *item = it.current(); m_currentStylesheetStructure.remove(item->text(0)); ++it; } m_currentListView->clear(); } void CSSSelector::removeSelected(){ if( m_currentItem ) { m_currentStylesheetStructure.remove(m_currentItem->text(0)); delete m_currentItem; m_currentItem = 0L; } } void CSSSelector::loadCSSContent(const TQString& s){ stylesheetParser p(s); connect(&p,TQT_SIGNAL(errorOccurred(const TQString&)), this, TQT_SLOT(setStylesheetProcessing(const TQString&))); p.parse(); m_orderNumber = p.orderNumber(); TQMap >::Iterator it; m_currentStylesheetStructure = p.stylesheetStructure(); for ( it = m_currentStylesheetStructure.begin(); it != m_currentStylesheetStructure.end(); ++it ) { if(!it.key().startsWith("@rule") && !it.key().startsWith("/*")){ TQListViewItem *item; if(it.key().contains(":")){ item = new TQListViewItem(lvPseudo); } else if(it.key().contains("#")){ item = new TQListViewItem(lvIDs); } else if(it.key().contains(".")){ item = new TQListViewItem(lvClasses); } else { item = new TQListViewItem(lvTags); } item->setText(0,it.key()); item->setText(1,it.data().first); } } } TQString CSSSelector::generateFormattedStyleSection(){ TQMap< TQString,TQPair >::Iterator it; TQString styleSection,tmpStr; unsigned int indentWidth, indentDisplacement = 2; for ( unsigned int i=0;i<=m_orderNumber;i++ ) { for ( it = m_currentStylesheetStructure.begin(); it != m_currentStylesheetStructure.end(); ++it ) { TQString key = it.key(); if(it.data().second == i){ if(key.startsWith("@rule")) styleSection += it.data().first; else if(key.startsWith("/*")) styleSection += it.data().first; else { key.remove(TQRegExp("-v[\\d]+$")); styleSection += "\n" + key + " {\n"; indentWidth = indentDisplacement + 2; TQStringList props = TQStringList::split(";",it.data().first.simplifyWhiteSpace()); TQString indentStr; indentStr.fill(' ',indentWidth); for ( TQStringList::Iterator it = props.begin(); it != props.end(); ++it ) { if((*it).startsWith(" ")) tmpStr += indentStr + (*it).remove(0,1) + ";\n"; else tmpStr += indentStr + (*it) + ";\n"; } indentStr.fill(' ', indentDisplacement); styleSection += tmpStr + indentStr + "}\n\n"; tmpStr = TQString(); } } } } return "\n"+styleSection; } void CSSSelector::enableApplyToFile(){ tlApplyToFile->setEnabled(true); kurApplyToFile->setEnabled(true); } void CSSSelector::setStylesheetProcessing(const TQString& msg) { m_stopProcessingStylesheet=true; KMessageBox::error (0L, msg ); } #include "cssselector.moc"