lib

kopalettemanager.cc

00001 /*
00002  *  Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org>
00003  *
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2, as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc.,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00016  */
00017 
00018 #include <qapplication.h>
00019 #include <qdockarea.h>
00020 #include <qdockwindow.h>
00021 #include <qdict.h>
00022 #include <qwidget.h>
00023 #include <qobject.h>
00024 #include <qevent.h>
00025 
00026 #include <kparts/event.h>
00027 #include <kapplication.h>
00028 #include <kpopupmenu.h>
00029 #include <kaction.h>
00030 #include <kactionclasses.h>
00031 #include <kdebug.h>
00032 #include <klocale.h>
00033 #include <kglobal.h>
00034 
00035 #include <KoView.h>
00036 #include <KoMainWindow.h>
00037 
00038 #include <kopalette.h>
00039 #include <kotabpalette.h>
00040 #include <kotoolboxpalette.h>
00041 
00042 #include <kopalettemanager.h>
00043 
00044 
00045 KoPaletteManager::KoPaletteManager(KoView * view, KActionCollection *ac, const char * name)
00046     : QObject(view, name)
00047 {
00048 
00049     m_view = view;
00050     m_view->installEventFilter(this);
00051     m_actionCollection = ac;
00052 
00053     m_actions = new QDict<KToggleAction>();
00054     m_widgets = new QDict<QWidget>();
00055     m_palettes = new QDict<KoPalette>();
00056     m_palettes->setAutoDelete(true);
00057     m_defaultMapping = new QMap<QString, QString>();
00058     m_currentMapping = new QMap<QString, QString>();
00059     m_fixedWidth = 0;
00060     m_setFixedWidth = false;
00061     
00062     m_widgetNames = new QStringList();
00063 
00064     m_mapper = new QSignalMapper(this);
00065     connect(m_mapper, SIGNAL(mapped(int)), this, SLOT(slotTogglePalette(int)));
00066     m_viewActionMenu = new KActionMenu(i18n("Palettes"), m_actionCollection, "view_palette_action_menu");
00067 
00068     KConfig * cfg = KGlobal::config();
00069     cfg->setGroup("palettes");
00070 
00071     bool palettesShown = cfg->readBoolEntry("palettesshown", true);
00072     KToggleAction * m_toggleShowHidePalettes;
00073 
00074     if ( palettesShown) {
00075         m_toggleShowHidePalettes = new KToggleAction(i18n("Hide All Palette Windows"),
00076                                     "CTRL+SHIFT+H", this,
00077                                     SLOT(slotToggleAllPalettes()),
00078                                     m_actionCollection, "toggleAllPaletteWindows");
00079 
00080         m_toggleShowHidePalettes->setCheckedState(i18n("Show Palette Windows Again"));
00081     }
00082     else {
00083         m_toggleShowHidePalettes = new KToggleAction(i18n("Show Palette Windows Again"),
00084                                     "CTRL+SHIFT+H", this,
00085                                     SLOT(slotToggleAllPalettes()),
00086                                     m_actionCollection, "toggleAllPaletteWindows");
00087 
00088         m_toggleShowHidePalettes->setCheckedState(i18n("Hide All Palette Windows"));
00089     }
00090     m_viewActionMenu->insert(m_toggleShowHidePalettes);
00091 
00092     // Recreate the palettes in the saved order
00093     QStringList paletteList = QStringList::split(",", cfg->readEntry("palettes"));
00094     QStringList::iterator it;
00095     for (it = paletteList.begin(); it != paletteList.end(); ++it) {
00096         if (cfg->hasGroup("palette-" + (*it))) {
00097 
00098             cfg->setGroup("palette-" + (*it));
00099 
00100             enumKoPaletteStyle style = (enumKoPaletteStyle)cfg->readNumEntry("style", 0);
00101             QString caption = cfg->readEntry("caption", "");
00102 
00103             createPalette((*it), caption, style);
00104         }
00105     }
00106 
00107 /*
00108     KAction * a = new KAction(i18n("Restore Palettes"),
00109                   0, this,
00110                   SLOT(slotReset()),
00111                   this, "restorePalettes");
00112     m_viewActionMenu->insert(a);
00113 */
00114     m_viewActionMenu->popupMenu()->insertSeparator();
00115 }
00116 
00117 
00118 KoPaletteManager::~KoPaletteManager()
00119 {
00120     save();
00121 
00122     delete m_viewActionMenu;
00123     delete m_widgetNames;
00124     delete m_widgets;
00125     delete m_palettes;
00126     delete m_actions;
00127     delete m_mapper;
00128     delete m_defaultMapping;
00129     delete m_currentMapping;
00130 }
00131 
00132 void KoPaletteManager::addWidget(QWidget * widget,
00133                                  const QString & name,
00134                                  const QString & paletteName,
00135                                  int position,
00136                                  enumKoPaletteStyle style,
00137                                  bool shown)
00138 {
00139 
00140     if (!widget) return;
00141 
00142     QString pname = paletteName;
00143 
00144     QWidget * w = m_widgets->find(name);
00145     if (w != 0 )
00146     {
00147         removeWidget(name);
00148     }
00149 
00150     bool visible = true;
00151 
00152     KConfig * cfg = KGlobal::config();
00153     if (cfg->hasGroup("palettetab-" + name)) {
00154         cfg->setGroup("palettetab-" + name);
00155 
00156         pname = cfg->readEntry("docker");
00157         visible = cfg->readBoolEntry("visible");
00158     }
00159 
00160     KoPalette * palette = m_palettes->find(pname);
00161 
00162     if (palette == 0) {
00163         palette = createPalette(pname, widget->caption(), style);
00164         m_defaultPaletteOrder.append(pname+ "," + QString::number(style));
00165     }
00166 
00167     KToggleAction * a;
00168     a = new KToggleAction(i18n("Show %1").arg(widget->caption()), 0, m_mapper, SLOT(map()), m_actionCollection);
00169     a->setCheckedState(i18n("Hide %1").arg(widget->caption()));
00170 
00171     m_mapper->setMapping(a, m_widgetNames->count()); // This is the position at which we'll insert the action
00172     m_actions->insert( name, a );
00173     m_viewActionMenu->insert(a);
00174 
00175     palette->plug(widget, name, position);
00176 
00177     m_widgets->insert(name, widget);
00178 
00179     // Default mappings ready for restoring
00180     m_defaultMapping->insert(name, pname);
00181     m_defaultWidgetOrder.append(name);
00182 
00183     // Find out the hidden state
00184     if(m_widgetNames->contains(name))
00185     {
00186 
00187         // The widget has already been added (and removed) during this session
00188         if(m_hiddenWidgets.contains(name))
00189             palette->hidePage( widget );
00190         else
00191         {
00192             a->setChecked(true);
00193             palette->showPage( widget );
00194         }
00195     }
00196     else
00197     {
00198         cfg->setGroup("palettes");
00199         if( cfg->readBoolEntry("palettesshown", shown))
00200         {
00201             if (visible)
00202             {
00203                 a->setChecked(true);
00204                 palette->showPage( widget );
00205             }
00206             else
00207                 palette->hidePage( widget );
00208         }
00209         else
00210         {
00211             if (visible)
00212                 m_hiddenWidgets.push(name);
00213             palette->hidePage( widget );
00214         }
00215     }
00216 
00217     // Fill the current mappings
00218     m_widgetNames->append(name);
00219     m_currentMapping->insert(name, pname);
00220 }
00221 
00222 
00223 void KoPaletteManager::slotReset()
00224 {
00225     // Clear all old palettes
00226     m_palettes->setAutoDelete( true );
00227     m_palettes->clear();
00228 
00229     m_widgetNames->clear();
00230 
00231     // Recreate the palettewindows in the saved order
00232     QStringList::iterator it;
00233     for (it = m_defaultPaletteOrder.begin(); it != m_defaultPaletteOrder.end(); ++it) {
00234         QString s = *it;
00235         QString pname = s.section( ",", 0, 0 );;
00236         enumKoPaletteStyle style = (enumKoPaletteStyle)s.section(",", 1,1).toInt();
00237         createPalette(pname, "", style);
00238     }
00239 
00240     // Place all existing (that we didn't throw away!) tabs in the right palette and in the right order
00241     for (it = m_defaultWidgetOrder.begin(); it != m_defaultWidgetOrder.end(); ++it) {
00242 
00243         QString widgetName = *it;
00244         QWidget * w = m_widgets->find(widgetName);
00245 
00246         if (!w) {
00247             continue;
00248         }
00249         QString paletteName = *m_defaultMapping->find(widgetName);
00250         KoPalette * p = m_palettes->find(paletteName);
00251 
00252         if (p == 0) {
00253             // Funny -- we should have a consistent set of palettes without holes!
00254             createPalette(paletteName, "", PALETTE_DOCKER);
00255         }
00256 
00257         p->plug(w, widgetName, -1); // XXX: This is not good: we should add it in the same place as originally placed
00258         m_widgetNames->append(widgetName);
00259         m_currentMapping->insert(widgetName, paletteName);
00260     }
00261 }
00262 
00263 void KoPaletteManager::slotResetFont()
00264 {
00265     QDictIterator<KoPalette> it(*m_palettes);
00266     for (; it.current(); ++it) {
00267         it.current()->resetFont();
00268     }
00269 
00270 }
00271 
00272 QWidget * KoPaletteManager::widget(const QString & name)
00273 {
00274     return m_widgets->find(name);
00275 }
00276 
00277 void KoPaletteManager::showWidget(const QString & name)
00278 {
00279     QWidget * w = m_widgets->find(name);
00280     if (!w) return;
00281 
00282     QString pname = *m_currentMapping->find(name);
00283     if (pname.isNull()) return;
00284 
00285     KoPalette * p = m_palettes->find(pname);
00286     p->showPage(w);
00287 
00288     KToggleAction * a = m_actions->find(name);
00289     a->setChecked(true);
00290 }
00291 
00292 void KoPaletteManager::hideWidget(const QString & name)
00293 {
00294     QWidget * w = m_widgets->find(name);
00295     if (!w) return;
00296 
00297     QString pname = *m_currentMapping->find(name);
00298     if (pname.isNull()) return;
00299 
00300     KoPalette * p = m_palettes->find(pname);
00301     p->hidePage(w);
00302 
00303     KToggleAction * a = m_actions->find(name);
00304     a->setChecked(false);
00305 }
00306 
00307 void KoPaletteManager::removeWidget(const QString & name)
00308 {
00309     QString palette = *(m_currentMapping->find(name));
00310     if (palette.isNull()) return;
00311 
00312     QWidget * w = m_widgets->find(name);
00313     if (!w) return;
00314 
00315     KoPalette * p = m_palettes->find(palette);
00316     if (!p) return;
00317 
00318     p->showPage(w);
00319     p->unplug(w);
00320     m_widgets->remove(name);
00321     m_currentMapping->remove(name);
00322 
00323     KAction * a = m_actions->take(name);
00324     m_viewActionMenu->remove(a);
00325     m_actionCollection->remove(a);
00326 }
00327 
00328 KoPalette * KoPaletteManager::createPalette(const QString & name, const QString & caption, enumKoPaletteStyle style)
00329 {
00330     Q_ASSERT(m_view);
00331     KoPalette * palette = 0;
00332 
00333     
00334     palette = m_palettes->find(name);
00335     if (palette) return palette;
00336 
00337 
00338     switch (style) {
00339         case (PALETTE_DOCKER):
00340             palette = new KoTabPalette(m_view, name.latin1());
00341             break;
00342         case (PALETTE_TOOLBOX):
00343             palette = new KoToolBoxPalette(m_view, name.latin1());
00344             break;
00345         default:
00346             // This is a custom palette that we cannot create
00347             return 0;
00348     };
00349 
00350     if(!palette) return 0;
00351 
00352     if (m_setFixedWidth)
00353         palette->setFixedWidth(m_fixedWidth);
00354     
00355     palette->setCaption(caption);
00356     m_palettes->insert(name, palette);
00357     placePalette(name);
00358 
00359     return palette;
00360 }
00361 
00362 void KoPaletteManager::placePalette(const QString & name, Qt::Dock location)
00363 {
00364     Q_ASSERT(!name.isNull());
00365     KoPalette * palette = m_palettes->find(name);
00366 
00367     if (!palette) return;
00368 
00369     //XXX:  Check whether this name occurs in the config list, retrieve the location, set the location
00370     KConfig * cfg = KGlobal::config();
00371 
00372     if (cfg->hasGroup("palette-" + name)) {
00373         cfg->setGroup("palette-" + name);
00374         QString dockarea = cfg->readEntry("dockarea", "right");
00375         QString caption = cfg->readEntry("caption", "");
00376         int height = cfg->readNumEntry("height", 120);
00377         int place = cfg->readNumEntry("place", 0);
00378         int width = cfg->readNumEntry("width", 200);
00379         int x = cfg->readNumEntry("x", 0);
00380         int y = cfg->readNumEntry("y", 0);
00381         int offset = cfg->readNumEntry("offset", 0);
00382         palette->setGeometry(x, y, width, height);
00383         palette->setOffset(offset);
00384         if (dockarea == "left" && place == 0) {
00385             location = Qt::DockLeft;
00386         }
00387         else if (dockarea == "right" && place == 0) {
00388             location = Qt::DockRight;
00389         }
00390         else {
00391             location = DockTornOff;
00392         }
00393     }
00394 
00395     cfg->setGroup("");
00396     m_dockability = (enumKoDockability) cfg->readNumEntry("palettesdockability");
00397 
00398     // Top and bottom will never accept docks
00399     m_view->mainWindow()->topDock()->setAcceptDockWindow(palette, false);
00400     m_view->mainWindow()->bottomDock()->setAcceptDockWindow(palette, false);
00401 
00402     // Left and right may accept docks. The height of the screen is important
00403     int h = qApp->desktop()->height();
00404     switch (m_dockability) {
00405         case (DOCK_ENABLED):
00406             m_view->mainWindow()->leftDock()->setAcceptDockWindow(palette, true);
00407             m_view->mainWindow()->rightDock()->setAcceptDockWindow(palette, true);
00408             m_view->mainWindow()->addDockWindow(palette, location);
00409             break;
00410         case (DOCK_DISABLED):
00411             m_view->mainWindow()->leftDock()->setAcceptDockWindow(palette, false);
00412             m_view->mainWindow()->rightDock()->setAcceptDockWindow(palette, false);
00413             m_view->mainWindow()->addDockWindow(palette, Qt::DockTornOff);
00414             break;
00415         case (DOCK_SMART):
00416             if (h > 768) {
00417                 m_view->mainWindow()->leftDock()->setAcceptDockWindow(palette, true);
00418                 m_view->mainWindow()->rightDock()->setAcceptDockWindow(palette, true);
00419                 m_view->mainWindow()->addDockWindow(palette, location);
00420             }
00421             else {
00422                 m_view->mainWindow()->leftDock()->setAcceptDockWindow(palette, false);
00423                 m_view->mainWindow()->rightDock()->setAcceptDockWindow(palette, false);
00424                 m_view->mainWindow()->addDockWindow(palette, Qt::DockTornOff);
00425            }
00426             break;
00427     };
00428     m_view->mainWindow()->lineUpDockWindows();
00429 }
00430 
00431 void KoPaletteManager::addPalette(KoPalette * palette, const QString & name, Qt::Dock location)
00432 {
00433     Q_ASSERT(palette);
00434     Q_ASSERT(!name.isNull());
00435 
00436     m_palettes->insert(name, palette);
00437     placePalette(name, location);
00438 }
00439 
00440 void KoPaletteManager::slotTogglePalette(int paletteIndex)
00441 {
00442     // Toggle the right palette
00443     QString name = *m_widgetNames->at(paletteIndex);
00444     QWidget * w = m_widgets->find(name);
00445     QString pname = *m_currentMapping->find(name);
00446     KoPalette * p = m_palettes->find(pname);
00447     p->togglePageHidden( w );
00448 
00449     m_hiddenWidgets.clear();
00450 }
00451 
00452 void KoPaletteManager::slotToggleAllPalettes()
00453 {
00454     if( ! m_hiddenWidgets.isEmpty())
00455     {
00456         // Restore previous visibility state
00457         while(!m_hiddenWidgets.isEmpty())
00458         {
00459             QString name = m_hiddenWidgets.pop();
00460             QWidget *w = m_widgets->find(name);
00461             KToggleAction * a = m_actions->find(name);
00462             a->setChecked(true);
00463 
00464             QString pname = *m_currentMapping->find(name);
00465             KoPalette * p = m_palettes->find(pname);
00466             p->showPage(w);
00467         }
00468     }
00469     else
00470     {
00471         // Save hidden state and hide all palettes
00472         m_hiddenWidgets.clear();
00473         QDictIterator<QWidget> it(*m_widgets);
00474         for (; it.current(); ++it)
00475         {
00476             KToggleAction * a = m_actions->find(it.currentKey());
00477             if(a->isChecked())
00478             {
00479                 a->setChecked(false);
00480                 m_hiddenWidgets.push(it.currentKey());
00481 
00482                 QString pname = *m_currentMapping->find(it.currentKey());
00483                 KoPalette * p = m_palettes->find(pname);
00484                 p->hidePage(it.current());
00485             }
00486         }
00487     }
00488 }
00489 
00490 void KoPaletteManager::showAllPalettes(bool shown)
00491 {
00492     QDictIterator<KoPalette> it(*m_palettes);
00493     for (; it.current(); ++it) {
00494         it.current()->makeVisible(shown);
00495     }
00496 }
00497 
00498 bool KoPaletteManager::eventFilter( QObject *o, QEvent *e )
00499 {
00500     if (o != m_view) return false;
00501 
00502     if(e && e->type() == (QEvent::User + 42)) {
00503          KParts::PartActivateEvent * pae = dynamic_cast<KParts::PartActivateEvent *>(e);
00504          if(pae && pae->widget() && pae->widget() == m_view) {
00505             if (pae->activated()) {
00506                 showAllPalettes( true );
00507             }
00508             else {
00509                 showAllPalettes( false );
00510             }
00511          }
00512     }
00513     return false;
00514 }
00515 
00516 
00517 
00518 void KoPaletteManager::save()
00519 {
00520     // XXX: Save to the configuration
00521     // We save:
00522     //   * which tab at which place in which palette
00523     //   * which tab is hidden
00524     //   * whether a palette is floating or docked
00525     //   * dock location of a docked palette
00526     //   * float location of a floated palette
00527     //   * order in which the palettes are docked.
00528 
00529     if (!m_view) return;
00530     if (!m_view->mainWindow()) return;
00531 
00532     KConfig * cfg = KGlobal::config();
00533     Q_ASSERT(cfg);
00534     cfg->setGroup("");
00535 
00536     QString widgets;
00537 
00538     // Save the list of palettes
00539     QDictIterator<KoPalette> itP(*m_palettes);
00540 
00541     QStringList paletteList;
00542 
00543     for (; itP.current(); ++itP) {
00544 
00545         KoPalette * p = itP.current();
00546 
00547         cfg->setGroup("palette-" + itP.currentKey());
00548 
00549         if ( p->area() == m_view->mainWindow()->leftDock() ) {
00550             cfg->writeEntry("dockarea", "left");
00551         }
00552         else {
00553             cfg->writeEntry("dockarea", "right");
00554         }
00555         cfg->writeEntry("place", p->place());
00556         cfg->writeEntry("x", p->x());
00557         cfg->writeEntry("y", p->y());
00558         cfg->writeEntry("height", p->height());
00559         cfg->writeEntry("width", p->width());
00560         cfg->writeEntry("palettestyle", p->style());
00561         cfg->writeEntry("caption", p->caption());
00562         cfg->writeEntry("offset", p->offset());
00563 
00564         // XXX: I dare say that it is immediately visible that I never have had
00565         //      any formal training in algorithms. BSAR.
00566         if (paletteList.isEmpty()) {
00567             paletteList.append(itP.currentKey());
00568         }
00569         else {
00570             QStringList::iterator it;
00571             bool inserted = false;
00572             for (it = paletteList.begin(); it != paletteList.end(); ++it) {
00573                 KoPalette * p2 = m_palettes->find((*it));
00574                 if (p2->y() > p->y()) {
00575                     paletteList.insert(it, itP.currentKey());
00576                     inserted = true;
00577                     break;
00578                 }
00579             }
00580             if (!inserted) {
00581                 paletteList.append(itP.currentKey());
00582             }
00583         }
00584     }
00585 
00586     cfg->setGroup("palettes");
00587 
00588     cfg->writeEntry("palettes", paletteList.join(","));
00589     bool palettesShown = m_hiddenWidgets.isEmpty();
00590     cfg->writeEntry("palettesshown", palettesShown);
00591 
00592     QDictIterator<QWidget> itW(*m_widgets);
00593     for (; itW.current(); ++itW) {
00594         cfg->setGroup("palettetab-" + itW.currentKey());
00595         QString pname = *m_currentMapping->find(itW.currentKey());
00596         KoPalette * p = m_palettes->find(pname);
00597         QWidget * w = itW.current();
00598         cfg->writeEntry("docker", pname);
00599 
00600         if(palettesShown)
00601             cfg->writeEntry("visible", !p->isHidden(w));
00602         else
00603             if(m_hiddenWidgets.contains(itW.currentKey()))
00604                cfg->writeEntry("visible", true);
00605             else
00606                 cfg->writeEntry("visible", false);
00607     }
00608 }
00609 
00610 void KoPaletteManager::setFixedWidth(int w)
00611 {
00612     m_fixedWidth = w;
00613     m_setFixedWidth = true;
00614 }
00615 
00616 #include "kopalettemanager.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys