You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdewebdev/quanta/components/csseditor/cssselector.cpp

396 lines
14 KiB

/***************************************************************************
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 <tqlineedit.h>
#include <tqcombobox.h>
#include <tqpushbutton.h>
#include <tqtextstream.h>
#include <tqtabwidget.h>
#include <tqobjectlist.h>
#include <tqfileinfo.h>
#include <tqlabel.h>
#include <tqregexp.h>
#include <tqwhatsthis.h>
#include <kstandarddirs.h>
#include <tdelocale.h>
#include <kdebug.h>
#include <tdemessagebox.h>
#include <kurlrequester.h>
#include <tdefiledialog.h>
#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,TQ_SIGNAL(activated(const TQString&)),this,TQ_SLOT(setDTDTags(const TQString&)));
connect(pbAddTag,TQ_SIGNAL(clicked()), this ,TQ_SLOT(addTag()));
connect(pbAddClass,TQ_SIGNAL(clicked()), this ,TQ_SLOT(addClass()));
connect(pbAddID,TQ_SIGNAL(clicked()), this ,TQ_SLOT(addID()));
connect(pbAddPseudo,TQ_SIGNAL(clicked()), this ,TQ_SLOT(addPseudo()));
connect(lvTags, TQ_SIGNAL(doubleClicked( TQListViewItem * )), this, TQ_SLOT(openCSSEditor(TQListViewItem *)));
connect(lvClasses, TQ_SIGNAL(doubleClicked( TQListViewItem * )), this, TQ_SLOT(openCSSEditor(TQListViewItem *)));
connect(lvIDs, TQ_SIGNAL(doubleClicked( TQListViewItem * )), this, TQ_SLOT(openCSSEditor(TQListViewItem *)));
connect(lvPseudo, TQ_SIGNAL(doubleClicked( TQListViewItem * )), this, TQ_SLOT(openCSSEditor(TQListViewItem *)));
connect(lvTags, TQ_SIGNAL(selectionChanged( TQListViewItem * )), this, TQ_SLOT(setCurrentItem(TQListViewItem *)));
connect(lvClasses, TQ_SIGNAL(selectionChanged( TQListViewItem * )), this, TQ_SLOT(setCurrentItem(TQListViewItem *)));
connect(lvIDs, TQ_SIGNAL(selectionChanged( TQListViewItem * )), this, TQ_SLOT(setCurrentItem(TQListViewItem *)));
connect(lvPseudo, TQ_SIGNAL( selectionChanged( TQListViewItem * )), this, TQ_SLOT(setCurrentItem(TQListViewItem *)));
connect(pbRemoveSelectedTag,TQ_SIGNAL(clicked()), this ,TQ_SLOT(removeSelected()));
connect(pbRemoveSelectedClass,TQ_SIGNAL(clicked()), this ,TQ_SLOT(removeSelected()));
connect(pbRemoveSelectedID,TQ_SIGNAL(clicked()), this ,TQ_SLOT(removeSelected()));
connect(pbRemoveSelectedPseudo,TQ_SIGNAL(clicked()), this ,TQ_SLOT(removeSelected()));
connect(twSelectors,TQ_SIGNAL(currentChanged ( TQWidget * )), this ,TQ_SLOT(setCurrentListView( TQWidget * )));
connect(pbRemoveAllTags,TQ_SIGNAL(clicked()), this ,TQ_SLOT(removeAll()));
connect(pbRemoveAllClasses,TQ_SIGNAL(clicked()), this ,TQ_SLOT(removeAll()));
connect(pbRemoveAllIDs,TQ_SIGNAL(clicked()), this ,TQ_SLOT(removeAll()));
connect(pbRemoveAllPseudo,TQ_SIGNAL(clicked()), this ,TQ_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<TQString, unsigned int> 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<TQString, unsigned int> 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<TQString, unsigned int> 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<TQString, unsigned int> 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<TQString, unsigned int> 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<TQListView*>(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,TQ_SIGNAL(errorOccurred(const TQString&)), this, TQ_SLOT(setStylesheetProcessing(const TQString&)));
p.parse();
m_orderNumber = p.orderNumber();
TQMap<TQString, TQPair<TQString,unsigned int> >::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<TQString,unsigned int> >::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"