/*************************************************************************** plugin_katetabbarextension.cpp ------------------- begin : 2004-04-20 copyright : (C) 2004 by Dominik Haumann email : dhdev@gmx.de ***************************************************************************/ /*************************************************************************** This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ***************************************************************************/ // BEGIN INCLUDES #include "plugin_katetabbarextension.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include // END class PluginView : public KXMLGUIClient { friend class KatePluginTabBarExtension; public: Kate::MainWindow *win; KateTabBarExtension* tabbar; }; extern "C" { void* init_libkatetabbarextensionplugin() { KGlobal::locale()->insertCatalogue("katetabbarextension"); return new KatePluginFactory; } } KatePluginFactory::KatePluginFactory() { s_instance = new TDEInstance( "kate" ); } KatePluginFactory::~KatePluginFactory() { delete s_instance; } TQObject* KatePluginFactory::createObject( TQObject* parent, const char* name, const char*, const TQStringList & ) { return new KatePluginTabBarExtension( parent, name ); } TDEInstance* KatePluginFactory::s_instance = 0L; // BEGIN KatePluginTabBarExtension KatePluginTabBarExtension::KatePluginTabBarExtension( TQObject* parent, const char* name ) : Kate::Plugin ( (Kate::Application*)parent, name ), pConfig(new KConfig("katetabbarextensionpluginrc")) { pConfig->setGroup("global"); } KatePluginTabBarExtension::~KatePluginTabBarExtension() { while (m_views.count() > 0) { removeView(m_views.at(0)->win); } delete pConfig; } void KatePluginTabBarExtension::addView(Kate::MainWindow *win) { PluginView *view = new PluginView (); bool bHoriz = pConfig->readBoolEntry("horizontal orientation", true); bool sort = pConfig->readBoolEntry("sort", true); view->tabbar = new KateTabBarExtension( application()->documentManager(), win, bHoriz, sort, 0, "tabs_hbox"); new KWidgetAction(view->tabbar, "tab_bar_widget", KShortcut::null(), 0, 0, view->actionCollection(), "tabbar_widget"); view->setInstance (new TDEInstance("kate")); view->setXMLFile("plugins/katetabbarextension/ui.rc"); win->guiFactory()->addClient (view); view->win = win; m_views.append (view); KToolBar* toolbar = dynamic_cast (win->guiFactory()->container("tabbarExtensionToolBar", view)); if (toolbar) { connect(toolbar, TQT_SIGNAL( orientationChanged(Qt::Orientation) ), view->tabbar, TQT_SLOT( slotMoved(Qt::Orientation) )); } } void KatePluginTabBarExtension::removeView(Kate::MainWindow *win) { for (uint z=0; z < m_views.count(); z++) { if (m_views.at(z)->win == win) { PluginView *view = m_views.at(z); // the last tabbar, save options if (m_views.count() == 1) { pConfig->writeEntry("horizontal orientation", view->tabbar->orientation()==Qt::Horizontal?true:false); pConfig->writeEntry("sort", view->tabbar->sortByName()); pConfig->sync(); } m_views.remove (view); win->guiFactory()->removeClient (view); delete view->tabbar; delete view; } } } Kate::PluginConfigPage* KatePluginTabBarExtension::configPage( uint, TQWidget *w, const char* /*name*/) { KateTabBarExtensionConfigPage* p = new KateTabBarExtensionConfigPage(this, w); initConfigPage( p ); connect( p, TQT_SIGNAL(configPageApplyRequest(KateTabBarExtensionConfigPage*)), TQT_SLOT(applyConfig(KateTabBarExtensionConfigPage*)) ); return (Kate::PluginConfigPage*)p; } void KatePluginTabBarExtension::initConfigPage( KateTabBarExtensionConfigPage* p ) { p->pSortAlpha->setChecked(m_views.at(0)->tabbar->sortByName()); } void KatePluginTabBarExtension::applyConfig( KateTabBarExtensionConfigPage* p ) { m_views.at(0)->tabbar->setSortByName(p->pSortAlpha->isChecked()); // sync m_config in destructor } // END KatePluginTabBarExtension // BEGIN KateTabBarButton KateTabBarButton::KateTabBarButton(Kate::ViewManager* pViewManager, Kate::Document *pDoc, TQWidget * parent, const char * name) : TQPushButton(parent, name), modified(false), myDocID(pDoc->documentNumber()), doc(pDoc), viewManager(pViewManager) { setFlat(true); setToggleButton(true); setFocusPolicy(TQ_NoFocus); setText(pDoc->docName()); connect(this, TQT_SIGNAL(toggled(bool)), TQT_SLOT(setOn(bool))); } KateTabBarButton::~KateTabBarButton() {} uint KateTabBarButton::documentNumber() { return myDocID; } void KateTabBarButton::setDirty(bool d) { if (d) { setIconSet(SmallIconSet("cancel")); } else { if (modified) setIconSet(SmallIconSet("modified")); else setIconSet(TQIconSet()); } } void KateTabBarButton::setText( const TQString& newText) { TQToolTip::remove(this); if (newText.length() > 20) { // squeeze to length 17+3=20 TQPushButton::setText(newText.left(9) + "..." + newText.right(8)); TQToolTip::add(this, newText); } else { TQPushButton::setText(newText); } } TQString KateTabBarButton::fullName() const { if (doc) { return doc->docName(); } else { return TQString(""); } } void KateTabBarButton::triggerModified() { modified = !modified; if (modified) { TQColor c(255, 0, 0); setPaletteForegroundColor( c ); setIconSet(SmallIconSet("modified")); } else { TQColor c(KGlobalSettings::textColor()); setPaletteForegroundColor( c ); setIconSet(TQIconSet()); } } void KateTabBarButton::setOn(bool on) { disconnect( TQT_SIGNAL(toggled(bool))); // kdDebug() << "setOn: " << (int)on << endl; if ((!on) && viewManager->activeView()->document()->documentNumber() == documentNumber()) { // kdDebug() << "setOn aborted " << endl; TQPushButton::setOn(true); } else { TQPushButton::setOn(on); if (on) emit myToggled(this); } connect(this, TQT_SIGNAL(toggled(bool)), TQT_SLOT(setOn(bool))); } // END KateTabBarButton // BEGIN KateTabBarExtension KateTabBarExtension::KateTabBarExtension( Kate::DocumentManager *pDocManager, Kate::MainWindow *win, bool bHorizOrientation, bool bSort, TQWidget* parent, const char* name, WFlags f ) : TQWidget(parent, name, f), pCurrentTab(0), m_win(win), m_docManager(pDocManager), m_sort(false) { if (bHorizOrientation) { top = new TQBoxLayout(this, TQBoxLayout::LeftToRight); m_orientation = Qt::Horizontal; } else { top = new TQBoxLayout(this, TQBoxLayout::TopToBottom); m_orientation = Qt::Vertical; } // add all already existing documents to the tabbar for (uint i = 0; i < pDocManager->documents(); i++) { slotDocumentCreated (pDocManager->document(i)); } connect(m_win->viewManager(), TQT_SIGNAL(viewChanged()), TQT_SLOT(slotViewChanged())); connect(pDocManager, TQT_SIGNAL(documentCreated(Kate::Document *)), TQT_SLOT(slotDocumentCreated(Kate::Document *))); connect(pDocManager, TQT_SIGNAL(documentDeleted(uint)), TQT_SLOT(slotDocumentDeleted(uint))); setSortByName(bSort); } KateTabBarExtension::~KateTabBarExtension() {} void KateTabBarExtension::slotMoved(Qt::Orientation o) { // the tabbar moved (top, right, bottom, left or fluently) switch (o) { case Qt::Vertical: top->setDirection(TQBoxLayout::TopToBottom); break; case Qt::Horizontal: top->setDirection(TQBoxLayout::LeftToRight); break; } m_orientation = o; } Qt::Orientation KateTabBarExtension::orientation() const { return m_orientation; } bool KateTabBarExtension::sortByName() const { return m_sort; } void KateTabBarExtension::setSortByName(bool sbn) { if (m_sort != sbn) { m_sort = sbn; if (m_sort) updateSort(); } } void KateTabBarExtension::updateSort() { // kdDebug() << "updateSort called" << endl; if (sortByName()) { // remove all tabs from the tabbar KateTabBarButton* tab; for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) { top->remove(tab); } // now sort m_tabs.sort(); // and finally add tabs again. FIXME: Is there a better way? :( for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) { top->addWidget(tab); } } } void KateTabBarExtension::slotDocumentCreated (Kate::Document *doc) { // kdDebug() << "slotDocumentCreated" << endl; if (!doc) return; KateTabBarButton* tab = new KateTabBarButton(m_win->viewManager(), doc, this); connect(tab, TQT_SIGNAL(myToggled(KateTabBarButton*)), TQT_SLOT(slotActivateView(KateTabBarButton*))); connect(doc, TQT_SIGNAL(nameChanged(Kate::Document *)), TQT_SLOT(slotNameChanged(Kate::Document *))); connect(doc, TQT_SIGNAL(modStateChanged(Kate::Document *)), TQT_SLOT(slotModChanged(Kate::Document *))); connect(doc, TQT_SIGNAL(modifiedOnDisc(Kate::Document *, bool, unsigned char)), TQT_SLOT(slotModifiedOnDisc(Kate::Document *, bool, unsigned char))); if(doc->isModified()) tab->triggerModified(); tab->show(); top->addWidget(tab); m_tabs.append(tab); updateSort(); } void KateTabBarExtension::slotDocumentDeleted (uint documentNumber) { // kdDebug() << "slotDocumentDeleted " << endl; KateTabBarButton* tab; for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) { if (tab->documentNumber() == documentNumber) { tab->disconnect(); top->remove(tab); m_tabs.removeRef(tab); delete tab; tab = 0; break; } } } void KateTabBarExtension::slotActivateView(KateTabBarButton* newTab) { // kdDebug() << "slotActiavateView" << endl; pCurrentTab = newTab; if (pCurrentTab) { KateTabBarButton* tab; for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) { if (tab->isOn() && tab != pCurrentTab) tab->setOn(false); } uint id = pCurrentTab->documentNumber(); m_win->viewManager()->activateView( id ); } } void KateTabBarExtension::slotModChanged (Kate::Document *doc) { // kdDebug() << "slotModChanged" << endl; if (!doc) return; KateTabBarButton* tab; for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) { if (tab->documentNumber() == doc->documentNumber()) { // found tab->triggerModified(); break; } } } void KateTabBarExtension::slotModifiedOnDisc ( Kate::Document *doc, bool b, unsigned char /*reason*/) { // kdDebug() << "slotModifiedOnDisc: " << (int)b << endl; // find corresponding tab KateTabBarButton* tab; for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) { if (tab->documentNumber() == doc->documentNumber()) { tab->setDirty(b); } } } void KateTabBarExtension::slotNameChanged (Kate::Document *doc) { if (!doc) return; // kdDebug() << "slotNameChanged " << doc->docName() << endl; KateTabBarButton* tab; for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) { if (tab->documentNumber() == doc->documentNumber()) { tab->setText(doc->docName()); break; } } updateSort(); } void KateTabBarExtension::slotViewChanged () { // kdDebug() << "slotVieChanged()" << endl; Kate::View *view = m_win->viewManager()->activeView(); if (!view) return; KateTabBarButton* tab; for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) { if (tab->documentNumber() == ((Kate::Document *)view->getDoc())->documentNumber()) { pCurrentTab = tab; for (tab = m_tabs.first(); tab; tab = m_tabs.next() ) { if (tab->isOn()) tab->setOn(false); } if (!pCurrentTab->isOn()) pCurrentTab->setOn(true); break; } } } // END KateTabBarExtension // BEGIN KateTabBarExtensionConfigPage KateTabBarExtensionConfigPage::KateTabBarExtensionConfigPage( TQObject* /*parent*/ /*= 0L*/, TQWidget *parentWidget /*= 0L*/) : Kate::PluginConfigPage( parentWidget ) { TQVBoxLayout* top = new TQVBoxLayout(this, 0, KDialogBase::spacingHint()); TQGroupBox* gb = new TQGroupBox( i18n("Sorting Behavior"), this, "tab_bar_extension_config_page_layout" ); gb->setColumnLayout(1, Qt::Vertical); gb->setInsideSpacing(KDialogBase::spacingHint()); pSortAlpha = new TQCheckBox(i18n("Sort files alphabetically"), gb); top->add(gb); top->addStretch(1); // throw signal changed connect(pSortAlpha, TQT_SIGNAL(toggled(bool)), this, TQT_SIGNAL(changed())); } KateTabBarExtensionConfigPage::~KateTabBarExtensionConfigPage() {} void KateTabBarExtensionConfigPage::apply() { emit configPageApplyRequest( this ); } // END KateTabBarExtensionConfigPage // BEGIN MyPtrList implementaion int MyPtrList::compareItems ( TQPtrCollection::Item item1_, TQPtrCollection::Item item2_ ) { KateTabBarButton* item1 = reinterpret_cast(item1_); KateTabBarButton* item2 = reinterpret_cast(item2_); if (item1->fullName().lower() < item2->fullName().lower()) { // kdDebug() << item1->fullName().lower() << " < " // << item2->fullName().lower() << endl; return -1; } else { if (item1->fullName().lower() > item2->fullName().lower()) { // kdDebug() << item1->fullName().lower() << " > " // << item2->fullName().lower() << endl; return 1; } else { // kdDebug() << item1->fullName().lower() << " == " // << item2->fullName().lower() << endl; return 0; } } } // END MyPtrList implementaion #include "plugin_katetabbarextension.moc"