1 /***************************************************************************
2         positionviewwidget - inherited class for doc position views.
3                              -------------------
4     begin                : 2006-02-20
5     copyright            : (C) 2006 by Klaas Freitag
6     email                : freitag@kde.org
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include <QWidget>
19 #include <QStackedWidget>
20 #include <QPainter>
21 #include <QTextEdit>
22 #include <QMenu>
23 #include <QIcon>
24 #include <QDebug>
25 #include <qdrawutil.h>
26 
27 #include "positionviewwidget.h"
28 #include "unitmanager.h"
29 #include "geld.h"
30 #include "kraftsettings.h"
31 #include "defaultprovider.h"
32 #include "kraftdb.h"
33 #include "itemtagdialog.h"
34 #include "tagman.h"
35 
36 
PositionViewWidget()37 PositionViewWidget::PositionViewWidget()
38     :QWidget(), Ui_positionWidget(),
39    mModified( false ),
40    m_skipModifiedSignal( false ),
41    mToDelete(false),
42    mOrdNumber(0),
43    mPositionPtr( 0 ),
44    mExecPopup( new QMenu( this ) ) ,
45    mStateSubmenu( 0 ),
46    mState( Active ),
47    mKind( Normal ),
48    mPositionPriceValid( false ),
49    mLocale( 0 )
50 {
51   setupUi( this );
52   m_sbUnitPrice->setMinimum( -999999.99 );
53   m_sbUnitPrice->setMaximum( 999999.99 );
54   m_sbUnitPrice->setDecimals( 2 );
55   const QString currSymbol = DefaultProvider::self()->locale()->currencySymbol();
56   m_sbUnitPrice->setSuffix(" " + currSymbol);
57 
58 
59   m_sbAmount->setMinimum( -999999.99 );
60   m_sbAmount->setMaximum( 999999.99 );
61   m_sbAmount->setDecimals( 2 );
62 
63   mDiscountPercent->setMinimum( -100.0 );
64   mDiscountPercent->setMaximum( 9999.99 );
65   mDiscountPercent->setDecimals( 2 );
66 
67   pbExec->setCheckable( false );
68   pbExec->setIcon( QIcon::fromTheme( "configure") );
69   pbTagging->setCheckable( false );
70   pbTagging->setIcon( QIcon::fromTheme( "flag" ) );
71 
72   connect( m_sbAmount, SIGNAL( valueChanged( double )),
73              this, SLOT( slotRefreshPrice( ) ) );
74   connect( m_sbUnitPrice, SIGNAL( valueChanged( double )),
75              this, SLOT( slotRefreshPrice( ) ) );
76   connect( mDiscountPercent, SIGNAL( valueChanged( double ) ),
77            this, SLOT( slotRefreshPrice() ) );
78 
79   connect( pbExec, SIGNAL( pressed() ),     this,  SLOT( slotExecButtonPressed() ) );
80   connect( pbTagging,  SIGNAL( pressed() ), this,  SLOT( slotTaggingButtonPressed() ) );
81 
82 
83   /* modified signals */
84   connect( m_cbUnit,      SIGNAL( activated(int) ), this,      SLOT( slotModified() ) );
85   connect( m_teFloskel,   SIGNAL( textChanged() ), this,       SLOT( slotModified() ) );
86 
87   connect( m_sbAmount,    SIGNAL( valueChanged(double)), this, SLOT( slotModified() ) );
88   connect( m_sbUnitPrice, SIGNAL( valueChanged(double)), this, SLOT( slotModified() ) );
89   connect( mDiscountPercent, SIGNAL( valueChanged( double ) ), this, SLOT( slotModified() ) );
90   connect( mDiscountTag,  SIGNAL( activated( int ) ), this,    SLOT( slotModified() ) );
91 
92   mExecPopup->setTitle(i18n("Item Actions") );
93 
94   // state submenu:
95   mStateSubmenu = mExecPopup->addMenu(i18n( "Item Kind" ));
96   mStateSubmenu->addAction( i18n( "Normal" ), this, SIGNAL( positionStateNormal() ) );
97   mStateSubmenu->addAction( QIcon::fromTheme( "kraft_alternative" ),
98                             i18n( "Alternative" ), this, SIGNAL( positionStateAlternative() ) );
99   mStateSubmenu->addAction( QIcon::fromTheme( "kraft_demand" ),
100                             i18n( "On Demand" ), this, SIGNAL( positionStateDemand() ) );
101 
102   // mExecPopup->addSeparator();
103 
104   // mTaxSubMenu
105   mTaxSubmenu = mExecPopup->addMenu(i18n( "Tax" ));
106   QActionGroup *agroup = new QActionGroup( this );
107   agroup->setExclusive ( true );
108   mNilTaxAction = new QAction( QIcon::fromTheme("kraft_notax"),  i18n("Taxfree Item"), this );
109   connect( mNilTaxAction, SIGNAL(triggered()), this, SLOT(slotSetNilTax()) );
110   mNilTaxAction->setCheckable( true );
111   agroup->addAction( mNilTaxAction );
112   mTaxSubmenu->addAction( mNilTaxAction );
113 
114   mRedTaxAction = new QAction( QIcon::fromTheme("kraft_redtax"), i18n("Reduced Tax"),  this );
115   connect( mRedTaxAction, SIGNAL(triggered()), this, SLOT(slotSetReducedTax()));
116   mRedTaxAction->setCheckable( true );
117   agroup->addAction( mRedTaxAction );
118   mTaxSubmenu->addAction( mRedTaxAction );
119 
120   mFullTaxAction = new QAction( QIcon::fromTheme("kraft_fulltax"), i18n("Full Tax"),  this );
121   connect( mFullTaxAction, SIGNAL(triggered()), this, SLOT(slotSetFullTax()));
122   mFullTaxAction->setCheckable( true );
123   agroup->addAction( mFullTaxAction );
124   mTaxSubmenu->addAction( mFullTaxAction );
125 
126   mExecPopup->addSeparator();
127 
128   mExecPopup->addAction(  QIcon::fromTheme("arrow-up"),
129                            i18n("Move Up"),         this, SIGNAL( moveUp() ) );
130   mExecPopup->addAction(  QIcon::fromTheme("arrow-down"),
131                            i18n("Move Down"),       this, SIGNAL( moveDown() ) );
132   mLockId = mExecPopup->addAction(  QIcon::fromTheme("object-locked"),
133                            i18n("Lock Item"),   this, SIGNAL( lockPosition() ) );
134   mUnlockId = mExecPopup->addAction(  QIcon::fromTheme("object-unlocked"),
135                            i18n("Unlock Item"), this, SIGNAL( unlockPosition() ) );
136   mDeleteId = mExecPopup->addAction(  QIcon::fromTheme("edit-delete"),
137                            i18n("Delete Item"), this, SIGNAL( deletePosition() ) );
138 
139 
140   connect( this, SIGNAL( positionStateNormal() ), this, SLOT( slotSetPositionNormal() ) );
141   connect( this, SIGNAL( positionStateAlternative() ), this, SLOT( slotSetPositionAlternative() ) );
142   connect( this, SIGNAL( positionStateDemand() ), this, SLOT( slotSetPositionDemand() ) );
143 
144 
145   connect( this, SIGNAL( lockPosition() ),   this, SLOT( slotLockPosition() ) );
146   connect( this, SIGNAL( unlockPosition() ), this, SLOT( slotUnlockPosition() ) );
147 
148   connect( mExecPopup, SIGNAL( aboutToShow() ), this, SLOT( slotMenuAboutToShow() ) );
149   connect( mExecPopup, SIGNAL( aboutToHide() ), this, SLOT( slotMenuAboutToHide() ) );
150 
151   mUnlockId->setEnabled(false);
152   lStatus->setPixmap( QPixmap() );
153   lKind->setPixmap( QPixmap() );
154 
155   this->setAutoFillBackground(true);
156   this->setBaseSize(this->width(), 100);
157   this->layout()->setMargin( 6 );
158 }
159 
setDocPosition(DocPositionBase * dp)160 void PositionViewWidget::setDocPosition( DocPositionBase *dp)
161 {
162   if( ! dp ) {
163     qCritical() << "setDocPosition got empty position!" << endl;
164     return;
165   }
166 
167   DocPosition *pos = static_cast<DocPosition*>(dp);
168 
169   mPositionPtr = pos;
170 
171   m_skipModifiedSignal = true;
172 
173   m_teFloskel->setText( pos->text() );
174 
175   lStatus->hide();
176   lKind->hide();
177 
178   AttributeMap amap = dp->attributes();
179 
180   QString unit = pos->unit().einheitSingular();
181   m_cbUnit->setCurrentIndex(m_cbUnit->findText( unit ));
182 
183   if( dp->type() == DocPositionBase::Position ) {
184     positionDetailStack->setCurrentWidget( positionPage );
185 
186     m_sbAmount->blockSignals( true );
187     m_sbAmount->setValue( pos->amount() );
188     m_sbAmount->blockSignals( false );
189 
190     m_sbUnitPrice->blockSignals( true );
191     m_sbUnitPrice->setValue( pos->unitPrice().toDouble() );
192     m_sbUnitPrice->blockSignals( false );
193 
194     if ( amap.contains( DocPosition::Kind ) ) {
195       Attribute kind = amap[DocPosition::Kind];
196       const QString kindStr = kind.value().toString();
197       if ( kindStr == kindString( Normal ) ) {
198           slotSetPositionNormal();
199       } else if ( kindStr == kindString( Alternative ) ) {
200         slotSetPositionAlternative();
201       } else if ( kindStr == kindString( Demand ) ) {
202         slotSetPositionDemand();
203       } else {
204         // qDebug () << "Unknown position kind!" << endl;
205       }
206     }
207     // qDebug () << "Setting position ptr. in viewwidget: " << pos << endl;
208   } else if ( dp->type() == DocPositionBase::ExtraDiscount ) {
209     positionDetailStack->setCurrentWidget( discountPage );
210     // qDebug() << " " << dp->type()<< endl;
211     Attribute discount = amap[DocPosition::Discount];
212     mDiscountPercent->setValue( discount.value().toDouble() );
213 
214     QString selTag;
215     if ( amap.contains( DocPosition::ExtraDiscountTagRequired ) ) {
216       Attribute tagSelector = amap[DocPosition::ExtraDiscountTagRequired];
217       selTag = tagSelector.value().toString();
218     }
219 
220     /* Fill and set the extra discount selection combo */
221     const QString allPos = i18n( "All items" );
222     mDiscountTag->addItem( allPos ); // , i18n( "Overall Position Discount" ) );
223     QStringList taglist = TagTemplateMan::self()->allTagTemplates();
224     QString currentEntry = allPos;
225 
226     for ( QStringList::Iterator tagIt = taglist.begin(); tagIt != taglist.end(); ++tagIt ) {
227       QString tagger;
228       TagTemplate tmpl = TagTemplateMan::self()->getTagTemplate( *tagIt );
229       QPixmap pix( 16, 12 );
230       pix.fill( tmpl.color() );
231       tagger = i18n( "%1-tagged items", *tagIt );
232       mDiscountTag->addItem(pix, tagger);
233       if ( selTag == *tagIt ) {
234         currentEntry = tagger;
235       }
236     }
237     mDiscountTag->setCurrentIndex(mDiscountTag->findText( currentEntry ));
238   } else {
239     // qDebug () << "unknown doc position type " << dp->type()<< endl;
240   }
241   slotSetOverallPrice( currentPrice() );
242 
243   // set tags marked
244   mTags = dp->tags();
245   slotUpdateTagToolTip();
246   slotSetTax( dp->taxType() );
247 
248   m_skipModifiedSignal = false;
249 }
250 
slotShowPrice(bool show)251 void PositionViewWidget::slotShowPrice( bool show )
252 {
253     m_sumLabel->setVisible(show);
254     m_sbUnitPrice->setVisible(show);
255 }
256 
slotUpdateTagToolTip()257 void PositionViewWidget::slotUpdateTagToolTip()
258 {
259   QString tip;
260   bool first = true;
261 
262   if ( mTags.count() == 1 ) {
263     tip = i18n( "Tag: %1", mTags.first() );
264   } else if ( mTags.count() > 1 ) {
265     tip = i18n( "Tags:<ul>" );
266     for ( QStringList::Iterator it = mTags.begin(); it != mTags.end(); ++it ) {
267       if ( first ) {
268         tip += QString( "<li>%1</li>" ).arg( *it );
269         first = false;
270       } else {
271         tip += QString( "<li>%1</li>" ).arg( *it );
272       }
273     }
274     tip += "</ul>";
275   } else {
276     tip = i18n( "No tags assigned yet." );
277   }
278 
279   pbTagging->setToolTip( tip );
280 }
281 
extraDiscountTagRestriction()282 QString PositionViewWidget::extraDiscountTagRestriction()
283 {
284   QStringList taglist = TagTemplateMan::self()->allTagTemplates();
285 
286   int currentItem = mDiscountTag->currentIndex();
287   if ( currentItem > 0 && currentItem <= taglist.count() ) {
288     // subtract one for the "all items" entry in the combo box at first position
289     currentItem -= 1;
290     return taglist[currentItem];
291   } else {
292     // qDebug () << "taglist index possibly out of range!";
293   }
294   return QString();
295 }
296 
slotTaggingButtonPressed()297 void PositionViewWidget::slotTaggingButtonPressed()
298 {
299   // qDebug () << "opening tagging dialog" << endl;
300 
301   ItemTagDialog dia( 0 );
302 
303   dia.setPositionTags( mTags );
304   if ( dia.exec() ) {
305     mTags = dia.getSelectedTags();
306     slotUpdateTagToolTip();
307     slotModified();
308     update();
309     // qDebug () << "Selected tags: " << mTags.join( ", " ) << endl;
310   }
311 }
312 
slotSetNilTax()313 void PositionViewWidget::slotSetNilTax()
314 {
315   slotSetTax( DocPositionBase::TaxNone );
316 }
317 
slotSetReducedTax()318 void PositionViewWidget::slotSetReducedTax()
319 {
320   slotSetTax( DocPositionBase::TaxReduced );
321 }
322 
slotSetFullTax()323 void PositionViewWidget::slotSetFullTax()
324 {
325   slotSetTax( DocPositionBase::TaxFull );
326 }
327 
slotSetTax(DocPosition::TaxType tt)328 void PositionViewWidget::slotSetTax( DocPosition::TaxType tt )
329 {
330   mTax = tt;
331 
332   QString icon;
333   if( tt == DocPositionBase::TaxFull ) {
334     icon = QString::fromLatin1("kraft_fulltax");
335     mFullTaxAction->setChecked( true );
336   } else if( tt == DocPositionBase::TaxReduced ) {
337     icon = QString::fromLatin1("kraft_redtax");
338     mRedTaxAction->setChecked( true );
339   } else if( tt == DocPositionBase::TaxNone ) {
340     icon = QString::fromLatin1("kraft_notax");
341     mNilTaxAction->setChecked( true );
342   }
343 
344   mTaxSubmenu->setIcon( QIcon::fromTheme( icon ));
345   emit positionModified();
346 }
347 
slotAllowIndividualTax(bool allow)348 void PositionViewWidget::slotAllowIndividualTax( bool allow )
349 {
350   mFullTaxAction->setEnabled(allow);
351   mRedTaxAction->setEnabled(allow);
352   mNilTaxAction->setEnabled(allow);
353   mTaxSubmenu->setEnabled( allow );
354 }
355 
taxType() const356 DocPositionBase::TaxType PositionViewWidget::taxType() const
357 {
358   return mTax;
359 }
360 
slotExecButtonPressed()361 void PositionViewWidget::slotExecButtonPressed()
362 {
363   // qDebug () << "Opening Context Menu over exec button" << endl;
364 
365   // set bg-color
366   mExecPopup->popup( QWidget::mapToGlobal( pbExec->pos() ) );
367 
368 }
369 
slotMenuAboutToShow()370 void PositionViewWidget::slotMenuAboutToShow()
371 {
372   QPalette palette;
373   palette.setColor(this->backgroundRole(), QColor("#757476"));
374   this->setPalette(palette);
375 }
376 
slotMenuAboutToHide()377 void PositionViewWidget::slotMenuAboutToHide()
378 {
379   // qDebug () << "Set normal again" << endl;
380   QPalette palette;
381   setPalette( palette );
382   pbExec->setChecked(false);
383 }
384 
slotLockPosition()385 void PositionViewWidget::slotLockPosition( )
386 {
387   slotSetState( Locked );
388 }
389 
slotUnlockPosition()390 void PositionViewWidget::slotUnlockPosition( )
391 {
392   slotSetState( Active );
393 }
394 
slotEnableKindMenu(bool s)395 void PositionViewWidget::slotEnableKindMenu( bool s )
396 {
397   mStateSubmenu->setEnabled( s );
398 }
399 
stateString(const State & state) const400 QString PositionViewWidget::stateString( const State& state ) const
401 {
402   QString str;
403 
404   if( state == Active ) {
405     str = i18n( "Active" );
406   } else if( state == New ) {
407     str = i18n( "New" );
408   } else if( state == Deleted ) {
409     str = i18n( "Deleted" );
410   } else if( state == Locked ) {
411     str = i18n( "Locked" );
412   } else {
413     str = i18n( "Unknown" );
414   }
415   return str;
416 }
417 
slotSetState(State state)418 void PositionViewWidget::slotSetState( State state )
419 {
420   mState = state;
421   // qDebug () << "Setting new widget state " << stateString( state ) << endl;
422   if( state == Active ) {
423     mLockId->setEnabled( true );
424     mUnlockId->setEnabled( false );
425 
426     lStatus->hide();
427     lStatus->setPixmap( QPixmap() );
428     mToDelete = false;
429     slotSetEnabled( true );
430   } else if( state == New ) {
431     lStatus->setPixmap( QIcon::fromTheme("filenew").pixmap(QSize(20,20)));
432     lStatus->show();
433   } else if( state == Deleted ) {
434     lStatus->setPixmap( QIcon::fromTheme( "remove" ).pixmap(QSize(20,20)) );
435     lStatus->show();
436     mToDelete = true;
437     slotSetEnabled( false );
438   } else if( state == Locked ) {
439     mLockId->setEnabled( false );
440     mUnlockId->setEnabled( true );
441     slotSetEnabled( false );
442     lStatus->setPixmap( QIcon::fromTheme( "encrypted" ).pixmap(QSize(20,20)));
443     lStatus->show();
444   }
445 }
446 
setOrdNumber(int o)447 void PositionViewWidget::setOrdNumber(int o)
448 {
449   mOrdNumber = o;
450   if( mModified ) {
451       QColor c( "darkred" );
452       QPalette palette = m_labelPosition->palette();
453       palette.setColor(m_labelPosition->foregroundRole(), c);
454       m_labelPosition->setPalette(palette);
455   }
456   m_labelPosition->setText( QString("%1.").arg( mOrdNumber ) );
457 }
458 
slotSetEnabled(bool doit)459 void PositionViewWidget::slotSetEnabled( bool doit )
460 {
461   if( !doit ) {
462     m_sbAmount->setEnabled( false );
463     m_sbUnitPrice->setEnabled( false );
464     m_labelPosition->setEnabled( false );
465     m_teFloskel->setEnabled( false );
466     m_sumLabel->setEnabled( false );
467     m_cbUnit->setEnabled( false );
468   } else {
469     m_sbAmount->setEnabled( true );
470     m_sbUnitPrice->setEnabled( true );
471     m_labelPosition->setEnabled( true );
472     m_teFloskel->setEnabled( true );
473     m_sumLabel->setEnabled( true );
474     m_cbUnit->setEnabled( true );
475   }
476 }
477 
priceValid()478 bool PositionViewWidget::priceValid()
479 {
480   bool isValid = true;
481 
482   if ( position()->type() == DocPosition::ExtraDiscount ) {
483     isValid = mPositionPriceValid;
484   }
485 
486   return isValid;
487 }
488 
setCurrentPrice(Geld g)489 void PositionViewWidget::setCurrentPrice( Geld g )
490 {
491   // do nothing for normal positions
492   if ( position()->type() == DocPosition::ExtraDiscount ) {
493     mPositionPrice = g;
494     mPositionPriceValid = true;
495   }
496 }
497 
currentPrice()498 Geld PositionViewWidget::currentPrice()
499 {
500   Geld sum;
501   if ( mKind == Normal ) {
502     if ( position()->type() == DocPosition::ExtraDiscount ) {
503       sum = mPositionPrice;
504       if ( ! mPositionPriceValid ) {
505         qWarning() << "Asking for price of Discount item, but invalid!" << endl;
506       }
507     } else {
508       double amount = m_sbAmount->value();
509       Geld g( m_sbUnitPrice->value() );
510       sum = g * amount;
511     }
512   }
513   return sum;
514 }
515 
unitPrice()516 Geld PositionViewWidget::unitPrice()
517 {
518   Geld p(  m_sbUnitPrice->value() );
519   return p;
520 }
521 
slotRefreshPrice()522 void PositionViewWidget::slotRefreshPrice()
523 {
524   const Geld sum = currentPrice();
525   slotSetOverallPrice( sum );
526   emit priceChanged( sum );
527 }
528 
slotSetOverallPrice(Geld g)529 void PositionViewWidget::slotSetOverallPrice( Geld g )
530 {
531   // if ( mPositionPtr->type() == DocPosition::ExtraDiscount ) {
532   //   m_sumLabel->setText( "--" );
533   // } else {
534     m_sumLabel->setText( g.toString() );
535     // }
536 }
537 
slotModified(bool emitSignal)538 void PositionViewWidget::slotModified( bool emitSignal )
539 {
540     Q_UNUSED(emitSignal)
541   if(m_skipModifiedSignal) return;
542   // qDebug () << "Modified Position!" << endl;
543 
544   mModified = true;
545 
546   m_labelPosition->setStyleSheet("font-weight: bold; color: red");
547 
548   emit positionModified();
549 }
550 
~PositionViewWidget()551 PositionViewWidget::~PositionViewWidget()
552 {
553 }
554 
PositionViewWidgetList()555 PositionViewWidgetList::PositionViewWidgetList()
556   : QList<PositionViewWidget*>()
557 {
558   // setAutoDelete( true );
559 }
560 
widgetFromPosition(DocPositionGuardedPtr ptr)561 PositionViewWidget* PositionViewWidgetList::widgetFromPosition( DocPositionGuardedPtr ptr)
562 {
563   PositionViewWidgetListIterator it( *this );
564   while( it.hasNext() ) {
565     PositionViewWidget *pvw = it.next();
566     if( pvw ->position() == ptr ) {
567       return pvw;
568     }
569   }
570 
571   return 0;
572 }
573 
nettoPrice()574 Geld PositionViewWidgetList::nettoPrice()
575 {
576   Geld res;
577 
578   PositionViewWidgetListIterator it( *this );
579   while( it.hasNext() ) {
580     PositionViewWidget *pvw = it.next();
581     res += pvw->currentPrice();
582   }
583   return res;
584 }
585 
slotSetPositionNormal()586 void PositionViewWidget::slotSetPositionNormal()
587 {
588   lKind->hide();
589   lKind->setPixmap( QPixmap() );
590   mKind = Normal;
591 
592   cleanKindString();
593   slotRefreshPrice();
594   emit positionModified();
595 }
596 
cleanKindString()597 void PositionViewWidget::cleanKindString()
598 {
599   QString current = m_teFloskel->toPlainText();
600   bool touched = false;
601 
602   if ( current.startsWith( kindLabel( Alternative ) ) ) {
603     current.remove( 0, QString( kindLabel( Alternative ) ).length() );
604     touched = true;
605   } else if ( current.startsWith( kindLabel( Demand ) ) ) {
606     current.remove( 0, QString( kindLabel( Demand ) ).length() );
607     touched = true;
608   }
609 
610   if ( touched ) {
611     m_teFloskel->setText( current );
612   }
613 }
614 
slotSetPositionAlternative()615 void PositionViewWidget::slotSetPositionAlternative()
616 {
617   lKind->show();
618   lKind->setToolTip( i18n( "This is an alternative item.<br/><br/>"
619                            " Use the position toolbox to change the item type." ) );
620   lKind->setPixmap( QIcon::fromTheme( "kraft_alternative" ).pixmap(QSize(20,20)));
621   mKind = Alternative;
622   slotRefreshPrice();
623 
624   cleanKindString();
625 
626   m_teFloskel->setText( kindLabel( Alternative ) + m_teFloskel->toPlainText() );
627 
628   emit positionModified();
629 }
630 
slotSetPositionDemand()631 void PositionViewWidget::slotSetPositionDemand()
632 {
633   lKind->show();
634   lKind->setToolTip( i18n( "This item is either completely optional or its "
635                            "amount varies depending on the needs.<br/><br/>"
636                            "Use the item toolbox to change the item type." ) );
637   lKind->setPixmap( QIcon::fromTheme("kraft_demand").pixmap(QSize(20,20)));
638   mKind = Demand;
639   slotRefreshPrice();
640 
641   cleanKindString();
642   m_teFloskel->setText( kindLabel( Demand ) + m_teFloskel->toPlainText() );
643 
644   emit positionModified();
645 }
646 
647 // The technical label
kindString(Kind k) const648 QString PositionViewWidget::kindString( Kind k ) const
649 {
650   Kind kind = k;
651 
652   if ( kind == Invalid ) kind = mKind;
653 
654   if ( kind == Normal )      return QString::fromLatin1( "Normal" );
655   if ( kind == Demand )      return QString::fromLatin1( "Demand" );
656   if ( kind == Alternative ) return QString::fromLatin1( "Alternative" );
657 
658   return QString::fromLatin1( "unknown" );
659 }
660 
661 // The label that is prepended to a positions text
kindLabel(Kind k) const662 QString PositionViewWidget::kindLabel( Kind k ) const
663 {
664   Kind kind = k;
665 
666   if ( kind == Invalid ) kind = mKind;
667 
668   QString re;
669   if ( kind == Normal ) {
670     re = KraftSettings::self()->normalLabel();
671     if ( re.isEmpty() ) re = i18n( "Normal" );
672   }
673   if ( kind == Demand ) {
674     re = KraftSettings::self()->demandLabel();
675     if ( re.isEmpty() ) re = i18n( "Demand" );
676   }
677   if ( kind == Alternative ) {
678     re = KraftSettings::self()->alternativeLabel();
679     if ( re.isEmpty() ) re = i18n( "Alternative" );
680   }
681 
682   if ( ! re.endsWith( ": " ) ) {
683     re += QString::fromLatin1( ": " );
684   }
685   return re;
686 }
687 
paintEvent(QPaintEvent *)688 void PositionViewWidget::paintEvent ( QPaintEvent*)
689 {
690   QScopedPointer<QPainter> painter(new QPainter( this ));
691 
692   // visualize the tags
693   const QStringList taglist = tagList();
694   if ( taglist.count() ) {
695     int share = ( height() - 24 ) / taglist.count();
696     int cnt = 0;
697 
698     for ( QStringList::ConstIterator it = taglist.begin(); it != taglist.end(); ++it ) {
699       const QString tag(*it);
700       TagTemplate tagTemplate = TagTemplateMan::self()->getTagTemplate( tag );
701 
702       const QColor c = tagTemplate.color();
703       // qDebug() << "color: " << c.red() << ", " << c.green() << ", " << c.blue() << endl;
704       painter->setBrush( c );
705 
706       int starty = 6+cnt*share;
707       qDrawShadeLine( painter.data(), QPoint(3, starty), QPoint(3, starty+share-1), tagTemplate.palette(), false, 1, 4 );
708       cnt++;
709     }
710   }
711 }
712 
713