XML Mill  1.0.0
A GUI based XML editor with a memory.
gctreewidgetitem.cpp
00001 /* Copyright (c) 2012 - 2013 by William Hallatt.
00002  *
00003  * This file forms part of "XML Mill".
00004  *
00005  * The official website for this project is <http://www.goblincoding.com> and,
00006  * although not compulsory, it would be appreciated if all works of whatever
00007  * nature using this source code (in whole or in part) include a reference to
00008  * this site.
00009  *
00010  * Should you wish to contact me for whatever reason, please do so via:
00011  *
00012  *                 <http://www.goblincoding.com/contact>
00013  *
00014  * This program is free software: you can redistribute it and/or modify it under
00015  * the terms of the GNU General Public License as published by the Free Software
00016  * Foundation, either version 3 of the License, or (at your option) any later
00017  * version.
00018  *
00019  * This program is distributed in the hope that it will be useful, but WITHOUT
00020  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00021  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU General Public License along with
00024  * this program (GNUGPL.txt).  If not, see
00025  *
00026  *                    <http://www.gnu.org/licenses/>
00027  */
00028 #include "gctreewidgetitem.h"
00029 #include "gcglobalspace.h"
00030 
00031 /*--------------------------------------------------------------------------------------*/
00032 
00033 GCTreeWidgetItem::GCTreeWidgetItem( QDomElement element )
00034 {
00035   init( element, -1 );
00036 }
00037 
00038 /*--------------------------------------------------------------------------------------*/
00039 
00040 GCTreeWidgetItem::GCTreeWidgetItem( QDomElement element, int index )
00041 {
00042   init( element, index );
00043 }
00044 
00045 /*--------------------------------------------------------------------------------------*/
00046 
00047 void GCTreeWidgetItem::init( QDomElement element, int index )
00048 {
00049   m_element = element;
00050   m_elementExcluded = false;
00051   m_index = index;
00052   m_verbose = GCGlobalSpace::showTreeItemsVerbose();
00053 
00054   QDomNamedNodeMap attributes = m_element.attributes();
00055 
00056   for( int i = 0; i < attributes.size(); ++i )
00057   {
00058     m_includedAttributes.append( attributes.item( i ).toAttr().name() );
00059   }
00060 
00061   setDisplayText();
00062 }
00063 
00064 /*--------------------------------------------------------------------------------------*/
00065 
00066 void GCTreeWidgetItem::setDisplayText()
00067 {
00068   if( m_verbose )
00069   {
00070     setText( 0, toString() );
00071     setToolTip( 0, "" );
00072   }
00073   else
00074   {
00075     setText( 0, m_element.tagName() );
00076     setToolTip( 0, toString() );
00077   }
00078 }
00079 
00080 /*--------------------------------------------------------------------------------------*/
00081 
00082 GCTreeWidgetItem* GCTreeWidgetItem::gcParent() const
00083 {
00084   return dynamic_cast< GCTreeWidgetItem* >( parent() );
00085 }
00086 
00087 /*--------------------------------------------------------------------------------------*/
00088 
00089 GCTreeWidgetItem* GCTreeWidgetItem::gcChild( int index ) const
00090 {
00091   return dynamic_cast< GCTreeWidgetItem* >( child( index ) );
00092 }
00093 
00094 /*--------------------------------------------------------------------------------------*/
00095 
00096 QDomElement GCTreeWidgetItem::element() const
00097 {
00098   return m_element;
00099 }
00100 
00101 /*--------------------------------------------------------------------------------------*/
00102 
00103 void GCTreeWidgetItem::setExcludeElement( bool exclude )
00104 {
00105   if( gcParent() )
00106   {
00107     if( exclude )
00108     {
00109       gcParent()->element().removeChild( m_element );
00110     }
00111     else
00112     {
00113       gcParent()->element().appendChild( m_element );
00114     }
00115   }
00116 
00117   m_elementExcluded = exclude;
00118 }
00119 
00120 /*--------------------------------------------------------------------------------------*/
00121 
00122 bool GCTreeWidgetItem::elementExcluded() const
00123 {
00124   return m_elementExcluded;
00125 }
00126 
00127 /*--------------------------------------------------------------------------------------*/
00128 
00129 void GCTreeWidgetItem::excludeAttribute( const QString& attribute )
00130 {
00131   m_element.removeAttribute( attribute );
00132   m_includedAttributes.removeAll( attribute );
00133   m_includedAttributes.sort();
00134   setDisplayText();
00135 }
00136 
00137 /*--------------------------------------------------------------------------------------*/
00138 
00139 void GCTreeWidgetItem::includeAttribute( const QString& attribute, const QString& value )
00140 {
00141   m_element.setAttribute( attribute, value );
00142   m_includedAttributes.append( attribute );
00143   m_includedAttributes.removeDuplicates();
00144   m_includedAttributes.sort();
00145   setDisplayText();
00146 }
00147 
00148 /*--------------------------------------------------------------------------------------*/
00149 
00150 bool GCTreeWidgetItem::attributeIncluded( const QString& attribute ) const
00151 {
00152   return m_includedAttributes.contains( attribute );
00153 }
00154 
00155 /*--------------------------------------------------------------------------------------*/
00156 
00157 void GCTreeWidgetItem::setIncrementAttribute( const QString& attribute, bool increment )
00158 {
00159   if( increment )
00160   {
00161     m_incrementedAttributes.append( attribute );
00162   }
00163   else
00164   {
00165     m_incrementedAttributes.removeAll( attribute );
00166   }
00167 
00168   m_incrementedAttributes.sort();
00169 }
00170 
00171 /*--------------------------------------------------------------------------------------*/
00172 
00173 bool GCTreeWidgetItem::incrementAttribute( const QString& attribute ) const
00174 {
00175   return m_incrementedAttributes.contains( attribute );
00176 }
00177 
00178 /*--------------------------------------------------------------------------------------*/
00179 
00180 void GCTreeWidgetItem::fixAttributeValues()
00181 {
00182   m_fixedValues.clear();
00183 
00184   QDomNamedNodeMap attributes = m_element.attributes();
00185 
00186   for( int i = 0; i < attributes.size(); ++i )
00187   {
00188     QDomAttr attribute = attributes.item( i ).toAttr();
00189     m_fixedValues.insert( attribute.name(), attribute.value() );
00190   }
00191 }
00192 
00193 /*--------------------------------------------------------------------------------------*/
00194 
00195 QString GCTreeWidgetItem::fixedValue( const QString& attribute ) const
00196 {
00197   return m_fixedValues.value( attribute, QString() );
00198 }
00199 
00200 /*--------------------------------------------------------------------------------------*/
00201 
00202 void GCTreeWidgetItem::revertToFixedValues()
00203 {
00204   foreach( QString attribute, m_fixedValues.keys() )
00205   {
00206     m_element.setAttribute( attribute, m_fixedValues.value( attribute ) );
00207   }
00208 }
00209 
00210 /*--------------------------------------------------------------------------------------*/
00211 
00212 QString GCTreeWidgetItem::toString() const
00213 {
00214   QString text( "<" );
00215   text += m_element.tagName();
00216 
00217   QDomNamedNodeMap attributes = m_element.attributes();
00218 
00219   /* For elements with no attributes (e.g. <element/>). */
00220   if( attributes.isEmpty() &&
00221       m_element.childNodes().isEmpty() )
00222   {
00223     text += "/>";
00224     return text;
00225   }
00226 
00227   if( !attributes.isEmpty() )
00228   {
00229     for( int i = 0; i < attributes.size(); ++i )
00230     {
00231       text += " ";
00232 
00233       QString attribute = attributes.item( i ).toAttr().name();
00234       text += attribute;
00235       text += "=\"";
00236 
00237       QString attributeValue = attributes.item( i ).toAttr().value();
00238       text += attributeValue;
00239       text += "\"";
00240     }
00241 
00242     /* For elements without children but with attributes. */
00243     if( m_element.firstChild().isNull() )
00244     {
00245       text += "/>";
00246     }
00247     else
00248     {
00249       /* For elements with children and attributes. */
00250       text += ">";
00251     }
00252   }
00253   else
00254   {
00255     text += ">";
00256   }
00257 
00258   return text;
00259 }
00260 
00261 /*--------------------------------------------------------------------------------------*/
00262 
00263 void GCTreeWidgetItem::setIndex( int index )
00264 {
00265   m_index = index;
00266 }
00267 
00268 /*--------------------------------------------------------------------------------------*/
00269 
00270 int GCTreeWidgetItem::index() const
00271 {
00272   return m_index;
00273 }
00274 
00275 /*--------------------------------------------------------------------------------------*/
00276 
00277 void GCTreeWidgetItem::rename( const QString& newName )
00278 {
00279   m_element.setTagName( newName );
00280   setDisplayText();
00281 }
00282 
00283 /*--------------------------------------------------------------------------------------*/
00284 
00285 QString GCTreeWidgetItem::name() const
00286 {
00287   if( !m_element.isNull() )
00288   {
00289     return m_element.tagName();
00290   }
00291 
00292   return QString( "" );
00293 }
00294 
00295 /*--------------------------------------------------------------------------------------*/
00296 
00297 void GCTreeWidgetItem::setVerbose( bool verbose )
00298 {
00299   m_verbose = verbose;
00300   setDisplayText();
00301 }
00302 
00303 /*--------------------------------------------------------------------------------------*/
00304 
00305 void GCTreeWidgetItem::insertGcChild( int index, GCTreeWidgetItem* item )
00306 {
00307   QTreeWidgetItem::insertChild( index + 1, item );
00308 
00309   QDomElement siblingElement = m_element.firstChildElement();
00310   int counter = 0;
00311 
00312   while( !siblingElement.isNull() )
00313   {
00314     if( counter == index )
00315     {
00316       break;
00317     }
00318 
00319     counter++;
00320     siblingElement = siblingElement.nextSiblingElement();
00321   }
00322 
00323   m_element.insertAfter( item->element(), siblingElement );
00324 }
00325 
00326 /*--------------------------------------------------------------------------------------*/