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;
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 
00897   // clear all attributes
00898   for (int i = 0; i < KateHlManager::self()->highlights(); ++i)
00899     KateHlManager::self()->getHl (i)->clearAttributeArrays ();
00900 
00901   // than reload the whole stuff
00902   KateRendererConfig::global()->setSchema (defaultSchemaCombo->currentItem());
00903   KateRendererConfig::global()->reloadSchema();
00904 
00905   // sync the hl config for real
00906   KateHlManager::self()->getKConfig()->sync ();
00907 }
00908 
00909 void KateSchemaConfigPage::reload()
00910 {
00911   // just reload the config from disc
00912   KateFactory::self()->schemaManager()->update ();
00913 
00914   // special for the highlighting stuff
00915   m_fontColorTab->reload ();
00916 
00917   update ();
00918 
00919   defaultSchemaCombo->setCurrentItem (KateRendererConfig::global()->schema());
00920 
00921   // initialize to the schema in the current document, or default schema
00922   schemaCombo->setCurrentItem( m_defaultSchema );
00923   schemaChanged( m_defaultSchema );
00924 }
00925 
00926 void KateSchemaConfigPage::reset()
00927 {
00928   reload ();
00929 }
00930 
00931 void KateSchemaConfigPage::defaults()
00932 {
00933   reload ();
00934 }
00935 
00936 void KateSchemaConfigPage::update ()
00937 {
00938   // soft update, no load from disk
00939   KateFactory::self()->schemaManager()->update (false);
00940 
00941   schemaCombo->clear ();
00942   schemaCombo->insertStringList (KateFactory::self()->schemaManager()->list ());
00943 
00944   defaultSchemaCombo->clear ();
00945   defaultSchemaCombo->insertStringList (KateFactory::self()->schemaManager()->list ());
00946 
00947   schemaCombo->setCurrentItem (0);
00948   schemaChanged (0);
00949 
00950   schemaCombo->setEnabled (schemaCombo->count() > 0);
00951 }
00952 
00953 void KateSchemaConfigPage::deleteSchema ()
00954 {
00955   int t = schemaCombo->currentItem ();
00956 
00957   KateFactory::self()->schemaManager()->removeSchema (t);
00958 
00959   update ();
00960 }
00961 
00962 void KateSchemaConfigPage::newSchema ()
00963 {
00964   QString t = KInputDialog::getText (i18n("Name for New Schema"), i18n ("Name:"), i18n("New Schema"), 0, this);
00965 
00966   KateFactory::self()->schemaManager()->addSchema (t);
00967 
00968   // soft update, no load from disk
00969   KateFactory::self()->schemaManager()->update (false);
00970   int i = KateFactory::self()->schemaManager()->list ().findIndex (t);
00971 
00972   update ();
00973   if (i > -1)
00974   {
00975     schemaCombo->setCurrentItem (i);
00976     schemaChanged (i);
00977   }
00978 }
00979 
00980 void KateSchemaConfigPage::schemaChanged (int schema)
00981 {
00982   btndel->setEnabled( schema > 1 );
00983 
00984   m_colorTab->schemaChanged( schema );
00985   m_fontTab->schemaChanged( schema );
00986   m_fontColorTab->schemaChanged (schema);
00987   m_highlightTab->schemaChanged (schema);
00988 
00989   m_lastSchema = schema;
00990 }
00991 
00992 void KateSchemaConfigPage::newCurrentPage (QWidget *w)
00993 {
00994   if (w == m_highlightTab)
00995     m_highlightTab->schemaChanged (m_lastSchema);
00996 }
00997 //END KateSchemaConfigPage
00998 
00999 //BEGIN SCHEMA ACTION -- the 'View->Schema' menu action
01000 void KateViewSchemaAction::init()
01001 {
01002   m_view = 0;
01003   last = 0;
01004 
01005   connect(popupMenu(),SIGNAL(aboutToShow()),this,SLOT(slotAboutToShow()));
01006 }
01007 
01008 void KateViewSchemaAction::updateMenu (KateView *view)
01009 {
01010   m_view = view;
01011 }
01012 
01013 void KateViewSchemaAction::slotAboutToShow()
01014 {
01015   KateView *view=m_view;
01016   int count = KateFactory::self()->schemaManager()->list().count();
01017 
01018   for (int z=0; z<count; z++)
01019   {
01020     QString hlName = KateFactory::self()->schemaManager()->list().operator[](z);
01021 
01022     if (names.contains(hlName) < 1)
01023     {
01024       names << hlName;
01025       popupMenu()->insertItem ( hlName, this, SLOT(setSchema(int)), 0,  z+1);
01026     }
01027   }
01028 
01029   if (!view) return;
01030 
01031   popupMenu()->setItemChecked (last, false);
01032   popupMenu()->setItemChecked (view->renderer()->config()->schema()+1, true);
01033 
01034   last = view->renderer()->config()->schema()+1;
01035 }
01036 
01037 void KateViewSchemaAction::setSchema (int mode)
01038 {
01039   KateView *view=m_view;
01040 
01041   if (view)
01042     view->renderer()->config()->setSchema (mode-1);
01043 }
01044 //END SCHEMA ACTION
01045 
01046 //BEGIN KateStyleListView
01047 KateStyleListView::KateStyleListView( QWidget *parent, bool showUseDefaults )
01048     : QListView( parent )
01049 {
01050   setSorting( -1 ); // disable sorting, let the styles appear in their defined order
01051   addColumn( i18n("Context") );
01052   addColumn( SmallIconSet("text_bold"), QString::null );
01053   addColumn( SmallIconSet("text_italic"), QString::null );
01054   addColumn( SmallIconSet("text_under"), QString::null );
01055   addColumn( SmallIconSet("text_strike"), QString::null );
01056   addColumn( i18n("Normal") );
01057   addColumn( i18n("Selected") );
01058   addColumn( i18n("Background") );
01059   addColumn( i18n("Background Selected") );
01060   if ( showUseDefaults )
01061     addColumn( i18n("Use Default Style") );
01062   connect( this, SIGNAL(mouseButtonPressed(int, QListViewItem*, const QPoint&, int)),
01063            this, SLOT(slotMousePressed(int, QListViewItem*, const QPoint&, int)) );
01064   connect( this, SIGNAL(contextMenuRequested(QListViewItem*,const QPoint&, int)),
01065            this, SLOT(showPopupMenu(QListViewItem*, const QPoint&)) );
01066   // grap the bg color, selected color and default font
01067   normalcol = KGlobalSettings::textColor();
01068   bgcol = KateRendererConfig::global()->backgroundColor();
01069   selcol = KateRendererConfig::global()->selectionColor();
01070   docfont = *KateRendererConfig::global()->font();
01071 
01072   viewport()->setPaletteBackgroundColor( bgcol );
01073 }
01074 
01075 void KateStyleListView::showPopupMenu( KateStyleListItem *i, const QPoint &globalPos, bool showtitle )
01076 {
01077   if ( !dynamic_cast<KateStyleListItem*>(i) ) return;
01078 
01079   KPopupMenu m( this );
01080   KateAttribute *is = i->style();
01081   int id;
01082   // the title is used, because the menu obscures the context name when
01083   // displayed on behalf of spacePressed().
01084   QPixmap cl(16,16);
01085   cl.fill( i->style()->textColor() );
01086   QPixmap scl(16,16);
01087   scl.fill( i->style()->selectedTextColor() );
01088   QPixmap bgcl(16,16);
01089   bgcl.fill( i->style()->itemSet(KateAttribute::BGColor) ? i->style()->bgColor() : viewport()->colorGroup().base() );
01090   QPixmap sbgcl(16,16);
01091   sbgcl.fill( i->style()->itemSet(KateAttribute::SelectedBGColor) ? i->style()->selectedBGColor() : viewport()->colorGroup().base() );
01092 
01093   if ( showtitle )
01094     m.insertTitle( i->contextName(), KateStyleListItem::ContextName );
01095   id = m.insertItem( i18n("&Bold"), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::Bold );
01096   m.setItemChecked( id, is->bold() );
01097   id = m.insertItem( i18n("&Italic"), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::Italic );
01098   m.setItemChecked( id, is->italic() );
01099   id = m.insertItem( i18n("&Underline"), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::Underline );
01100   m.setItemChecked( id, is->underline() );
01101   id = m.insertItem( i18n("S&trikeout"), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::Strikeout );
01102   m.setItemChecked( id, is->strikeOut() );
01103 
01104   m.insertSeparator();
01105 
01106   m.insertItem( QIconSet(cl), i18n("Normal &Color..."), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::Color );
01107   m.insertItem( QIconSet(scl), i18n("&Selected Color..."), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::SelColor );
01108   m.insertItem( QIconSet(bgcl), i18n("&Background Color..."), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::BgColor );
01109   m.insertItem( QIconSet(sbgcl), i18n("S&elected Background Color..."), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::SelBgColor );
01110 
01111   // Unset [some] colors. I could show one only if that button was clicked, but that
01112   // would disable setting this with the keyboard (how many aren't doing just
01113   // that every day? ;)
01114   // ANY ideas for doing this in a nicer way will be warmly wellcomed.
01115   KateAttribute *style = i->style();
01116   if ( style->itemSet( KateAttribute::BGColor) || style->itemSet( KateAttribute::SelectedBGColor ) )
01117   {
01118     m.insertSeparator();
01119     if ( style->itemSet( KateAttribute::BGColor) )
01120       m.insertItem( i18n("Unset Background Color"), this, SLOT(unsetColor(int)), 0, 100 );
01121     if ( style->itemSet( KateAttribute::SelectedBGColor ) )
01122       m.insertItem( i18n("Unset Selected Background Color"), this, SLOT(unsetColor(int)), 0, 101 );
01123   }
01124 
01125   if ( ! i->isDefault() && ! i->defStyle() ) {
01126     m.insertSeparator();
01127     id = m.insertItem( i18n("Use &Default Style"), this, SLOT(mSlotPopupHandler(int)), 0, KateStyleListItem::UseDefStyle );
01128     m.setItemChecked( id, i->defStyle() );
01129   }
01130   m.exec( globalPos );
01131 }
01132 
01133 void KateStyleListView::showPopupMenu( QListViewItem *i, const QPoint &pos )
01134 {
01135   if ( dynamic_cast<KateStyleListItem*>(i) )
01136     showPopupMenu( (KateStyleListItem*)i, pos, true );
01137 }
01138 
01139 void KateStyleListView::mSlotPopupHandler( int z )
01140 {
01141   ((KateStyleListItem*)currentItem())->changeProperty( (KateStyleListItem::Property)z );
01142 }
01143 
01144 void KateStyleListView::unsetColor( int c )
01145 {
01146   ((KateStyleListItem*)currentItem())->unsetColor( c );
01147   emitChanged();
01148 }
01149 
01150 // Because QListViewItem::activatePos() is going to become deprecated,
01151 // and also because this attempt offers more control, I connect mousePressed to this.
01152 void KateStyleListView::slotMousePressed(int btn, QListViewItem* i, const QPoint& pos, int c)
01153 {
01154   if ( dynamic_cast<KateStyleListItem*>(i) ) {
01155      if ( btn == Qt::LeftButton && c > 0 ) {
01156       // map pos to item/column and call KateStyleListItem::activate(col, pos)
01157       ((KateStyleListItem*)i)->activate( c, viewport()->mapFromGlobal( pos ) - QPoint( 0, itemRect(i).top() ) );
01158     }
01159   }
01160 }
01161 
01162 //END
01163 
01164 //BEGIN KateStyleListItem
01165 static const int BoxSize = 16;
01166 static const int ColorBtnWidth = 32;
01167 
01168 KateStyleListItem::KateStyleListItem( QListViewItem *parent, const QString & stylename,
01169                               KateAttribute *style, KateHlItemData *data )
01170         : QListViewItem( parent, stylename ),
01171           ds( style ),
01172           st( data )
01173 {
01174   initStyle();
01175 }
01176 
01177 KateStyleListItem::KateStyleListItem( QListView *parent, const QString & stylename,
01178                               KateAttribute *style, KateHlItemData *data )
01179         : QListViewItem( parent, stylename ),
01180           ds( style ),
01181           st( data )
01182 {
01183   initStyle();
01184 }
01185 
01186 void KateStyleListItem::initStyle()
01187 {
01188   if (!st)
01189     is = ds;
01190   else
01191   {
01192     is = new KateAttribute (*ds);
01193 
01194     if (st->isSomethingSet())
01195       *is += *st;
01196   }
01197 }
01198 
01199 void KateStyleListItem::updateStyle()
01200 {
01201   // nothing there, not update it, will crash
01202   if (!st)
01203     return;
01204 
01205   if ( is->itemSet(KateAttribute::Weight) )
01206   {
01207     if ( is->weight() != st->weight())
01208       st->setWeight( is->weight() );
01209   }
01210 
01211   if ( is->itemSet(KateAttribute::Italic) )
01212   {
01213     if ( is->italic() != st->italic())
01214       st->setItalic( is->italic() );
01215   }
01216 
01217   if ( is->itemSet(KateAttribute::StrikeOut) )
01218   {
01219     if ( is->strikeOut() != st->strikeOut())
01220 
01221       st->setStrikeOut( is->strikeOut() );
01222   }
01223 
01224   if ( is->itemSet(KateAttribute::Underline) )
01225   {
01226     if ( is->underline() != st->underline())
01227       st->setUnderline( is->underline() );
01228   }
01229 
01230   if ( is->itemSet(KateAttribute::Outline) )
01231   {
01232     if ( is->outline() != st->outline())
01233       st->setOutline( is->outline() );
01234   }
01235 
01236   if ( is->itemSet(KateAttribute::TextColor) )
01237   {
01238     if ( is->textColor() != st->textColor())
01239       st->setTextColor( is->textColor() );
01240   }
01241 
01242   if ( is->itemSet(KateAttribute::SelectedTextColor) )
01243   {
01244     if ( is->selectedTextColor() != st->selectedTextColor())
01245       st->setSelectedTextColor( is->selectedTextColor() );
01246   }
01247 
01248   if ( is->itemSet(KateAttribute::BGColor) )
01249   {
01250     if ( is->bgColor() != st->bgColor())
01251       st->setBGColor( is->bgColor() );
01252   }
01253 
01254   if ( is->itemSet(KateAttribute::SelectedBGColor) )
01255   {
01256     if ( is->selectedBGColor() != st->selectedBGColor())
01257       st->setSelectedBGColor( is->selectedBGColor() );
01258   }
01259 }
01260 
01261 /* only true for a hl mode item using it's default style */
01262 bool KateStyleListItem::defStyle() { return st && st->itemsSet() != ds->itemsSet(); }
01263 
01264 /* true for default styles */
01265 bool KateStyleListItem::isDefault() { return st ? false : true; }
01266 
01267 int KateStyleListItem::width( const QFontMetrics & /*fm*/, const QListView * lv, int col ) const
01268 {
01269   int m = lv->itemMargin() * 2;
01270   switch ( col ) {
01271     case ContextName:
01272       // FIXME: width for name column should reflect bold/italic
01273       // (relevant for non-fixed fonts only - nessecary?)
01274       return QListViewItem::width( QFontMetrics( ((KateStyleListView*)lv)->docfont), lv, col);
01275     case Bold:
01276     case Italic:
01277     case UseDefStyle:
01278       return BoxSize + m;
01279     case Color:
01280     case SelColor:
01281     case BgColor:
01282     case SelBgColor:
01283       return ColorBtnWidth +m;
01284     default:
01285       return 0;
01286   }
01287 }
01288 
01289 void KateStyleListItem::activate( int column, const QPoint &localPos )
01290 {
01291   QListView *lv = listView();
01292   int x = 0;
01293   for( int c = 0; c < column-1; c++ )
01294     x += lv->columnWidth( c );
01295   int w;
01296   switch( column ) {
01297     case Bold:
01298     case Italic:
01299     case Underline:
01300     case Strikeout:
01301     case UseDefStyle:
01302       w = BoxSize;
01303       break;
01304     case Color:
01305     case SelColor:
01306     case BgColor:
01307     case SelBgColor:
01308       w = ColorBtnWidth;
01309       break;
01310     default:
01311       return;
01312   }
01313   if ( !QRect( x, 0, w, BoxSize ).contains( localPos ) )
01314   changeProperty( (Property)column );
01315 }
01316 
01317 void KateStyleListItem::changeProperty( Property p )
01318 {
01319   if ( p == Bold )
01320     is->setBold( ! is->bold() );
01321   else if ( p == Italic )
01322     is->setItalic( ! is->italic() );
01323   else if ( p == Underline )
01324     is->setUnderline( ! is->underline() );
01325   else if ( p == Strikeout )
01326     is->setStrikeOut( ! is->strikeOut() );
01327   else if ( p == UseDefStyle )
01328     toggleDefStyle();
01329   else
01330     setColor( p );
01331 
01332   updateStyle ();
01333 
01334   ((KateStyleListView*)listView())->emitChanged();
01335 }
01336 
01337 void KateStyleListItem::toggleDefStyle()
01338 {
01339   if ( *is == *ds ) {
01340     KMessageBox::information( listView(),
01341          i18n("\"Use Default Style\" will be automatically unset when you change any style properties."),
01342          i18n("Kate Styles"),
01343          "Kate hl config use defaults" );
01344   }
01345   else {
01346     delete is;
01347     is = new KateAttribute( *ds );
01348     repaint();
01349   }
01350 }
01351 
01352 void KateStyleListItem::setColor( int column )
01353 {
01354   QColor c; // use this
01355   QColor d; // default color
01356   if ( column == Color)
01357   {
01358     c = is->textColor();
01359     d = ds->textColor();
01360   }
01361   else if ( column == SelColor )
01362   {
01363     c = is->selectedTextColor();
01364     d = is->selectedTextColor();
01365   }
01366   else if ( column == BgColor )
01367   {
01368     c = is->bgColor();
01369     d = ds->bgColor();
01370   }
01371   else if ( column == SelBgColor )
01372   {
01373     c = is->selectedBGColor();
01374     d = ds->selectedBGColor();
01375   }
01376 
01377   if ( KColorDialog::getColor( c, d, listView() ) != QDialog::Accepted) return;
01378 
01379   bool def = ! c.isValid();
01380 
01381   // if set default, and the attrib is set in the default style use it
01382   // else if set default, unset it
01383   // else set the selected color
01384   switch (column)
01385   {
01386     case Color:
01387       if ( def )
01388       {
01389         if ( ds->itemSet(KateAttribute::TextColor) )
01390           is->setTextColor( ds->textColor());
01391         else
01392           is->clearAttribute(KateAttribute::TextColor);
01393       }
01394       else
01395         is->setTextColor( c );
01396     break;
01397     case SelColor:
01398       if ( def )
01399       {
01400         if ( ds->itemSet(KateAttribute::SelectedTextColor) )
01401           is->setSelectedTextColor( ds->selectedTextColor());
01402         else
01403           is->clearAttribute(KateAttribute::SelectedTextColor);
01404       }
01405       else
01406         is->setSelectedTextColor( c );
01407     break;
01408     case BgColor:
01409       if ( def )
01410       {
01411         if ( ds->itemSet(KateAttribute::BGColor) )
01412           is->setBGColor( ds->bgColor());
01413         else
01414           is->clearAttribute(KateAttribute::BGColor);
01415       }
01416       else
01417         is->setBGColor( c );
01418     break;
01419     case SelBgColor:
01420       if ( def )
01421       {
01422         if ( ds->itemSet(KateAttribute::SelectedBGColor) )
01423           is->setSelectedBGColor( ds->selectedBGColor());
01424         else
01425           is->clearAttribute(KateAttribute::SelectedBGColor);
01426       }
01427       else
01428         is->setSelectedBGColor( c );
01429     break;
01430   }
01431 
01432   repaint();
01433 }
01434 
01435 void KateStyleListItem::unsetColor( int c )
01436 {
01437   if ( c == 100 && is->itemSet(KateAttribute::BGColor) )
01438     is->clearAttribute(KateAttribute::BGColor);
01439   else if ( c == 101 && is->itemSet(KateAttribute::SelectedBGColor) )
01440     is->clearAttribute(KateAttribute::SelectedBGColor);
01441 }
01442 
01443 void KateStyleListItem::paintCell( QPainter *p, const QColorGroup& /*cg*/, int col, int width, int align )
01444 {
01445 
01446   if ( !p )
01447     return;
01448 
01449   QListView *lv = listView();
01450   if ( !lv )
01451     return;
01452   Q_ASSERT( lv ); //###
01453 
01454   // use a private color group and set the text/highlighted text colors
01455   QColorGroup mcg = lv->viewport()->colorGroup();
01456 
01457   if ( col ) // col 0 is drawn by the superclass method
01458     p->fillRect( 0, 0, width, height(), QBrush( mcg.base() ) );
01459 
01460   int marg = lv->itemMargin();
01461 
01462   QColor c;
01463 
01464   switch ( col )
01465   {
01466     case ContextName:
01467     {
01468       mcg.setColor(QColorGroup::Text, is->textColor());
01469       mcg.setColor(QColorGroup::HighlightedText, is->selectedTextColor());
01470       // text background color
01471       c = is->bgColor();
01472       if ( c.isValid() && is->itemSet(KateAttribute::BGColor) )
01473         mcg.setColor( QColorGroup::Base, c );
01474       if ( isSelected() && is->itemSet(KateAttribute::SelectedBGColor) )
01475       {
01476         c = is->selectedBGColor();
01477         if ( c.isValid() )
01478           mcg.setColor( QColorGroup::Highlight, c );
01479       }
01480       QFont f ( ((KateStyleListView*)lv)->docfont );
01481       p->setFont( is->font(f) );
01482       // FIXME - repainting when text is cropped, and the column is enlarged is buggy.
01483       // Maybe I need painting the string myself :(
01484       // (wilbert) it depends on the font used
01485       QListViewItem::paintCell( p, mcg, col, width, align );
01486     }
01487     break;
01488     case Bold:
01489     case Italic:
01490     case Underline:
01491     case Strikeout:
01492     case UseDefStyle:
01493     {
01494       // Bold/Italic/use default checkboxes
01495       // code allmost identical to QCheckListItem
01496       int x = 0;
01497       int y = (height() - BoxSize) / 2;
01498 
01499       if ( isEnabled() )
01500         p->setPen( QPen( mcg.text(), 2 ) );
01501       else
01502         p->setPen( QPen( lv->palette().color( QPalette::Disabled, QColorGroup::Text ), 2 ) );
01503 
01504       p->drawRect( x+marg, y+2, BoxSize-4, BoxSize-4 );
01505       x++;
01506       y++;
01507       if ( (col == Bold && is->bold()) ||
01508           (col == Italic && is->italic()) ||
01509           (col == Underline && is->underline()) ||
01510           (col == Strikeout && is->strikeOut()) ||
01511           (col == UseDefStyle && *is == *ds ) )
01512       {
01513         QPointArray a( 7*2 );
01514         int i, xx, yy;
01515         xx = x+1+marg;
01516         yy = y+5;
01517         for ( i=0; i<3; i++ ) {
01518           a.setPoint( 2*i,   xx, yy );
01519           a.setPoint( 2*i+1, xx, yy+2 );
01520           xx++; yy++;
01521         }
01522         yy -= 2;
01523         for ( i=3; i<7; i++ ) {
01524           a.setPoint( 2*i,   xx, yy );
01525           a.setPoint( 2*i+1, xx, yy+2 );
01526           xx++; yy--;
01527         }
01528         p->drawLineSegments( a );
01529       }
01530     }
01531     break;
01532     case Color:
01533     case SelColor:
01534     case BgColor:
01535     case SelBgColor:
01536     {
01537       bool set( false );
01538       if ( col == Color)
01539       {
01540         c = is->textColor();
01541         set = is->itemSet(KateAttribute::TextColor);
01542       }
01543       else if ( col == SelColor )
01544       {
01545         c = is->selectedTextColor();
01546         set = is->itemSet( KateAttribute::SelectedTextColor);
01547       }
01548       else if ( col == BgColor )
01549       {
01550         set = is->itemSet(KateAttribute::BGColor);
01551         c = set ? is->bgColor() : mcg.base();
01552       }
01553       else if ( col == SelBgColor )
01554       {
01555         set = is->itemSet(KateAttribute::SelectedBGColor);
01556         c = set ? is->selectedBGColor(): mcg.base();
01557       }
01558 
01559       // color "buttons"
01560       int x = 0;
01561       int y = (height() - BoxSize) / 2;
01562       if ( isEnabled() )
01563         p->setPen( QPen( mcg.text(), 2 ) );
01564       else
01565         p->setPen( QPen( lv->palette().color( QPalette::Disabled, QColorGroup::Text ), 2 ) );
01566 
01567       p->drawRect( x+marg, y+2, ColorBtnWidth-4, BoxSize-4 );
01568       p->fillRect( x+marg+1,y+3,ColorBtnWidth-7,BoxSize-7,QBrush( c ) );
01569       // if this item is unset, draw a diagonal line over the button
01570       if ( ! set )
01571         p->drawLine( x+marg-1, BoxSize-3, ColorBtnWidth-4, y+1 );
01572     }
01573     //case default: // no warning...
01574   }
01575 }
01576 //END
01577 
01578 //BEGIN KateStyleListCaption
01579 KateStyleListCaption::KateStyleListCaption( QListView *parent, const QString & name )
01580       :  QListViewItem( parent, name )
01581 {
01582 }
01583 
01584 void KateStyleListCaption::paintCell( QPainter *p, const QColorGroup& /*cg*/, int col, int width, int align )
01585 {
01586   QListView *lv = listView();
01587   if ( !lv )
01588     return;
01589   Q_ASSERT( lv ); //###
01590 
01591   // use the same colorgroup as the other items in the viewport
01592   QColorGroup mcg = lv->viewport()->colorGroup();
01593 
01594   QListViewItem::paintCell( p, mcg, col, width, align );
01595 }
01596 //END
01597 
01598 // kate: space-indent on; indent-width 2; replace-tabs on;
KDE Home | KDE Accessibility Home | Description of Access Keys