kopalettemanager.cpp
1/*
2 * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org>
3 *
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2, as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc.,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 */
17
18#include <tqapplication.h>
19#include <tqdockarea.h>
20#include <tqdockwindow.h>
21#include <tqdict.h>
22#include <tqwidget.h>
23#include <tqobject.h>
24#include <tqevent.h>
25
26#include <tdeparts/event.h>
27#include <tdeapplication.h>
28#include <tdepopupmenu.h>
29#include <tdeaction.h>
30#include <tdeactionclasses.h>
31#include <kdebug.h>
32#include <tdelocale.h>
33#include <tdeglobal.h>
34
35#include <KoView.h>
36#include <KoMainWindow.h>
37
38#include <kopalette.h>
39#include <kotabpalette.h>
40#include <kotoolboxpalette.h>
41
42#include <kopalettemanager.h>
43
44
45KoPaletteManager::KoPaletteManager(KoView * view, TDEActionCollection *ac, const char * name)
46 : TQObject(view, name)
47{
48
49 m_view = view;
50 m_view->installEventFilter(this);
51 m_actionCollection = ac;
52
53 m_actions = new TQDict<TDEToggleAction>();
54 m_widgets = new TQDict<TQWidget>();
55 m_palettes = new TQDict<KoPalette>();
56 m_palettes->setAutoDelete(true);
57 m_defaultMapping = new TQMap<TQString, TQString>();
58 m_currentMapping = new TQMap<TQString, TQString>();
59 m_fixedWidth = 0;
60 m_setFixedWidth = false;
61
62 m_widgetNames = new TQStringList();
63
64 m_mapper = new TQSignalMapper(this);
65 connect(m_mapper, TQ_SIGNAL(mapped(int)), this, TQ_SLOT(slotTogglePalette(int)));
66 m_viewActionMenu = new TDEActionMenu(i18n("Palettes"), m_actionCollection, "view_palette_action_menu");
67
68 TDEConfig * cfg = TDEGlobal::config();
69 cfg->setGroup("palettes");
70
71 bool palettesShown = cfg->readBoolEntry("palettesshown", true);
72 TDEToggleAction * m_toggleShowHidePalettes;
73
74 if ( palettesShown) {
75 m_toggleShowHidePalettes = new TDEToggleAction(i18n("Hide All Palette Windows"),
76 "CTRL+SHIFT+H", this,
77 TQ_SLOT(slotToggleAllPalettes()),
78 m_actionCollection, "toggleAllPaletteWindows");
79
80 m_toggleShowHidePalettes->setCheckedState(i18n("Show Palette Windows Again"));
81 }
82 else {
83 m_toggleShowHidePalettes = new TDEToggleAction(i18n("Show Palette Windows Again"),
84 "CTRL+SHIFT+H", this,
85 TQ_SLOT(slotToggleAllPalettes()),
86 m_actionCollection, "toggleAllPaletteWindows");
87
88 m_toggleShowHidePalettes->setCheckedState(i18n("Hide All Palette Windows"));
89 }
90 m_viewActionMenu->insert(m_toggleShowHidePalettes);
91
92 // Recreate the palettes in the saved order
93 TQStringList paletteList = TQStringList::split(",", cfg->readEntry("palettes"));
94 TQStringList::iterator it;
95 for (it = paletteList.begin(); it != paletteList.end(); ++it) {
96 if (cfg->hasGroup("palette-" + (*it))) {
97
98 cfg->setGroup("palette-" + (*it));
99
100 enumKoPaletteStyle style = (enumKoPaletteStyle)cfg->readNumEntry("style", 0);
101 TQString caption = cfg->readEntry("caption", "");
102
103 createPalette((*it), caption, style);
104 }
105 }
106
107/*
108 TDEAction * a = new TDEAction(i18n("Restore Palettes"),
109 0, this,
110 TQ_SLOT(slotReset()),
111 this, "restorePalettes");
112 m_viewActionMenu->insert(a);
113*/
114 m_viewActionMenu->popupMenu()->insertSeparator();
115}
116
117
118KoPaletteManager::~KoPaletteManager()
119{
120 save();
121
122 delete m_viewActionMenu;
123 delete m_widgetNames;
124 delete m_widgets;
125 delete m_palettes;
126 delete m_actions;
127 delete m_mapper;
128 delete m_defaultMapping;
129 delete m_currentMapping;
130}
131
132void KoPaletteManager::addWidget(TQWidget * widget,
133 const TQString & name,
134 const TQString & paletteName,
135 int position,
136 enumKoPaletteStyle style,
137 bool shown)
138{
139
140 if (!widget) return;
141
142 TQString pname = paletteName;
143
144 TQWidget * w = m_widgets->find(name);
145 if (w != 0 )
146 {
147 removeWidget(name);
148 }
149
150 bool visible = true;
151
152 TDEConfig * cfg = TDEGlobal::config();
153 if (cfg->hasGroup("palettetab-" + name)) {
154 cfg->setGroup("palettetab-" + name);
155
156 pname = cfg->readEntry("docker");
157 visible = cfg->readBoolEntry("visible");
158 }
159
160 KoPalette * palette = m_palettes->find(pname);
161
162 if (palette == 0) {
163 palette = createPalette(pname, widget->caption(), style);
164 m_defaultPaletteOrder.append(pname+ "," + TQString::number(style));
165 }
166
167 TDEToggleAction * a;
168 a = new TDEToggleAction(i18n("Show %1").arg(widget->caption()), 0, m_mapper, TQ_SLOT(map()), m_actionCollection);
169 a->setCheckedState(i18n("Hide %1").arg(widget->caption()));
170
171 m_mapper->setMapping(a, m_widgetNames->count()); // This is the position at which we'll insert the action
172 m_actions->insert( name, a );
173 m_viewActionMenu->insert(a);
174
175 palette->plug(widget, name, position);
176
177 m_widgets->insert(name, widget);
178
179 // Default mappings ready for restoring
180 m_defaultMapping->insert(name, pname);
181 m_defaultWidgetOrder.append(name);
182
183 // Find out the hidden state
184 if(m_widgetNames->contains(name))
185 {
186
187 // The widget has already been added (and removed) during this session
188 if(m_hiddenWidgets.contains(name))
189 palette->hidePage( widget );
190 else
191 {
192 a->setChecked(true);
193 palette->showPage( widget );
194 }
195 }
196 else
197 {
198 cfg->setGroup("palettes");
199 if( cfg->readBoolEntry("palettesshown", shown))
200 {
201 if (visible)
202 {
203 a->setChecked(true);
204 palette->showPage( widget );
205 }
206 else
207 palette->hidePage( widget );
208 }
209 else
210 {
211 if (visible)
212 m_hiddenWidgets.push(name);
213 palette->hidePage( widget );
214 }
215 }
216
217 // Fill the current mappings
218 m_widgetNames->append(name);
219 m_currentMapping->insert(name, pname);
220}
221
222
224{
225 // Clear all old palettes
226 m_palettes->setAutoDelete( true );
227 m_palettes->clear();
228
229 m_widgetNames->clear();
230
231 // Recreate the palettewindows in the saved order
232 TQStringList::iterator it;
233 for (it = m_defaultPaletteOrder.begin(); it != m_defaultPaletteOrder.end(); ++it) {
234 TQString s = *it;
235 TQString pname = s.section( ",", 0, 0 );;
236 enumKoPaletteStyle style = (enumKoPaletteStyle)s.section(",", 1,1).toInt();
237 createPalette(pname, "", style);
238 }
239
240 // Place all existing (that we didn't throw away!) tabs in the right palette and in the right order
241 for (it = m_defaultWidgetOrder.begin(); it != m_defaultWidgetOrder.end(); ++it) {
242
243 TQString widgetName = *it;
244 TQWidget * w = m_widgets->find(widgetName);
245
246 if (!w) {
247 continue;
248 }
249 TQString paletteName = *m_defaultMapping->find(widgetName);
250 KoPalette * p = m_palettes->find(paletteName);
251
252 if (p == 0) {
253 // Funny -- we should have a consistent set of palettes without holes!
254 createPalette(paletteName, "", PALETTE_DOCKER);
255 }
256
257 p->plug(w, widgetName, -1); // XXX: This is not good: we should add it in the same place as originally placed
258 m_widgetNames->append(widgetName);
259 m_currentMapping->insert(widgetName, paletteName);
260 }
261}
262
264{
265 TQDictIterator<KoPalette> it(*m_palettes);
266 for (; it.current(); ++it) {
267 it.current()->resetFont();
268 }
269
270}
271
272TQWidget * KoPaletteManager::widget(const TQString & name)
273{
274 return m_widgets->find(name);
275}
276
277void KoPaletteManager::showWidget(const TQString & name)
278{
279 TQWidget * w = m_widgets->find(name);
280 if (!w) return;
281
282 TQString pname = *m_currentMapping->find(name);
283 if (pname.isNull()) return;
284
285 KoPalette * p = m_palettes->find(pname);
286 p->showPage(w);
287
288 TDEToggleAction * a = m_actions->find(name);
289 a->setChecked(true);
290}
291
292void KoPaletteManager::hideWidget(const TQString & name)
293{
294 TQWidget * w = m_widgets->find(name);
295 if (!w) return;
296
297 TQString pname = *m_currentMapping->find(name);
298 if (pname.isNull()) return;
299
300 KoPalette * p = m_palettes->find(pname);
301 p->hidePage(w);
302
303 TDEToggleAction * a = m_actions->find(name);
304 a->setChecked(false);
305}
306
307void KoPaletteManager::removeWidget(const TQString & name)
308{
309 TQString palette = *(m_currentMapping->find(name));
310 if (palette.isNull()) return;
311
312 TQWidget * w = m_widgets->find(name);
313 if (!w) return;
314
315 KoPalette * p = m_palettes->find(palette);
316 if (!p) return;
317
318 p->showPage(w);
319 p->unplug(w);
320 m_widgets->remove(name);
321 m_currentMapping->remove(name);
322
323 TDEAction * a = m_actions->take(name);
324 m_viewActionMenu->remove(a);
325 m_actionCollection->remove(a);
326}
327
328KoPalette * KoPaletteManager::createPalette(const TQString & name, const TQString & caption, enumKoPaletteStyle style)
329{
330 Q_ASSERT(m_view);
331 KoPalette * palette = 0;
332
333
334 palette = m_palettes->find(name);
335 if (palette) return palette;
336
337
338 switch (style) {
339 case (PALETTE_DOCKER):
340 palette = new KoTabPalette(m_view, name.latin1());
341 break;
342 case (PALETTE_TOOLBOX):
343 palette = new KoToolBoxPalette(m_view, name.latin1());
344 break;
345 default:
346 // This is a custom palette that we cannot create
347 return 0;
348 };
349
350 if(!palette) return 0;
351
352 if (m_setFixedWidth)
353 palette->setFixedWidth(m_fixedWidth);
354
355 palette->setCaption(caption);
356 m_palettes->insert(name, palette);
357 placePalette(name);
358
359 return palette;
360}
361
362void KoPaletteManager::placePalette(const TQString & name, TQt::Dock location)
363{
364 Q_ASSERT(!name.isNull());
365 KoPalette * palette = m_palettes->find(name);
366
367 if (!palette) return;
368
369 //XXX: Check whether this name occurs in the config list, retrieve the location, set the location
370 TDEConfig * cfg = TDEGlobal::config();
371
372 if (cfg->hasGroup("palette-" + name)) {
373 cfg->setGroup("palette-" + name);
374 TQString dockarea = cfg->readEntry("dockarea", "right");
375 TQString caption = cfg->readEntry("caption", "");
376 int height = cfg->readNumEntry("height", 120);
377 int place = cfg->readNumEntry("place", 0);
378 int width = cfg->readNumEntry("width", 200);
379 int x = cfg->readNumEntry("x", 0);
380 int y = cfg->readNumEntry("y", 0);
381 int offset = cfg->readNumEntry("offset", 0);
382 palette->setGeometry(x, y, width, height);
383 palette->setOffset(offset);
384 if (dockarea == "left" && place == 0) {
385 location = TQt::DockLeft;
386 }
387 else if (dockarea == "right" && place == 0) {
388 location = TQt::DockRight;
389 }
390 else {
391 location = DockTornOff;
392 }
393 }
394
395 cfg->setGroup("");
396 m_dockability = (enumKoDockability) cfg->readNumEntry("palettesdockability");
397
398 // Top and bottom will never accept docks
399 m_view->mainWindow()->topDock()->setAcceptDockWindow(palette, false);
400 m_view->mainWindow()->bottomDock()->setAcceptDockWindow(palette, false);
401
402 // Left and right may accept docks. The height of the screen is important
403 int h = tqApp->desktop()->height();
404 switch (m_dockability) {
405 case (DOCK_ENABLED):
406 m_view->mainWindow()->leftDock()->setAcceptDockWindow(palette, true);
407 m_view->mainWindow()->rightDock()->setAcceptDockWindow(palette, true);
408 m_view->mainWindow()->addDockWindow(palette, location);
409 break;
410 case (DOCK_DISABLED):
411 m_view->mainWindow()->leftDock()->setAcceptDockWindow(palette, false);
412 m_view->mainWindow()->rightDock()->setAcceptDockWindow(palette, false);
413 m_view->mainWindow()->addDockWindow(palette, TQt::DockTornOff);
414 break;
415 case (DOCK_SMART):
416 if (h > 768) {
417 m_view->mainWindow()->leftDock()->setAcceptDockWindow(palette, true);
418 m_view->mainWindow()->rightDock()->setAcceptDockWindow(palette, true);
419 m_view->mainWindow()->addDockWindow(palette, location);
420 }
421 else {
422 m_view->mainWindow()->leftDock()->setAcceptDockWindow(palette, false);
423 m_view->mainWindow()->rightDock()->setAcceptDockWindow(palette, false);
424 m_view->mainWindow()->addDockWindow(palette, TQt::DockTornOff);
425 }
426 break;
427 };
428 m_view->mainWindow()->lineUpDockWindows();
429}
430
431void KoPaletteManager::addPalette(KoPalette * palette, const TQString & name, TQt::Dock location)
432{
433 Q_ASSERT(palette);
434 Q_ASSERT(!name.isNull());
435
436 m_palettes->insert(name, palette);
437 placePalette(name, location);
438}
439
440void KoPaletteManager::slotTogglePalette(int paletteIndex)
441{
442 // Toggle the right palette
443 TQString name = *m_widgetNames->at(paletteIndex);
444 TQWidget * w = m_widgets->find(name);
445 TQString pname = *m_currentMapping->find(name);
446 KoPalette * p = m_palettes->find(pname);
447 p->togglePageHidden( w );
448
449 m_hiddenWidgets.clear();
450}
451
452void KoPaletteManager::slotToggleAllPalettes()
453{
454 if( ! m_hiddenWidgets.isEmpty())
455 {
456 // Restore previous visibility state
457 while(!m_hiddenWidgets.isEmpty())
458 {
459 TQString name = m_hiddenWidgets.pop();
460 TQWidget *w = m_widgets->find(name);
461 TDEToggleAction * a = m_actions->find(name);
462 a->setChecked(true);
463
464 TQString pname = *m_currentMapping->find(name);
465 KoPalette * p = m_palettes->find(pname);
466 p->showPage(w);
467 }
468 }
469 else
470 {
471 // Save hidden state and hide all palettes
472 m_hiddenWidgets.clear();
473 TQDictIterator<TQWidget> it(*m_widgets);
474 for (; it.current(); ++it)
475 {
476 TDEToggleAction * a = m_actions->find(it.currentKey());
477 if(a->isChecked())
478 {
479 a->setChecked(false);
480 m_hiddenWidgets.push(it.currentKey());
481
482 TQString pname = *m_currentMapping->find(it.currentKey());
483 KoPalette * p = m_palettes->find(pname);
484 p->hidePage(it.current());
485 }
486 }
487 }
488}
489
490void KoPaletteManager::showAllPalettes(bool shown)
491{
492 TQDictIterator<KoPalette> it(*m_palettes);
493 for (; it.current(); ++it) {
494 it.current()->makeVisible(shown);
495 }
496}
497
498bool KoPaletteManager::eventFilter( TQObject *o, TQEvent *e )
499{
500 if (o != m_view) return false;
501
502 if(e && e->type() == (TQEvent::User + 42)) {
503 KParts::PartActivateEvent * pae = dynamic_cast<KParts::PartActivateEvent *>(e);
504 if(pae && pae->widget() && pae->widget() == m_view) {
505 if (pae->activated()) {
506 showAllPalettes( true );
507 }
508 else {
509 showAllPalettes( false );
510 }
511 }
512 }
513 return false;
514}
515
516
517
518void KoPaletteManager::save()
519{
520 // XXX: Save to the configuration
521 // We save:
522 // * which tab at which place in which palette
523 // * which tab is hidden
524 // * whether a palette is floating or docked
525 // * dock location of a docked palette
526 // * float location of a floated palette
527 // * order in which the palettes are docked.
528
529 if (!m_view) return;
530 if (!m_view->mainWindow()) return;
531
532 TDEConfig * cfg = TDEGlobal::config();
533 Q_ASSERT(cfg);
534 cfg->setGroup("");
535
536 TQString widgets;
537
538 // Save the list of palettes
539 TQDictIterator<KoPalette> itP(*m_palettes);
540
541 TQStringList paletteList;
542
543 for (; itP.current(); ++itP) {
544
545 KoPalette * p = itP.current();
546
547 cfg->setGroup("palette-" + itP.currentKey());
548
549 if ( p->area() == m_view->mainWindow()->leftDock() ) {
550 cfg->writeEntry("dockarea", "left");
551 }
552 else {
553 cfg->writeEntry("dockarea", "right");
554 }
555 cfg->writeEntry("place", p->place());
556 cfg->writeEntry("x", p->x());
557 cfg->writeEntry("y", p->y());
558 cfg->writeEntry("height", p->height());
559 cfg->writeEntry("width", p->width());
560 cfg->writeEntry("palettestyle", p->style());
561 cfg->writeEntry("caption", p->caption());
562 cfg->writeEntry("offset", p->offset());
563
564 // XXX: I dare say that it is immediately visible that I never have had
565 // any formal training in algorithms. BSAR.
566 if (paletteList.isEmpty()) {
567 paletteList.append(itP.currentKey());
568 }
569 else {
570 TQStringList::iterator it;
571 bool inserted = false;
572 for (it = paletteList.begin(); it != paletteList.end(); ++it) {
573 KoPalette * p2 = m_palettes->find((*it));
574 if (p2->y() > p->y()) {
575 paletteList.insert(it, itP.currentKey());
576 inserted = true;
577 break;
578 }
579 }
580 if (!inserted) {
581 paletteList.append(itP.currentKey());
582 }
583 }
584 }
585
586 cfg->setGroup("palettes");
587
588 cfg->writeEntry("palettes", paletteList.join(","));
589 bool palettesShown = m_hiddenWidgets.isEmpty();
590 cfg->writeEntry("palettesshown", palettesShown);
591
592 TQDictIterator<TQWidget> itW(*m_widgets);
593 for (; itW.current(); ++itW) {
594 cfg->setGroup("palettetab-" + itW.currentKey());
595 TQString pname = *m_currentMapping->find(itW.currentKey());
596 KoPalette * p = m_palettes->find(pname);
597 TQWidget * w = itW.current();
598 cfg->writeEntry("docker", pname);
599
600 if(palettesShown)
601 cfg->writeEntry("visible", !p->isHidden(w));
602 else
603 if(m_hiddenWidgets.contains(itW.currentKey()))
604 cfg->writeEntry("visible", true);
605 else
606 cfg->writeEntry("visible", false);
607 }
608}
609
611{
612 m_fixedWidth = w;
613 m_setFixedWidth = true;
614}
615
616#include "kopalettemanager.moc"
virtual KoPalette * createPalette(const TQString &name, const TQString &caption, enumKoPaletteStyle style=PALETTE_DOCKER)
Create an empty palette in the given style.
virtual void addPalette(KoPalette *palette, const TQString &name, Dock location=DockRight)
Add a palette; this can be used to add palettes other than those in the two default styles.
virtual TQWidget * widget(const TQString &name)
Get a certain widget by name.
virtual void slotReset()
Restores the palette configuration to the default layout, i.e, the layout preferred by each docker.
virtual void addWidget(TQWidget *widget, const TQString &name, const TQString &paletteName, int position=-1, enumKoPaletteStyle style=PALETTE_DOCKER, bool shown=true)
Add a new tab with the given name an description to the specified palette.
virtual void slotResetFont()
Reset the font for all palettes.
virtual void removeWidget(const TQString &name)
Remove the widget with the specified name from whichever palette it is currently in.
virtual void hideWidget(const TQString &name)
hide the specified widget
virtual void showWidget(const TQString &name)
Show a the specified palette wherever it currently is.
virtual void placePalette(const TQString &name, Dock location=DockRight)
Move the specified palette to the specified location.
virtual void setFixedWidth(int w)
Sets all palettes to the specified fixed width.
A floating palette that allows the adding and removing of widgets to its organzing principle.
Definition kopalette.h:39
This is a palette with a tabwidget.
A palette based on a toolbox widget.
This class is used to display a KoDocument.
Definition KoView.h:58
TDEMainWindow * mainWindow() const
Definition KoView.cpp:677
void remove(TDEAction *action)
bool isChecked() const
void setCheckedState(const KGuiItem &checkedItem)
virtual void setChecked(bool)
const char * name(StdAction id)