kateschema.cpp

00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2001-2003 Christoph Cullmann <cullmann@kde.org>
00003    Copyright (C) 2002, 2003 Anders Lund <anders.lund@lund.tdcadsl.dk>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License version 2 as published by the Free Software Foundation.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
00018 */
00019 
00020 //BEGIN Includes
00021 #include "kateschema.h"
00022 #include "kateschema.moc"
00023 
00024 #include "kateconfig.h"
00025 #include "katedocument.h"
00026 #include "katefactory.h"
00027 #include "kateview.h"
00028 #include "katerenderer.h"
00029 
00030 #include <klocale.h>
00031 #include <kdialogbase.h>
00032 #include <kcolorbutton.h>
00033 #include <kcombobox.h>
00034 #include <kinputdialog.h>
00035 #include <kfontdialog.h>
00036 #include <kdebug.h>
00037 #include <kiconloader.h>
00038 #include <kmessagebox.h>
00039 #include <kpopupmenu.h>
00040 #include <kcolordialog.h>
00041 #include <kapplication.h>
00042 #include <kaboutdata.h>
00043 #include <ktexteditor/markinterface.h>
00044 
00045 #include <qbuttongroup.h>
00046 #include <qcheckbox.h>
00047 #include <qptrcollection.h>
00048 #include <qdialog.h>
00049 #include <qgrid.h>
00050 #include <qgroupbox.h>
00051 #include <qlabel.h>
00052 #include <qtextcodec.h>
00053 #include <qlayout.h>
00054 #include <qlineedit.h>
00055 #include <qheader.h>
00056 #include <qlistbox.h>
00057 #include <qhbox.h>
00058 #include <qpainter.h>
00059 #include <qobjectlist.h>
00060 #include <qpixmap.h>
00061 #include <qpushbutton.h>
00062 #include <qradiobutton.h>
00063 #include <qspinbox.h>
00064 #include <qstringlist.h>
00065 #include <qtabwidget.h>
00066 #include <qvbox.h>
00067 #include <qvgroupbox.h>
00068 #include <qwhatsthis.h>
00069 //END
00070 
00071 //BEGIN KateStyleListViewItem decl
00072 /*
00073     QListViewItem subclass to display/edit a style, bold/italic is check boxes,
00074     normal and selected colors are boxes, which will display a color chooser when
00075     activated.
00076     The context name for the style will be drawn using the editor default font and
00077     the chosen colors.
00078     This widget id designed to handle the default as well as the individual hl style
00079     lists.
00080     This widget is designed to work with the KateStyleListView class exclusively.
00081     Added by anders, jan 23 2002.
00082 */
00083 class KateStyleListItem : public QListViewItem
00084 {
00085   public:
00086     KateStyleListItem( QListViewItem *parent=0, const QString & stylename=0,
00087                    class KateAttribute* defaultstyle=0, class KateHlItemData *data=0 );
00088     KateStyleListItem( QListView *parent, const QString & stylename=0,
00089                    class KateAttribute* defaultstyle=0, class KateHlItemData *data=0 );
00090     ~KateStyleListItem() { if (st) delete is; };
00091 
00092     /* mainly for readability */
00093     enum Property { ContextName, Bold, Italic, Underline, Strikeout, Color, SelColor, BgColor, SelBgColor, UseDefStyle };
00094 
00095     /* initializes the style from the default and the hldata */
00096     void initStyle();
00097     /* updates the hldata's style */
00098     void updateStyle();
00099     /* reimp */
00100     virtual int width ( const QFontMetrics & fm, const QListView * lv, int c ) const;
00101     /* calls changeProperty() if it makes sense considering pos. */
00102     void activate( int column, const QPoint &localPos );
00103     /* For bool fields, toggles them, for color fields, display a color chooser */
00104     void changeProperty( Property p );
00108     void unsetColor( int c );
00109     /* style context name */
00110     QString contextName() { return text(0); };
00111     /* only true for a hl mode item using it's default style */
00112     bool defStyle();
00113     /* true for default styles */
00114     bool isDefault();
00115     /* whichever style is active (st for hl mode styles not using
00116        the default style, ds otherwise) */
00117     class KateAttribute* style() { return is; };
00118 
00119   protected:
00120     /* reimp */
00121     void paintCell(QPainter *p, const QColorGroup& cg, int col, int width, int align);
00122 
00123   private:
00124     /* private methods to change properties */
00125     void toggleDefStyle();
00126     void setColor( int );
00127     /* helper function to copy the default style into the KateHlItemData,
00128        when a property is changed and we are using default style. */
00129 
00130     class KateAttribute *is, // the style currently in use
00131               *ds;           // default style for hl mode contexts and default styles
00132     class KateHlItemData *st;      // itemdata for hl mode contexts
00133 };
00134 //END
00135 
00136 //BEGIN KateStyleListCaption decl
00137 /*
00138     This is a simple subclass for drawing the language names in a nice treeview
00139     with the styles.  It is needed because we do not like to mess with the default
00140     palette of the containing ListView.  Only the paintCell method is overwritten
00141     to use our own palette (that is set on the viewport rather than on the listview
00142     itself).
00143 */
00144 class KateStyleListCaption : public QListViewItem
00145 {
00146   public:
00147     KateStyleListCaption( QListView *parent, const QString & name );
00148     ~KateStyleListCaption() {};
00149 
00150   protected:
00151     void paintCell(QPainter *p, const QColorGroup& cg, int col, int width, int align);
00152 };
00153 //END
00154 
00155 //BEGIN KateSchemaManager
00156 QString KateSchemaManager::normalSchema ()
00157 {
00158   return KApplication::kApplication()->aboutData()->appName () + QString (" - Normal");
00159 }
00160 
00161 QString KateSchemaManager::printingSchema ()
00162 {
00163   return KApplication::kApplication()->aboutData()->appName () + QString (" - Printing");
00164 }
00165 
00166 KateSchemaManager::KateSchemaManager ()
00167   : m_config ("kateschemarc", false, false)
00168 {
00169   update ();
00170 }
00171 
00172 KateSchemaManager::~KateSchemaManager ()
00173 {
00174 }
00175 
00176 //
00177 // read the types from config file and update the internal list
00178 //
00179 void KateSchemaManager::update (bool readfromfile)
00180 {
00181   if (readfromfile)
00182     m_config.reparseConfiguration ();
00183 
00184   m_schemas = m_config.groupList();
00185   m_schemas.sort ();
00186 
00187   m_schemas.remove (printingSchema());
00188   m_schemas.remove (normalSchema());
00189   m_schemas.prepend (printingSchema());
00190   m_schemas.prepend (normalSchema());
00191 }
00192 
00193 //
00194 // get the right group
00195 // special handling of the default schemas ;)
00196 //
00197 KConfig *KateSchemaManager::schema (uint number)
00198 {
00199   if ((number>1) && (number < m_schemas.count()))
00200     m_config.setGroup (m_schemas[number]);
00201   else if (number == 1)
00202     m_config.setGroup (printingSchema());
00203   else
00204     m_config.setGroup (normalSchema());
00205 
00206   return &m_config;
00207 }
00208 
00209 void KateSchemaManager::addSchema (const QString &t)
00210 {
00211   m_config.setGroup (t);
00212   m_config.writeEntry("Color Background", KGlobalSettings::baseColor());
00213 
00214   update (false);
00215 }
00216 
00217 void KateSchemaManager::removeSchema (uint number)
00218 {
00219   if (number >= m_schemas.count())
00220     return;
00221 
00222   if (number < 2)
00223     return;
00224 
00225   m_config.deleteGroup (name (number));
00226 
00227   update (false);
00228 }
00229 
00230 bool KateSchemaManager::validSchema (uint number)
00231 {
00232   if (number < m_schemas.count())
00233     return true;
00234 
00235   return false;
00236 }
00237 
00238 uint KateSchemaManager::number (const QString &name)
00239 {
00240   if (name == normalSchema())
00241     return 0;
00242 
00243   if (name == printingSchema())
00244     return 1;
00245 
00246   int i;
00247   if ((i = m_schemas.findIndex(name)) > -1)
00248     return i;
00249 
00250   return 0;
00251 }
00252 
00253 QString KateSchemaManager::name (uint number)
00254 {
00255   if ((number>1) && (number < m_schemas.count()))
00256     return m_schemas[number];
00257   else if (number == 1)
00258     return printingSchema();
00259 
00260   return normalSchema();
00261 }
00262 //END
00263 
00264 //
00265 // DIALOGS !!!
00266 //
00267 
00268 //BEGIN KateSchemaConfigColorTab -- 'Colors' tab
00269 KateSchemaConfigColorTab::KateSchemaConfigColorTab( QWidget *parent, const char * )
00270   : QWidget (parent)
00271 {
00272   m_schema = -1;
00273 
00274   QHBox *b, *b1;
00275   QLabel *label;
00276 
00277   QVBoxLayout *blay=new QVBoxLayout(this, 0, KDialog::spacingHint());
00278 
00279   QVGroupBox *gbTextArea = new QVGroupBox(i18n("Text Area Background"), this);
00280 
00281   b1 = new QHBox (gbTextArea);
00282   b1->setSpacing(KDialog::spacingHint());
00283 
00284   b = new QHBox (b1);
00285   b->setSpacing(KDialog::spacingHint());
00286   label = new QLabel( i18n("Normal text:"), b);
00287   label->setAlignment( AlignLeft|AlignVCenter);
00288   m_back = new KColorButton(b);
00289 
00290   b = new QHBox (b1);
00291   b->setSpacing(KDialog::spacingHint());
00292   label = new QLabel( i18n("Selected text:"), b);
00293   label->setAlignment( AlignLeft|AlignVCenter);
00294   m_selected = new KColorButton(b);
00295 
00296   b1 = new QHBox (gbTextArea);
00297   b1->setSpacing(KDialog::spacingHint());
00298 
00299   b = new QHBox (b1);
00300   b->setSpacing(KDialog::spacingHint());
00301   label = new QLabel( i18n("Current line:"), b);
00302   label->setAlignment( AlignLeft|AlignVCenter);
00303   m_current = new KColorButton(b);
00304 
00305   // Markers from kdelibs/interfaces/ktextinterface/markinterface.h
00306   b = new QHBox (b1);
00307   b->setSpacing(KDialog::spacingHint());
00308   m_combobox = new KComboBox(b, "color_combo_box");
00309   // add the predefined mark types as defined in markinterface.h
00310   m_combobox->insertItem(i18n("Bookmark"));            // markType01
00311   m_combobox->insertItem(i18n("Active Breakpoint"));   // markType02
00312   m_combobox->insertItem(i18n("Reached Breakpoint"));  // markType03
00313   m_combobox->insertItem(i18n("Disabled Breakpoint")); // markType04
00314   m_combobox->insertItem(i18n("Execution"));           // markType05
00315   m_combobox->insertItem(i18n("Warning"));             // markType06
00316   m_combobox->insertItem(i18n("Error"));               // markType07
00317   m_combobox->setCurrentItem(0);
00318   m_markers = new KColorButton(b, "marker_color_button");
00319   connect( m_combobox, SIGNAL( activated( int ) ), SLOT( slotComboBoxChanged( int ) ) );
00320 
00321   blay->addWidget(gbTextArea);
00322 
00323   QVGroupBox *gbBorder = new QVGroupBox(i18n("Additional Elements"), this);
00324 
00325   b = new QHBox (gbBorder);
00326   b->setSpacing(KDialog::spacingHint());
00327   label = new QLabel( i18n("Left border background:"), b);
00328   label->setAlignment( AlignLeft|AlignVCenter);
00329   m_iconborder = new KColorButton(b);
00330 
00331   b = new QHBox (gbBorder);
00332   b->setSpacing(KDialog::spacingHint());
00333   label = new QLabel( i18n("Line numbers:"), b);
00334   label->setAlignment( AlignLeft|AlignVCenter);
00335   m_linenumber = new KColorButton(b);
00336 
00337   b = new QHBox (gbBorder);
00338   b->setSpacing(KDialog::spacingHint());
00339   label = new QLabel( i18n("Bracket highlight:"), b);
00340   label->setAlignment( AlignLeft|AlignVCenter);
00341   m_bracket = new KColorButton(b);
00342 
00343   b = new QHBox (gbBorder);
00344   b->setSpacing(KDialog::spacingHint());
00345   label = new QLabel( i18n("Word wrap markers:"), b);
00346   label->setAlignment( AlignLeft|AlignVCenter);
00347   m_wwmarker = new KColorButton(b);
00348 
00349   b = new QHBox (gbBorder);
00350   b->setSpacing(KDialog::spacingHint());
00351   label = new QLabel( i18n("Tab markers:"), b);
00352   label->setAlignment( AlignLeft|AlignVCenter);
00353   m_tmarker = new KColorButton(b);
00354 
00355   blay->addWidget(gbBorder);
00356 
00357   blay->addStretch();
00358 
00359   // connect signal changed(); changed is emitted by a ColorButton change!
00360   connect( this, SIGNAL( changed() ), parent->parentWidget(), SLOT( slotChanged() ) );
00361 
00362   // QWhatsThis help
00363   QWhatsThis::add(m_back, i18n("<p>Sets the background color of the editing area.</p>"));
00364   QWhatsThis::add(m_selected, i18n("<p>Sets the background color of the selection.</p>"
00365         "<p>To set the text color for selected text, use the \"<b>Configure "
00366         "Highlighting</b>\" dialog.</p>"));
00367   QWhatsThis::add(m_markers, i18n("<p>Sets the background color of the selected "
00368         "marker type.</p><p><b>Note</b>: The marker color is displayed lightly because "
00369         "of transparency.</p>"));
00370   QWhatsThis::add(m_combobox, i18n("<p>Select the marker type you want to change.</p>"));
00371   QWhatsThis::add(m_current, i18n("<p>Sets the background color of the currently "
00372         "active line, which means the line where your cursor is positioned.</p>"));
00373   QWhatsThis::add( m_linenumber, i18n(
00374         "<p>This color will be used to draw the line numbers (if enabled) and the "
00375         "lines in the code-folding pane.</p>" ) );
00376   QWhatsThis::add(m_bracket, i18n("<p>Sets the bracket matching color. This means, "
00377         "if you place the cursor e.g. at a <b>(</b>, the matching <b>)</b> will "
00378         "be highlighted with this color.</p>"));
00379   QWhatsThis::add(m_wwmarker, i18n(
00380         "<p>Sets the color of Word Wrap-related markers:</p>"
00381         "<dl><dt>Static Word Wrap</dt><dd>A vertical line which shows the column where "
00382         "text is going to be wrapped</dd>"
00383         "<dt>Dynamic Word Wrap</dt><dd>An arrow shown to the left of "
00384         "visually-wrapped lines</dd></dl>"));
00385   QWhatsThis::add(m_tmarker, i18n(
00386         "<p>Sets the color of the tabulator marks:</p>"));
00387 }
00388 
00389 KateSchemaConfigColorTab::~KateSchemaConfigColorTab()
00390 {
00391 }
00392 
00393 void KateSchemaConfigColorTab::schemaChanged ( int newSchema )
00394 {
00395   // save curent schema
00396   if ( m_schema > -1 )
00397   {
00398     m_schemas[ m_schema ].back = m_back->color();
00399     m_schemas[ m_schema ].selected = m_selected->color();
00400     m_schemas[ m_schema ].current = m_current->color();
00401     m_schemas[ m_schema ].bracket = m_bracket->color();
00402     m_schemas[ m_schema ].wwmarker = m_wwmarker->color();
00403     m_schemas[ m_schema ].iconborder = m_iconborder->color();
00404     m_schemas[ m_schema ].tmarker = m_tmarker->color();
00405     m_schemas[ m_schema ].linenumber = m_linenumber->color();
00406   }
00407 
00408   if ( newSchema == m_schema ) return;
00409 
00410   // switch
00411   m_schema = newSchema;
00412 
00413   // first disconnect all signals otherwise setColor emits changed
00414   m_back      ->disconnect( SIGNAL( changed( const QColor & ) ) );
00415   m_selected  ->disconnect( SIGNAL( changed( const QColor & ) ) );
00416   m_current   ->disconnect( SIGNAL( changed( const QColor & ) ) );
00417   m_bracket   ->disconnect( SIGNAL( changed( const QColor & ) ) );
00418   m_wwmarker  ->disconnect( SIGNAL( changed( const QColor & ) ) );
00419   m_iconborder->disconnect( SIGNAL( changed( const QColor & ) ) );
00420   m_tmarker   ->disconnect( SIGNAL( changed( const QColor & ) ) );
00421   m_markers   ->disconnect( SIGNAL( changed( const QColor & ) ) );
00422   m_linenumber->disconnect( SIGNAL( changed( const QColor & ) ) );
00423 
00424   // If we havent this schema, read in from config file
00425   if ( ! m_schemas.contains( newSchema ) )
00426   {
00427     // fallback defaults
00428     QColor tmp0 (KGlobalSettings::baseColor());
00429     QColor tmp1 (KGlobalSettings::highlightColor());
00430     QColor tmp2 (KGlobalSettings::alternateBackgroundColor());
00431     QColor tmp3 ( "#FFFF99" );
00432     QColor tmp4 (tmp2.dark());
00433     QColor tmp5 ( KGlobalSettings::textColor() );
00434     QColor tmp6 ( "#EAE9E8" );
00435     QColor tmp7 ( "#000000" );
00436 
00437     // same std colors like in KateDocument::markColor
00438     QValueVector <QColor> mark(KTextEditor::MarkInterface::reservedMarkersCount());
00439     Q_ASSERT(mark.size() > 6);
00440     mark[0] = Qt::blue;
00441     mark[1] = Qt::red;
00442     mark[2] = Qt::yellow;
00443     mark[3] = Qt::magenta;
00444     mark[4] = Qt::gray;
00445     mark[5] = Qt::green;
00446     mark[6] = Qt::red;
00447 
00448     SchemaColors c;
00449     KConfig *config = KateFactory::self()->schemaManager()->schema(newSchema);
00450 
00451     c.back= config->readColorEntry("Color Background", &tmp0);
00452     c.selected = config->readColorEntry("Color Selection", &tmp1);
00453     c.current = config->readColorEntry("Color Highlighted Line", &tmp2);
00454     c.bracket = config->readColorEntry("Color Highlighted Bracket", &tmp3);
00455     c.wwmarker = config->readColorEntry("Color Word Wrap Marker", &tmp4);
00456     c.tmarker = config->readColorEntry("Color Tab Marker", &tmp5);
00457     c.iconborder = config->readColorEntry("Color Icon Bar", &tmp6);
00458     c.linenumber = config->readColorEntry("Color Line Number", &tmp7);
00459 
00460     for (int i = 0; i < KTextEditor::MarkInterface::reservedMarkersCount(); i++)
00461       c.markerColors[i] =  config->readColorEntry( QString("Color MarkType%1").arg(i+1), &mark[i] );
00462 
00463      m_schemas[ newSchema ] = c;
00464   }
00465 
00466   m_back->setColor(  m_schemas[ newSchema ].back);
00467   m_selected->setColor(  m_schemas [ newSchema ].selected );
00468   m_current->setColor(  m_schemas [ newSchema ].current );
00469   m_bracket->setColor(  m_schemas [ newSchema ].bracket );
00470   m_wwmarker->setColor(  m_schemas [ newSchema ].wwmarker );
00471   m_tmarker->setColor(  m_schemas [ newSchema ].tmarker );
00472   m_iconborder->setColor(  m_schemas [ newSchema ].iconborder );
00473   m_linenumber->setColor(  m_schemas [ newSchema ].linenumber );
00474 
00475   // map from 0..reservedMarkersCount()-1 - the same index as in markInterface
00476   for (int i = 0; i < KTextEditor::MarkInterface::reservedMarkersCount(); i++)
00477   {
00478     QPixmap pix(16, 16);
00479     pix.fill( m_schemas [ newSchema ].markerColors[i]);
00480     m_combobox->changeItem(pix, m_combobox->text(i), i);
00481   }
00482   m_markers->setColor(  m_schemas [ newSchema ].markerColors[ m_combobox->currentItem() ] );
00483 
00484   connect( m_back      , SIGNAL( changed( const QColor& ) ), SIGNAL( changed() ) );
00485   connect( m_selected  , SIGNAL( changed( const QColor& ) ), SIGNAL( changed() ) );
00486   connect( m_current   , SIGNAL( changed( const QColor& ) ), SIGNAL( changed() ) );
00487   connect( m_bracket   , SIGNAL( changed( const QColor& ) ), SIGNAL( changed() ) );
00488   connect( m_wwmarker  , SIGNAL( changed( const QColor& ) ), SIGNAL( changed() ) );
00489   connect( m_iconborder, SIGNAL( changed( const QColor& ) ), SIGNAL( changed() ) );
00490   connect( m_tmarker   , SIGNAL( changed( const QColor& ) ), SIGNAL( changed() ) );
00491   connect( m_linenumber, SIGNAL( changed( const QColor& ) ), SIGNAL( changed() ) );
00492   connect( m_markers   , SIGNAL( changed( const QColor& ) ), SLOT( slotMarkerColorChanged( const QColor& ) ) );
00493 }
00494 
00495 void KateSchemaConfigColorTab::apply ()
00496 {
00497   schemaChanged( m_schema );
00498   QMap<int,SchemaColors>::Iterator it;
00499   for ( it =  m_schemas.begin(); it !=  m_schemas.end(); ++it )
00500   {
00501     kdDebug(13030)<<"APPLY scheme = "<<it.key()<<endl;
00502     KConfig *config = KateFactory::self()->schemaManager()->schema( it.key() );
00503     kdDebug(13030)<<"Using config group "<<config->group()<<endl;
00504     SchemaColors c = it.data();
00505 
00506     config->writeEntry("Color Background", c.back);
00507     config->writeEntry("Color Selection", c.selected);
00508     config->writeEntry("Color Highlighted Line", c.current);
00509     config->writeEntry("Color Highlighted Bracket", c.bracket);
00510     config->writeEntry("Color Word Wrap Marker", c.wwmarker);
00511     config->writeEntry("Color Tab Marker", c.tmarker);
00512     config->writeEntry("Color Icon Bar", c.iconborder);
00513     config->writeEntry("Color Line Number", c.linenumber);
00514 
00515     for (int i = 0; i < KTextEditor::MarkInterface::reservedMarkersCount(); i++)
00516     {
00517       config->writeEntry(QString("Color MarkType%1").arg(i + 1), c.markerColors[i]);
00518     }
00519   }
00520 }
00521 
00522 void KateSchemaConfigColorTab::slotMarkerColorChanged( const QColor& color)
00523 {
00524   int index = m_combobox->currentItem();
00525    m_schemas[ m_schema ].markerColors[ index ] = color;
00526   QPixmap pix(16, 16);
00527   pix.fill(color);
00528   m_combobox->changeItem(pix, m_combobox->text(index), index);
00529 
00530   emit changed();
00531 }
00532 
00533 void KateSchemaConfigColorTab::slotComboBoxChanged(int index)
00534 {
00535   // temporarily disconnect the changed-signal because setColor emits changed as well
00536   m_markers->disconnect( SIGNAL( changed( const QColor& ) ) );
00537   m_markers->setColor( m_schemas[m_schema].markerColors[index] );
00538   connect( m_markers, SIGNAL( changed( const QColor& ) ), SLOT( slotMarkerColorChanged( const QColor& ) ) );
00539 }
00540 
00541 //END KateSchemaConfigColorTab
00542 
00543 //BEGIN FontConfig -- 'Fonts' tab
00544 KateSchemaConfigFontTab::KateSchemaConfigFontTab( QWidget *parent, const char * )
00545   : QWidget (parent)
00546 {
00547     // sizemanagment
00548   QGridLayout *grid = new QGridLayout( this, 1, 1 );
00549 
00550   m_fontchooser = new KFontChooser ( this, 0L, false, QStringList(), false );
00551   m_fontchooser->enableColumn(KFontChooser::StyleList, false);
00552   grid->addWidget( m_fontchooser, 0, 0);
00553 
00554   connect (this, SIGNAL( changed()), parent->parentWidget(), SLOT (slotChanged()));
00555   m_schema = -1;
00556 }
00557 
00558 KateSchemaConfigFontTab::~KateSchemaConfigFontTab()
00559 {
00560 }
00561 
00562 void KateSchemaConfigFontTab::slotFontSelected( const QFont &font )
00563 {
00564   if ( m_schema > -1 )
00565   {
00566     m_fonts[m_schema] = font;
00567     emit changed();
00568   }
00569 }
00570 
00571 void KateSchemaConfigFontTab::apply()
00572 {
00573   FontMap::Iterator it;
00574   for ( it = m_fonts.begin(); it != m_fonts.end(); ++it )
00575   {
00576     KateFactory::self()->schemaManager()->schema( it.key() )->writeEntry( "Font", it.data() );
00577   }
00578 }
00579 
00580 void KateSchemaConfigFontTab::schemaChanged( int newSchema )
00581 {
00582   if ( m_schema > -1 )
00583     m_fonts[ m_schema ] = m_fontchooser->font();
00584 
00585   m_schema = newSchema;
00586 
00587   QFont f (KGlobalSettings::fixedFont());
00588 
00589   m_fontchooser->disconnect ( this );
00590   m_fontchooser->setFont ( KateFactory::self()->schemaManager()->schema( newSchema )->readFontEntry("Font", &f) );
00591   m_fonts[ newSchema ] = m_fontchooser->font();
00592   connect (m_fontchooser, SIGNAL (fontSelected( const QFont & )), this, SLOT (slotFontSelected( const QFont & )));
00593 }
00594 //END FontConfig
00595 
00596 //BEGIN FontColorConfig -- 'Normal Text Styles' tab
00597 KateSchemaConfigFontColorTab::KateSchemaConfigFontColorTab( QWidget *parent, const char * )
00598   : QWidget (parent)
00599 {
00600   m_defaultStyleLists.setAutoDelete(true);
00601 
00602   // sizemanagment
00603   QGridLayout *grid = new QGridLayout( this, 1, 1 );
00604 
00605   m_defaultStyles = new KateStyleListView( this, false );
00606   grid->addWidget( m_defaultStyles, 0, 0);
00607 
00608   connect (m_defaultStyles, SIGNAL (changed()), parent->parentWidget(), SLOT (slotChanged()));
00609 
00610   QWhatsThis::add( m_defaultStyles,  i18n(
00611       "This list displays the default styles for the current schema and "
00612       "offers the means to edit them. The style name reflects the current "
00613       "style settings."
00614       "<p>To edit the colors, click the colored squares, or select the color "
00615       "to edit from the popup menu.<p>You can unset the Background and Selected "
00616       "Background colors from the popup menu when appropriate.") );
00617 }
00618 
00619 KateSchemaConfigFontColorTab::~KateSchemaConfigFontColorTab()
00620 {
00621 }
00622 
00623 KateAttributeList *KateSchemaConfigFontColorTab::attributeList (uint schema)
00624 {
00625   if (!m_defaultStyleLists[schema])
00626   {
00627     KateAttributeList *list = new KateAttributeList ();
00628     KateHlManager::self()->getDefaults(schema, *list);
00629 
00630     m_defaultStyleLists.insert (schema, list);
00631   }
00632 
00633   return m_defaultStyleLists[schema];
00634 }
00635 
00636 void KateSchemaConfigFontColorTab::schemaChanged (uint schema)
00637 {
00638   m_defaultStyles->clear ();
00639 
00640   KateAttributeList *l = attributeList (schema);
00641 
00642   // set colors
00643   QPalette p ( m_defaultStyles->palette() );
00644   QColor _c ( KGlobalSettings::baseColor() );
00645   p.setColor( QColorGroup::Base,
00646     KateFactory::self()->schemaManager()->schema(schema)->
00647       readColorEntry( "Color Background", &_c ) );
00648   _c = KGlobalSettings::highlightColor();
00649   p.setColor( QColorGroup::Highlight,
00650     KateFactory::self()->schemaManager()->schema(schema)->
00651       readColorEntry( "Color Selection", &_c ) );
00652   _c = l->at(0)->textColor(); // not quite as much of an assumption ;)
00653   p.setColor( QColorGroup::Text, _c );
00654   m_defaultStyles->viewport()->setPalette( p );
00655 
00656   // insert the default styles backwards to get them in the right order
00657   for ( int i = KateHlManager::self()->defaultStyles() - 1; i >= 0; i-- )
00658   {
00659     new KateStyleListItem( m_defaultStyles, KateHlManager::self()->defaultStyleName(i, true), l->at( i ) );
00660   }
00661 }
00662 
00663 void KateSchemaConfigFontColorTab::reload ()
00664 {
00665   m_defaultStyles->clear ();
00666   m_defaultStyleLists.clear ();
00667 }
00668 
00669 void KateSchemaConfigFontColorTab::apply ()
00670 {
00671   for ( QIntDictIterator<KateAttributeList> it( m_defaultStyleLists ); it.current(); ++it )
00672     KateHlManager::self()->setDefaults(it.currentKey(), *(it.current()));
00673 }
00674 
00675 //END FontColorConfig
00676 
00677 //BEGIN KateSchemaConfigHighlightTab -- 'Highlighting Text Styles' tab
00678 KateSchemaConfigHighlightTab::KateSchemaConfigHighlightTab( QWidget *parent, const char *, KateSchemaConfigFontColorTab *page, uint hl )
00679   : QWidget (parent)
00680 {
00681   m_defaults = page;
00682 
00683   m_schema = 0;
00684   m_hl = 0;
00685 
00686   m_hlDict.setAutoDelete (true);
00687 
00688   QVBoxLayout *layout = new QVBoxLayout(this, 0, KDialog::spacingHint() );
00689 
00690   // hl chooser
00691   QHBox *hbHl = new QHBox( this );
00692   layout->add (hbHl);
00693 
00694   hbHl->setSpacing( KDialog::spacingHint() );
00695   QLabel *lHl = new QLabel( i18n("H&ighlight:"), hbHl );
00696   hlCombo = new QComboBox( false, hbHl );
00697   lHl->setBuddy( hlCombo );
00698   connect( hlCombo, SIGNAL(activated(int)),
00699            this, SLOT(hlChanged(int)) );
00700 
00701   for( int i = 0; i < KateHlManager::self()->highlights(); i++) {
00702     if (KateHlManager::self()->hlSection(i).length() > 0)
00703       hlCombo->insertItem(KateHlManager::self()->hlSection(i) + QString ("/") + KateHlManager::self()->hlNameTranslated(i));
00704     else
00705       hlCombo->insertItem(KateHlManager::self()->hlNameTranslated(i));
00706   }
00707   hlCombo->setCurrentItem(0);
00708 
00709   // styles listview
00710   m_styles = new KateStyleListView( this, true );
00711   layout->addWidget (m_styles, 999);
00712 
00713   hlCombo->setCurrentItem ( hl );
00714   hlChanged ( hl );
00715 
00716   QWhatsThis::add( m_styles,  i18n(
00717     "This list displays the contexts of the current syntax highlight mode and "
00718     "offers the means to edit them. The context name reflects the current "
00719     "style settings.<p>To edit using the keyboard, press "
00720     "<strong>&lt;SPACE&gt;</strong> and choose a property from the popup menu."
00721     "<p>To edit the colors, click the colored squares, or select the color "
00722     "to edit from the popup menu.<p>You can unset the Background and Selected "
00723     "Background colors from the context menu when appropriate.") );
00724 
00725   connect (m_styles, SIGNAL (changed()), parent->parentWidget(), SLOT (slotChanged()));
00726 }
00727 
00728 KateSchemaConfigHighlightTab::~KateSchemaConfigHighlightTab()
00729 {
00730 }
00731 
00732 void KateSchemaConfigHighlightTab::hlChanged(int z)
00733 {
00734   m_hl = z;
00735 
00736   schemaChanged (m_schema);
00737 }
00738 
00739 void KateSchemaConfigHighlightTab::schemaChanged (uint schema)
00740 {
00741   m_schema = schema;
00742 
00743   kdDebug(13030) << "NEW SCHEMA: " << m_schema << " NEW HL: " << m_hl << endl;
00744 
00745   m_styles->clear ();
00746 
00747   if (!m_hlDict[m_schema])
00748   {
00749     kdDebug(13030) << "NEW SCHEMA, create dict" << endl;
00750 
00751     m_hlDict.insert (schema, new QIntDict<KateHlItemDataList>);
00752     m_hlDict[m_schema]->setAutoDelete (true);
00753   }
00754 
00755   if (!m_hlDict[m_schema]->find(m_hl))
00756   {
00757     kdDebug(13030) << "NEW HL, create list" << endl;
00758 
00759     KateHlItemDataList *list = new KateHlItemDataList ();
00760     KateHlManager::self()->getHl( m_hl )->getKateHlItemDataListCopy (m_schema, *list);
00761     m_hlDict[m_schema]->insert (m_hl, list);
00762   }
00763 
00764   KateAttributeList *l = m_defaults->attributeList (schema);
00765 
00766   // Set listview colors
00767   // We do that now, because we can now get the "normal text" color.
00768   // TODO this reads of the KConfig object, which should be changed when
00769   // the color tab is fixed.
00770   QPalette p ( m_styles->palette() );
00771   QColor _c ( KGlobalSettings::baseColor() );
00772   p.setColor( QColorGroup::Base,
00773     KateFactory::self()->schemaManager()->schema(m_schema)->
00774       readColorEntry( "Color Background", &_c ) );
00775   _c = KGlobalSettings::highlightColor();
00776   p.setColor( QColorGroup::Highlight,
00777     KateFactory::self()->schemaManager()->schema(m_schema)->
00778       readColorEntry( "Color Selection", &_c ) );
00779   _c = l->at(0)->textColor(); // not quite as much of an assumption ;)
00780   p.setColor( QColorGroup::Text, _c );
00781   m_styles->viewport()->setPalette( p );
00782 
00783   QDict<KateStyleListCaption> prefixes;
00784   for ( KateHlItemData *itemData = m_hlDict[m_schema]->find(m_hl)->last();
00785         itemData != 0L;
00786         itemData = m_hlDict[m_schema]->find(m_hl)->prev())
00787   {
00788     kdDebug(13030) << "insert items " << itemData->name << endl;
00789 
00790     // All stylenames have their language mode prefixed, e.g. HTML:Comment
00791     // split them and put them into nice substructures.
00792     int c = itemData->name.find(':');
00793     if ( c > 0 ) {
00794       QString prefix = itemData->name.left(c);
00795       QString name   = itemData->name.mid(c+1);
00796 
00797       KateStyleListCaption *parent = prefixes.find( prefix );
00798       if ( ! parent )
00799       {
00800         parent = new KateStyleListCaption( m_styles, prefix );
00801         parent->setOpen(true);
00802         prefixes.insert( prefix, parent );
00803       }
00804       new KateStyleListItem( parent, name, l->at(itemData->defStyleNum), itemData );
00805     } else {
00806       new KateStyleListItem( m_styles, itemData->name, l->at(itemData->defStyleNum), itemData );
00807     }
00808   }
00809 }
00810 
00811 void KateSchemaConfigHighlightTab::reload ()
00812 {
00813   m_styles->clear ();
00814   m_hlDict.clear ();
00815 
00816   hlChanged (0);
00817 }
00818 
00819 void KateSchemaConfigHighlightTab::apply ()
00820 {
00821   for ( QIntDictIterator< QIntDict<KateHlItemDataList> > it( m_hlDict ); it.current(); ++it )
00822     for ( QIntDictIterator< KateHlItemDataList > it2( *it.current() ); it2.current(); ++it2 )
00823     {
00824       KateHlManager::self()->getHl( it2.currentKey() )->setKateHlItemDataList (it.currentKey(), *(it2.current()));
00825     }
00826 }
00827 
00828 //END KateSchemaConfigHighlightTab
00829 
00830 //BEGIN KateSchemaConfigPage -- Main dialog page
00831 KateSchemaConfigPage::KateSchemaConfigPage( QWidget *parent, KateDocument *doc )
00832   : KateConfigPage( parent ),
00833     m_lastSchema (-1)
00834 {
00835   QVBoxLayout *layout = new QVBoxLayout(this, 0, KDialog::spacingHint() );
00836 
00837   QHBox *hbHl = new QHBox( this );
00838   layout->add (hbHl);
00839   hbHl->setSpacing( KDialog::spacingHint() );
00840   QLabel *lHl = new QLabel( i18n("&Schema:"), hbHl );
00841   schemaCombo = new QComboBox( false, hbHl );
00842   lHl->setBuddy( schemaCombo );
00843   connect( schemaCombo, SIGNAL(activated(int)),
00844            this, SLOT(schemaChanged(int)) );
00845 
00846   QPushButton *btnnew = new QPushButton( i18n("&New..."), hbHl );
00847   connect( btnnew, SIGNAL(clicked()), this, SLOT(newSchema()) );
00848 
00849   btndel = new QPushButton( i18n("&Delete"), hbHl );
00850   connect( btndel, SIGNAL(clicked()), this, SLOT(deleteSchema()) );
00851 
00852   m_tabWidget = new QTabWidget ( this );
00853   m_tabWidget->setMargin (KDialog::marginHint());
00854   layout->add (m_tabWidget);
00855 
00856   connect (m_tabWidget, SIGNAL (currentChanged (QWidget *)), this, SLOT (newCurrentPage (QWidget *)));
00857 
00858   m_colorTab = new KateSchemaConfigColorTab (m_tabWidget);
00859   m_tabWidget->addTab (m_colorTab, i18n("Colors"));
00860 
00861   m_fontTab = new KateSchemaConfigFontTab (m_tabWidget);
00862   m_tabWidget->addTab (m_fontTab, i18n("Font"));
00863 
00864   m_fontColorTab = new KateSchemaConfigFontColorTab (m_tabWidget);
00865   m_tabWidget->addTab (m_fontColorTab, i18n("Normal Text Styles"));
00866 
00867   uint hl = doc ? doc->hlMode() : 0;
00868   m_highlightTab = new KateSchemaConfigHighlightTab (m_tabWidget, "", m_fontColorTab, hl );
00869   m_tabWidget->addTab (m_highlightTab, i18n("Highlighting Text Styles"));
00870 
00871   hbHl = new QHBox( this );
00872   layout->add (hbHl);
00873   hbHl->setSpacing( KDialog::spacingHint() );
00874   lHl = new QLabel( i18n("&Default schema for %1:").arg(KApplication::kApplication()->aboutData()->programName ()), hbHl );
00875   defaultSchemaCombo = new QComboBox( false, hbHl );
00876   lHl->setBuddy( defaultSchemaCombo );
00877 
00878 
00879   m_defaultSchema = (doc && doc->activeView()) ? doc->activeView()->renderer()->config()->schema() : KateRendererConfig::global()->schema();
00880 
00881   reload();
00882 
00883   connect( defaultSchemaCombo, SIGNAL(activated(int)),
00884            this, SLOT(slotChanged()) );
00885 }
00886 
00887 KateSchemaConfigPage::~KateSchemaConfigPage ()
00888 {
00889   // just reload config from disc
00890   KateFactory::self()->schemaManager()->update ();
00891 }
00892 
00893 void KateSchemaConfigPage::apply()
00894 {
00895   m_colorTab->apply();
00896   m_fontTab->apply();
00897   m_fontColorTab->apply ();
00898   m_highlightTab->apply ();
00899 
00900   // just sync the config
00901   KateFactory::self()->schemaManager()->schema (0)->sync();
00902 
00903   KateFactory::self()->schemaManager()->update ();
00904 
00905   // clear all attributes
00906   for (int i = 0; i < KateHlManager::self()->highlights(); ++i)
00907     KateHlManager::self()->getHl (i)->clearAttributeArrays ();
00908 
00909   // than reload the whole stuff
00910   KateRendererConfig::global()->setSchema (defaultSchemaCombo->currentItem());
00911   KateRendererConfig::global()->reloadSchema();
00912 
00913   // sync the hl config for real
00914   KateHlManager::self()->getKConfig()->sync ();
00915 }
00916 
00917 void KateSchemaConfigPage::reload()
00918 {
00919   // just reload the config from disc
00920   KateFactory::self()->schemaManager()->update ();
00921 
00922   // special for the highlighting stuff
00923   m_fontColorTab->reload ();
00924 
00925   update ();
00926 
00927   defaultSchemaCombo->setCurrentItem (KateRendererConfig::global()->schema());
00928 
00929   // initialize to the schema in the current document, or default schema
00930   schemaCombo->setCurrentItem( m_defaultSchema );
00931   schemaChanged( m_defaultSchema );
00932 }
00933 
00934 void KateSchemaConfigPage::reset()
00935 {
00936   reload ();
00937 }
00938 
00939 void KateSchemaConfigPage::defaults()
00940 {
00941   reload ();
00942 }
00943 
00944 void KateSchemaConfigPage::update ()
00945 {
00946   // soft update, no load from disk
00947   KateFactory::self()->schemaManager()->update (false);
00948 
00949   schemaCombo->clear ();
00950   schemaCombo->insertStringList (KateFactory::self()->schemaManager()->list ());
00951 
00952   defaultSchemaCombo->clear ();
00953   defaultSchemaCombo->insertStringList (KateFactory::self()->schemaManager()->list ());
00954 
00955   schemaCombo->setCurrentItem (0);
00956   schemaChanged (0);
00957 
00958   schemaCombo->setEnabled (schemaCombo->count() > 0);
00959 }
00960 
00961 void KateSchemaConfigPage::deleteSchema ()
00962 {
00963   int t = schemaCombo->currentItem ();
00964 
00965   KateFactory::self()->schemaManager()->removeSchema (t);
00966 
00967   update ();
00968 }
00969 
00970 void KateSchemaConfigPage::newSchema ()
00971 {
00972   QString t = KInputDialog::getText (i18n("Name for New Schema"), i18n ("Name:"), i18n("New Schema"), 0, this);
00973 
00974   KateFactory::self()->schemaManager()->addSchema (t);
00975 
00976   // soft update, no load from disk
00977   KateFactory::self()->schemaManager()->update (false);
00978   int i = KateFactory::self()->schemaManager()->list ().findIndex (t);
00979 
00980   update ();
00981   if (i > -1)
00982   {
00983     schemaCombo->setCurrentItem (i);
00984     schemaChanged (i);
00985   }
00986 }
00987 
00988 void KateSchemaConfigPage::schemaChanged (int schema)
00989 {
00990   btndel->setEnabled( schema > 1 );
00991 
00992   m_colorTab->schemaChanged( schema );
00993   m_fontTab->schemaChanged( schema );
00994   m_fontColorTab->schemaChanged (schema);
00995   m_highlightTab->schemaChanged (schema);
00996 
00997   m_lastSchema = schema;
00998 }
00999 
01000 void KateSchemaConfigPage::newCurrentPage (QWidget *w)
01001 {
01002   if (w == m_highlightTab)
01003     m_highlightTab->schemaChanged (m_lastSchema);
01004 }
01005 //END KateSchemaConfigPage
01006 
01007 //BEGIN SCHEMA ACTION -- the 'View->Schema' menu action
01008 void KateViewSchemaAction::init()
01009 {
01010   m_view = 0;
01011   last = 0;
01012 
01013   connect(popupMenu(),SIGNAL(aboutToShow()),this,SLOT(slotAboutToShow()));
01014 }
01015 
01016 void KateViewSchemaAction::updateMenu (KateView *view)
01017 {
01018   m_view = view;
01019 }
01020 
01021 void KateViewSchemaAction::slotAboutToShow()
01022 {
01023   KateView *view=m_view;
01024   int count = KateFactory::self()->schemaManager()->list().count();
01025 
01026   for (int z=0; z<count; z++)
01027   {
01028     QString hlName = KateFactory::self()->schemaManager()->list().operator[](z);
01029 
01030     if (names.contains(hlName) < 1)
01031     {
01032       names << hlName;
01033       popupMenu()->insertItem ( hlName, this, SLOT(setSchema(int)), 0,  z+1);
01034     }
01035   }
01036 
01037   if (!view) return;
01038 
01039   popupMenu()->setItemChecked (last, false);
01040   popupMenu()->setItemChecked (view->renderer()->config()->schema()+1, true);
01041 
01042   last = view->renderer()->config()->schema()+1;
01043 }
01044 
01045 void KateViewSchemaAction::setSchema (int mode)
01046 {
01047   KateView *view=m_view;
01048 
01049   if (view)
01050     view->renderer()->config()->setSchema (mode-1);
01051 }
01052 //END SCHEMA ACTION
01053 
01054 //BEGIN KateStyleListView
01055 KateStyleListView::KateStyleListView( QWidget *parent, bool showUseDefaults )
01056     : QListView( parent )
01057 {
01058   setSorting( -1 ); // disable sorting, let the styles appear in their defined order
01059   addColumn( i18n("Context") );
01060   addColumn( SmallIconSet("text_bold"), QString::null );
01061   addColumn( SmallIconSet("text_italic"), QString::null );
01062   addColumn( SmallIconSet("text_under"), QString::null );
01063   addColumn( SmallIconSet("text_strike"), QString::null );
01064   addColumn( i18n("Normal") );
01065   addColumn( i18n("Selected") );
01066   addColumn( i18n("Background") );
01067   addColumn( i18n("Background Selected") );
01068   if ( showUseDefaults )
01069     addColumn( i18n("Use Default Style") );
01070   connect( this, SIGNAL(mouseButtonPressed(int, QListViewItem*, const QPoint&, int)),
01071            this, SLOT(slotMousePressed(int, QListViewItem*, const QPoint&, int)) );
01072   connect( this, SIGNAL(contextMenuRequested(QListViewItem*,const QPoint&, int)),
01073            this, SLOT(showPopupMenu(QListViewItem*, const QPoint&)) );
01074   // grap the bg color, selected color and default font
01075   normalcol = KGlobalSettings::textColor();
01076   bgcol = KateRendererConfig::global()->backgroundColor();
01077   selcol = KateRendererConfig::global()->selectionColor();
01078   docfont = *KateRendererConfig::global()->font();
01079 
01080   viewport()->setPaletteBackgroundColor( bgcol );
01081 }
01082 
01083 void KateStyleListView::showPopupMenu( KateStyleListItem *i, const QPoint &globalPos, bool showtitle )
01084 {
01085   if ( !dynamic_cast<KateStyleListItem*>(i) ) return;
01086 
01087   KPopupMenu m( this );
01088   KateAttribute *is = i->style();
01089   int id;
01090   // the title is used, because the menu obscures the context name when
01091   // displayed on behalf of spacePressed().
01092   QPixmap cl(16,16);
01093   cl.fill( i->style()->textColor() );
01094   QPixmap scl(16,16);
01095   scl.fill( i->style()->selectedTextColor() );
01096   QPixmap bgcl(16,16);
01097   bgcl.fill( i->style()->itemSet(KateAttribute::BGColor) ? i->style()->bgColor() : viewport()->colorGroup().base() );
01098   QPixmap sbgcl(16,16);
01099   sbgcl.fill( i->style()->itemSet(KateAttribute::SelectedBGColor) ? i->style()->selectedBGColor() : viewport()->colorGroup().base() );
01100 
01101   if ( showtitle )
01102     m.insertTitle( i->contextName(), KateStyleListItem::ContextName );
01103   id = m.insertItem( i18n("&Bold"), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::Bold );
01104   m.setItemChecked( id, is->bold() );
01105   id = m.insertItem( i18n("&Italic"), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::Italic );
01106   m.setItemChecked( id, is->italic() );
01107   id = m.insertItem( i18n("&Underline"), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::Underline );
01108   m.setItemChecked( id, is->underline() );
01109   id = m.insertItem( i18n("S&trikeout"), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::Strikeout );
01110   m.setItemChecked( id, is->strikeOut() );
01111 
01112   m.insertSeparator();
01113 
01114   m.insertItem( QIconSet(cl), i18n("Normal &Color..."), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::Color );
01115   m.insertItem( QIconSet(scl), i18n("&Selected Color..."), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::SelColor );
01116   m.insertItem( QIconSet(bgcl), i18n("&Background Color..."), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::BgColor );
01117   m.insertItem( QIconSet(sbgcl), i18n("S&elected Background Color..."), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::SelBgColor );
01118 
01119   // Unset [some] colors. I could show one only if that button was clicked, but that
01120   // would disable setting this with the keyboard (how many aren't doing just
01121   // that every day? ;)
01122   // ANY ideas for doing this in a nicer way will be warmly wellcomed.
01123   KateAttribute *style = i->style();
01124   if ( style->itemSet( KateAttribute::BGColor) || style->itemSet( KateAttribute::SelectedBGColor ) )
01125   {
01126     m.insertSeparator();
01127     if ( style->itemSet( KateAttribute::BGColor) )
01128       m.insertItem( i18n("Unset Background Color"), this, SLOT(unsetColor(int)), 0, 100 );
01129     if ( style->itemSet( KateAttribute::SelectedBGColor ) )
01130       m.insertItem( i18n("Unset Selected Background Color"), this, SLOT(unsetColor(int)), 0, 101 );
01131   }
01132 
01133   if ( ! i->isDefault() && ! i->defStyle() ) {
01134     m.insertSeparator();
01135     id = m.insertItem( i18n("Use &Default Style"), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::UseDefStyle );
01136     m.setItemChecked( id, i->defStyle() );
01137   }
01138   m.exec( globalPos );
01139 }
01140 
01141 void KateStyleListView::showPopupMenu( QListViewItem *i, const QPoint &pos )
01142 {
01143   if ( dynamic_cast<KateStyleListItem*>(i) )
01144     showPopupMenu( (KateStyleListItem*)i, pos, true );
01145 }
01146 
01147 void KateStyleListView::mSlotPopupHandler( int z )
01148 {
01149   ((KateStyleListItem*)currentItem())->changeProperty( (KateStyleListItem::Property)z );
01150 }
01151 
01152 void KateStyleListView::unsetColor( int c )
01153 {
01154   ((KateStyleListItem*)currentItem())->unsetColor( c );
01155   emitChanged();
01156 }
01157 
01158 // Because QListViewItem::activatePos() is going to become deprecated,
01159 // and also because this attempt offers more control, I connect mousePressed to this.
01160 void KateStyleListView::slotMousePressed(int btn, QListViewItem* i, const QPoint& pos, int c)
01161 {
01162   if ( dynamic_cast<KateStyleListItem*>(i) ) {
01163      if ( btn == Qt::LeftButton && c > 0 ) {
01164       // map pos to item/column and call KateStyleListItem::activate(col, pos)
01165       ((KateStyleListItem*)i)->activate( c, viewport()->mapFromGlobal( pos ) - QPoint( 0, itemRect(i).top() ) );
01166     }
01167   }
01168 }
01169 
01170 //END
01171 
01172 //BEGIN KateStyleListItem
01173 static const int BoxSize = 16;
01174 static const int ColorBtnWidth = 32;
01175 
01176 KateStyleListItem::KateStyleListItem( QListViewItem *parent, const QString & stylename,
01177                               KateAttribute *style, KateHlItemData *data )
01178         : QListViewItem( parent, stylename ),
01179           ds( style ),
01180           st( data )
01181 {
01182   initStyle();
01183 }
01184 
01185 KateStyleListItem::KateStyleListItem( QListView *parent, const QString & stylename,
01186                               KateAttribute *style, KateHlItemData *data )
01187         : QListViewItem( parent, stylename ),
01188           ds( style ),
01189           st( data )
01190 {
01191   initStyle();
01192 }
01193 
01194 void KateStyleListItem::initStyle()
01195 {
01196   if (!st)
01197     is = ds;
01198   else
01199   {
01200     is = new KateAttribute (*ds);
01201 
01202     if (st->isSomethingSet())
01203       *is += *st;
01204   }
01205 }
01206 
01207 void KateStyleListItem::updateStyle()
01208 {
01209   // nothing there, not update it, will crash
01210   if (!st)
01211     return;
01212 
01213   if ( is->itemSet(KateAttribute::Weight) )
01214   {
01215     if ( is->weight() != st->weight())
01216       st->setWeight( is->weight() );
01217   }
01218   else st->clearAttribute( KateAttribute::Weight );
01219 
01220   if ( is->itemSet(KateAttribute::Italic) )
01221   {
01222     if ( is->italic() != st->italic())
01223       st->setItalic( is->italic() );
01224   }
01225   else st->clearAttribute( KateAttribute::Italic );
01226 
01227   if ( is->itemSet(KateAttribute::StrikeOut) )
01228   {
01229     if ( is->strikeOut() != st->strikeOut())
01230 
01231       st->setStrikeOut( is->strikeOut() );
01232   }
01233   else st->clearAttribute( KateAttribute::StrikeOut );
01234 
01235   if ( is->itemSet(KateAttribute::Underline) )
01236   {
01237     if ( is->underline() != st->underline())
01238       st->setUnderline( is->underline() );
01239   }
01240   else st->clearAttribute( KateAttribute::Underline );
01241 
01242   if ( is->itemSet(KateAttribute::Outline) )
01243   {
01244     if ( is->outline() != st->outline())
01245       st->setOutline( is->outline() );
01246   }
01247   else st->clearAttribute( KateAttribute::Outline );
01248 
01249   if ( is->itemSet(KateAttribute::TextColor) )
01250   {
01251     if ( is->textColor() != st->textColor())
01252       st->setTextColor( is->textColor() );
01253   }
01254   else st->clearAttribute( KateAttribute::TextColor );
01255 
01256   if ( is->itemSet(KateAttribute::SelectedTextColor) )
01257   {
01258     if ( is->selectedTextColor() != st->selectedTextColor())
01259       st->setSelectedTextColor( is->selectedTextColor() );
01260   }
01261   else st->clearAttribute( KateAttribute::SelectedTextColor);
01262 
01263   if ( is->itemSet(KateAttribute::BGColor) )
01264   {
01265     if ( is->bgColor() != st->bgColor())
01266       st->setBGColor( is->bgColor() );
01267   }
01268   else st->clearAttribute( KateAttribute::BGColor );
01269 
01270   if ( is->itemSet(KateAttribute::SelectedBGColor) )
01271   {
01272     if ( is->selectedBGColor() != st->selectedBGColor())
01273       st->setSelectedBGColor( is->selectedBGColor() );
01274   }
01275   else st->clearAttribute( KateAttribute::SelectedBGColor );
01276 }
01277 
01278 /* only true for a hl mode item using it's default style */
01279 bool KateStyleListItem::defStyle() { return st && st->itemsSet() != ds->itemsSet(); }
01280 
01281 /* true for default styles */
01282 bool KateStyleListItem::isDefault() { return st ? false : true; }
01283 
01284 int KateStyleListItem::width( const QFontMetrics & /*fm*/, const QListView * lv, int col ) const
01285 {
01286   int m = lv->itemMargin() * 2;
01287   switch ( col ) {
01288     case ContextName:
01289       // FIXME: width for name column should reflect bold/italic
01290       // (relevant for non-fixed fonts only - nessecary?)
01291       return QListViewItem::width( QFontMetrics( ((KateStyleListView*)lv)->docfont), lv, col);
01292     case Bold:
01293     case Italic:
01294     case UseDefStyle:
01295       return BoxSize + m;
01296     case Color:
01297     case SelColor:
01298     case BgColor:
01299     case SelBgColor:
01300       return ColorBtnWidth +m;
01301     default:
01302       return 0;
01303   }
01304 }
01305 
01306 void KateStyleListItem::activate( int column, const QPoint &localPos )
01307 {
01308   QListView *lv = listView();
01309   int x = 0;
01310   for( int c = 0; c < column-1; c++ )
01311     x += lv->columnWidth( c );
01312   int w;
01313   switch( column ) {
01314     case Bold:
01315     case Italic:
01316     case Underline:
01317     case Strikeout:
01318     case UseDefStyle:
01319       w = BoxSize;
01320       break;
01321     case Color:
01322     case SelColor:
01323     case BgColor:
01324     case SelBgColor:
01325       w = ColorBtnWidth;
01326       break;
01327     default:
01328       return;
01329   }
01330   if ( !QRect( x, 0, w, BoxSize ).contains( localPos ) )
01331   changeProperty( (Property)column );
01332 }
01333 
01334 void KateStyleListItem::changeProperty( Property p )
01335 {
01336   if ( p == Bold )
01337     is->setBold( ! is->bold() );
01338   else if ( p == Italic )
01339     is->setItalic( ! is->italic() );
01340   else if ( p == Underline )
01341     is->setUnderline( ! is->underline() );
01342   else if ( p == Strikeout )
01343     is->setStrikeOut( ! is->strikeOut() );
01344   else if ( p == UseDefStyle )
01345     toggleDefStyle();
01346   else
01347     setColor( p );
01348 
01349   updateStyle ();
01350 
01351   ((KateStyleListView*)listView())->emitChanged();
01352 }
01353 
01354 void KateStyleListItem::toggleDefStyle()
01355 {
01356   if ( *is == *ds ) {
01357     KMessageBox::information( listView(),
01358          i18n("\"Use Default Style\" will be automatically unset when you change any style properties."),
01359          i18n("Kate Styles"),
01360          "Kate hl config use defaults" );
01361   }
01362   else {
01363     delete is;
01364     is = new KateAttribute( *ds );
01365     updateStyle();
01366     repaint();
01367   }
01368 }
01369 
01370 void KateStyleListItem::setColor( int column )
01371 {
01372   QColor c; // use this
01373   QColor d; // default color
01374   if ( column == Color)
01375   {
01376     c = is->textColor();
01377     d = ds->textColor();
01378   }
01379   else if ( column == SelColor )
01380   {
01381     c = is->selectedTextColor();
01382     d = is->selectedTextColor();
01383   }
01384   else if ( column == BgColor )
01385   {
01386     c = is->bgColor();
01387     d = ds->bgColor();
01388   }
01389   else if ( column == SelBgColor )
01390   {
01391     c = is->selectedBGColor();
01392     d = ds->selectedBGColor();
01393   }
01394 
01395   if ( KColorDialog::getColor( c, d, listView() ) != QDialog::Accepted) return;
01396 
01397   bool def = ! c.isValid();
01398 
01399   // if set default, and the attrib is set in the default style use it
01400   // else if set default, unset it
01401   // else set the selected color
01402   switch (column)
01403   {
01404     case Color:
01405       if ( def )
01406       {
01407         if ( ds->itemSet(KateAttribute::TextColor) )
01408           is->setTextColor( ds->textColor());
01409         else
01410           is->clearAttribute(KateAttribute::TextColor);
01411       }
01412       else
01413         is->setTextColor( c );
01414     break;
01415     case SelColor:
01416       if ( def )
01417       {
01418         if ( ds->itemSet(KateAttribute::SelectedTextColor) )
01419           is->setSelectedTextColor( ds->selectedTextColor());
01420         else
01421           is->clearAttribute(KateAttribute::SelectedTextColor);
01422       }
01423       else
01424         is->setSelectedTextColor( c );
01425     break;
01426     case BgColor:
01427       if ( def )
01428       {
01429         if ( ds->itemSet(KateAttribute::BGColor) )
01430           is->setBGColor( ds->bgColor());
01431         else
01432           is->clearAttribute(KateAttribute::BGColor);
01433       }
01434       else
01435         is->setBGColor( c );
01436     break;
01437     case SelBgColor:
01438       if ( def )
01439       {
01440         if ( ds->itemSet(KateAttribute::SelectedBGColor) )
01441           is->setSelectedBGColor( ds->selectedBGColor());
01442         else
01443           is->clearAttribute(KateAttribute::SelectedBGColor);
01444       }
01445       else
01446         is->setSelectedBGColor( c );
01447     break;
01448   }
01449 
01450   repaint();
01451 }
01452 
01453 void KateStyleListItem::unsetColor( int c )
01454 {
01455   if ( c == 100 && is->itemSet(KateAttribute::BGColor) )
01456     is->clearAttribute(KateAttribute::BGColor);
01457   else if ( c == 101 && is->itemSet(KateAttribute::SelectedBGColor) )
01458     is->clearAttribute(KateAttribute::SelectedBGColor);
01459   updateStyle();
01460 }
01461 
01462 void KateStyleListItem::paintCell( QPainter *p, const QColorGroup& /*cg*/, int col, int width, int align )
01463 {
01464 
01465   if ( !p )
01466     return;
01467 
01468   QListView *lv = listView();
01469   if ( !lv )
01470     return;
01471   Q_ASSERT( lv ); //###
01472 
01473   // use a private color group and set the text/highlighted text colors
01474   QColorGroup mcg = lv->viewport()->colorGroup();
01475 
01476   if ( col ) // col 0 is drawn by the superclass method
01477     p->fillRect( 0, 0, width, height(), QBrush( mcg.base() ) );
01478 
01479   int marg = lv->itemMargin();
01480 
01481   QColor c;
01482 
01483   switch ( col )
01484   {
01485     case ContextName:
01486     {
01487       mcg.setColor(QColorGroup::Text, is->textColor());
01488       mcg.setColor(QColorGroup::HighlightedText, is->selectedTextColor());
01489       // text background color
01490       c = is->bgColor();
01491       if ( c.isValid() && is->itemSet(KateAttribute::BGColor) )
01492         mcg.setColor( QColorGroup::Base, c );
01493       if ( isSelected() && is->itemSet(KateAttribute::SelectedBGColor) )
01494       {
01495         c = is->selectedBGColor();
01496         if ( c.isValid() )
01497           mcg.setColor( QColorGroup::Highlight, c );
01498       }
01499       QFont f ( ((KateStyleListView*)lv)->docfont );
01500       p->setFont( is->font(f) );
01501       // FIXME - repainting when text is cropped, and the column is enlarged is buggy.
01502       // Maybe I need painting the string myself :(
01503       // (wilbert) it depends on the font used
01504       QListViewItem::paintCell( p, mcg, col, width, align );
01505     }
01506     break;
01507     case Bold:
01508     case Italic:
01509     case Underline:
01510     case Strikeout:
01511     case UseDefStyle:
01512     {
01513       // Bold/Italic/use default checkboxes
01514       // code allmost identical to QCheckListItem
01515       int x = 0;
01516       int y = (height() - BoxSize) / 2;
01517 
01518       if ( isEnabled() )
01519         p->setPen( QPen( mcg.text(), 2 ) );
01520       else
01521         p->setPen( QPen( lv->palette().color( QPalette::Disabled, QColorGroup::Text ), 2 ) );
01522 
01523       p->drawRect( x+marg, y+2, BoxSize-4, BoxSize-4 );
01524       x++;
01525       y++;
01526       if ( (col == Bold && is->bold()) ||
01527           (col == Italic && is->italic()) ||
01528           (col == Underline && is->underline()) ||
01529           (col == Strikeout && is->strikeOut()) ||
01530           (col == UseDefStyle && *is == *ds ) )
01531       {
01532         QPointArray a( 7*2 );
01533         int i, xx, yy;
01534         xx = x+1+marg;
01535         yy = y+5;
01536         for ( i=0; i<3; i++ ) {
01537           a.setPoint( 2*i,   xx, yy );
01538           a.setPoint( 2*i+1, xx, yy+2 );
01539           xx++; yy++;
01540         }
01541         yy -= 2;
01542         for ( i=3; i<7; i++ ) {
01543           a.setPoint( 2*i,   xx, yy );
01544           a.setPoint( 2*i+1, xx, yy+2 );
01545           xx++; yy--;
01546         }
01547         p->drawLineSegments( a );
01548       }
01549     }
01550     break;
01551     case Color:
01552     case SelColor:
01553     case BgColor:
01554     case SelBgColor:
01555     {
01556       bool set( false );
01557       if ( col == Color)
01558       {
01559         c = is->textColor();
01560         set = is->itemSet(KateAttribute::TextColor);
01561       }
01562       else if ( col == SelColor )
01563       {
01564         c = is->selectedTextColor();
01565         set = is->itemSet( KateAttribute::SelectedTextColor);
01566       }
01567       else if ( col == BgColor )
01568       {
01569         set = is->itemSet(KateAttribute::BGColor);
01570         c = set ? is->bgColor() : mcg.base();
01571       }
01572       else if ( col == SelBgColor )
01573       {
01574         set = is->itemSet(KateAttribute::SelectedBGColor);
01575         c = set ? is->selectedBGColor(): mcg.base();
01576       }
01577 
01578       // color "buttons"
01579       int x = 0;
01580       int y = (height() - BoxSize) / 2;
01581       if ( isEnabled() )
01582         p->setPen( QPen( mcg.text(), 2 ) );
01583       else
01584         p->setPen( QPen( lv->palette().color( QPalette::Disabled, QColorGroup::Text ), 2 ) );
01585 
01586       p->drawRect( x+marg, y+2, ColorBtnWidth-4, BoxSize-4 );
01587       p->fillRect( x+marg+1,y+3,ColorBtnWidth-7,BoxSize-7,QBrush( c ) );
01588       // if this item is unset, draw a diagonal line over the button
01589       if ( ! set )
01590         p->drawLine( x+marg-1, BoxSize-3, ColorBtnWidth-4, y+1 );
01591     }
01592     //case default: // no warning...
01593   }
01594 }
01595 //END
01596 
01597 //BEGIN KateStyleListCaption
01598 KateStyleListCaption::KateStyleListCaption( QListView *parent, const QString & name )
01599       :  QListViewItem( parent, name )
01600 {
01601 }
01602 
01603 void KateStyleListCaption::paintCell( QPainter *p, const QColorGroup& /*cg*/, int col, int width, int align )
01604 {
01605   QListView *lv = listView();
01606   if ( !lv )
01607     return;
01608   Q_ASSERT( lv ); //###
01609 
01610   // use the same colorgroup as the other items in the viewport
01611   QColorGroup mcg = lv->viewport()->colorGroup();
01612 
01613   QListViewItem::paintCell( p, mcg, col, width, align );
01614 }
01615 //END
01616 
01617 // kate: space-indent on; indent-width 2; replace-tabs on;
KDE Home | KDE Accessibility Home | Description of Access Keys