1 /* This file is part of the KDE libraries
2    Copyright (C) 2005 Christoph Cullmann <cullmann@kde.org>
3    Copyright (C) 2002, 2003 Joseph Wenninger <jowenn@kde.org>
4 
5    GUIClient partly based on ktoolbarhandler.cpp: Copyright (C) 2002 Simon Hausmann <hausmann@kde.org>
6 
7    This library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Library General Public
9    License as published by the Free Software Foundation; either
10    version 2 of the License, or (at your option) any later version.
11 
12    This library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Library General Public License for more details.
16 
17    You should have received a copy of the GNU Library General Public License
18    along with this library; see the file COPYING.LIB.  If not, write to
19    the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
20    Boston, MA 02110-1301, USA.
21 */
22 
23 #include "katemdi.h"
24 
25 
26 #include <KLocalizedString>
27 #include <KSharedConfig>
28 //#include <kpopupmenu.h>
29 #include <KActionCollection>
30 #include <KXMLGUIFactory>
31 #include <KConfigGroup>
32 #include <KWindowConfig>
33 
34 // #include <q3intdict.h>
35 #include <QContextMenuEvent>
36 #include <QVBoxLayout>
37 #include <QHBoxLayout>
38 #include <QDebug>
39 #include <QEvent>
40 #include <QMenu>
41 #include <QIcon>
42 
43 
44 typedef QList<int> IntList;
45 
getSpaces(int count)46 static QString getSpaces(int count) {
47     QString s;
48     for (int i = 0; i < count; ++i ) {
49         s += "| ";
50     }
51     return s;
52 }
53 
printObjChildren(int startLevel,const QObject * obj)54 static void printObjChildren(int startLevel, const QObject *obj) {
55     QObjectList chl = obj->children();
56     QMutableListIterator<QObject*> itCh( chl );
57     while (itCh.hasNext()) {
58         itCh.next();
59         qDebug() << getSpaces(startLevel) << itCh.value();
60         printObjChildren(startLevel + 1, itCh.value());
61     }
62 }
63 
64 namespace KateMDI {
65 
66 //BEGIN SPLITTER
67 
Splitter(Qt::Orientation o,QWidget * parent,const char * name)68 Splitter::Splitter(Qt::Orientation o, QWidget* parent, const char* name)
69   : QSplitter(o, parent /*, name*/)
70 {
71     setObjectName(name);
72 }
73 
~Splitter()74 Splitter::~Splitter()
75 {
76 }
77 /*
78 bool Splitter::isLastChild(QWidget* w) const
79 {
80   return indexOf(w) == (count() - 1);
81   //return ( idAfter( w ) == 0 );
82 }
83 
84 int Splitter::idAfter ( QWidget * w ) const
85 {
86   //return QSplitter::idAfter (w);
87     return indexOf(w);
88 }*/
89 
90 //END SPLITTER
91 
92 
93 //BEGIN GUICLIENT
94 
GUIClient(MainWindow * mw)95 GUIClient::GUIClient ( MainWindow *mw )
96  : QObject ( mw )
97  , KXMLGUIClient ( mw )
98  , m_mw (mw)
99 {
100   connect( m_mw->guiFactory(), SIGNAL( clientAdded( KXMLGUIClient * ) ),
101            this, SLOT( clientAdded( KXMLGUIClient * ) ) );
102 
103   //if (actionCollection()->kaccel()==0)  // TODO what does this do?
104   {
105     actionCollection()->associateWidget(m_mw);
106   }
107 
108 
109   // read shortcuts
110   //actionCollection()->readShortcutSettings( "Shortcuts", kapp->config() );
111   KConfigGroup grShortcuts = KSharedConfig::openConfig()->group("Shortcuts");
112   actionCollection()->readSettings(&grShortcuts);
113 }
114 
~GUIClient()115 GUIClient::~GUIClient()
116 {
117 }
118 
registerToolView(ToolView * tv)119 void GUIClient::registerToolView (ToolView *tv)
120 {
121   QString aname = QString("kate_mdi_toolview_") + tv->id;
122 
123   // try to read the action shortcut
124 //   KShortcut sc;
125 
126 //   KConfig *cfg = kapp->config();
127 //   QString _grp = cfg->group();
128 //   cfg->setGroup("Shortcuts");
129 //   sc = KShortcut( cfg->readEntry( aname, "" ) );
130 //   cfg->setGroup( _grp );
131 
132   KConfigGroup grSh = KSharedConfig::openConfig()->group("Shortcuts");
133 //   sc = KShortcut( grSh.readEntry(aname, "") );
134 }
135 
clientAdded(KXMLGUIClient * client)136 void GUIClient::clientAdded( KXMLGUIClient *client )
137 {
138   if ( client == this )
139     updateActions();
140 }
141 
updateActions()142 void GUIClient::updateActions()
143 {
144   if ( !factory() )
145     return;
146 }
147 
148 //END GUICLIENT
149 
150 
151 //BEGIN TOOLVIEW
152 
ToolView(MainWindow * mainwin,Sidebar * sidebar,QWidget * parent)153 ToolView::ToolView (MainWindow *mainwin, Sidebar *sidebar, QWidget *parent)
154  : QWidget (parent)
155  , m_mainWin (mainwin)
156  , m_sidebar (sidebar)
157  , m_visible (false)
158  , persistent (false)
159 {
160     QVBoxLayout *vboxLayout = new QVBoxLayout;
161     setLayout(vboxLayout);
162 }
163 
~ToolView()164 ToolView::~ToolView ()
165 {
166   m_mainWin->toolViewDeleted (this);
167 }
168 
setVisibleToolView(bool vis)169 void ToolView::setVisibleToolView (bool vis)
170 {
171   if (m_visible == vis)
172     return;
173 
174   m_visible = vis;
175   emit visibleChanged (m_visible);
176 }
177 
visible() const178 bool ToolView::visible () const
179 {
180   return m_visible;
181 }
182 
childEvent(QChildEvent * ev)183 void ToolView::childEvent ( QChildEvent *ev )
184 {
185   // set the widget to be focus proxy if possible
186     QWidget *childWidget =  qobject_cast< QWidget* >( ev->child() );
187   if ((ev->type() == QEvent::ChildAdded) && ev->child() && childWidget) {
188     //setFocusProxy ((QWidget *)(ev->child()->qt_cast("QWidget")));
189     setFocusProxy( childWidget );
190   }
191 
192   QWidget::childEvent (ev);
193 }
194 
195 //END TOOLVIEW
196 
197 
198 //BEGIN SIDEBAR
199 
Sidebar(KMultiTabBar::KMultiTabBarPosition pos,MainWindow * mainwin,QWidget * parent)200 Sidebar::Sidebar (KMultiTabBar::KMultiTabBarPosition pos, MainWindow *mainwin, QWidget *parent)
201   : KMultiTabBar (
202       //(pos == KMultiTabBar::Top || pos == KMultiTabBar::Bottom) ? KMultiTabBar::Horizontal : KMultiTabBar::Vertical, parent)
203       pos, parent)
204   , m_mainWin (mainwin)
205   , m_splitter (nullptr)
206   , m_ownSplit (nullptr)
207   , m_lastSize (0)
208 {
209   setObjectName(  (QString("Sidebar-%1").arg(pos)).toLatin1().data() );
210   setSidebarPosition( pos );
211   setFocusPolicy( Qt::NoFocus );
212   hide ();
213 }
214 
~Sidebar()215 Sidebar::~Sidebar ()
216 {
217 }
218 
setSidebarPosition(KMultiTabBarPosition pos)219 void Sidebar::setSidebarPosition( KMultiTabBarPosition pos )
220 {
221 	m_pos = pos;
222 	setPosition(pos);
223 }
224 
setSidebarStyle(KMultiTabBarStyle style)225 void Sidebar::setSidebarStyle( KMultiTabBarStyle style )
226 {
227 	m_sidebarTabStyle = style;
228 	setStyle(style);
229 }
230 
setSplitter(Splitter * sp)231 void Sidebar::setSplitter (Splitter *sp)
232 {
233   m_splitter = sp;
234   Qt::Orientation splitOrient = (sidebarPosition() == KMultiTabBar::Top || sidebarPosition() == KMultiTabBar::Bottom) ? Qt::Horizontal : Qt::Vertical;
235   m_ownSplit = new Splitter (splitOrient, m_splitter, "own-Split");
236   m_ownSplit->setChildrenCollapsible( false );
237   //m_splitter->setResizeMode( m_ownSplit, QSplitter::KeepSize ); // 2018.11.22
238   m_splitter->setStretchFactor( m_splitter->indexOf(m_ownSplit), 0);
239   m_ownSplit->hide ();
240 }
241 
addWidget(const QPixmap & icon,const QString & text,ToolView * widget)242 ToolView *Sidebar::addWidget (const QPixmap &icon, const QString &text, ToolView *widget)
243 {
244   static int id = 0;
245 
246   if (widget)
247   {
248     if (widget->sidebar() == this)
249       return widget;
250 
251     widget->sidebar()->removeWidget (widget);
252   }
253 
254   int newId = ++id;
255 
256   appendTab (icon, newId, text);
257 
258   if (!widget)
259   {
260     widget = new ToolView (m_mainWin, this, m_ownSplit);
261     widget->hide ();
262     widget->icon = icon;
263     widget->text = text;
264   }
265   else
266   {
267     widget->hide ();
268     //widget->reparent (m_ownSplit, 0, QPoint()); // 2018.11.22
269     widget->setParent(m_ownSplit, nullptr);
270     QPoint p;
271     widget->setGeometry(p.x(),p.y(),width(),height());
272     widget->m_sidebar = this;
273   }
274 
275   // save it's pos ;)
276   widget->persistent = false;
277 
278   m_idToWidget.insert (newId, widget);
279   m_widgetToId.insert (widget, newId);
280   m_toolviews.push_back (widget);
281 
282   show ();
283 
284   connect(tab(newId),SIGNAL(clicked(int)),this,SLOT(tabClicked(int)));
285   tab(newId)->installEventFilter(this);
286 
287   return widget;
288 }
289 
updateMinimumSize()290 void Sidebar::updateMinimumSize()
291 {
292 // 	qDebug() << "layout()->margin()="<<layout()->margin()<<endl;
293 
294 	QSize minSize;
295 
296 	QList<ToolView*>::iterator end = m_toolviews.end();
297 	for ( QList<ToolView*>::iterator it = m_toolviews.begin(); it != end; ++it )
298 	{
299 		QSize s = (*it)->childrenRect().size();
300 		minSize = minSize.expandedTo( s );
301 // 		qDebug() << "s="<<s<<"(*it)->minimumSize()="<<(*it)->minimumSize()<<endl;
302 // 		qDebug() << "(*it)->layout()->margin()="<<(*it)->margin()<<endl;
303 	}
304 
305 	minSize.setWidth( minSize.width() - 30 );
306 	minSize.setHeight( minSize.height() - 30 );
307 
308 	for ( QList<ToolView*>::iterator it = m_toolviews.begin(); it != end; ++it )
309 	{
310 		(*it)->setMinimumSize( minSize );
311 	}
312 }
313 
removeWidget(ToolView * widget)314 bool Sidebar::removeWidget (ToolView *widget)
315 {
316   if (!m_widgetToId.contains(widget))
317     return false;
318 
319   removeTab(m_widgetToId[widget]);
320 
321   m_idToWidget.remove (m_widgetToId[widget]);
322   m_widgetToId.remove (widget);
323   m_toolviews.removeAll(widget);
324 
325   bool anyVis = false;
326   //Q3IntDictIterator<ToolView> it( m_idToWidget );
327 
328   for ( QMap<int, ToolView*>::iterator it = m_idToWidget.begin(); it != m_idToWidget.end(); ++it )
329   {
330     if (!anyVis)
331       anyVis =  it.value()->isVisible();
332   }
333 
334   if (m_idToWidget.isEmpty())
335   {
336     m_ownSplit->hide ();
337     hide ();
338   }
339   else if (!anyVis)
340     m_ownSplit->hide ();
341 
342   return true;
343 }
344 
showWidget(ToolView * widget)345 bool Sidebar::showWidget (ToolView *widget)
346 {
347   if (!m_widgetToId.contains(widget))
348     return false;
349 
350   // hide other non-persistent views
351   //Q3IntDictIterator<ToolView> it( m_idToWidget );
352   for ( QMap<int, ToolView*>::iterator it = m_idToWidget.begin(); it != m_idToWidget.end(); ++it )
353     if ((it.value() != widget) && !it.value()->persistent)
354     {
355       it.value()->hide();
356       setTab (it.key(), false);
357       it.value()->setVisibleToolView(false);
358     }
359 
360   setTab (m_widgetToId[widget], true);
361 
362   m_ownSplit->show ();
363   widget->show ();
364 
365   widget->setVisibleToolView (true);
366 
367   return true;
368 }
369 
hideWidget(ToolView * widget)370 bool Sidebar::hideWidget (ToolView *widget)
371 {
372   if (!m_widgetToId.contains(widget))
373     return false;
374 
375   bool anyVis = false;
376 
377    updateLastSize ();
378 
379   //for ( Q3IntDictIterator<ToolView> it( m_idToWidget ); it.current(); ++it )
380   for ( QMap<int, ToolView*>::iterator it = m_idToWidget.begin(); it != m_idToWidget.end(); ++it )
381   {
382     if (it.value() == widget)
383     {
384       it.value()->hide();
385       continue;
386     }
387 
388     if (!anyVis)
389       anyVis =  it.value()->isVisible();
390   }
391 
392   // lower tab
393   setTab (m_widgetToId[widget], false);
394 
395   if (!anyVis)
396     m_ownSplit->hide ();
397 
398   widget->setVisibleToolView (false);
399 
400   return true;
401 }
402 
tabClicked(int i)403 void Sidebar::tabClicked(int i)
404 {
405   ToolView *w = m_idToWidget[i];
406 
407   if (!w) {
408       qWarning() << Q_FUNC_INFO << " unexpected tab number " << i;
409     return;
410   }
411 
412   if (isTabRaised(i))
413   {
414     showWidget (w);
415     w->setFocus ();
416   }
417   else
418   {
419     hideWidget (w);
420     m_mainWin->centralWidget()->setFocus ();
421   }
422 }
423 
eventFilter(QObject * obj,QEvent * ev)424 bool Sidebar::eventFilter(QObject *obj, QEvent *ev)
425 {
426   if (ev->type()==QEvent::ContextMenu)
427   {
428     QContextMenuEvent *e = (QContextMenuEvent *) ev;
429     KMultiTabBarTab *bt = dynamic_cast<KMultiTabBarTab*>(obj);
430     if (bt)
431     {
432       qDebug()<<"Request for popup"<<endl;
433 
434       m_popupButton = bt->id();
435 
436       ToolView *w = m_idToWidget[m_popupButton];
437 
438       if (w)
439       {
440         QMenu *p = new QMenu (this);
441 
442         p->addSection(QIcon::fromTheme("view_remove"), i18n("Behavior"));
443 
444         //p->insertItem(w->persistent ? SmallIcon("view-restore") : SmallIcon("view-fullscreen"), w->persistent ? i18n("Make Non-Persistent") : i18n("Make Persistent"), 10); // 2018.11.22
445         p->addAction(
446             w->persistent ? QIcon::fromTheme("view-restore") : QIcon::fromTheme("view-fullscreen"),
447             w->persistent ? i18n("Make Non-Persistent") : i18n("Make Persistent")
448         )->setData(10);
449 
450         p->addSection(QIcon::fromTheme("transform-move"), i18n("Move To"));
451 
452 		if (sidebarPosition() != 0)
453           //p->insertItem(SmallIcon("go-previous"), i18n("Left Sidebar"),0);  // 2018.11.22
454           p->addAction(QIcon::fromTheme("go-previous"), i18n("Left Sidebar"))->setData(0);
455 
456 		if (sidebarPosition() != 1)
457           //p->insertItem(SmallIcon("go-next"), i18n("Right Sidebar"),1); // 2018.11.22
458           p->addAction(QIcon::fromTheme("go-next"), i18n("Right Sidebar"))->setData(1);
459 
460 		if (sidebarPosition() != 2)
461           //p->insertItem(SmallIcon("go-up"), i18n("Top Sidebar"),2); // 2018.11.22
462           p->addAction(QIcon::fromTheme("go-up"), i18n("Top Sidebar"))->setData(2);
463 
464 		if (sidebarPosition() != 3) {
465           //p->insertItem(SmallIcon("go-down"), i18n("Bottom Sidebar"),3); // 2018.11.22
466           p->addAction(QIcon::fromTheme("go-down"), i18n("Bottom Sidebar"))->setData(3);
467         }
468         connect(p, SIGNAL(triggered(QAction*)),
469               this, SLOT(buttonPopupActivate(QAction*)));
470 
471         p->exec(e->globalPos());
472         delete p;
473 
474         return true;
475       }
476     }
477   }
478 
479   return false;
480 }
481 
buttonPopupActivate(QAction * action)482 void Sidebar::buttonPopupActivate (QAction* action)
483 {
484   int id = action->data().toInt();
485   ToolView *w = m_idToWidget[m_popupButton];
486 
487   if (!w)
488     return;
489 
490   // move ids
491   if (id < 4)
492   {
493     // move + show ;)
494     m_mainWin->moveToolView (w, (KMultiTabBar::KMultiTabBarPosition) id);
495     m_mainWin->showToolView (w);
496   }
497 
498   // toggle persistent
499   if (id == 10)
500     w->persistent = !w->persistent;
501 }
502 
updateLastSize()503 void Sidebar::updateLastSize ()
504 {
505    QList<int> s = m_splitter->sizes ();
506 
507   int i = 0;
508   if ((sidebarPosition() == KMultiTabBar::Right || sidebarPosition() == KMultiTabBar::Bottom))
509     i = 2;
510 
511   // little threshold
512   if (s[i] > 2)
513     m_lastSize = s[i];
514 }
515 
516 class TmpToolViewSorter
517 {
518   public:
519     ToolView *tv;
520     unsigned int pos;
521 };
522 
restoreSession(KConfigGroup * configGr)523 void Sidebar::restoreSession (KConfigGroup *configGr)
524 {
525   // get the last correct placed toolview
526   unsigned int firstWrong = 0;
527   for ( ; firstWrong < m_toolviews.size(); ++firstWrong )
528   {
529     ToolView *tv = m_toolviews[firstWrong];
530 
531     unsigned int pos = configGr->readEntry (QString ("Kate-MDI-ToolView-%1-Sidebar-Position").arg(tv->id), firstWrong);
532 
533     if (pos != firstWrong)
534       break;
535   }
536 
537   // we need to reshuffle, ahhh :(
538   if (firstWrong < m_toolviews.size())
539   {
540     // first: collect the items to reshuffle
541     QList<TmpToolViewSorter> toSort;
542     for (unsigned int i=firstWrong; i < m_toolviews.size(); ++i)
543     {
544       TmpToolViewSorter s;
545       s.tv = m_toolviews[i];
546       s.pos = configGr->readEntry (QString ("Kate-MDI-ToolView-%1-Sidebar-Position").arg(m_toolviews[i]->id), i);
547       toSort.push_back (s);
548     }
549 
550     // now: sort the stuff we need to reshuffle
551     for (unsigned int m=0; m < toSort.size(); ++m)
552       for (unsigned int n=m+1; n < toSort.size(); ++n)
553         if (toSort[n].pos < toSort[m].pos)
554         {
555           TmpToolViewSorter tmp = toSort[n];
556           toSort[n] = toSort[m];
557           toSort[m] = tmp;
558         }
559 
560     // then: remove this items from the button bar
561     // do this backwards, to minimize the relayout efforts
562     for (int i=m_toolviews.size()-1; i >= (int)firstWrong; --i)
563     {
564       removeTab (m_widgetToId[m_toolviews[i]]);
565     }
566 
567     // insert the reshuffled things in order :)
568     for (unsigned int i=0; i < toSort.size(); ++i)
569     {
570       ToolView *tv = toSort[i].tv;
571 
572       m_toolviews[firstWrong+i] = tv;
573 
574       // readd the button
575       int newId = m_widgetToId[tv];
576       appendTab (tv->icon, newId, tv->text);
577       connect(tab(newId),SIGNAL(clicked(int)),this,SLOT(tabClicked(int)));
578       tab(newId)->installEventFilter(this);
579 
580       // reshuffle in splitter
581       m_ownSplit->addWidget(tv);
582     }
583   }
584 
585   // update last size if needed
586   updateLastSize ();
587 
588   // restore the own splitter sizes
589   QList<int> s = configGr->readEntry (QString ("Kate-MDI-Sidebar-%1-Splitter").arg(sidebarPosition()), IntList());
590   m_ownSplit->setSizes (s);
591 
592   // show only correct toolviews, remember persistent values ;)
593   bool anyVis = false;
594   for ( unsigned int i=0; i < m_toolviews.size(); ++i )
595   {
596     ToolView *tv = m_toolviews[i];
597 
598     tv->persistent = configGr->readEntry (QString ("Kate-MDI-ToolView-%1-Persistent").arg(tv->id), false);
599     tv->setVisibleToolView (configGr->readEntry (QString ("Kate-MDI-ToolView-%1-Visible").arg(tv->id), false));
600 
601     if (!anyVis)
602       anyVis = tv->visible();
603 
604     setTab (m_widgetToId[tv],tv->visible());
605 
606     if (tv->visible())
607       tv->show();
608     else
609       tv->hide ();
610   }
611 
612   if (anyVis)
613     m_ownSplit->show();
614   else
615     m_ownSplit->hide();
616 }
617 
saveSession(KConfigGroup * config)618 void Sidebar::saveSession (KConfigGroup *config)
619 {
620   // store the own splitter sizes
621   QList<int> s = m_ownSplit->sizes();
622   config->writeEntry (QString ("Kate-MDI-Sidebar-%1-Splitter").arg(sidebarPosition()), s);
623 
624   // store the data about all toolviews in this sidebar ;)
625   for ( unsigned int i=0; i < m_toolviews.size(); ++i )
626   {
627     ToolView *tv = m_toolviews[i];
628 
629 	config->writeEntry (QString ("Kate-MDI-ToolView-%1-Position").arg(tv->id), (int)tv->sidebar()->sidebarPosition());
630     config->writeEntry (QString ("Kate-MDI-ToolView-%1-Sidebar-Position").arg(tv->id), i);
631     config->writeEntry (QString ("Kate-MDI-ToolView-%1-Visible").arg(tv->id), tv->visible());
632     config->writeEntry (QString ("Kate-MDI-ToolView-%1-Persistent").arg(tv->id), tv->persistent);
633   }
634 }
635 
636 //END SIDEBAR
637 
638 
639 //BEGIN MAIN WINDOW
640 
MainWindow(QWidget * parentWidget,const char * name)641 MainWindow::MainWindow (QWidget* parentWidget, const char* name)
642  : KParts::MainWindow(parentWidget)
643  , m_restoreConfig (nullptr)
644  , m_guiClient (new GUIClient (this))
645 {
646     setObjectName(name);
647   // init the internal widgets
648   QWidget *hb = new QWidget(this); // Q3HBox (this);
649   QHBoxLayout *hbl = new QHBoxLayout;
650   hb->setLayout(hbl);
651 
652   hb->setObjectName("MainWindow-central-HBox");
653   setCentralWidget(hb);
654 
655   m_sidebars[KMultiTabBar::Left] = new Sidebar (KMultiTabBar::Left, this, hb);
656   m_sidebars[KMultiTabBar::Left]->setObjectName("Main-Left-Sidebar");
657   hbl->addWidget( m_sidebars[KMultiTabBar::Left] );
658 
659   m_hSplitter = new Splitter (Qt::Horizontal, hb);
660   m_hSplitter->setObjectName("Main-Left-Splitter");
661   hbl->addWidget( m_hSplitter );
662 
663   m_sidebars[KMultiTabBar::Left]->setSplitter (m_hSplitter);
664 
665   //Q3VBox *vb = new Q3VBox (m_hSplitter);
666   QWidget *vb = new QWidget (m_hSplitter);
667   QVBoxLayout *vbl = new QVBoxLayout;
668   vb->setLayout(vbl);
669   vb->setObjectName("Main-Center-VBox");
670   m_hSplitter->setCollapsible(m_hSplitter->indexOf(vb), false);
671 
672   m_sidebars[KMultiTabBar::Top] = new Sidebar (KMultiTabBar::Top, this, vb);
673   m_sidebars[KMultiTabBar::Top]->setObjectName("Main-Top-Sidebar");
674   vbl->addWidget( m_sidebars[KMultiTabBar::Top] );
675 
676   m_vSplitter = new Splitter (Qt::Vertical, vb);
677   m_vSplitter->setObjectName("Main-Top-Splitter");
678   vbl->addWidget( m_vSplitter );
679 
680   m_sidebars[KMultiTabBar::Top]->setSplitter (m_vSplitter);
681 
682   m_centralWidget = new QWidget (m_vSplitter);
683   //m_centralWidget = new Q3VBox (m_vSplitter );
684   QVBoxLayout *vbCl = new QVBoxLayout;
685   m_centralWidget->setLayout( vbCl );
686   m_centralWidget->setObjectName("Main-Central-Vbox");
687   m_vSplitter->setCollapsible(m_vSplitter->indexOf(m_centralWidget), false);
688   //vbl->addLayout( vbCl ); // 2016.05.03 - apparently generates a warning about already having a parent
689 
690   m_sidebars[KMultiTabBar::Bottom] = new Sidebar (KMultiTabBar::Bottom, this, vb);
691   m_sidebars[KMultiTabBar::Bottom]->setObjectName("Main-Bottom-Sidebar");
692   m_sidebars[KMultiTabBar::Bottom]->setSplitter (m_vSplitter);
693   vbl->addWidget( m_sidebars[KMultiTabBar::Bottom] );
694 
695   m_sidebars[KMultiTabBar::Right] = new Sidebar (KMultiTabBar::Right, this, hb);
696   m_sidebars[KMultiTabBar::Right]->setObjectName("Main-Right-Sidebar");
697   m_sidebars[KMultiTabBar::Right]->setSplitter (m_hSplitter);
698   hbl->addWidget( m_sidebars[KMultiTabBar::Right] );
699 }
700 
~MainWindow()701 MainWindow::~MainWindow ()
702 {
703   // cu toolviews
704   while (!m_toolviews.isEmpty())
705     delete m_toolviews[0];
706 
707   // seems like we really should delete this by hand ;)
708   delete m_centralWidget;
709 
710   for (unsigned int i=0; i < 4; ++i)
711     delete m_sidebars[i];
712 }
713 
centralWidget() const714 QWidget *MainWindow::centralWidget () const
715 {
716   return m_centralWidget;
717 }
718 
createToolView(const QString & identifier,KMultiTabBar::KMultiTabBarPosition pos,const QPixmap & icon,const QString & text)719 ToolView *MainWindow::createToolView (const QString &identifier, KMultiTabBar::KMultiTabBarPosition pos, const QPixmap &icon, const QString &text)
720 {
721   if (m_idToWidget[identifier])
722     return nullptr;
723 
724   // try the restore config to figure out real pos
725   if (m_restoreConfig && m_restoreConfig->hasGroup (m_restoreGroup))
726   {
727     KConfigGroup grRest = m_restoreConfig->group (m_restoreGroup);
728     pos = (KMultiTabBar::KMultiTabBarPosition) grRest.readEntry (QString ("Kate-MDI-ToolView-%1-Position").arg(identifier), (int) pos);
729   }
730 
731   ToolView *v  = m_sidebars[pos]->addWidget (icon, text, nullptr);
732   v->id = identifier;
733 
734   m_idToWidget.insert (identifier, v);
735   m_toolviews.push_back (v);
736 
737   // register for menu stuff
738   m_guiClient->registerToolView (v);
739 
740   return v;
741 }
742 
toolView(const QString & identifier) const743 ToolView *MainWindow::toolView (const QString &identifier) const
744 {
745   return m_idToWidget[identifier];
746 }
747 
toolViewDeleted(ToolView * widget)748 void MainWindow::toolViewDeleted (ToolView *widget)
749 {
750   if (!widget)
751     return;
752 
753   if (widget->mainWindow() != this)
754     return;
755 
756   // unregister from menu stuff
757 
758   widget->sidebar()->removeWidget (widget);
759 
760   m_idToWidget.remove (widget->id);
761   m_toolviews.removeAll (widget);
762 }
763 
setToolViewStyle(KMultiTabBar::KMultiTabBarStyle style)764 void MainWindow::setToolViewStyle (KMultiTabBar::KMultiTabBarStyle style)
765 {
766 	m_sidebars[0]->setSidebarStyle(style);
767 	m_sidebars[1]->setSidebarStyle(style);
768 	m_sidebars[2]->setSidebarStyle(style);
769 	m_sidebars[3]->setSidebarStyle(style);
770 }
771 
toolViewStyle() const772 KMultiTabBar::KMultiTabBarStyle MainWindow::toolViewStyle () const
773 {
774   // all sidebars have the same style, so just take Top
775   return m_sidebars[KMultiTabBar::Top]->sidebarTabStyle();
776 }
777 
moveToolView(ToolView * widget,KMultiTabBar::KMultiTabBarPosition pos)778 bool MainWindow::moveToolView (ToolView *widget, KMultiTabBar::KMultiTabBarPosition pos)
779 {
780   if (!widget || widget->mainWindow() != this)
781     return false;
782 
783   // try the restore config to figure out real pos
784   if (m_restoreConfig && m_restoreConfig->hasGroup (m_restoreGroup))
785   {
786     KConfigGroup grRest = m_restoreConfig->group (m_restoreGroup);
787     pos = (KMultiTabBar::KMultiTabBarPosition) grRest.readEntry (QString ("Kate-MDI-ToolView-%1-Position").arg(widget->id), (int) pos);
788   }
789 
790   m_sidebars[pos]->addWidget (widget->icon, widget->text, widget);
791 
792   return true;
793 }
794 
showToolView(ToolView * widget)795 bool MainWindow::showToolView (ToolView *widget)
796 {
797   if (!widget || widget->mainWindow() != this)
798     return false;
799 
800   // skip this if happens during restoring, or we will just see flicker
801   if (m_restoreConfig && m_restoreConfig->hasGroup (m_restoreGroup))
802     return true;
803 
804   return widget->sidebar()->showWidget (widget);
805 }
806 
hideToolView(ToolView * widget)807 bool MainWindow::hideToolView (ToolView *widget)
808 {
809   if (!widget || widget->mainWindow() != this)
810     return false;
811 
812   // skip this if happens during restoring, or we will just see flicker
813   if (m_restoreConfig && m_restoreConfig->hasGroup (m_restoreGroup))
814     return true;
815 
816   return widget->sidebar()->hideWidget (widget);
817 }
818 
startRestore(KConfig * config,const QString & group)819 void MainWindow::startRestore (KConfig *config, const QString &group)
820 {
821   // first save this stuff
822   m_restoreConfig = config;
823   m_restoreGroup = group;
824 
825   if (!m_restoreConfig || !m_restoreConfig->hasGroup (m_restoreGroup))
826   {
827 	  //BEGIN Added stuff specifically for ktechlab
828 	  QList<int> hs;
829 	  hs << 220 << 100 << 230;
830 	  QList<int> vs;
831 	  vs << 0 << 100 << 150;
832 
833 	  m_sidebars[0]->setLastSize (hs[0]);
834 	  m_sidebars[1]->setLastSize (hs[2]);
835 	  m_sidebars[2]->setLastSize (vs[0]);
836 	  m_sidebars[3]->setLastSize (vs[2]);
837 
838 	  m_hSplitter->setSizes(hs);
839 	  m_vSplitter->setSizes(vs);
840 	  //END Added stuff specifically for ktechlab
841 
842     return;
843   }
844 
845   // apply size once, to get sizes ready ;)
846   KConfigGroup grRestWnd = m_restoreConfig->group (m_restoreGroup);
847   KWindowConfig::restoreWindowSize(windowHandle(), grRestWnd);
848 
849   //m_restoreConfig->group (m_restoreGroup);
850 
851   // get main splitter sizes ;)
852   QList<int> hs = grRestWnd.readEntry ("Kate-MDI-H-Splitter", IntList());
853   QList<int> vs = grRestWnd.readEntry ("Kate-MDI-V-Splitter", IntList());
854 
855   m_sidebars[0]->setLastSize (hs[0]);
856   m_sidebars[1]->setLastSize (hs[2]);
857   m_sidebars[2]->setLastSize (vs[0]);
858   m_sidebars[3]->setLastSize (vs[2]);
859 
860   m_hSplitter->setSizes(hs);
861   m_vSplitter->setSizes(vs);
862 
863   setToolViewStyle( (KMultiTabBar::KMultiTabBarStyle)grRestWnd.readEntry ("Kate-MDI-Sidebar-Style", (int)toolViewStyle()) );
864 }
865 
finishRestore()866 void MainWindow::finishRestore ()
867 {
868   if (!m_restoreConfig)
869     return;
870 
871   if (m_restoreConfig->hasGroup (m_restoreGroup))
872   {
873     // apply all settings, like toolbar pos and more ;)
874     applyMainWindowSettings(m_restoreConfig->group(m_restoreGroup));
875 
876     // reshuffle toolviews only if needed
877     KConfigGroup grRest = m_restoreConfig->group (m_restoreGroup);
878     for ( unsigned int i=0; i < m_toolviews.size(); ++i )
879     {
880 		KMultiTabBar::KMultiTabBarPosition newPos = (KMultiTabBar::KMultiTabBarPosition)grRest.readEntry(
881             QString ("Kate-MDI-ToolView-%1-Position").arg(m_toolviews[i]->id), (int) m_toolviews[i]->sidebar()->sidebarPosition());
882 
883 		if (m_toolviews[i]->sidebar()->sidebarPosition() != newPos)
884       {
885         moveToolView (m_toolviews[i], newPos);
886       }
887     }
888 
889     // restore the sidebars
890     for (unsigned int i=0; i < 4; ++i)
891       m_sidebars[i]->restoreSession (&grRest);
892   }
893 
894   // clear this stuff, we are done ;)
895   m_restoreConfig = nullptr;
896   m_restoreGroup = "";
897 }
898 
saveSession(KConfigGroup * grConf)899 void MainWindow::saveSession (KConfigGroup *grConf)
900 {
901   if (!grConf)
902     return;
903 
904   saveMainWindowSettings (*grConf);
905 
906   // save main splitter sizes ;)
907   QList<int> hs = m_hSplitter->sizes();
908   QList<int> vs = m_vSplitter->sizes();
909 
910   if (hs[0] <= 2 && !m_sidebars[0]->splitterVisible ())
911     hs[0] = m_sidebars[0]->lastSize();
912   if (hs[2] <= 2 && !m_sidebars[1]->splitterVisible ())
913     hs[2] = m_sidebars[1]->lastSize();
914   if (vs[0] <= 2 && !m_sidebars[2]->splitterVisible ())
915     vs[0] = m_sidebars[2]->lastSize();
916   if (vs[2] <= 2 && !m_sidebars[3]->splitterVisible ())
917     vs[2] = m_sidebars[3]->lastSize();
918 
919   grConf->writeEntry ("Kate-MDI-H-Splitter", hs);
920   grConf->writeEntry ("Kate-MDI-V-Splitter", vs);
921 
922   // save sidebar style
923   grConf->writeEntry ("Kate-MDI-Sidebar-Style", (int)toolViewStyle());
924 
925   // save the sidebars
926   for (unsigned int i=0; i < 4; ++i)
927     m_sidebars[i]->saveSession (grConf);
928 }
929 
updateSidebarMinimumSizes()930 void KateMDI::MainWindow::updateSidebarMinimumSizes( )
931 {
932 // 	for (unsigned int i=0; i < 4; ++i)
933 // 		m_sidebars[i]->updateMinimumSize();
934 	m_sidebars[KMultiTabBar::Right]->updateMinimumSize();
935 }
936 
937 //END MAIN WINDOW
938 
939 }
940