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 <tqwidgetstack.h> 00037 #include <tqpainter.h> 00038 #include <tqlabel.h> 00039 #include <tqcursor.h> 00040 #include <tqpopupmenu.h> 00041 #include <tqpixmap.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 TQScrollView with frame 00049 looks slightly clumsy... 00050 Slight 3D effect. I looked for suitable TQStyle props or methods, 00051 but found none, though maybe it should use TQStyle::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, TQStatusBar is up to now completely ignorant to style. 00058 -anders 00059 */ 00060 class KVSSBSep : public TQWidget { 00061 public: 00062 KVSSBSep( KateViewSpace *parent=0) : TQWidget(parent) 00063 { 00064 setFixedHeight( 2 ); 00065 } 00066 protected: 00067 void paintEvent( TQPaintEvent *e ) 00068 { 00069 TQPainter 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 TQWidget* parent, const char* name ) 00081 : TQVBox(parent, name), 00082 m_viewManager( viewManager ) 00083 { 00084 mViewList.setAutoDelete(false); 00085 00086 stack = new TQWidgetStack( 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 = TQString::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 TQString fn = v->getDoc()->url().prettyURL(); 00113 if ( ! fn.isEmpty() ) 00114 { 00115 TQString vgroup = TQString("%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(), TQT_SIGNAL(modifiedChanged()), 00142 mStatusBar, TQT_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 TQPtrListIterator<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(), TQT_SIGNAL(modifiedChanged()), 00171 mStatusBar, TQT_SLOT(modifiedChanged()) ); 00172 00173 Kate::View* kv = it.current(); 00174 connect( kv->getDoc(), TQT_SIGNAL(modifiedChanged()), 00175 mStatusBar, TQT_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 TQPalette pal( palette() ); 00208 if ( ! active ) 00209 { 00210 pal.setColor( TQColorGroup::Background, pal.active().mid() ); 00211 pal.setColor( TQColorGroup::Light, pal.active().midlight() ); 00212 } 00213 00214 mStatusBar->setPalette( pal ); 00215 mStatusBar->update(); 00216 //sep->update(); 00217 } 00218 00219 bool KateViewSpace::event( TQEvent *e ) 00220 { 00221 if ( e->type() == TQEvent::PaletteChange ) 00222 { 00223 setActive( mIsActiveSpace ); 00224 return true; 00225 } 00226 return TQVBox::event( e ); 00227 } 00228 00229 void KateViewSpace::slotStatusChanged (Kate::View *view, int r, int c, int ovr, bool block, int mod, const TQString &msg) 00230 { 00231 if ((TQWidgetStack *)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 TQString& viewConfGrp) 00237 { 00238 // kdDebug()<<"KateViewSpace::saveConfig("<<myIndex<<", "<<viewConfGrp<<") - currentView: "<<currentView()<<")"<<endl; 00239 TQString group = TQString(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 TQPtrListIterator<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( TQString("View %1").arg( idx ), it.current()->getDoc()->url().prettyURL() ); 00257 00258 // view config, group: "ViewSpace <n> url" 00259 TQString vgroup = TQString("%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 TQString &group ) 00275 { 00276 config->setGroup (group); 00277 TQString fn = config->readEntry( "Active View" ); 00278 00279 if ( !fn.isEmpty() ) 00280 { 00281 Kate::Document *doc = KateDocManager::self()->findDocumentByUrl (KURL(fn)); 00282 00283 if (doc) 00284 { 00285 // view config, group: "ViewSpace <n> url" 00286 TQString vgroup = TQString("%1 %2").arg(group).arg(fn); 00287 config->setGroup( vgroup ); 00288 00289 viewMan->createView (doc); 00290 00291 Kate::View *v = viewMan->activeView (); 00292 00293 if (v) 00294 v->readSessionConfig( config ); 00295 } 00296 } 00297 00298 if (mViewList.isEmpty()) 00299 viewMan->createView (KateDocManager::self()->document(0)); 00300 00301 m_group = group; // used for restroing view configs later 00302 } 00303 //END KateViewSpace 00304 00305 //BEGIN KateVSStatusBar 00306 KateVSStatusBar::KateVSStatusBar ( KateViewSpace *parent, const char *name ) 00307 : KStatusBar( parent, name ), 00308 m_viewSpace( parent ) 00309 { 00310 m_lineColLabel = new TQLabel( this ); 00311 addWidget( m_lineColLabel, 0, false ); 00312 m_lineColLabel->setAlignment( Qt::AlignCenter ); 00313 m_lineColLabel->installEventFilter( this ); 00314 00315 m_modifiedLabel = new TQLabel( TQString(" "), this ); 00316 addWidget( m_modifiedLabel, 0, false ); 00317 m_modifiedLabel->setAlignment( Qt::AlignCenter ); 00318 m_modifiedLabel->installEventFilter( this ); 00319 00320 m_insertModeLabel = new TQLabel( i18n(" INS "), this ); 00321 addWidget( m_insertModeLabel, 0, false ); 00322 m_insertModeLabel->setAlignment( Qt::AlignCenter ); 00323 m_insertModeLabel->installEventFilter( this ); 00324 00325 m_selectModeLabel = new TQLabel( i18n(" NORM "), this ); 00326 addWidget( m_selectModeLabel, 0, false ); 00327 m_selectModeLabel->setAlignment( Qt::AlignCenter ); 00328 m_selectModeLabel->installEventFilter( this ); 00329 00330 m_fileNameLabel=new KSqueezedTextLabel( this ); 00331 addWidget( m_fileNameLabel, 1, true ); 00332 m_fileNameLabel->setMinimumSize( 0, 0 ); 00333 m_fileNameLabel->setSizePolicy(TQSizePolicy( TQSizePolicy::Ignored, TQSizePolicy::Fixed )); 00334 m_fileNameLabel->setAlignment( /*Qt::AlignRight*/Qt::AlignLeft ); 00335 m_fileNameLabel->installEventFilter( this ); 00336 00337 installEventFilter( this ); 00338 m_modPm = SmallIcon("modified"); 00339 m_modDiscPm = SmallIcon("modonhd"); 00340 m_modmodPm = SmallIcon("modmod"); 00341 m_noPm = SmallIcon("null"); 00342 } 00343 00344 KateVSStatusBar::~KateVSStatusBar () 00345 { 00346 } 00347 00348 void KateVSStatusBar::setStatus( int r, int c, int ovr, bool block, int, const TQString &msg ) 00349 { 00350 m_lineColLabel->setText( 00351 i18n(" Line: %1 Col: %2 ").arg(KGlobal::locale()->formatNumber(r+1, 0)) 00352 .arg(KGlobal::locale()->formatNumber(c+1, 0)) ); 00353 00354 if (ovr == 0) 00355 m_insertModeLabel->setText( i18n(" R/O ") ); 00356 else if (ovr == 1) 00357 m_insertModeLabel->setText( i18n(" OVR ") ); 00358 else if (ovr == 2) 00359 m_insertModeLabel->setText( i18n(" INS ") ); 00360 00361 // updateMod( mod ); 00362 00363 m_selectModeLabel->setText( block ? i18n(" BLK ") : i18n(" NORM ") ); 00364 00365 m_fileNameLabel->setText( msg ); 00366 } 00367 00368 void KateVSStatusBar::updateMod( bool mod ) 00369 { 00370 Kate::View *v = m_viewSpace->currentView(); 00371 if ( v ) 00372 { 00373 const KateDocumentInfo *info 00374 = KateDocManager::self()->documentInfo ( v->getDoc() ); 00375 00376 bool modOnHD = info && info->modifiedOnDisc; 00377 00378 m_modifiedLabel->setPixmap( 00379 mod ? 00380 info && modOnHD ? 00381 m_modmodPm : 00382 m_modPm : 00383 info && modOnHD ? 00384 m_modDiscPm : 00385 m_noPm 00386 ); 00387 } 00388 } 00389 00390 void KateVSStatusBar::modifiedChanged() 00391 { 00392 Kate::View *v = m_viewSpace->currentView(); 00393 if ( v ) 00394 updateMod( v->getDoc()->isModified() ); 00395 } 00396 00397 void KateVSStatusBar::showMenu() 00398 { 00399 KMainWindow* mainWindow = static_cast<KMainWindow*>( topLevelWidget() ); 00400 TQPopupMenu* menu = static_cast<TQPopupMenu*>( mainWindow->factory()->container("viewspace_popup", mainWindow ) ); 00401 00402 if (menu) 00403 menu->exec(TQCursor::pos()); 00404 } 00405 00406 bool KateVSStatusBar::eventFilter(TQObject*,TQEvent *e) 00407 { 00408 if (e->type()==TQEvent::MouseButtonPress) 00409 { 00410 if ( m_viewSpace->currentView() ) 00411 m_viewSpace->currentView()->setFocus(); 00412 00413 if ( ((TQMouseEvent*)e)->button()==Qt::RightButton) 00414 showMenu(); 00415 00416 return true; 00417 } 00418 00419 return false; 00420 } 00421 //END KateVSStatusBar 00422 // kate: space-indent on; indent-width 2; replace-tabs on;