kateviewspace.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
00003    Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
00004    Copyright (C) 2001, 2005 Anders Lund <anders.lund@lund.tdcadsl.dk>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License version 2 as published by the Free Software Foundation.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018    Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "kateviewspace.h"
00022 #include "kateviewspace.moc"
00023 
00024 #include "katemainwindow.h"
00025 #include "kateviewspacecontainer.h"
00026 #include "katedocmanager.h"
00027 #include "kateapp.h"
00028 #include "katesession.h"
00029 
00030 #include <kiconloader.h>
00031 #include <klocale.h>
00032 #include <ksqueezedtextlabel.h>
00033 #include <kconfig.h>
00034 #include <kdebug.h>
00035 
00036 #include <qwidgetstack.h>
00037 #include <qpainter.h>
00038 #include <qlabel.h>
00039 #include <qcursor.h>
00040 #include <qpopupmenu.h>
00041 #include <qpixmap.h>
00042 
00043 //BEGIN KVSSBSep
00044 /*
00045    "KateViewSpaceStatusBarSeparator"
00046    A 2 px line to separate the statusbar from the view.
00047    It is here to compensate for the lack of a frame in the view,
00048    I think Kate looks very nice this way, as QScrollView with frame
00049    looks slightly clumsy...
00050    Slight 3D effect. I looked for suitable QStyle props or methods,
00051    but found none, though maybe it should use QStyle::PM_DefaultFrameWidth
00052    for height (TRY!).
00053    It does look a bit funny with flat styles (Light, .Net) as is,
00054    but there are on methods to paint panel lines separately. And,
00055    those styles tends to look funny on their own, as a light line
00056    in a 3D frame next to a light contents widget is not functional.
00057    Also, QStatusBar is up to now completely ignorant to style.
00058    -anders
00059 */
00060 class KVSSBSep : public QWidget {
00061 public:
00062   KVSSBSep( KateViewSpace *parent=0) : QWidget(parent)
00063   {
00064     setFixedHeight( 2 );
00065   }
00066 protected:
00067   void paintEvent( QPaintEvent *e )
00068   {
00069     QPainter p( this );
00070     p.setPen( colorGroup().shadow() );
00071     p.drawLine( e->rect().left(), 0, e->rect().right(), 0 );
00072     p.setPen( ((KateViewSpace*)parentWidget())->isActiveSpace() ? colorGroup().light() : colorGroup().midlight() );
00073     p.drawLine( e->rect().left(), 1, e->rect().right(), 1 );
00074   }
00075 };
00076 //END KVSSBSep
00077 
00078 //BEGIN KateViewSpace
00079 KateViewSpace::KateViewSpace( KateViewSpaceContainer *viewManager,
00080                               QWidget* parent, const char* name )
00081   : QVBox(parent, name),
00082     m_viewManager( viewManager )
00083 {
00084   mViewList.setAutoDelete(false);
00085 
00086   stack = new QWidgetStack( this );
00087   setStretchFactor(stack, 1);
00088   stack->setFocus();
00089   //sep = new KVSSBSep( this );
00090   mStatusBar = new KateVSStatusBar(this);
00091   mIsActiveSpace = false;
00092   mViewCount = 0;
00093 
00094   setMinimumWidth (mStatusBar->minimumWidth());
00095   m_group = QString::null;
00096 }
00097 
00098 KateViewSpace::~KateViewSpace()
00099 {
00100 }
00101 
00102 void KateViewSpace::polish()
00103 {
00104   mStatusBar->show();
00105 }
00106 
00107 void KateViewSpace::addView(Kate::View* v, bool show)
00108 {
00109   // restore the config of this view if possible
00110   if ( !m_group.isEmpty() )
00111   {
00112     QString fn = v->getDoc()->url().prettyURL();
00113     if ( ! fn.isEmpty() )
00114     {
00115       QString vgroup = QString("%1 %2").arg(m_group).arg(fn);
00116 
00117       KateSession::Ptr as = KateSessionManager::self()->activeSession ();
00118       if ( as->configRead() && as->configRead()->hasGroup( vgroup ) )
00119       {
00120         as->configRead()->setGroup( vgroup );
00121         v->readSessionConfig ( as->configRead() );
00122       }
00123     }
00124   }
00125 
00126   uint id = mViewList.count();
00127   stack->addWidget(v, id);
00128   if (show) {
00129     mViewList.append(v);
00130     showView( v );
00131   }
00132   else {
00133     Kate::View* c = mViewList.current();
00134     mViewList.prepend( v );
00135     showView( c );
00136   }
00137 }
00138 
00139 void KateViewSpace::removeView(Kate::View* v)
00140 {
00141   disconnect( v->getDoc(), SIGNAL(modifiedChanged()),
00142               mStatusBar, SLOT(modifiedChanged()) );
00143 
00144   bool active = ( v == currentView() );
00145 
00146   mViewList.remove (v);
00147   stack->removeWidget (v);
00148 
00149   if ( ! active )
00150     return;
00151 
00152   if (currentView() != 0L)
00153     showView(mViewList.current());
00154   else if (mViewList.count() > 0)
00155     showView(mViewList.last());
00156 }
00157 
00158 bool KateViewSpace::showView(Kate::View* v)
00159 {
00160   return showView( v->getDoc()->documentNumber() );
00161 }
00162 
00163 bool KateViewSpace::showView(uint documentNumber)
00164 {
00165   QPtrListIterator<Kate::View> it (mViewList);
00166   it.toLast();
00167   for( ; it.current(); --it ) {
00168     if (((Kate::Document*)it.current()->getDoc())->documentNumber() == documentNumber) {
00169       if ( currentView() )
00170         disconnect( currentView()->getDoc(), SIGNAL(modifiedChanged()),
00171                     mStatusBar, SLOT(modifiedChanged()) );
00172 
00173       Kate::View* kv = it.current();
00174       connect( kv->getDoc(), SIGNAL(modifiedChanged()),
00175                mStatusBar, SLOT(modifiedChanged()) );
00176 
00177       mViewList.removeRef( kv );
00178       mViewList.append( kv );
00179       stack->raiseWidget( kv );
00180       kv->show();
00181       mStatusBar->modifiedChanged();
00182       return true;
00183     }
00184   }
00185    return false;
00186 }
00187 
00188 
00189 Kate::View* KateViewSpace::currentView()
00190 {
00191   if (mViewList.count() > 0)
00192     return (Kate::View*)stack->visibleWidget();
00193 
00194   return 0L;
00195 }
00196 
00197 bool KateViewSpace::isActiveSpace()
00198 {
00199   return mIsActiveSpace;
00200 }
00201 
00202 void KateViewSpace::setActive( bool active, bool )
00203 {
00204   mIsActiveSpace = active;
00205 
00206   // change the statusbar palette and make sure it gets updated
00207   QPalette pal( palette() );
00208   if ( ! active )
00209   {
00210     pal.setColor( QColorGroup::Background, pal.active().mid() );
00211     pal.setColor( QColorGroup::Light, pal.active().midlight() );
00212   }
00213 
00214   mStatusBar->setPalette( pal );
00215   mStatusBar->update();
00216   //sep->update();
00217 }
00218 
00219 bool KateViewSpace::event( QEvent *e )
00220 {
00221   if ( e->type() == QEvent::PaletteChange )
00222   {
00223     setActive( mIsActiveSpace );
00224     return true;
00225   }
00226   return QVBox::event( e );
00227 }
00228 
00229 void KateViewSpace::slotStatusChanged (Kate::View *view, int r, int c, int ovr, bool block, int mod, const QString &msg)
00230 {
00231   if ((QWidgetStack *)view->parentWidget() != stack)
00232     return;
00233   mStatusBar->setStatus( r, c, ovr, block, mod, msg );
00234 }
00235 
00236 void KateViewSpace::saveConfig ( KConfig* config, int myIndex ,const QString& viewConfGrp)
00237 {
00238 //   kdDebug()<<"KateViewSpace::saveConfig("<<myIndex<<", "<<viewConfGrp<<") - currentView: "<<currentView()<<")"<<endl;
00239   QString group = QString(viewConfGrp+"-ViewSpace %1").arg( myIndex );
00240 
00241   config->setGroup (group);
00242   config->writeEntry ("Count", mViewList.count());
00243 
00244   if (currentView())
00245     config->writeEntry( "Active View", currentView()->getDoc()->url().prettyURL() );
00246 
00247   // Save file list, includeing cursor position in this instance.
00248   QPtrListIterator<Kate::View> it(mViewList);
00249 
00250   int idx = 0;
00251   for (; it.current(); ++it)
00252   {
00253     if ( !it.current()->getDoc()->url().isEmpty() )
00254     {
00255       config->setGroup( group );
00256       config->writeEntry( QString("View %1").arg( idx ), it.current()->getDoc()->url().prettyURL() );
00257 
00258       // view config, group: "ViewSpace <n> url"
00259       QString vgroup = QString("%1 %2").arg(group).arg(it.current()->getDoc()->url().prettyURL());
00260       config->setGroup( vgroup );
00261       it.current()->writeSessionConfig( config );
00262     }
00263 
00264     idx++;
00265   }
00266 }
00267 
00268 void KateViewSpace::modifiedOnDisc(Kate::Document *, bool, unsigned char)
00269 {
00270   if ( currentView() )
00271     mStatusBar->updateMod( currentView()->getDoc()->isModified() );
00272 }
00273 
00274 void KateViewSpace::restoreConfig ( KateViewSpaceContainer *viewMan, KConfig* config, const QString &group )
00275 {
00276   config->setGroup (group);
00277   QString fn = config->readEntry( "Active View" );
00278 
00code" href="classKateViewSpace.html#552961cfd89ab3f196bdb5c0f1994b58">stack->visibleWidget();
00193 
00194   return 0L;
00195 }
00196 
00197 bool KateViewSpace::isActiveSpace()
00198 {
00199   return mIsActiveSpace;
00200 }
00201 
00202 void KateViewSpace::setActive( bool active, bool )
00203 {
00204   mIsActiveSpace = active;
00205 
00206   // change the statusbar palette and make sure it gets updated
00207   QPalette pal( palette() );
00208   if ( ! active )
00209   {
00210     pal.setColor( QColorGroup::Background, pal.active().mid() );
00211     pal.setColor( QColorGroup::Light, pal.active().midlight() );
00212   }
00213 
00214   mStatusBar->setPalette( pal );
00215   mStatusBar->update();
00216   //sep->update();
00217 }
00218 
00219 bool KateViewSpace::event( QEvent *e )
00220 {
00221   if ( e->type() == QEvent::PaletteChange )
00222   {
00223     setActive( mIsActiveSpace );
00224     return true;
00225   }
00226   return QVBox::event( e );
00227 }
00228 
00229 void KateViewSpace::slotStatusChanged (Kate::View *view, int r, int c, int ovr, bool block, int mod, const QString &msg)
00230 {
00231   if ((QWidgetStack *)view->parentWidget() != stack)
00232     return;
00233   mStatusBar->setStatus( r, c, ovr, block, mod, msg );
00234 }
00235 
00236 void KateViewSpace::saveConfig ( KConfig* config, int myIndex ,const QString& viewConfGrp)
00237 {
00238 //   kdDebug()<<"KateViewSpace::saveConfig("<<myIndex<<", "<<viewConfGrp<<") - currentView: "<<currentView()<<")"<<endl;
00239   QString group = QString(viewConfGrp+"-ViewSpace %1").arg( myIndex );
00240 
00241   config->setGroup (group);
00242   config->writeEntry ("Count", mViewList.count());
00243 
00244   if (currentView())
00245     config->writeEntry( "Active View", currentView()->getDoc()->url().prettyURL() );
00246 
00247   // Save file list, includeing cursor position in this instance.
00248   QPtrListIterator<Kate::View> it(mViewList);
00249 
00250   int idx = 0;
00251   for (; it.current(); ++it)
00252   {
00253     if ( !it.current()->getDoc()->url().isEmpty() )
00254     {
00255       config->setGroup( group );
00256       config->writeEntry( QString("View %1").arg( idx ), it.current()->getDoc()->url().prettyURL() );
00257 
00258       // view config, group: "ViewSpace <n> url"
00259       QString vgroup = QString("%1 %2").arg(group).arg(it.current()->getDoc()->url().prettyURL());
00260       config->setGroup( vgroup );
00261       it.current()->writeSessionConfig( config );
00262     }
00263 
00264     idx++;
00265   }
00266 }
00267 
00268 void KateViewSpace::modifiedOnDisc(Kate::Document *, bool, unsigned char)
00269 {
00270   if ( currentView() )
00271     mStatusBar->updateMod( currentView()->getDoc()->isModified() );
00272 }
00273 
00274 void KateViewSpace::restoreConfig ( KateViewSpaceContainer *viewMan, KConfig* config, const QString &group )
00275 {
00276   config->setGroup (group);
00277   QString fn = config->readEntry( "Active View" );
00278 
00code" href="classKateViewSpace.html#552961cfd89ab3f196bdb5c0f1994b58">stack->visibleWidget();
00193 
00194   return 0L;
00195 }
00196 
00197 bool KateViewSpace::isActiveSpace()
00198 {
00199   return mIsActiveSpace;
00200 }
00201 
00202 void KateViewSpace::setActive( bool active, bool )
00203 {
00204   mIsActiveSpace = active;
00205 
00206   // change the statusbar palette and make sure it gets updated
00207   QPalette pal( palette() );
00208   if ( ! active )
00209   {
00210     pal.setColor( QColorGroup::Background, pal.active().mid() );
00211     pal.setColor( QColorGroup::Light, pal.active().midlight() );
00212   }
00213 
00214   mStatusBar->setPalette( pal );
00215   mStatusBar->update();
00216   //sep->update();
00217 }
00218 
00219 bool KateViewSpace::event( QEvent *e )
00220 {
00221   if ( e->type() == QEvent::PaletteChange )
00222   {
00223     setActive( mIsActiveSpace );
00224     return true;
00225   }
00226   return QVBox::event( e );
00227 }
00228 
00229 void KateViewSpace::slotStatusChanged (Kate::View *view, int r, int c, int ovr, bool block, int mod, const QString &msg)
00230 {
00231   if ((QWidgetStack *)view->parentWidget() != stack)
00232     return;
00233   mStatusBar->setStatus( r, c, ovr, block, mod, msg );
00234 }
00235 
00236 void KateViewSpace::saveConfig ( KConfig* config, int myIndex ,const QString& viewConfGrp)
00237 {
00238 //   kdDebug()<<"KateViewSpace::saveConfig("<<myIndex<<", "<<viewConfGrp<<") - currentView: "<<currentView()<<")"<<endl;
00239   QString group = QString(viewConfGrp+"-ViewSpace %1").arg( myIndex );
00240 
00241   config->setGroup (group);
00242   config->writeEntry ("Count", mViewList.count());
00243 
00244   if (currentView())
00245     config->writeEntry( "Active View", currentView()->getDoc()->url().prettyURL() );
00246 
00247   // Save file list, includeing cursor position in this instance.
00248   QPtrListIterator<Kate::View> it(mViewList);
00249 
00250   int idx = 0;
00251   for (; it.current(); ++it)
00252   {
00253     if ( !it.current()->getDoc()->url().isEmpty() )
00254     {
00255       config->setGroup( group );
00256       config->writeEntry( QString("View %1").arg( idx ), it.current()->getDoc()->url().prettyURL() );
00257 
00258       // view config, group: "ViewSpace <n> url"
00259       QString vgroup = QString("%1 %2").arg(group).arg(it.current()->getDoc()->url().prettyURL());
00260       config->setGroup( vgroup );
00261       it.current()->writeSessionConfig( config );
00262     }
00263 
00264     idx++;
00265   }
00266 }
00267 
00268 void KateViewSpace::modifiedOnDisc(Kate::Document *, bool, unsigned char)
00269 {
00270   if ( currentView() )
00271     mStatusBar->updateMod( currentView()->getDoc()->isModified() );
00272 }
00273 
00274 void KateViewSpace::restoreConfig ( KateViewSpaceContainer *viewMan, KConfig* config, const QString &group )
00275 {
00276   config->setGroup (group);
00277   QString fn = config->readEntry( "Active View" );
00278 
00code" href="classKateViewSpace.html#552961cfd89ab3f196bdb5c0f1994b58">stack->visibleWidget();
00193 
00194   return 0L;
00195 }
00196 
00197 bool KateViewSpace::isActiveSpace()
00198 {
00199   return mIsActiveSpace;
00200 }
00201 
00202 void KateViewSpace::setActive( bool active, bool )
00203 {
00204   mIsActiveSpace = active;
00205 
00206   // change the statusbar palette and make sure it gets updated
00207   QPalette pal( palette() );
00208   if ( ! active )
00209   {
00210     pal.setColor( QColorGroup::Background, pal.active().mid() );
00211     pal.setColor( QColorGroup::Light, pal.active().midlight() );
00212   }
00213 
00214   mStatusBar->setPalette( pal );
00215   mStatusBar->update();
00216   //sep->update();
00217 }
00218 
00219 bool KateViewSpace::event( QEvent *e )
00220 {
00221   if ( e->type() == QEvent::PaletteChange )
00222   {
00223     setActive( mIsActiveSpace );
00224     return true;
00225   }
00226   return QVBox::event( e );
00227 }
00228 
00229 void KateViewSpace::slotStatusChanged (Kate::View *view, int r, int c, int ovr, bool block, int mod, const QString &msg)
00230 {
00231   if ((QWidgetStack *)view->parentWidget() != stack)
00232     return;
00233   mStatusBar->setStatus( r, c, ovr, block, mod, msg );
00234 }
00235 
00236 void KateViewSpace::saveConfig ( KConfig* config, int myIndex ,const QString& viewConfGrp)
00237 {
00238 //