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.
krecipes/krecipes/src/dialogs/setupdisplay.cpp

603 lines
18 KiB

/***************************************************************************
* Copyright (C) 2003-2005 *
* Jason Kivlighn (jkivlighn@gmail.com) *
* *
* 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 "setupdisplay.h"
#include <tdeapplication.h>
#include <tdeconfig.h>
#include <kdebug.h>
#include <tdefontdialog.h>
#include <kcolordialog.h>
#include <tdelocale.h>
#include <tdepopupmenu.h>
#include <kiconloader.h>
#include <kstandarddirs.h>
#include <tdetempfile.h>
#include <tdehtmlview.h>
#include <dom/dom_doc.h>
#include <dom/css_rule.h>
#include <ntqinputdialog.h>
#include <ntqaction.h>
#include <ntqlabel.h>
#include <ntqfile.h>
#include <ntqregexp.h>
#include <ntqtextedit.h>
#include <ntqtooltip.h>
#include <ntqobjectlist.h>
#include <ntqvaluelist.h>
#include <ntqlayout.h>
#include "datablocks/mixednumber.h"
#include "dialogs/borderdialog.h"
#include "exporters/htmlexporter.h"
#include <cmath>
KreDisplayItem::KreDisplayItem( const TQString &n, const TQString &_name ) : nodeId(n), name(_name)
{
clear();
}
void KreDisplayItem::clear()
{
alignment = TQt::AlignHCenter;
show = true;
backgroundColor = TQColor(255,255,255);
textColor = TQColor(0,0,0);
columns = 1;
}
SetupDisplay::SetupDisplay( const Recipe &sample, TQWidget *parent ) : TDEHTMLPart(parent),
box_properties( new PropertiesMap ),
node_item_map( new TQMap<TQString, KreDisplayItem*> ),
has_changes( false ),
popup(0)
{
connect( this, TQ_SIGNAL( popupMenu(const TQString &,const TQPoint &) ), TQ_SLOT( nodeClicked(const TQString &,const TQPoint &) ) );
if ( sample.recipeID != -1 )
m_sample = sample;
else {
m_sample.title = i18n("Recipe Title");
m_sample.yield.amount = 0;
m_sample.categoryList.append( Element(i18n( "Category 1, Category 2, ..." ) ) );
m_sample.instructions = i18n("Instructions");
m_sample.prepTime = TQTime(0,0);
m_sample.authorList.append( Element(i18n( "Author 1, Author 2, ..." )) );
Ingredient ing;
ing.name = i18n("Ingredient 1");
m_sample.ingList.append( ing );
ing.name = i18n("Ingredient 2");
m_sample.ingList.append( ing );
ing.name = "...";
m_sample.ingList.append( ing );
RatingCriteria rc;
Rating rating1;
rating1.rater = i18n("Rater");
rating1.comment = i18n("Comment");
rc.name = i18n("Criteria 1");
rc.stars = 5.0;
rating1.append(rc);
rc.name = i18n("Criteria 2");
rc.stars = 2.5;
rating1.append(rc);
IngredientProperty prop;
prop.name = i18n("Property 1");
m_sample.properties.append(prop);
prop.name = i18n("Property 2");
m_sample.properties.append(prop);
prop.name = "...";
m_sample.properties.append(prop);
m_sample.ratingList.append(rating1);
}
kdDebug()<<"first load"<<endl;
loadHTMLView();
show();
createItem( "background", i18n("Background"), BackgroundColor );
createItem( "title", i18n("Title"), Font | BackgroundColor | TextColor | Visibility | Alignment | Border );
createItem( "instructions", i18n("Instructions"), Font | BackgroundColor | TextColor | Visibility | Alignment | Border );
createItem( "prep_time", i18n("Preparation Time"), Font | BackgroundColor | TextColor | Visibility | Alignment | Border );
createItem( "photo", i18n("Photo"), Visibility | Border );
createItem( "authors", i18n("Authors"), Font | BackgroundColor | TextColor | Visibility | Alignment | Border );
createItem( "categories", i18n("Categories"), Font | BackgroundColor | TextColor | Visibility | Alignment | Border );
createItem( "ingredients", i18n("Ingredients"), Font | BackgroundColor | TextColor | Visibility | Alignment | Border | Columns );
createItem( "properties", i18n("Properties"), Font | BackgroundColor | TextColor | Visibility | Alignment | Border | Columns );
createItem( "ratings", i18n("Ratings"), Font | BackgroundColor | TextColor | Visibility | Alignment | Border );
createItem( "yield", i18n("Yield"), Font | BackgroundColor | TextColor | Visibility | Alignment | Border );
}
SetupDisplay::~SetupDisplay()
{
delete box_properties;
delete node_item_map;
}
void SetupDisplay::loadHTMLView( const TQString &templateFile, const TQString &styleFile )
{
kdDebug()<<"loading template: "<<templateFile<<" style: "<<styleFile<<endl;
TQString tmp_filename = locateLocal( "tmp", "krecipes_recipe_view" );
HTMLExporter exporter( tmp_filename + ".html", "html" );
if ( templateFile != TQString::null )
exporter.setTemplate( templateFile );
if ( styleFile != TQString::null )
exporter.setStyle( styleFile );
RecipeList recipeList;
recipeList.append(m_sample);
TQFile file(tmp_filename + ".html");
if ( file.open( IO_WriteOnly ) ) {
TQTextStream stream(&file);
exporter.writeStream(stream,recipeList);
}
else {
kdDebug()<<"Unable to open file for writing"<<endl;
}
file.close();
KURL url;
url.setPath( tmp_filename + ".html" );
openURL( url );
kdDebug() << "Opening URL: " << url.htmlURL() << endl;
}
void SetupDisplay::reload()
{
loadHTMLView( m_activeTemplate, m_activeStyle );
}
void SetupDisplay::loadTemplate( const TQString &filename )
{
bool storeChangedState = has_changes;
KTempFile tmpFile;
saveLayout(tmpFile.name());
has_changes = storeChangedState; //saveLayout() sets changes to false
loadHTMLView( filename, tmpFile.name() );
m_activeTemplate = filename;
}
void SetupDisplay::createItem( const TQString &node, const TQString &name, unsigned int properties )
{
KreDisplayItem * item = new KreDisplayItem( node, name );
box_properties->insert( item, properties );
node_item_map->insert( node, item );
}
void SetupDisplay::loadLayout( const TQString &filename )
{
TQFile input( filename );
if ( input.open( IO_ReadOnly ) ) {
TQDomDocument doc;
TQString error;
int line;
int column;
if ( !doc.setContent( &input, &error, &line, &column ) ) {
kdDebug() << TQString( i18n( "\"%1\" at line %2, column %3. This may not be a Krecipes layout file." ) ).arg( error ).arg( line ).arg( column ) << endl;
return ;
}
m_styleSheet = DOM::CSSStyleSheet();
TQMap<TQString,KreDisplayItem*>::iterator it;
for ( it = node_item_map->begin(); it != node_item_map->end(); ++it ) {
it.data()->clear();
}
processDocument( doc );
loadHTMLView(m_activeTemplate, filename);
m_activeStyle = filename;
has_changes = false;
}
else
kdDebug() << "Unable to open file: " << filename << endl;
}
void SetupDisplay::beginObject( const TQString &object )
{
TQMap<TQString, KreDisplayItem*>::iterator map_it = node_item_map->find( object );
if ( map_it != node_item_map->end() )
m_currentItem = map_it.data();
else
m_currentItem = 0;
}
void SetupDisplay::endObject()
{
m_currentItem = 0;
}
void SetupDisplay::loadBackgroundColor( const TQString &object, const TQColor &color )
{
if ( m_currentItem ) {
m_currentItem->backgroundColor = color;
m_styleSheet.insertRule("."+object+" { "+bgColorAsCSS(color)+" }",m_styleSheet.cssRules().length());
}
}
void SetupDisplay::loadFont( const TQString &object, const TQFont &font )
{
if ( m_currentItem ) {
m_currentItem->font = font;
m_styleSheet.insertRule("."+object+" { "+fontAsCSS(font)+" }",m_styleSheet.cssRules().length());
}
}
void SetupDisplay::loadTextColor( const TQString &object, const TQColor &color )
{
if ( m_currentItem ) {
m_currentItem->textColor = color;
m_styleSheet.insertRule("."+object+" { "+textColorAsCSS(color)+" }",m_styleSheet.cssRules().length());
}
}
void SetupDisplay::loadVisibility( const TQString &object, bool visible )
{
if ( m_currentItem ) {
m_currentItem->show = visible;
emit itemVisibilityChanged( m_currentItem, visible );
m_styleSheet.insertRule("."+object+" { "+visibilityAsCSS(visible)+" }",m_styleSheet.cssRules().length());
}
}
void SetupDisplay::loadAlignment( const TQString &object, int alignment )
{
if ( m_currentItem ) {
m_currentItem->alignment = alignment;
m_styleSheet.insertRule("."+object+" { "+alignmentAsCSS(alignment)+" }",m_styleSheet.cssRules().length());
}
}
void SetupDisplay::loadBorder( const TQString &object, const KreBorder& border )
{
if ( m_currentItem ) {
m_currentItem->border = border;
m_styleSheet.insertRule("."+object+" { "+borderAsCSS(border)+" }",m_styleSheet.cssRules().length());
}
}
void SetupDisplay::loadColumns( const TQString &/*object*/, int cols )
{
if ( m_currentItem ) {
m_currentItem->columns = cols;
}
}
void SetupDisplay::saveLayout( const TQString &filename )
{
TQDomImplementation dom_imp;
TQDomDocument doc = dom_imp.createDocument( TQString::null, "krecipes-layout", dom_imp.createDocumentType( "krecipes-layout", TQString::null, TQString::null ) );
TQDomElement layout_tag = doc.documentElement();
layout_tag.setAttribute( "version", 0.4 );
//layout_tag.setAttribute( "generator", TQString("Krecipes v%1").arg(krecipes_version()) );
doc.appendChild( layout_tag );
for ( TQMap<TQString, KreDisplayItem*>::const_iterator it = node_item_map->begin(); it != node_item_map->end(); ++it ) {
TQDomElement base_tag = doc.createElement( it.key() );
layout_tag.appendChild( base_tag );
int properties = (*box_properties)[it.data()];
if ( properties & BackgroundColor ) {
TQDomElement backgroundcolor_tag = doc.createElement( "background-color" );
backgroundcolor_tag.appendChild( doc.createTextNode( it.data()->backgroundColor.name() ) );
base_tag.appendChild( backgroundcolor_tag );
}
if ( properties & TextColor ) {
TQDomElement textcolor_tag = doc.createElement( "text-color" );
textcolor_tag.appendChild( doc.createTextNode( it.data()->textColor.name() ) );
base_tag.appendChild( textcolor_tag );
}
if ( properties & Font ) {
TQDomElement font_tag = doc.createElement( "font" );
font_tag.appendChild( doc.createTextNode( it.data()->font.toString() ) );
base_tag.appendChild( font_tag );
}
if ( properties & Visibility ) {
TQDomElement visibility_tag = doc.createElement( "visible" );
visibility_tag.appendChild( doc.createTextNode( (it.data()->show) ? "true" : "false" ) );
base_tag.appendChild( visibility_tag );
}
if ( properties & Alignment ) {
TQDomElement alignment_tag = doc.createElement( "alignment" );
alignment_tag.appendChild( doc.createTextNode( TQString::number( it.data()->alignment ) ) );
base_tag.appendChild( alignment_tag );
}
if ( properties & Border ) {
TQDomElement border_tag = doc.createElement( "border" );
border_tag.setAttribute( "width", it.data()->border.width );
border_tag.setAttribute( "style", it.data()->border.style );
border_tag.setAttribute( "color", it.data()->border.color.name() );
base_tag.appendChild( border_tag );
}
if ( properties & Columns ) {
TQDomElement columns_tag = doc.createElement( "columns" );
columns_tag.appendChild( doc.createTextNode( TQString::number( it.data()->columns ) ) );
base_tag.appendChild( columns_tag );
}
}
TQFile out_file( filename );
if ( out_file.open( IO_WriteOnly ) ) {
has_changes = false;
TQTextStream stream( &out_file );
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" << doc.toString();
}
else
kdDebug() << "Error: Unable to write to file " << filename << endl;
}
void SetupDisplay::begin(const KURL &url, int xOffset, int yOffset)
{
kdDebug()<<"begin"<<endl;
TDEHTMLPart::begin(url,xOffset,yOffset);
kdDebug()<<"end"<<endl;
DOM::Document doc = document();
DOM::DOMImplementation impl = doc.implementation();
kdDebug() << "(1) document: " << document().handle() << endl;
#if 0
if ( !impl.isNull() ) {
//m_styleSheet = impl.createCSSStyleSheet("-krecipes","screen");
//m_styleSheet = DOM::CSSStyleSheet();
//doc.addStyleSheet(m_styleSheet);
//applyStylesheet();
}
#endif
}
void SetupDisplay::nodeClicked(const TQString &/*url*/,const TQPoint &point)
{
DOM::Node node = nodeUnderMouse();
DOM::Element element;
if ( node.nodeType() != DOM::Node::ELEMENT_NODE ) {
kdDebug()<<"not an element"<<endl;
element = (DOM::Element)node.parentNode();
}
else
element = (DOM::Element)node;
while ( !element.parentNode().isNull() ) {
if ( element.hasAttribute("class") ) {
TQString id = element.getAttribute("class").string();
if ( node_item_map->keys().contains(id) )
break;
}
element = (DOM::Element)element.parentNode();
}
m_currNodeId = element.getAttribute("class").string();
if ( m_currNodeId.isEmpty() ) {
kdDebug()<<"Code error: unable to determine class of selected element"<<endl;
return;
}
KreDisplayItem *item = *node_item_map->find( m_currNodeId );
delete popup;
popup = new TDEPopupMenu( view() );
popup->insertTitle( item->name );
unsigned int properties = 0;
for ( PropertiesMap::const_iterator it = box_properties->begin(); it != box_properties->end(); ++it ) {
if ( it.key()->nodeId == m_currNodeId ) {
properties = it.data();
break;
}
}
TDEIconLoader il;
if ( properties & BackgroundColor )
popup->insertItem( i18n( "Background Color..." ), this, TQ_SLOT( setBackgroundColor() ) );
if ( properties & TextColor )
popup->insertItem( i18n( "Text Color..." ), this, TQ_SLOT( setTextColor() ) );
if ( properties & Font )
popup->insertItem( il.loadIconSet( "text", TDEIcon::Small, 16 ), i18n( "Font..." ), this, TQ_SLOT( setFont() ) );
if ( properties & Visibility ) {
int id = popup->insertItem( i18n( "Show" ), this, TQ_SLOT( setShown( int ) ) );
popup->setItemChecked( id, item->show );
}
if ( properties & Alignment ) {
TQPopupMenu * sub_popup = new TQPopupMenu( popup );
TQActionGroup *alignment_actions = new TQActionGroup( this );
alignment_actions->setExclusive( true );
TQAction *c_action = new TQAction( i18n( "Center" ), i18n( "Center" ), 0, alignment_actions, 0, true );
TQAction *l_action = new TQAction( i18n( "Left" ), i18n( "Left" ), 0, alignment_actions, 0, true );
TQAction *r_action = new TQAction( i18n( "Right" ), i18n( "Right" ), 0, alignment_actions, 0, true );
int align = item->alignment;
if ( align & TQt::AlignHCenter )
c_action->setOn(true);
if ( align & TQt::AlignLeft )
l_action->setOn(true);
if ( align & TQt::AlignRight )
r_action->setOn(true);
connect( alignment_actions, TQ_SIGNAL( selected( TQAction* ) ), TQ_SLOT( setAlignment( TQAction* ) ) );
popup->insertItem( i18n( "Alignment" ), sub_popup );
alignment_actions->addTo( sub_popup );
}
if ( properties & Border )
popup->insertItem( i18n( "Border..." ), this, TQ_SLOT( setBorder() ) );
if ( properties & Columns )
popup->insertItem( i18n( "Columns..." ), this, TQ_SLOT( setColumns() ) );
popup->popup( point );
}
void SetupDisplay::applyStylesheet()
{
loadTemplate( m_activeTemplate );
if ( !document().isNull() && !m_styleSheet.isNull() ) {
//document().removeStyleSheet(m_styleSheet);
//document().addStyleSheet(m_styleSheet);
}
}
void SetupDisplay::setBackgroundColor()
{
KreDisplayItem *item = *node_item_map->find( m_currNodeId );
if ( KColorDialog::getColor( item->backgroundColor, view() ) == TQDialog::Accepted ) {
m_currentItem = item;
loadBackgroundColor(m_currNodeId,item->backgroundColor);
m_currentItem = 0;
applyStylesheet();
has_changes = true;
}
}
void SetupDisplay::setBorder()
{
KreDisplayItem *item = *node_item_map->find( m_currNodeId );
BorderDialog borderDialog( item->border, view() );
if ( borderDialog.exec() == TQDialog::Accepted ) {
m_currentItem = item;
loadBorder( m_currNodeId, borderDialog.border() );
m_currentItem = 0;
applyStylesheet();
has_changes = true;
}
}
void SetupDisplay::setColumns()
{
KreDisplayItem *item = *node_item_map->find( m_currNodeId );
int cols = TQInputDialog::getInteger( TQString::null, i18n("Select the number of columns to use:"), item->columns, 1, 100, 1, 0, view() );
if ( cols > 0 ) {
m_currentItem = item;
loadColumns( m_currNodeId, cols );
m_currentItem = 0;
loadTemplate( m_activeTemplate );
has_changes = true;
}
}
void SetupDisplay::setTextColor()
{
KreDisplayItem *item = *node_item_map->find( m_currNodeId );
if ( KColorDialog::getColor( item->textColor, view() ) == TQDialog::Accepted ) {
m_currentItem = item;
loadTextColor(m_currNodeId,item->textColor);
m_currentItem = 0;
applyStylesheet();
has_changes = true;
}
}
void SetupDisplay::setShown( int id )
{
KreDisplayItem *item = *node_item_map->find( m_currNodeId );
emit itemVisibilityChanged( item, !popup->isItemChecked( id ) );
m_currentItem = item;
loadVisibility(m_currNodeId,!popup->isItemChecked( id ));
m_currentItem = 0;
applyStylesheet();
has_changes = true;
}
void SetupDisplay::setFont()
{
KreDisplayItem *item = *node_item_map->find( m_currNodeId );
if ( TDEFontDialog::getFont( item->font, false, view() ) == TQDialog::Accepted ) {
m_currentItem = item;
loadFont(m_currNodeId,item->font);
m_currentItem = 0;
applyStylesheet();
has_changes = true;
}
}
void SetupDisplay::setAlignment( TQAction *action )
{
KreDisplayItem *item = *node_item_map->find( m_currNodeId );
//TODO: isn't there a simpler way to do this...
//preserve non-horizontal alignment flags
if ( item->alignment & TQt::AlignRight )
item->alignment ^= TQt::AlignRight;
if ( item->alignment & TQt::AlignHCenter )
item->alignment ^= TQt::AlignHCenter;
if ( item->alignment & TQt::AlignLeft )
item->alignment ^= TQt::AlignLeft;
if ( action->text() == i18n( "Center" ) )
item->alignment |= TQt::AlignHCenter;
else if ( action->text() == i18n( "Left" ) )
item->alignment |= TQt::AlignLeft;
else if ( action->text() == i18n( "Right" ) )
item->alignment |= TQt::AlignRight;
m_currentItem = item;
loadAlignment(m_currNodeId,item->alignment);
m_currentItem = 0;
applyStylesheet();
has_changes = true;
}
void SetupDisplay::setItemShown( KreDisplayItem *item, bool visible )
{
item->show = visible;
m_styleSheet.insertRule("."+item->nodeId+" { visibility:"+(item->show?"visible":"hidden")+" }",m_styleSheet.cssRules().length());
applyStylesheet();
has_changes = true;
}
void SetupDisplay::changeMade( void )
{
has_changes = true;
}
#include "setupdisplay.moc"