Unity 8
modelactionrootstate.cpp
1 /*
2  * Copyright 2013 Canonical Ltd.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation; version 3.
7  *
8  * This program 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
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authors:
17  * Nick Dedekind <nick.dedekind@canonical.com>
18  */
19 
20 #include "modelactionrootstate.h"
21 #include "indicators.h"
22 
23 #include <unitymenumodel.h>
24 #include <QVariant>
25 #include <QIcon>
26 
27 extern "C" {
28 #include <glib.h>
29 #include <gio/gio.h>
30 }
31 
32 ModelActionRootState::ModelActionRootState(QObject *parent)
33  : RootStateObject(parent),
34  m_menu(nullptr)
35 {
36 }
37 
38 ModelActionRootState::~ModelActionRootState()
39 {
40 }
41 
42 UnityMenuModel* ModelActionRootState::menu() const
43 {
44  return m_menu;
45 }
46 
47 void ModelActionRootState::setMenu(UnityMenuModel* menu)
48 {
49  if (m_menu != menu) {
50  bool wasValid = valid();
51 
52  if (m_menu) {
53  m_menu->disconnect(this);
54  }
55  m_menu = menu;
56 
57  if (m_menu) {
58  connect(m_menu, &UnityMenuModel::rowsInserted, this, &ModelActionRootState::onModelRowsAdded);
59  connect(m_menu, &UnityMenuModel::rowsRemoved, this, &ModelActionRootState::onModelRowsRemoved);
60  connect(m_menu, &UnityMenuModel::dataChanged, this, &ModelActionRootState::onModelDataChanged);
61 
62  connect(m_menu, &UnityMenuModel::destroyed, this, &ModelActionRootState::reset);
63  }
64  updateActionState();
65  Q_EMIT menuChanged();
66 
67  if (wasValid != valid())
68  Q_EMIT validChanged();
69  }
70 }
71 
72 bool ModelActionRootState::valid() const
73 {
74  return !currentState().empty();
75 }
76 
77 void ModelActionRootState::onModelRowsAdded(const QModelIndex& parent, int start, int end)
78 {
79  Q_UNUSED(parent);
80  if (start == 0 && end >= 0) {
81  updateActionState();
82  }
83 }
84 
85 void ModelActionRootState::onModelRowsRemoved(const QModelIndex& parent, int start, int end)
86 {
87  Q_UNUSED(parent);
88  if (start == 0 && end >= 0) {
89  updateActionState();
90  }
91 }
92 
93 void ModelActionRootState::onModelDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles)
94 {
95  Q_UNUSED(roles);
96  if (!topLeft.isValid() || !bottomRight.isValid()) {
97  return;
98  }
99 
100  if (topLeft.row() <= 0 && bottomRight.row() >= 0) {
101  updateActionState();
102  }
103 }
104 
105 void ModelActionRootState::reset()
106 {
107  m_menu = nullptr;
108 
109  Q_EMIT menuChanged();
110  setCurrentState(QVariantMap());
111 }
112 
113 void ModelActionRootState::updateActionState()
114 {
115  if (m_menu && m_menu->rowCount() > 0) {
116  ActionStateParser* oldParser = m_menu->actionStateParser();
117  m_menu->setActionStateParser(&m_parser);
118 
119  QVariantMap state = m_menu->get(0, "actionState").toMap();
120 
121  m_menu->setActionStateParser(oldParser);
122 
123  setCurrentState(state);
124  } else if (!m_menu) {
125  setCurrentState(QVariantMap());
126  }
127  // else if m_menu->rowCount() == 0, let's leave existing cache in place
128  // until the new menu comes in, to avoid flashing the UI empty for a moment
129 }