/*************************************************************************** visualframeeditor.cpp - description ------------------- begin : mar mar 25 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 "visualframeeditor.h" #include #include //#include #include "qextfileinfo.h" #include "project.h" static int cancelledPixels(int n){ return (n-1)*6; } TQMap > SIZES; static int splitterIdNumber = 0; VisualFrameEditor::VisualFrameEditor(TQWidget * tqparent, const char * name) : TQHBox(tqparent,name){ m_internalTree = new tree; m_internalTree->root()->atts()->setGeometry(TQRect(0,0,510,422)); m_firstInsertedSA = 0L; m_markupLanguage = HTML; } VisualFrameEditor::~VisualFrameEditor(){ delete m_internalTree; delete m_firstInsertedSA; } void VisualFrameEditor::setGeometries(const TQString &l){ int cP = cancelledPixels(m_internalTree->findNode(l)->countChildren()); TQRect newGeometry(m_internalTree->findNode(l)->atts()->tqgeometry()); TQPtrList list=m_internalTree->findNode(l)->tqchildrenList(); TQPtrListIterator it( list ); treeNode *node; if(m_internalTree->findNode(l)->splitType() == VERTICAL){ int dummyDimension=m_internalTree->findNode(l)->atts()->tqgeometry().width()-cP; while ( (node = it.current()) != 0 ) { ++it; newGeometry.setWidth( int(dummyDimension/m_internalTree->findNode(l)->countChildren()) ); m_internalTree->findNode(node->label())->atts()->setGeometry(newGeometry); } } else if(m_internalTree->findNode(l)->splitType() == HORIZONTAL){ int dummyDimension=m_internalTree->findNode(l)->atts()->tqgeometry().height()-cP; while ( (node = it.current()) != 0 ) { ++it; newGeometry.setHeight( int(dummyDimension/m_internalTree->findNode(l)->countChildren()) ); m_internalTree->findNode(node->label())->atts()->setGeometry(newGeometry); } } } void VisualFrameEditor::split(const TQString &l, int n, SplitType type) { if(l==m_internalTree->root()->label()){ m_internalTree->root()->setSplitType(type); for(int i = 1; i<=n; i++) m_internalTree->addChildNode(l); setGeometries(l); } else { TQString tqparentLabel=m_internalTree->findNode(l)->tqparentLabel(); SplitType tqparentSplit=m_internalTree->findNode(tqparentLabel)->splitType(); if( tqparentSplit != type ) { m_internalTree->findNode(l)->setSplitType(type); for(int i = 1; i<=n; i++) m_internalTree->addChildNode(l); setGeometries(l); } else { for(int i = 1; i<=n; i++) m_internalTree->insertChildNode(l); m_internalTree->findNode(tqparentLabel)->removeChildNode(l,true); setGeometries(m_internalTree->findNode(tqparentLabel)->label()); } } } void VisualFrameEditor::loadExistingStructure(const TQStringList &list){ if(!list.isEmpty()) { m_existingStructure = list; m_existingStructure.remove("");//closure tag not needed buildInternalTree(m_internalTree->root()->label()); } } TQStringList VisualFrameEditor::convertAsterisks(const TQString &s,int d){ TQStringList list=TQStringList::split(",",s); int leftPercentage = 100; int leftPercentageDistributedAmongAsterisks=0; int weightAsteriskCounter=0; // This for is used to determine how much percentage must be assign to an asterisk // example cols="40%,5*,*" // then every asterisk must be assigned a percentage of 10% so the real percentage // notation is cols="40%,50%,10%" for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it ) { if(!(*it).tqcontains("%") && !(*it).tqcontains("*")) leftPercentage -= ( (*it).toInt()*100 )/d; if((*it).tqcontains("%")) leftPercentage -= (*it).section("%",0,0).toInt(); if((*it).tqcontains("*")) { int weight= (*it).section("*",0,0).toInt(); if( weight==0 ) weight=1; weightAsteriskCounter += weight; } } if(weightAsteriskCounter!=0) leftPercentageDistributedAmongAsterisks = proxInt(double(leftPercentage)/double(weightAsteriskCounter)); // this for changes asterisk notation in percentage notation // This part of the comment is for me: // NB: I valori delle percentuali generati da if .. else possono non corrispondere // a quelli effettivamente generati dal metodo build che opera un'altra normalizzazione. // In genere la differenza �dell' 1% for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it ) { if((*it).tqcontains("*")){ int weight= (*it).section("*",0,0).toInt(); if(weight==0) weight=1; int newPercentage = weight*leftPercentageDistributedAmongAsterisks; (*it)=(TQString::number(newPercentage,10)+"%"); leftPercentage-=newPercentage; } } return list; } void VisualFrameEditor::buildInternalTree(const TQString &tqparent){ TQString line = m_existingStructure.first(); if(line.tqcontains("findNode(tqparent)->atts()->tqgeometry(); TQStringList percentages = convertAsterisks(pattern.cap(1),dummy.height()); int dummyDimension=dummy.height()-cancelledPixels(line.tqcontains(",")+1); TQPtrList list=m_internalTree->findNode(tqparent)->tqchildrenList(); TQPtrListIterator it( list ); treeNode *node; while ( (node = it.current()) != 0 ) { ++it; TQRect newGeometry(dummy); double newDimension; if(percentages.first().tqcontains("%")) newDimension=(dummyDimension*(percentages.first().remove("%").toInt()))/100.0; else newDimension=(double)percentages.first().toInt(); newGeometry.setHeight( proxInt(newDimension) ); node->atts()->setGeometry(newGeometry); percentages.pop_front(); } } else if(line.tqcontains("cols")) { split(tqparent,(line.tqcontains(",")+1),VERTICAL); TQRegExp pattern("cols\\s*=\"([\\s\\d%,\\*]*)\""); pattern.search(line); TQRect dummy=m_internalTree->findNode(tqparent)->atts()->tqgeometry(); TQStringList percentages = convertAsterisks(pattern.cap(1),dummy.width()); int dummyDimension=dummy.width()-cancelledPixels(line.tqcontains(",")+1); TQPtrList list=m_internalTree->findNode(tqparent)->tqchildrenList(); TQPtrListIterator it( list ); treeNode *node; while ( (node = it.current()) != 0 ) { ++it; TQRect newGeometry(dummy); double newDimension; if(percentages.first().tqcontains("%")) newDimension=(dummyDimension*(percentages.first().remove("%").toInt()))/100.0; else newDimension=(double)percentages.first().toInt(); newGeometry.setWidth( proxInt(newDimension) ); node->atts()->setGeometry(newGeometry); percentages.pop_front(); } } m_existingStructure.pop_front(); m_internalTree->findNode(tqparent)->firstChild(); while(m_internalTree->findNode(tqparent)->currentChild()) { buildInternalTree(m_internalTree->findNode(tqparent)->currentChild()->label()); m_internalTree->findNode(tqparent)->nextChild(); } } else { TQMap attributeMap; if( line.tqcontains( TQRegExp("\\s+noresize") ) ) attributeMap["noresize"] = "noresize"; else attributeMap["noresize"] = TQString(); TQRegExp srcPattern("\\s+src\\s*=\\s*\"([%-\\w\\s\\./_\\+\\d]*)\""); //search for files if(srcPattern.search(line) !=-1 ) { KURL pathToConvert, basePath; pathToConvert.setPath(srcPattern.cap(1)); basePath.setPath( Project::ref()->projectBaseURL().path() ); attributeMap["src"] = QExtFileInfo::toAbsolute( pathToConvert, basePath ).path(); line.remove(srcPattern);//we don't need to operate on this anymore } TQRegExp pattern("\\s+(\\w+\\s*=\\s*\"[\\w\\s\\./_\\+\\d]*\")"); int pos = 0; while ( pos >= 0 ) { pos = pattern.search( line, pos ); attributeMap[ pattern.cap(1).section( TQRegExp("=\\s*\"") ,0,0) ] = pattern.cap(1).section(TQRegExp("=\\s*\""),1,1).remove("\""); if ( pos >= 0 ) pos += pattern.matchedLength(); } m_internalTree->findNode(tqparent)->atts()->setAllAttributes(attributeMap); m_existingStructure.pop_front(); } } void VisualFrameEditor::paintEvent ( TQPaintEvent * ){ hide(); delete m_firstInsertedSA; m_firstInsertedSA = 0L; TQObjectList* splitterList = queryList(TQSPLITTER_OBJECT_NAME_STRING); for (uint i = 0; i < splitterList->count(); i++) { TQObject* o = splitterList->at(i); removeChild(o); //this will delete all childr of "o" } delete splitterList; splitterIdNumber = 0; drawGUI( m_internalTree->root(), this); show(); } void VisualFrameEditor::removeNode(const TQString &l){ if( l == m_internalTree->root()->label() ) m_internalTree->reset();//trying to remove root node is equivalent to reinitialize else { TQString tqparentLabel=m_internalTree->findNode(l)->tqparentLabel(); if(m_internalTree->findNode(tqparentLabel)->countChildren()>=3) m_internalTree->removeChildNode(tqparentLabel,l,true); else { m_internalTree->removeChildNode(tqparentLabel,l,true); if( !m_internalTree->findNode(tqparentLabel)->firstChild()->hasChildren() ){ //final nodes TQMap map = m_internalTree->findNode(tqparentLabel)->firstChild()->atts()->attributeMap(); m_internalTree->findNode(tqparentLabel)->removeChildren(); m_internalTree->findNode(tqparentLabel)->atts()->setAllAttributes( map ) ; m_internalTree->findNode(tqparentLabel)->setSplitType(NONE); } else { TQPtrList list = m_internalTree->findNode(tqparentLabel)->firstChild()->tqchildrenList(); if( tqparentLabel != m_internalTree->root()->label() ) { TQString grandParentLabel = m_internalTree->findNode(tqparentLabel)->tqparentLabel(); m_internalTree->removeChildNode( tqparentLabel,m_internalTree->findNode(tqparentLabel)->firstChild()->label(),false ); m_internalTree->removeChildNode( grandParentLabel ,tqparentLabel, true ); treeNode *node; for ( node = list.first(); node; node = list.next() ) { node->setParentLabel(grandParentLabel); m_internalTree->findNode(grandParentLabel)->addChildNode(node); } } else { m_internalTree->findNode(tqparentLabel)->setSplitType( m_internalTree->findNode(tqparentLabel)->firstChild()->splitType() ); m_internalTree->removeChildNode( tqparentLabel,m_internalTree->findNode(tqparentLabel)->firstChild()->label(),false ); treeNode *node; for ( node = list.first(); node; node = list.next() ) { node->setParentLabel(tqparentLabel); m_internalTree->findNode(tqparentLabel)->addChildNode(node); } } } } } } void VisualFrameEditor::drawGUI(treeNode *n, TQWidget* tqparent){ if(n->hasChildren()) { TQString splitterName("splitter"+TQString::number(++splitterIdNumber,10)); TQSplitter *splitter = new TQSplitter(tqparent,splitterName.ascii()); if(SIZES.tqcontains(splitterName)) splitter->setSizes( SIZES[splitterName] ); switch( n->splitType() ){ case VERTICAL : splitter->setOrientation(Qt::Horizontal);break; case HORIZONTAL : splitter->setOrientation(Qt::Vertical);break; default:break; } n->firstChild(); while(n->currentChild()) { drawGUI(n->currentChild(),splitter); n->nextChild(); } } else { SelectableArea *sa=new SelectableArea(tqparent,n->label().ascii()); if(tqparent->isA(TQSPLITTER_OBJECT_NAME_STRING)) dynamic_cast(tqparent)->setResizeMode(sa->view(),TQSplitter::KeepSize ); else if(!m_firstInsertedSA) m_firstInsertedSA = sa; sa->view()->setGeometry(n->atts()->tqgeometry()); sa->setIdLabel( n->label() ); sa->setSource( n->atts()->src() ); connect(sa, TQT_SIGNAL(Resized(TQRect)), m_internalTree->findNode(sa->idLabel())->atts(), TQT_SLOT(setGeometry(TQRect))); connect(sa, TQT_SIGNAL(selected(const TQString &)),this, TQT_SIGNAL(areaSelected(const TQString &))); } } TQString VisualFrameEditor::createFrameTag(areaAttribute *a){ TQString Src(a->attributeValue("src")), Longdesc(a->attributeValue("longdesc")), Name(a->attributeValue("name")), Scrolling(a->attributeValue("scrolling")), Id(a->attributeValue("id")), Style(a->attributeValue("style")), Title(a->attributeValue("title")), Class(a->attributeValue("class")), Noresize(a->attributeValue("noresize")), Frameborder(a->attributeValue("frameborder")), Marginwidth(a->attributeValue("marginwidth")), Marginheight(a->attributeValue("marginheight")); TQString tagBegin="projectBaseURL().path() ); KURL u; u.setPath(Src); tagMiddle+= (" src=\"" + QExtFileInfo::toRelative( u, base).path() + "\""); } if( !Longdesc.isEmpty() ) tagMiddle+= (" longdesc=\""+Longdesc+"\""); //if( !Name.isEmpty() ) tagMiddle+=(" name=\""+Name+"\""); if( Scrolling!="auto" && !Scrolling.isEmpty() ) tagMiddle+=(" scrolling=\""+Scrolling+"\""); if( !Id.isEmpty() ) tagMiddle+=(" id=\""+Id+"\""); if( !Style.isEmpty() ) tagMiddle+=(" style=\""+Style+"\""); if( !Title.isEmpty() ) tagMiddle+=(" title=\""+Title+"\""); if( !Class.isEmpty() ) tagMiddle+=(" class=\""+Class+"\""); if( Frameborder=="0" ) tagMiddle+=(" frameborder=\""+Frameborder+"\""); if( Marginwidth!="0" && !Marginwidth.isEmpty() ) tagMiddle+=(" marginwidth=\""+Marginwidth+"\""); if( Marginheight!="0" && !Marginheight.isEmpty()) tagMiddle+=(" marginheight=\""+Marginheight+"\""); switch(m_markupLanguage){ case HTML: if( Noresize=="noresize" ) tagMiddle+=(" "+Noresize); tagEnd=">\n";break; case XHTML: if( Noresize=="noresize" ) tagMiddle+=(" noresize=\""+Noresize+"\""); tagEnd="/>\n";break; default:; } return tagBegin+tagMiddle+tagEnd; } TQString VisualFrameEditor::RCvalue(treeNode *n) { TQString s; TQMap dimMap; double percentage = 100.0; int remainingPercentage=100; int child_number = n->countChildren(); int lostPixels = (6*(child_number-1)); // 6 pixels are lost every time a splitter is drawn switch( n->splitType() ) { case VERTICAL: percentage/=n->atts()->tqgeometry().width(); for(int i=1;i<=child_number;++i) dimMap[i]=n->tqchildrenList().at(i-1)->atts()->tqgeometry().width(); break; case HORIZONTAL: percentage/=n->atts()->tqgeometry().height(); for(int i=1;i<=child_number;++i) dimMap[i]=n->tqchildrenList().at(i-1)->atts()->tqgeometry().height(); break; default:break; } while( lostPixels > 0) { for(int i=1;i<=child_number;++i){ dimMap[i]+=1; lostPixels--; if(lostPixels == 0) break; } } for(int i=1;i<=child_number-1;++i) { remainingPercentage-=proxInt(dimMap[i]*percentage); s+=TQString::number(proxInt(dimMap[i]*percentage),10); s+="%,"; } return s+=(TQString::number(remainingPercentage,10)+"%"); } static TQStringList nonFormattedStructure; void VisualFrameEditor::createStructure(treeNode* n){ if(n==m_internalTree->root() && !n->hasChildren()) return; if(n->hasChildren()) { switch( n->splitType() ){ case VERTICAL: nonFormattedStructure.append("\n");break; case HORIZONTAL: nonFormattedStructure.append("\n");break; default:break; } n->firstChild(); while(n->currentChild()){ createStructure(n->currentChild()); n->nextChild(); } nonFormattedStructure.append("\n"); } else nonFormattedStructure.append(createFrameTag(n->atts())); } TQString VisualFrameEditor::formatStructure(){ TQString s; int tabNum = 0; for ( TQStringList::Iterator it = nonFormattedStructure.begin(); it != nonFormattedStructure.end(); ++it ) { if((*it).tqcontains("")) { tabNum--; s.truncate(s.length()-1); } s+=*it; for(int i=1;i<=tabNum;i++) s+='\t'; } nonFormattedStructure.clear(); return s; } TQString VisualFrameEditor::framesetStructure() { m_internalTree->refreshGeometries(m_internalTree->root()); createStructure(m_internalTree->root()); return formatStructure(); } void VisualFrameEditor::setMarkupLanguage(const TQString& s){ if( s.tqcontains("xhtml",false)!=0 ) m_markupLanguage = XHTML; else if( s.tqcontains("html",false)!=0 ) m_markupLanguage = HTML; } #include "visualframeeditor.moc"