Keyset Memory Management Bugfix
[pierogi] / macros / pirmacro.cpp
1 #include "pirmacro.h"
2
3 #include "pirmacrocommanditem.h"
4 #include "pirmacropack.h"
5 #include "mainwindow.h"
6
7 #include <QSettings>
8
9 #include <iostream>
10
11 bool PIRMacro::macroRunning = false;
12
13 PIRMacro::PIRMacro(
14   PIRMacroPack *parent,
15   QString name,
16   char k,
17   unsigned int b,
18   MainWindow *mw)
19   : QTreeWidgetItem(parent),
20     key(k),
21     buttonID(b),
22     mainWindow(mw)
23 {
24   setText(0, name);
25
26   if (key)
27   {
28     parent->registerKey(key, this);
29   }
30
31   if (buttonID)
32   {
33     parent->registerButton(buttonID, this);
34   }
35 }
36
37
38 PIRMacro::~PIRMacro()
39 {
40   PIRMacroPack *mp = dynamic_cast<PIRMacroPack*> (QTreeWidgetItem::parent());
41
42   if (key)
43   {
44     mp->eraseKey(key, this);
45   }
46
47   if (buttonID)
48   {
49     mp->eraseButton(buttonID, this);
50   }
51
52   currentCommand = commands.begin();
53   while (currentCommand != commands.end())
54   {
55     delete *currentCommand;
56     commands.pop_front();
57     currentCommand = commands.begin();
58   }
59 }
60
61
62 QString PIRMacro::getName()
63 {
64   return text(0);
65 }
66
67
68 void PIRMacro::setName(
69   QString name)
70 {
71   setText(0, name);
72 }
73
74
75 char PIRMacro::getKey()
76 {
77   return key;
78 }
79
80
81 void PIRMacro::setKey(
82   char k)
83 {
84   key = k;
85 }
86
87
88 unsigned int PIRMacro::getButtonID()
89 {
90   return buttonID;
91 }
92
93
94 void PIRMacro::setButtonID(
95   unsigned int id)
96 {
97   buttonID = id;
98 }
99
100 void PIRMacro::appendCommand(
101   PIRMacroCommandItem *c)
102 {
103   commands.push_back(c);
104 }
105
106
107 bool PIRMacro::deleteCommand(
108   int index)
109 {
110   CommandSequence::iterator i = commands.begin();
111   int count = 0;
112
113   while (i != commands.end())
114   {
115     if (index == count)
116     {
117       delete (*i);
118       commands.erase(i);
119       return true;
120     }
121     ++count;
122     ++i;
123   }
124
125   return false;
126 }
127
128
129 bool PIRMacro::moveUp(
130   int index)
131 {
132   CommandSequence::iterator i = commands.begin();
133   int count = 0;
134   CommandSequence::iterator previ = commands.begin();
135
136   while (i != commands.end())
137   {
138     if (index == count)
139     {
140       PIRMacroCommandItem *mci = *i;
141       commands.erase(i);
142       commands.insert(previ, mci);
143       return true;
144     }
145
146     previ = i;
147     ++count;
148     ++i;
149   }
150
151   return false;
152 }
153
154
155 bool PIRMacro::moveDown(
156   int index)
157 {
158   CommandSequence::iterator i = commands.begin();
159   CommandSequence::iterator nexti = commands.begin();
160   int count = 0;
161
162   while (i != commands.end())
163   {
164     ++nexti;
165     if ((index == count) && nexti != commands.end())
166     {
167       PIRMacroCommandItem *mci = *i;
168       commands.erase(i);
169       ++nexti;
170       commands.insert(nexti, mci);
171       return true;
172     }
173
174     ++count;
175     ++i;
176   }
177
178   return false;
179 }
180
181
182 void PIRMacro::populateList(
183   QListWidget *lw)
184 {
185   lw->clear();
186
187   CommandSequence::const_iterator i = commands.begin();
188
189   while (i != commands.end())
190   {
191     lw->addItem(new QListWidgetItem((*i)->getName()));
192     ++i;
193   }
194 }
195
196
197 // executeMacro() returns false if it was unable to start the macro running:
198 bool PIRMacro::executeMacro()
199 {
200   // Don't start a new macro if one is already running:
201   if (macroRunning) return false;
202
203   // Start running the list of commands:
204   macroRunning = true;
205
206   currentCommand = commands.begin();
207
208   // If this macro is empty, just return:
209   if (currentCommand == commands.end())
210   {
211     emit macroCompleted();
212     macroRunning = false;
213     return true;
214   }
215
216   // Take note of the current keyset id:
217   preMacroKeysetID = mainWindow->getCurrentKeyset();
218
219   connect(
220     *currentCommand,
221     SIGNAL(commandCompleted()),
222     this,
223     SLOT(startNextCommand()));
224
225   (*currentCommand)->executeCommand();
226
227   return true;
228 }
229
230
231 void PIRMacro::startNextCommand()
232 {
233   disconnect(
234     *currentCommand,
235     SIGNAL(commandCompleted()),
236     0,
237     0);
238
239   ++currentCommand;
240
241   // Are we done?
242   if (currentCommand == commands.end())
243   {
244     // We are done.
245     macroRunning = false;
246     mainWindow->updateKeysetSelection(preMacroKeysetID);
247     emit macroCompleted();
248     return;
249   }
250
251   // We are not done; run the next command.
252   connect(
253     *currentCommand,
254     SIGNAL(commandCompleted()),
255     this,
256     SLOT(startNextCommand()));
257
258   (*currentCommand)->executeCommand();
259 }
260
261
262 void PIRMacro::storeSettings(
263   QSettings &settings)
264 {
265   settings.setValue("macroName", text(0));
266   settings.setValue("macroKey", key);
267   settings.setValue("macroButtonID", buttonID);
268
269   CommandSequence::const_iterator i = commands.begin();
270
271   int index = 0;
272   while (i != commands.end())
273   {
274     (*i)->storeSettings(settings, index);
275     ++index;
276     ++i;
277   }
278 }
279
280
281 QString PIRMacro::getCommandType(
282   int index)
283 {
284   CommandSequence::iterator i = commands.begin();
285
286   // Advance 'index' steps into the sequence:
287   while (i != commands.end() && index)
288   {
289     ++i;
290     --index;
291   }
292
293   if (i != commands.end())
294   {
295     return (*i)->getTypeString();
296   }
297
298   return "";
299 }
300
301
302 QString PIRMacro::getCommandName(
303   int index)
304 {
305   CommandSequence::iterator i = commands.begin();
306
307   while (i != commands.end() && index)
308   {
309     ++i;
310     --index;
311   }
312
313   if (i != commands.end())
314   {
315     return (*i)->getName();
316   }
317
318   return "";
319 }