root/deus/AuthorInterface_impl.cpp

Revision 8, 16.3 kB (checked in by pantley2, 4 years ago)

added old DEUS project to SVN

Line 
1 /**
2  * AuthorInterface_impl.cpp
3  *
4  * Concrete extension of AuthorInterface UI
5  */
6
7 #include "AuthorInterface_impl.h"
8
9 #include <qlayout.h>
10 #include <qslider.h>
11 #include <qstring.h>
12 #include <qpushbutton.h>
13 #include <qmultilineedit.h>
14 #include <qtable.h>
15 #include <qlabel.h>
16 #include <qlineedit.h>
17 #include <qlistview.h>
18 #include <qmessagebox.h>
19
20 AuthorForm_impl::AuthorForm_impl( QWidget* parent, const char* name, WFlags fl)
21         : AuthorForm(parent, name, fl)
22 {
23         is_closing = false;
24         viewing = STORY_VIEW;
25         current_story = NULL;
26         selected = NULL;
27         ld = NULL;
28
29         gd = new AuthorGraphDisplay(this, (QWidget*)Frame, "graph_display");
30         QBoxLayout * l = new QVBoxLayout((QWidget *)Frame);     // auto deallocated
31         l->addWidget(gd);       
32
33         connect((QObject *)CenterButton, SIGNAL(clicked()), gd, SLOT(center()));
34         connect((QObject *)FitButton, SIGNAL(clicked()), gd, SLOT(fit()));
35         connect((QObject *)ZoomSlider, SIGNAL(valueChanged(int)), gd, SLOT(setZoom(int)));
36         connect(gd, SIGNAL(zoomChanged(int)), (QObject *)ZoomSlider, SLOT(setValue(int)));
37         ZoomSlider->setValue(DEFAULT_ZOOM);
38
39         connect((QObject *)NewNodeButton, SIGNAL(clicked()), this, SLOT(addNode()));
40         connect((QObject *)NewNodeName, SIGNAL(textChanged()), this, SLOT(newNodeTextChanged()));
41         connect((QObject *)ReturnButton, SIGNAL(clicked()), this, SLOT(storyView()));
42         connect((QObject *)Table, SIGNAL(valueChanged(int,int)), this, SLOT(cellValueChanged(int,int)));
43         connect((QObject *)SaveName, SIGNAL(textChanged(const QString &)), this, SLOT(saveTextChanged(const QString &)));
44         connect((QObject *)SaveButton, SIGNAL(clicked()), this, SLOT(save()));
45         connect((QObject *)LoadButton, SIGNAL(clicked()), this, SLOT(load()));
46
47         connect((QObject *)DoneButton, SIGNAL(clicked()), this, SLOT(close()));
48
49         Table->setSelectionMode(QTable::NoSelection);
50 }
51
52
53 void
54 AuthorForm_impl::addNode()
55 {
56         if (viewing == STORY_VIEW)
57         {
58                 if (selected == NULL && story_root != NULL)
59                         printf("Error: BZZZZT, how did you get here?");
60                 else if (story_root == NULL)
61                 {
62                         // this is the first node, make it the root
63                         story_root = new StoryNode();
64                         story_root->name = NewNodeName->text();
65                         changeSelected(story_root);
66                         gd->fit();
67                 }
68                 else if (selected != NULL)
69                 {
70                         // add a new node, selected is parent
71                         StoryNode *n = new StoryNode();
72                         n->name = NewNodeName->text();
73                         n->parent = (StoryNode *)selected;
74                         ((StoryNode *)selected)->next.push_back(n);
75                         changeSelected(n);
76                 }
77                 else printf("Error: BZZZZT, how did you get here?");
78         }
79
80         else if (viewing == KEYFRAME_VIEW)
81         {
82                 ASSERT(current_story);
83                 if (selected == NULL && current_story->frame != NULL)
84                         printf("Error: BZZZZT, how did you get here?");
85                 else if (current_story->frame == NULL)
86                 {
87                         // this is the first keyframe node, make it the frame
88                         current_story->frame = new KeyFrameNode();
89                         current_story->frame->name = NewNodeName->text();
90                         changeSelected(current_story->frame);
91                         gd->fit();
92                 }
93                 else if (selected != NULL)
94                 {
95                         // add a new node, selected is parent
96                         KeyFrameNode *n = new KeyFrameNode();
97                         n->name = NewNodeName->text();
98                         n->parent = (KeyFrameNode *)selected;
99                         ((KeyFrameNode *)selected)->preconds.push_back(n);
100                         changeSelected(n);
101                 }
102                 else printf("Error: BZZZZT, how did you get here?");
103         }
104
105         else printf("Error: What kind of view is this? %d\n", viewing);
106
107         NewNodeName->clear();
108         NewNodeButton->setEnabled(false);
109
110         gd->repaint();
111 }
112
113
114 void
115 AuthorForm_impl::newNodeTextChanged()
116 {
117         QString text = NewNodeName->text();
118
119         if ((text.length() > 0) && (
120                 ((viewing == STORY_VIEW) && (selected || story_root == NULL)) ||
121                 ((viewing == KEYFRAME_VIEW) && (selected || current_story->frame == NULL))
122            ))
123                 NewNodeButton->setEnabled(true);
124         else
125                 NewNodeButton->setEnabled(false);
126 }
127
128
129 void
130 AuthorForm_impl::saveTextChanged(const QString &text)
131 {
132         if (text.length() > 0)  SaveButton->setEnabled(true);
133         else                                    SaveButton->setEnabled(false);
134 }
135
136
137 void
138 AuthorForm_impl::changeSelected(AuthorNode *n)
139 {
140         if (selected) selected->icon->deselect();
141
142         if (!n) {
143                 // Hack to make sure things don't crash if cell is being edited
144                 for (int x = 0; x < Table->numRows(); x++)
145                         for (int y = 0; y < Table->numCols(); y++) {
146                                 Table->clearCellWidget(x,y);
147                                 Table->clearCell(x,y);
148                         }
149                 Table->setEnabled(false);
150         }
151         else
152         {
153                 n->icon->select();
154                 if (n->type == NODE_STORY) {
155                         // Hack to make sure things don't crash if cell is being edited
156                         for (int x = 0; x < Table->numRows(); x++)
157                                 for (int y = 0; y < Table->numCols(); y++) {
158                                         Table->clearCellWidget(x,y);
159                                         Table->clearCell(x,y);
160                                 }
161                         Table->setEnabled(false);
162                 }
163                 else {
164                         Table->setEnabled(true);
165
166                         // Populate table
167                         for (int i = 0; i < NUM_COND; i++)
168                                 for (int j = 0; j < NUM_COND; j++)
169                                         if (((KeyFrameNode*)n)->conditions.conditions[i][j].size() > 0)
170                                                 Table->setText(i, j, ((KeyFrameNode*)n)->conditions.conditions[i][j].c_str());
171                                         else Table->clearCell(i,j);
172                 }
173         }
174
175         selected = n;
176         gd->repaint();
177 }
178
179
180 void
181 AuthorForm_impl::storyView()
182 {
183         ViewLabel->setText("Story View");
184         ReturnButton->setEnabled(false);
185         viewing = STORY_VIEW;
186         changeSelected(NULL);
187
188         gd->fit();
189         gd->repaint();
190 }
191
192 void
193 AuthorForm_impl::keyframeView(StoryNode* current)
194 {
195         ASSERT(current);
196
197         ViewLabel->setText("Keyframe View");
198         ReturnButton->setEnabled(true);
199         viewing = KEYFRAME_VIEW;
200         current_story = current;
201         changeSelected(current->frame);
202
203         gd->fit();
204         gd->repaint();
205 }
206
207
208 void
209 AuthorForm_impl::cellValueChanged(int x, int y)
210 {
211         if (selected && viewing == KEYFRAME_VIEW) {
212                 QTableItem *i = Table->item(x,y);
213
214                 if (CheckValidOps(string(Table->text(x,y)), x, y) || (Table->text(x,y).length() == 0))
215                 {
216                         ((KeyFrameNode *)selected)->conditions.conditions[x][y] =
217                                 Table->text(x,y);
218                         QPixmap p;
219                         i->setPixmap(p);
220                 }
221                 else
222                 {
223                         QPixmap p(100,100);
224                         p.fill(QColor(255,0,0));
225                         i->setPixmap(p);
226                 }
227         }
228 }
229
230
231
232
233 /************************************************
234  * Save()/Load()/Delete() implementations --
235  *      This just seemed like a convenient place to put them...
236  ************************************************/
237 void
238 AuthorForm_impl::save()
239 {
240         if (!conn) {printf("No DB connection!\n"); return;}
241         char query[256], escape[256];
242         MYSQL_ROW row;
243         MYSQL_RES *result;
244         int story_id = -1;
245
246         // See if it already exists
247         mysql_escape_string(escape, SaveName->text().latin1(), strlen(SaveName->text().latin1()));
248         _snprintf(query, 256,
249                 "SELECT story_id FROM Stories "
250                 "WHERE name = '%s'", escape);
251         mysql_query(conn, query);
252         if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
253         result = mysql_store_result(conn);
254         if (row = mysql_fetch_row(result))
255                 del_story(atoi(row[0]));        // Make way for new data
256         mysql_free_result(result);
257
258         // Insert data
259         _snprintf(query, 256,
260                 "INSERT INTO Stories "
261                 "VALUES(0, '%s', NOW())", escape);
262         mysql_query(conn, query);
263         if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
264         story_id = mysql_insert_id(conn);       // Auto increment field
265
266         if (story_root) story_root->save(story_id, 0);
267 }
268
269
270 int
271 StoryNode::save(int story_id, int parent_id)
272 {
273         if (!conn) {printf("No DB connection!\n"); return -1;}
274         char query[256], escape[256];
275         int node_id = -1, frame_id = -1;
276
277         // Save this node's frame
278         if (frame) frame_id = frame->save(story_id, 0);
279
280         // Save this node
281         mysql_escape_string(escape, name.c_str(), strlen(name.c_str()));
282         _snprintf(query, 256,
283                 "INSERT INTO StoryNodes "
284                 "VALUES(0, %d, '%s', %d, %d, %d, %d)",
285                 story_id, escape, parent_id, frame_id, icon->ul_x, icon->ul_y);
286         mysql_query(conn, query);
287         if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
288         node_id = mysql_insert_id(conn);        // Auto increment field
289
290         // Save children
291         std::vector<StoryNode*>::iterator It;
292         for (It = next.begin(); It != next.end(); It++)
293                 if (*It) (*It)->save(story_id, node_id);
294
295         return node_id;
296 }
297
298
299 int
300 KeyFrameNode::save(int story_id, int parent_id)
301 {
302         if (!conn) {printf("No DB connection!\n"); return -1;}
303         char query[256], escape[256];
304         int node_id = -1;
305
306         // Save this node
307         mysql_escape_string(escape, name.c_str(), strlen(name.c_str()));
308         _snprintf(query, 256,
309                 "INSERT INTO KeyFrameNodes "
310                 "VALUES(0, %d, '%s', %d, %d, %d)",
311                 story_id, escape, parent_id, icon->ul_x, icon->ul_y);
312         mysql_query(conn, query);
313         if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
314         node_id = mysql_insert_id(conn);        // Auto increment field
315
316         // Save this node's conditions
317         for (int x = 0; x < NUM_COND; x++)
318                 for (int y = 0; y < NUM_COND; y++)
319                         if (conditions.conditions[x][y].size() > 0)
320                         {
321                                 mysql_escape_string(escape, conditions.conditions[x][y].c_str(),
322                                         strlen(conditions.conditions[x][y].c_str()));
323                                 _snprintf(query, 256,
324                                         "INSERT INTO Conditions "
325                                         "VALUES(%d, %d, %d, %d, '%s')",
326                                         node_id, story_id, x, y, escape);
327                                 mysql_query(conn, query);
328                                 if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
329                         }
330
331         // Save children
332         std::vector<KeyFrameNode*>::iterator It;
333         for (It = preconds.begin(); It != preconds.end(); It++)
334                 if (*It) (*It)->save(story_id, node_id);
335
336         return node_id;
337 }
338
339
340 void
341 AuthorForm_impl::del_story(int story_id)
342 {
343         if (!conn) {printf("No DB connection!\n"); return;}
344         char query[256];
345
346         // Stories...
347         _snprintf(query, 256,
348                 "DELETE FROM Stories WHERE story_id = %d", story_id);
349         mysql_query(conn, query);
350         if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
351
352         // Conditions...
353         _snprintf(query, 256,
354                 "DELETE FROM Conditions WHERE story_id = %d", story_id);
355         mysql_query(conn, query);
356         if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
357
358         // StoryNodes...
359         _snprintf(query, 256,
360                 "DELETE FROM StoryNodes WHERE story_id = %d", story_id);
361         mysql_query(conn, query);
362         if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
363
364         // KeyFrameNodes...
365         _snprintf(query, 256,
366                 "DELETE FROM KeyFrameNodes WHERE story_id = %d", story_id);
367         mysql_query(conn, query);
368         if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
369 }
370
371
372 void 
373 AuthorForm_impl::del_story()
374 {
375         if (!ld) return;
376
377         if (!QMessageBox::warning(this, "DEUS", "Delete for good?", "Yes", "No way!", 0, 0, 1)) {
378                 del_story(atoi(ld->ListView->selectedItem()->text(0)));
379                 populateLoad();
380         }
381 }
382
383
384 void
385 StoryNode::del_node()
386 {
387         // Clear out children
388         std::vector<StoryNode*>::iterator It;
389         for (It = next.begin(); It != next.end(); It++) {
390                 if (*It) (*It)->del_node();
391                 delete *It;
392         }
393        
394         // Clear out frame
395         if (frame)      {
396                 frame->del_node();
397                 delete frame;
398         }
399
400         delete icon;
401 }
402
403
404 void
405 KeyFrameNode::del_node()
406 {
407         // Clear out children
408         std::vector<KeyFrameNode*>::iterator It;
409         for (It = preconds.begin(); It != preconds.end(); It++) {
410                 if (*It) (*It)->del_node();
411                 delete *It;
412         }
413
414         delete icon;
415 }
416
417
418 void
419 AuthorForm_impl::load(int story_id)
420 {
421         // First, clear out what's in memory
422         if (story_root) {
423                 story_root->del_node();
424                 delete story_root;
425                 story_root = NULL;
426                 selected = NULL;
427         }
428
429         // Then, start loading from the story root
430         if (!conn) {printf("No DB connection!\n"); return;}
431         char query[256];
432         MYSQL_ROW row;
433         MYSQL_RES *result;
434
435         // Story
436         _snprintf(query, 256,
437                 "SELECT name FROM Stories "
438                 "WHERE story_id = %d", story_id);
439         mysql_query(conn, query);
440         if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
441         result = mysql_store_result(conn);
442         if (row = mysql_fetch_row(result))
443                         SaveName->setText(row[0]);
444         mysql_free_result(result);
445
446
447         // StoryNodes
448         int cur_id; StoryNode* cur_node; std::pair<int,StoryNode*> cur_pair;
449         map<int,StoryNode*> story_nodes;        // node_id -> Node*
450         map<int,StoryNode*> saved_nodes;
451         story_nodes.insert(std::pair<int,StoryNode*>(0,NULL));
452        
453         while (story_nodes.size() > 0)
454         {
455                 cur_pair = *(story_nodes.begin());
456                 cur_id = cur_pair.first;
457                 cur_node = cur_pair.second;
458                 story_nodes.erase(cur_id);
459
460                 _snprintf(query, 256,
461                         "SELECT * FROM StoryNodes "
462                         "WHERE story_id = %d "
463                         "       AND parent_id = %d", story_id, cur_id);
464                 mysql_query(conn, query);
465                 if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
466                 result = mysql_store_result(conn);
467                 while (row = mysql_fetch_row(result))
468                 {
469                         StoryNode *n = new StoryNode();
470                         n->name = row[2];
471                         n->parent = cur_node;
472                         n->icon->ul_x = atoi(row[5]);
473                         n->icon->ul_y = atoi(row[6]);
474                         n->icon->draw();
475
476                         story_nodes.insert(std::pair<int,StoryNode*>(atoi(row[0]), n));
477                         saved_nodes.insert(std::pair<int,StoryNode*>(atoi(row[4]), n));
478                        
479                         if (cur_node) cur_node->next.push_back(n);
480                         else story_root = n;
481                 }               
482                 mysql_free_result(result);
483         }
484
485
486         // KeyFrameNodes
487         KeyFrameNode* cur_key; int cur_key_id; std::pair<int,KeyFrameNode*> cur_key_pair;
488         std::map<int,KeyFrameNode*> keyframe_nodes, saved_keys;
489         std::map<int,StoryNode*>::iterator It;
490         for (It = saved_nodes.begin(); It != saved_nodes.end(); It++)
491         {
492                 cur_id = It->first;             // this is now the frame_id
493                 cur_node = It->second;
494
495                 // root of each keyframe
496                 _snprintf(query, 256,
497                         "SELECT * FROM KeyFrameNodes "
498                         "WHERE node_id = %d ", cur_id);
499                 mysql_query(conn, query);
500                 if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
501                 result = mysql_store_result(conn);
502                 if (row = mysql_fetch_row(result))
503                 {
504                         KeyFrameNode *n = new KeyFrameNode();
505                         n->name = row[2];
506                         n->parent = NULL;
507                         n->icon->ul_x = atoi(row[4]);
508                         n->icon->ul_y = atoi(row[5]);
509                         n->icon->draw();
510
511                         keyframe_nodes.insert(std::pair<int,KeyFrameNode*>(atoi(row[0]), n));
512                         saved_keys.insert(std::pair<int,KeyFrameNode*>(atoi(row[0]), n));
513                         cur_node->frame = n;
514                 }
515                 mysql_free_result(result);
516                        
517                 // keyframe children
518                 while (keyframe_nodes.size() > 0)
519                 {
520                         cur_key_pair = *(keyframe_nodes.begin());
521                         cur_key_id = cur_key_pair.first;
522                         cur_key = cur_key_pair.second;
523                         keyframe_nodes.erase(cur_key_id);
524
525                         _snprintf(query, 256,
526                                 "SELECT * FROM KeyFrameNodes "
527                                 "WHERE parent_id = %d ", cur_key_id);
528                         mysql_query(conn, query);
529                         if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
530                         result = mysql_store_result(conn);
531                         while (row = mysql_fetch_row(result))
532                         {
533                                 KeyFrameNode *n = new KeyFrameNode();
534                                 n->name = row[2];
535                                 n->parent = cur_key;
536                                 n->icon->ul_x = atoi(row[4]);
537                                 n->icon->ul_y = atoi(row[5]);
538                                 n->icon->draw();
539
540                                 keyframe_nodes.insert(std::pair<int,KeyFrameNode*>(atoi(row[0]), n));
541                                 saved_keys.insert(std::pair<int,KeyFrameNode*>(atoi(row[0]), n));
542                                 cur_key->preconds.push_back(n);
543                         }
544                         mysql_free_result(result);
545                 }
546         }
547
548        
549         // Conditions
550         std::map<int,KeyFrameNode*>::iterator It2;
551         for (It2 = saved_keys.begin(); It2 != saved_keys.end(); It2++)
552         {
553                 cur_key_id = It2->first;
554                 cur_key = It2->second;
555
556                 _snprintf(query, 256,
557                         "SELECT * FROM Conditions "
558                         "WHERE node_id = %d ", cur_key_id);
559                 mysql_query(conn, query);
560                 if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
561                 result = mysql_store_result(conn);
562                 while (row = mysql_fetch_row(result))
563                         cur_key->conditions.conditions[atoi(row[2])][atoi(row[3])] = row[4];
564                 mysql_free_result(result);
565         }
566
567         storyView();   
568 }
569
570
571 void
572 AuthorForm_impl::load()
573 {
574         delete ld;
575         ld = new LoadDialog(this, "load_story", true);
576         connect((QObject *)ld->LoadButton, SIGNAL(clicked()), (QObject *)ld, SLOT(accept()));
577         connect((QObject *)ld->CancelButton, SIGNAL(clicked()), (QObject *)ld, SLOT(reject()));
578         connect((QObject *)ld->DeleteButton, SIGNAL(clicked()), this, SLOT(del_story()));
579        
580         // populate load dialog
581         populateLoad();
582
583         if (ld->exec())
584                 load(atoi(ld->ListView->selectedItem()->text(0)));
585 }
586
587
588 void 
589 AuthorForm_impl::populateLoad()
590 {
591         if (!ld) return;
592         ld->ListView->clear();
593
594         // Populate the list
595         if (!conn) {printf("No DB connection!\n"); return;}
596         MYSQL_ROW row;
597         MYSQL_RES *result;
598         QListViewItem *lv = NULL;       // this will be the selected item
599
600         mysql_query(conn, "SELECT * FROM Stories");
601         if (mysql_error(conn)[0] != '\0') printf("%s\n", mysql_error(conn));
602         result = mysql_store_result(conn);
603         while (row = mysql_fetch_row(result))
604         {
605                 QListViewItem * li = new QListViewItem(ld->ListView, row[0], row[1], row[2]);
606                 if (!lv) lv = li;
607         }
608         mysql_free_result(result);
609         ld->ListView->setSelected(lv, true);
610 }
611
612
Note: See TracBrowser for help on using the browser.