1 //=========================================================
2 //	MusE
3 //	Linux Music Editor
4 //	$Id: cobject.cpp,v 1.4 2004/02/02 12:10:09 wschweer Exp $
5 //
6 //	(C) Copyright 1999/2000 Werner Schweer (ws@seh.de)
7 //
8 //	This program is free software; you can redistribute it and/or
9 //	modify it under the terms of the GNU General Public License
10 //	as published by the Free Software Foundation; version 2 of
11 //	the License, or (at your option) any later version.
12 //
13 //	This program is distributed in the hope that it will be useful,
14 //	but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
16 //	GNU General Public License for more details.
17 //
18 //	You should have received a copy of the GNU General Public License
19 //	along with this program; if not, write to the Free Software
20 //	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA	02110-1301, USA.
21 //
22 //=========================================================
23 
24 #include "cobject.h"
25 #include "gui.h"
26 #include "globals.h"
27 #include "app.h"
28 #include "shortcuts.h"
29 #include "songpos_toolbar.h"
30 #include "sig_tempo_toolbar.h"
31 #include "gconfig.h"
32 #include "helper.h"
33 #include "song.h"
34 #include "icons.h"
35 #include "rectoolbar.h"
36 #include "postoolbar.h"
37 #include "synctoolbar.h"
38 
39 #include <QMenuBar>
40 #include <QWidgetAction>
41 #include <QLabel>
42 
43 // Forwards from header:
44 #include <QMdiSubWindow>
45 #include <QFocusEvent>
46 #include <QCloseEvent>
47 #include <QToolBar>
48 #include <QAction>
49 #include "xml.h"
50 
51 // For debugging output: Uncomment the fprintf section.
52 #define ERROR_COBJECT(dev, format, args...)  fprintf(dev, format, ##args)
53 #define DEBUG_COBJECT(dev, format, args...) // fprintf(dev, format, ##args)
54 
55 using std::list;
56 using MusEGlobal::muse;
57 
58 namespace MusEGui {
59 
60 int TopWin::_widthInit[TOPLEVELTYPE_LAST_ENTRY];
61 int TopWin::_heightInit[TOPLEVELTYPE_LAST_ENTRY];
62 QByteArray TopWin::_toolbarSharedInit[TOPLEVELTYPE_LAST_ENTRY];
63 QByteArray TopWin::_toolbarNonsharedInit[TOPLEVELTYPE_LAST_ENTRY];
64 bool TopWin::_openTabbed[TOPLEVELTYPE_LAST_ENTRY];
65 bool TopWin::initInited=false;
66 
TopWin(ToplevelType t,QWidget * parent,const char * name,Qt::WindowFlags f)67 TopWin::TopWin(ToplevelType t, QWidget* parent, const char* name, Qt::WindowFlags f)
68     : QMainWindow(parent, f)
69 {
70     _initalizing = true;
71     _isDeleting = false;
72 
73     if (!initInited)
74         initConfiguration();
75 
76     _type=t;
77 
78     setObjectName(name ? QString(name) : "TopWin");
79     //setDockNestingEnabled(true); // Allow multiple rows.	Tim.
80     setIconSize(QSize(MusEGlobal::config.iconSize, MusEGlobal::config.iconSize));
81 
82     setWindowIcon(typeIcon(_type));
83 
84     setAttribute(Qt::WA_DeleteOnClose);
85 
86     subwinAction = new QAction(tr("Tabbed/Floating"), this);
87     subwinAction->setCheckable(true);
88     subwinAction->setStatusTip(tr("Display editor in a tab or in a separate window (preset in Global Settings->Editors)."));
89     subwinAction->setShortcut(shortcuts[SHRT_TABBED_WIN].key);
90     connect(subwinAction, SIGNAL(toggled(bool)), SLOT(setIsMdiWin(bool)));
91 
92 //    shareAction=new QAction(tr("Shares Tools and Menu"), this);
93 //    shareAction->setCheckable(true);
94 //    connect(shareAction, SIGNAL(toggled(bool)), SLOT(shareToolsAndMenu(bool)));
95 
96     fullscreenAction=new QAction(tr("Fullscreen"), this);
97     fullscreenAction->setCheckable(true);
98     fullscreenAction->setChecked(false);
99     fullscreenAction->setShortcut(shortcuts[SHRT_FULLSCREEN].key);
100     connect(fullscreenAction, SIGNAL(toggled(bool)), SLOT(setFullscreen(bool)));
101 
102 
103     mdisubwin = nullptr;
104 
105     _sharesToolsAndMenu=_openTabbed[_type];
106 
107     if (_openTabbed[_type] && !MusEGlobal::unityWorkaround)
108     {
109         setIsMdiWin(true);
110         _savedToolbarState=_toolbarNonsharedInit[_type];
111     }
112 
113     if (_sharesToolsAndMenu)
114         menuBar()->hide();
115 
116     subwinAction->setChecked(isMdiWin());
117 //    shareAction->setChecked(_sharesToolsAndMenu);
118 
119     if (MusEGlobal::unityWorkaround)
120     {
121         _sharesToolsAndMenu=false;
122 //        shareAction->setEnabled(false);
123         subwinAction->setEnabled(false);
124     }
125 
126     fullscreenAction->setEnabled(!isMdiWin());
127 
128     if (_type == ARRANGER) {
129 //            shareAction->setEnabled(false);
130         subwinAction->setEnabled(false);
131     }
132 
133     if (!mdisubwin)
134         resize(_widthInit[_type], _heightInit[_type]);
135 
136 
137     //--------------------------------------------------
138     //    Toolbar
139     //--------------------------------------------------
140 
141     // NOTICE: Please ensure that any tool bar object names here match the names
142     //          assigned in the 'toolbar' creation section of MusE::MusE(),
143     //           or any other TopWin class.
144     //         This allows MusE::setCurrentMenuSharingTopwin() to do some magic
145     //          to retain the original toolbar layout. If it finds an existing
146     //          toolbar with the same object name, it /replaces/ it using insertToolBar(),
147     //          instead of /appending/ with addToolBar().
148 
149     QToolBar* undo_tools=addToolBar(tr("Undo/Redo"));
150     undo_tools->setObjectName("Undo/Redo");
151     undo_tools->addActions(MusEGlobal::undoRedo->actions());
152 
153     QToolBar* panic_toolbar = addToolBar(tr("Panic"));
154     panic_toolbar->setObjectName("Panic tool");
155     panic_toolbar->addAction(MusEGlobal::panicAction);
156 
157     QToolBar* metronome_toolbar = addToolBar(tr("Metronome"));
158     metronome_toolbar->setObjectName("Metronome tool");
159     metronome_toolbar->addAction(MusEGlobal::metronomeAction);
160 
161     QToolBar* songpos_tb = addToolBar(tr("Timeline"));
162     songpos_tb->setObjectName("Timeline tool");
163     songpos_tb->addWidget(new MusEGui::SongPosToolbarWidget(songpos_tb));
164     songpos_tb->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
165     songpos_tb->setContextMenuPolicy(Qt::PreventContextMenu);
166 
167     QToolBar* transportToolbar = addToolBar(tr("Transport"));
168     transportToolbar->setObjectName("Transport tool");
169     transportToolbar->addActions(MusEGlobal::transportAction->actions());
170     transportToolbar->setIconSize(QSize(MusEGlobal::config.iconSize, MusEGlobal::config.iconSize));
171 
172     RecToolbar *recToolbar = new RecToolbar(tr("Recording"), this);
173     addToolBar(recToolbar);
174 
175     SyncToolbar *syncToolbar = new SyncToolbar(tr("Sync"), this);
176     addToolBar(syncToolbar);
177 
178     addToolBarBreak();
179 
180     TempoToolbar* tempo_tb = new TempoToolbar(tr("Tempo"), this);
181     addToolBar(tempo_tb);
182 
183     SigToolbar* sig_tb = new SigToolbar(tr("Signature"), this);
184     addToolBar(sig_tb);
185 
186     PosToolbar *posToolbar = new PosToolbar(tr("Position"), this);
187     addToolBar(posToolbar);
188 
189     connect(tempo_tb, SIGNAL(returnPressed()), SLOT(focusCanvas()));
190     connect(tempo_tb, SIGNAL(escapePressed()), SLOT(focusCanvas()));
191     connect(tempo_tb, SIGNAL(masterTrackChanged(bool)), MusEGlobal::song, SLOT(setMasterFlag(bool)));
192 
193     connect(sig_tb, SIGNAL(returnPressed()), SLOT(focusCanvas()));
194     connect(sig_tb, SIGNAL(escapePressed()), SLOT(focusCanvas()));
195 
196 // this is not (longer?) the case, to be tested on KDE (kybos)
197 // what about changing from MDI to top window later? then the parent remains anyway... (kybos)
198 //    // NOTICE: It seems after the switch to Qt5, windows with a parent have stay-on-top behaviour.
199 //    // But with the fix below, other TopWin destructors are not called when closing the app.
200 //    // So there is now an additional fix in MusE::closeEvent() which deletes all parentless TopWin.
201 //    //
202 //    /* unconnect parent if window is not mdi */
203 //    /* to make editor windows not stay on top */
204 //    if(!isMdiWin())
205 //    {
206 //        setParent(nullptr);
207 //    }
208 }
209 
~TopWin()210 TopWin::~TopWin()
211 {
212     DEBUG_COBJECT(stderr, "TopWin dtor: %s\n", objectName().toLatin1().constData());
213 
214     // Toolbars must be deleted explicitly to avoid memory leakage and corruption.
215     // For some reason (toolbar sharing?) they are reparented and thus
216     // not destroyed by the original parent topwin when closed.
217     for (auto& it : _toolbars) {
218         if (it) {
219             delete it;
220             it = nullptr;
221         }
222     }
223 
224     if (mdisubwin)
225         mdisubwin->close();
226 }
227 
228 //---------------------------------------------------------
229 //	 readStatus
230 //---------------------------------------------------------
231 
readStatus(MusECore::Xml & xml)232 void TopWin::readStatus(MusECore::Xml& xml)
233 {
234     int x=0, y=0, width=800, height=600;
235     bool wsMinimized = false;
236     bool wsMaximized = false;
237     bool wsFullScreen = false;
238     bool wsActive = false;
239 
240     for (;;)
241     {
242         MusECore::Xml::Token token = xml.parse();
243         if (token == MusECore::Xml::Error || token == MusECore::Xml::End)
244             break;
245 
246         QString tag = xml.s1();
247         switch (token)
248         {
249         case MusECore::Xml::TagStart:
250             if (tag == "x")
251                 x=xml.parseInt();
252             else if (tag == "y")
253                 y=xml.parseInt();
254             else if (tag == "width")
255                 width=xml.parseInt();
256             else if (tag == "height")
257                 height=xml.parseInt();
258             else if (tag == "wsMinimized")
259                 wsMinimized=xml.parseInt();
260             else if (tag == "wsMaximized")
261                 wsMaximized=xml.parseInt();
262             else if (tag == "wsFullScreen")
263                 wsFullScreen=xml.parseInt();
264             else if (tag == "wsActive")
265                 wsActive=xml.parseInt();
266             else if (tag == "toolbars")
267             {
268                 if (!sharesToolsAndMenu())
269                 {
270                     if (!restoreState(QByteArray::fromHex(xml.parse1().toLatin1())))
271                     {
272                         fprintf(stderr,"ERROR: couldn't restore toolbars. trying default configuration...\n");
273                         if (!restoreState(_toolbarNonsharedInit[_type]))
274                             fprintf(stderr,"ERROR: couldn't restore default toolbars. this is not really a problem.\n");
275                     }
276                 }
277                 else
278                 {
279                     _savedToolbarState = QByteArray::fromHex(xml.parse1().toLatin1());
280                     if (_savedToolbarState.isEmpty())
281                         _savedToolbarState=_toolbarNonsharedInit[_type];
282                 }
283             }
284 //            else if (tag == "shares_menu")
285 //            {
286 //                shareToolsAndMenu(xml.parseInt());
287 //            }
288             else if (tag == "is_subwin")
289             {
290                 setIsMdiWin(xml.parseInt());
291             }
292             else
293                 xml.unknown("TopWin");
294             break;
295 
296         case MusECore::Xml::TagEnd:
297             if (tag == "topwin")
298             {
299                 if (mdisubwin) {
300                     QFlags<Qt::WindowState> wstate = Qt::WindowMaximized;
301                     if (wsActive)
302                         wstate |= Qt::WindowActive;
303                     setWindowState(wstate);
304                 }
305                 else {
306                     const QRect geo(x, y, width, height);
307                     QFlags<Qt::WindowState> wstate;
308                     if(wsMinimized)
309                         wstate |= Qt::WindowMinimized;
310                     if(wsMaximized)
311                         wstate |= Qt::WindowMaximized;
312                     if(wsFullScreen)
313                         wstate |= Qt::WindowFullScreen;
314                     if(wsActive)
315                         wstate |= Qt::WindowActive;
316 
317                     setGeometry(geo);
318                     setWindowState(wstate);
319                 }
320 
321                 return;
322             }
323             break;
324 
325         default:
326             break;
327         }
328     }
329 }
330 
331 //---------------------------------------------------------
332 //	 writeStatus
333 //---------------------------------------------------------
334 
writeStatus(int level,MusECore::Xml & xml) const335 void TopWin::writeStatus(int level, MusECore::Xml& xml) const
336 {
337     xml.tag(level++, "topwin");
338 
339     // the order of these tags has a certain sense
340     // changing it won't break muse, but it may break proper
341     // restoring of the positions
342     xml.intTag(level, "is_subwin", isMdiWin());
343 
344     QRect geo;
345     QFlags<Qt::WindowState> wstate;
346     if (mdisubwin)
347     {
348         wstate = mdisubwin->windowState();
349         geo = mdisubwin->normalGeometry();
350         // TESTED on Qt5.3: For MDI geo was invalid (0, 0, -1, -1) when window maximized.
351         // This may be a reported Qt bug I read about.
352         if(!geo.isValid())
353             geo = mdisubwin->geometry();
354     }
355     else
356     {
357         wstate = windowState();
358         geo = normalGeometry();
359         if(!geo.isValid())
360             geo = geometry();
361     }
362     // The order of geo first then state may be important here.
363     xml.intTag(level, "x", geo.x());
364     xml.intTag(level, "y", geo.y());
365     xml.intTag(level, "width", geo.width());
366     xml.intTag(level, "height", geo.height());
367     if(wstate.testFlag(Qt::WindowMinimized))
368         xml.intTag(level, "wsMinimized", 1);
369     if(wstate.testFlag(Qt::WindowMaximized))
370         xml.intTag(level, "wsMaximized", 1);
371     if(wstate.testFlag(Qt::WindowFullScreen))
372         xml.intTag(level, "wsFullScreen", 1);
373     if(wstate.testFlag(Qt::WindowActive))
374         xml.intTag(level, "wsActive", 1);
375 
376 //    xml.intTag(level, "shares_menu", sharesToolsAndMenu());
377 
378     if (sharesToolsAndMenu())
379         xml.strTag(level, "toolbars", _savedToolbarState.toHex().data());
380     else
381         xml.strTag(level, "toolbars", saveState().toHex().data());
382 
383     xml.tag(level, "/topwin");
384 }
385 
hide()386 void TopWin::hide()
387 {
388     if (mdisubwin)
389         mdisubwin->hide();
390 
391     QMainWindow::hide();
392 }
393 
show()394 void TopWin::show()
395 {
396     if (mdisubwin)
397         mdisubwin->showMaximized();
398 
399     QMainWindow::show();
400 }
401 
setVisible(bool param)402 void TopWin::setVisible(bool param)
403 {
404     if (mdisubwin)
405     {
406         if (param)
407             mdisubwin->show();
408         else
409             mdisubwin->hide();
410     }
411 
412     QMainWindow::setVisible(param);
413 }
414 
createMdiWrapper()415 void TopWin::createMdiWrapper()
416 {
417     if (mdisubwin == nullptr)
418     {
419         mdisubwin = new QMdiSubWindow();
420         mdisubwin->setWidget(this);
421         mdisubwin->setWindowIcon(typeIcon(_type));
422 
423         if (_type == ARRANGER) {
424             mdisubwin->setWindowFlags(Qt::CustomizeWindowHint);
425         } else {
426             mdisubwin->setAttribute(Qt::WA_DeleteOnClose);
427             mdisubwin->setWindowFlags(Qt::CustomizeWindowHint
428                                       | Qt::WindowCloseButtonHint);
429         }
430     }
431 }
432 
setIsMdiWin(bool val)433 void TopWin::setIsMdiWin(bool val)
434 {
435     if (MusEGlobal::unityWorkaround)
436         return;
437 
438     if (!val && _type == ARRANGER)
439         return;
440 
441     if (val)
442     {
443         if (!isMdiWin())
444         {
445             _savedToolbarState = saveState();
446 
447             createMdiWrapper();
448             muse->addMdiSubWindow(mdisubwin);
449 
450             if (windowTitle().startsWith("MusE: "))
451                 setWindowTitle(windowTitle().mid(6));
452 
453             shareToolsAndMenu(true);
454 
455             fullscreenAction->setEnabled(false);
456             fullscreenAction->setChecked(false);
457             {
458                 const QSignalBlocker blocker(subwinAction);
459                 subwinAction->setChecked(true);
460             }
461             muse->updateWindowMenu();
462             mdisubwin->showMaximized();
463             muse->setActiveMdiSubWindow(mdisubwin);
464         }
465         else
466         {
467             if (MusEGlobal::debugMsg) printf("TopWin::setIsMdiWin(true) called, but window is already a MDI win\n");
468         }
469     }
470     else
471     {
472         if (isMdiWin())
473         {
474             mdisubwin->setWidget(nullptr);
475             mdisubwin->close();
476             mdisubwin = nullptr;
477 
478             setParent(muse);
479             setWindowFlags(Qt::Window);
480 
481 
482             if (!windowTitle().startsWith("MusE: "))
483                 setWindowTitle(windowTitle().insert(0, "MusE: "));
484 
485             shareToolsAndMenu(false);
486 
487             fullscreenAction->setEnabled(true);
488             {
489                 const QSignalBlocker blocker(subwinAction);
490                 subwinAction->setChecked(false);
491             }
492             muse->updateWindowMenu();
493             QMainWindow::show();
494         }
495         else
496         {
497             if (MusEGlobal::debugMsg) printf("TopWin::setIsMdiWin(false) called, but window is not a MDI win\n");
498         }
499     }
500 }
501 
isMdiWin() const502 bool TopWin::isMdiWin() const
503 {
504     return (mdisubwin != nullptr);
505 }
506 
insertToolBar(QToolBar *,QToolBar *)507 void TopWin::insertToolBar(QToolBar*, QToolBar*) { printf("ERROR: THIS SHOULD NEVER HAPPEN: TopWin::insertToolBar called, but it's not implemented! ignoring it\n"); }
insertToolBarBreak(QToolBar *)508 void TopWin::insertToolBarBreak(QToolBar*) { printf("ERROR: THIS SHOULD NEVER HAPPEN: TopWin::insertToolBarBreak called, but it's not implemented! ignoring it\n"); }
removeToolBar(QToolBar *)509 void TopWin::removeToolBar(QToolBar*) { printf("ERROR: THIS SHOULD NEVER HAPPEN: TopWin::removeToolBar called, but it's not implemented! ignoring it\n"); }
removeToolBarBreak(QToolBar *)510 void TopWin::removeToolBarBreak(QToolBar*) { printf("ERROR: THIS SHOULD NEVER HAPPEN: TopWin::removeToolBarBreak called, but it's not implemented! ignoring it\n"); }
addToolBar(Qt::ToolBarArea,QToolBar * tb)511 void TopWin::addToolBar(Qt::ToolBarArea, QToolBar* tb) { printf("ERROR: THIS SHOULD NEVER HAPPEN: TopWin::addToolBar(Qt::ToolBarArea, QToolBar*) called, but it's not implemented!\nusing addToolBar(QToolBar*) instead\n"); addToolBar(tb);}
512 
addToolBar(QToolBar * toolbar)513 void TopWin::addToolBar(QToolBar* toolbar)
514 {
515     _toolbars.push_back(toolbar);
516 
517     if (!_sharesToolsAndMenu || MusEGlobal::unityWorkaround)
518         QMainWindow::addToolBar(toolbar);
519     else
520         toolbar->hide();
521 
522     toolbar->setIconSize(QSize(MusEGlobal::config.iconSize, MusEGlobal::config.iconSize));
523 }
524 
addToolBar(const QString & title)525 QToolBar* TopWin::addToolBar(const QString& title)
526 {
527     QToolBar* toolbar = new QToolBar(title, this);
528     addToolBar(toolbar);
529     return toolbar;
530 }
531 
532 
addToolBarBreak(Qt::ToolBarArea area)533 void TopWin::addToolBarBreak(Qt::ToolBarArea area)
534 {
535     QMainWindow::addToolBarBreak(area);
536     _toolbars.push_back(nullptr);
537 }
538 
539 
shareToolsAndMenu(bool val)540 void TopWin::shareToolsAndMenu(bool val)
541 {
542     if (MusEGlobal::unityWorkaround)
543         return;
544 
545     if (_sharesToolsAndMenu == val)
546     {
547         if (MusEGlobal::debugMsg) printf("TopWin::shareToolsAndMenu() called but has no effect\n");
548         return;
549     }
550 
551     _sharesToolsAndMenu = val;
552 
553     if (!val)
554     {
555         muse->shareMenuAndToolbarChanged(this, false);
556 
557         for (const auto& it : _toolbars)
558             if (it) {
559                 QMainWindow::addToolBar(it);
560                 it->show();
561             }
562             else
563                 QMainWindow::addToolBarBreak();
564 
565         restoreState(_savedToolbarState);
566         _savedToolbarState.clear();
567 
568         menuBar()->show();
569     }
570     else
571     {
572         if (_savedToolbarState.isEmpty())	 // this check avoids overwriting a previously saved state
573             _savedToolbarState = saveState(); // (by setIsMdiWin) with a now incorrect (empty) state
574 
575         for (const auto& it : _toolbars)
576             if (it) {
577                 QMainWindow::removeToolBar(it); // this does NOT delete the toolbar, which is good
578                 it->setParent(nullptr);
579             }
580 
581         menuBar()->hide();
582 
583         muse->shareMenuAndToolbarChanged(this, true);
584     }
585 }
586 
587 //---------------------------------------------------------
588 //	 storeInitialState
589 //---------------------------------------------------------
590 
storeInitialState() const591 void TopWin::storeInitialState() const
592 {
593     if (mdisubwin)
594     {
595         _widthInit[_type] = mdisubwin->width();
596         _heightInit[_type] = mdisubwin->height();
597     }
598     else
599     {
600         _widthInit[_type] = width();
601         _heightInit[_type] = height();
602     }
603 
604     if (sharesToolsAndMenu())
605     {
606         if (muse->getCurrentMenuSharingTopwin() == this)
607             _toolbarSharedInit[_type] = muse->saveState();
608     }
609     else
610         _toolbarNonsharedInit[_type] = saveState();
611 
612     // Store class-specific view settings.
613     storeInitialViewState();
614 }
615 
616 
617 
618 //initConfiguration() restores default tabbed configuration
initConfiguration()619 void TopWin::initConfiguration()
620 {
621     if (initInited)
622         return;
623 
624     for (int i = 0; i < TOPLEVELTYPE_LAST_ENTRY; i++)
625     {
626         _widthInit[i] = 800;
627         _heightInit[i] = 600;
628         _openTabbed[i] = true;
629     }
630 
631     initInited = true;
632 }
633 
634 //---------------------------------------------------------
635 //	 readConfiguration
636 //---------------------------------------------------------
637 
readConfiguration(ToplevelType t,MusECore::Xml & xml)638 void TopWin::readConfiguration(ToplevelType t, MusECore::Xml& xml)
639 {
640     if (!initInited)
641         initConfiguration();
642 
643     for (;;)
644     {
645         MusECore::Xml::Token token = xml.parse();
646         if (token == MusECore::Xml::Error || token == MusECore::Xml::End)
647             break;
648 
649         const QString& tag = xml.s1();
650         switch (token)
651         {
652         case MusECore::Xml::TagStart:
653             if (tag == "width")
654                 _widthInit[t] = xml.parseInt();
655             else if (tag == "height")
656                 _heightInit[t] = xml.parseInt();
657             else if (tag == "nonshared_toolbars")
658                 _toolbarNonsharedInit[t] = QByteArray::fromHex(xml.parse1().toLatin1());
659             else if (tag == "shared_toolbars")
660                 _toolbarSharedInit[t] = QByteArray::fromHex(xml.parse1().toLatin1());
661             else if (tag == "default_subwin")
662                 _openTabbed[t] = xml.parseInt();
663             else
664                 xml.unknown("TopWin");
665             break;
666 
667         case MusECore::Xml::TagEnd:
668             if (tag == "topwin")
669                 return;
670             break;
671 
672         default:
673             break;
674         }
675     }
676 }
677 
678 
679 //---------------------------------------------------------
680 //	 writeConfiguration
681 //---------------------------------------------------------
682 
writeConfiguration(ToplevelType t,int level,MusECore::Xml & xml)683 void TopWin::writeConfiguration(ToplevelType t, int level, MusECore::Xml& xml)
684 {
685     if (!initInited)
686     {
687         printf ("WARNING: TopWin::writeConfiguration() called although the config hasn't been\n"
688                 "				 initialized! writing default configuration\n");
689         initConfiguration();
690     }
691     xml.tag(level++, "topwin");
692     xml.intTag(level, "width", _widthInit[t]);
693     xml.intTag(level, "height", _heightInit[t]);
694     xml.strTag(level, "nonshared_toolbars", _toolbarNonsharedInit[t].toHex().data());
695     xml.strTag(level, "shared_toolbars", _toolbarSharedInit[t].toHex().data());
696     xml.intTag(level, "default_subwin", _openTabbed[t]);
697     xml.etag(level, "topwin");
698 }
699 
finalizeInit()700 void TopWin::finalizeInit()
701 {
702     MusEGlobal::muse->topwinMenuInited(this);
703     _initalizing=false;
704 }
705 
initTopwinState()706 void TopWin::initTopwinState()
707 {
708     if (sharesToolsAndMenu())
709     {
710         if (this == muse->getCurrentMenuSharingTopwin())
711             muse->restoreState(_toolbarSharedInit[_type]);
712     }
713     else
714         restoreState(_toolbarNonsharedInit[_type]);
715 }
716 
restoreMainwinState()717 void TopWin::restoreMainwinState()
718 {
719     if (sharesToolsAndMenu())
720         initTopwinState();
721 }
722 
typeName(ToplevelType t)723 QString TopWin::typeName(ToplevelType t)
724 {
725     switch (t)
726     {
727     case PIANO_ROLL: return tr("Piano roll");
728 //    case LISTE: return tr("List editor");
729     case DRUM: return tr("Drum editor");
730     case MASTER: return tr("Master track editor");
731     case WAVE: return tr("Wave editor");
732     case SCORE: return tr("Score editor");
733     case ARRANGER: return tr("Arranger");
734     default: return tr("<unknown toplevel type>");
735     }
736 }
737 
typeIcon(ToplevelType t)738 QIcon TopWin::typeIcon(ToplevelType t)
739 {
740     switch (t)
741     {
742     case ARRANGER: return QIcon(*arrangerSVGIcon);
743     case PIANO_ROLL: return QIcon(*pianorollSVGIcon);
744     case DRUM: return QIcon(*drumeditSVGIcon);
745     case MASTER: return QIcon(*mastereditSVGIcon);
746     case WAVE: return QIcon(*waveeditorSVGIcon);
747     case SCORE: return QIcon(*scoreeditSVGIcon);
748     default: return QIcon();
749     }
750 }
751 
752 
setFullscreen(bool val)753 void TopWin::setFullscreen(bool val)
754 {
755     if (val)
756         showFullScreen();
757     else
758         showNormal();
759 }
760 
resize(int w,int h)761 void TopWin::resize(int w, int h)
762 {
763     if (isMdiWin())
764         return;
765 
766     QMainWindow::resize(w,h);
767 }
768 
setWindowTitle(const QString & title)769 void TopWin::setWindowTitle (const QString& title)
770 {
771     QMainWindow::setWindowTitle(title);
772     muse->updateWindowMenu();
773 }
774 
storeSettings()775 void TopWin::storeSettings() {}
776 
777 //void TopWin::windowStateChanged(Qt::WindowStates oldState, Qt::WindowStates newState)
778 //{
779 //    // Due to bug in Oxygen and Breeze at least on *buntu 16.04 LTS and some other distros,
780 //    //  force the style and stylesheet again. Otherwise the window freezes.
781 //    // Ignore the Qt::WindowActive flag.
782 //    if((oldState & (Qt::WindowNoState | Qt::WindowMinimized | Qt::WindowMaximized | Qt::WindowFullScreen)) !=
783 //            (newState & (Qt::WindowNoState | Qt::WindowMinimized | Qt::WindowMaximized | Qt::WindowFullScreen)))
784 //    {
785 //        if(MusEGlobal::debugMsg)
786 //            fprintf(stderr, "TopWin::windowStateChanged oldState:%d newState:%d Calling updateThemeAndStyle()\n", int(oldState), int(newState));
787 //        MusEGui::updateThemeAndStyle(true);
788 //    }
789 //}
790 
findType(TopWin::ToplevelType type) const791 TopWin* ToplevelList::findType(TopWin::ToplevelType type) const
792 {
793     for (ciToplevel i = begin(); i != end(); ++i)
794     {
795         if((*i)->type() == type)
796             return (*i);
797     }
798     return nullptr;
799 }
800 
801 } // namespace MusEGui
802