kate Library API Documentation

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