OSDN Git Service

[UI][Qt][EMU] Available to build.Some features still be wrong :-(
[csp-qt/common_source_project-fm7.git] / source / src / qt / gui / menu_metaclass.cpp
1 /*
2  * Widget: Meta Menu Class.
3  * (C) 2015 K.Ohta <whatisthis.sowhat _at_ gmail.com>
4  * License: GPLv2
5  * History: 2015-11-11 Initial.
6  */
7
8 #include <QAction>
9 #include <QActionGroup>
10 #include <QWidget>
11 #include <QDir>
12 #include <QStyle>
13 #include <QApplication>
14 #include <QMenuBar>
15
16 //#include "emu.h"
17 //#include "vm.h"
18 #include "qt_dialogs.h"
19 #include "menu_metaclass.h"
20 #include "commonclasses.h"
21 #include "mainwidget_base.h"
22 #include "commonclasses.h"
23 #include "qt_main.h"
24
25 Menu_MetaClass::Menu_MetaClass(QMenuBar *root_entry, QString desc, std::shared_ptr<USING_FLAGS> p, QWidget *parent, int drv, int base_drv) : QMenu(root_entry)
26 {
27         QString tmps;
28         int ii;
29         
30         p_wid = parent;
31         menu_root = root_entry;
32
33         //p_emu = ep;
34         p_emu = NULL;
35         using_flags = p;
36         p_config = p->get_config_ptr();
37         
38         media_drive = drv;
39         base_drive = base_drv;
40         
41         tmps.setNum(drv);
42         object_desc = QString::fromUtf8("Obj_") + desc;
43         object_desc.append(tmps);
44         setObjectName(object_desc);
45
46         for(ii = 0; ii < using_flags->get_max_d88_banks(); ii++) {
47                 action_select_media_list[ii] = NULL;
48         }
49         use_write_protect = true;
50         use_d88_menus = false;
51         initial_dir = QString::fromUtf8("");
52         
53         ext_filter.clear();
54
55         history.clear();
56
57         dialogs.clear();
58         
59         inner_media_list.clear();
60         window_title = QString::fromUtf8("");
61
62         icon_insert = QIcon(":/icon_open.png");
63         icon_eject = QIcon(":/icon_eject.png");
64         icon_write_protected = QApplication::style()->standardIcon(QStyle::SP_DialogApplyButton);
65         icon_write_enabled = QIcon();
66         setToolTipsVisible(true);
67         
68         connect(this, SIGNAL(sig_emu_update_config()), p_wid, SLOT(do_emu_update_config()));
69         
70         tmps = QString::fromUtf8("%1").arg(drv + base_drv);
71         tmps = desc + tmps;
72         setTitle(tmps);
73 }
74
75 Menu_MetaClass::~Menu_MetaClass()
76 {
77         for(auto i = dialogs.begin(); i != dialogs.end(); ++i) {
78                 if((*i) != nullptr) {
79                         dialogs.erase(i);
80                         (*i)->deleteLater();
81                 }
82         }
83 }
84
85
86 // This is virtual function, pls. override.
87 void Menu_MetaClass::do_set_write_protect(bool f)
88 {
89         write_protect = f;
90         if(f) {
91                 if(use_write_protect) {
92                         menu_write_protect->setIcon(icon_write_protected);
93                 }
94                 action_write_protect_on->setChecked(true);
95         } else {
96                 if(use_write_protect) {
97                         menu_write_protect->setIcon(icon_write_enabled);
98                 }
99                 action_write_protect_off->setChecked(true);
100         }               
101 }
102
103 void Menu_MetaClass::do_set_initialize_directory(const char *s)
104 {
105         initial_dir = QString::fromLocal8Bit(s);
106 }
107
108 void Menu_MetaClass::do_open_media(int drv, QString name)
109 {
110         //write_protect = false; // Right? On D88, May be writing entry  exists. 
111         emit sig_open_media(drv, name);
112 }
113
114 void Menu_MetaClass::do_insert_media(void)
115 {
116         //write_protect = false; // Right? On D88, May be writing entry  exists. 
117         emit sig_insert_media(media_drive);
118 }
119
120 void Menu_MetaClass::do_eject_media(void)
121 {
122         write_protect = false;
123         emit sig_eject_media(media_drive);
124 }
125
126 void Menu_MetaClass::do_open_inner_media(void)
127 {
128         QAction *cp = qobject_cast<QAction*>(QObject::sender());
129         if(cp == nullptr) return;
130         struct CSP_Ui_Menu::DriveIndexPair tmp = cp->data().value<CSP_Ui_Menu::DriveIndexPair>();
131         
132         emit sig_set_inner_slot(tmp.drive, tmp.index);
133 }
134
135 void Menu_MetaClass::do_open_recent_media(void)
136 {
137         QAction *cp = qobject_cast<QAction*>(QObject::sender());
138         if(cp == nullptr) return;
139         struct CSP_Ui_Menu::DriveIndexPair tmp = cp->data().value<CSP_Ui_Menu::DriveIndexPair>();
140         
141   //   write_protect = false; // Right? On D88, May be writing entry  exists. 
142         emit sig_set_recent_media(tmp.drive, tmp.index);
143 }
144
145 void Menu_MetaClass::do_write_protect_media(void)
146 {
147         write_protect = true;
148         {
149                 if(use_write_protect) {
150                         menu_write_protect->setIcon(icon_write_protected);
151                 }
152                 action_write_protect_on->setChecked(true);
153         }               
154         emit sig_write_protect_media(media_drive, write_protect);
155 }
156
157 void Menu_MetaClass::do_write_unprotect_media(void) {
158         write_protect = false;
159         {
160                 if(use_write_protect) {
161                         menu_write_protect->setIcon(icon_write_enabled);
162                 }
163                 action_write_protect_off->setChecked(true);
164         }               
165         emit sig_write_protect_media(media_drive, write_protect);
166 }
167
168 void Menu_MetaClass::do_set_window_title(QString s) {
169         window_title = s;
170 }
171
172 void Menu_MetaClass::do_add_media_extension(QString ext, QString description)
173 {
174         QString tmps = description;
175         QString all = QString::fromUtf8("All Files (*.*)");
176
177         tmps.append(QString::fromUtf8(" ("));
178         tmps.append(ext.toLower());
179         tmps.append(QString::fromUtf8(" "));
180         tmps.append(ext.toUpper());
181         tmps.append(QString::fromUtf8(")"));
182
183         ext_filter << tmps;
184         ext_filter << all;
185
186         ext_filter.removeDuplicates();
187 }
188
189 void Menu_MetaClass::do_select_inner_media(int num)
190 {
191         if(use_d88_menus && (num < using_flags->get_max_d88_banks())) {
192                 if(action_select_media_list[num] != NULL) {
193                         action_select_media_list[num]->setChecked(true);
194                 }
195         }
196 }
197 void Menu_MetaClass::do_close_window()
198 {
199         CSP_DiskDialog *p = qobject_cast<CSP_DiskDialog*>(QObject::sender());
200         for(auto i = dialogs.begin(); i != dialogs.end(); ++i) {
201                 if((*i) == p) {
202                         dialogs.erase(i);
203                         p->deleteLater();
204                         //dialogs.squeeze();
205                         return;
206                 }
207         }
208 }
209 void Menu_MetaClass::do_finish(int i)
210 {
211         do_close_window();
212 }
213
214 void Menu_MetaClass::do_open_dialog()
215 {
216         CSP_DiskDialog *dlg = new CSP_DiskDialog(this);
217         do_open_dialog_common(dlg);
218         emit sig_show();
219 }       
220 void Menu_MetaClass::do_open_dialog_common(CSP_DiskDialog* dlg)
221 {
222         // ToDo : Load State of Qt.
223         if(initial_dir.isEmpty()) { 
224                 QDir dir;
225                 char app[PATH_MAX];
226                 initial_dir = dir.currentPath();
227                 strncpy(app, initial_dir.toLocal8Bit().constData(), PATH_MAX - 1);
228                 initial_dir = QString::fromLocal8Bit(get_parent_dir(app));
229         }
230
231         dlg->setOption(QFileDialog::ReadOnly, false);
232         dlg->setOption(QFileDialog::DontUseNativeDialog, true);
233         //dlg->setAcceptMode(QFileDialog::AcceptSave);
234         dlg->setFileMode(QFileDialog::AnyFile);
235         //dlg->setLabelText(QFileDialog::Accept, QApplication::translate("MenuMedia", "Open File", 0));
236         dlg->param->setDrive(media_drive);
237         dlg->param->setPlay(true);
238         dlg->param->setDirectory(initial_dir);
239         dlg->param->setNameFilters(ext_filter);
240
241         QString tmps;
242         tmps = QApplication::translate("MenuMedia", "Open", 0);
243         if(!window_title.isEmpty()) {
244                 tmps = tmps + QString::fromUtf8(" ") + window_title;
245         } else {
246                 tmps = tmps + QString::fromUtf8(" ") + this->title();
247         }
248         dlg->setWindowTitle(tmps);
249
250         dlg->setModal(false);
251
252         connect(dlg, SIGNAL(fileSelected(QString)), dlg->param, SLOT(_open_disk(QString))); 
253         connect(dlg->param, SIGNAL(sig_open_disk(int, QString)), this, SLOT(do_open_media(int, QString)));
254         connect(dlg, SIGNAL(accepted()), this, SLOT(do_close_window()), Qt::QueuedConnection); 
255         connect(dlg, SIGNAL(rejected()), this, SLOT(do_close_window()), Qt::QueuedConnection); 
256         connect(dlg, SIGNAL(finished(int)), this, SLOT(do_finish(int)), Qt::QueuedConnection); 
257
258         connect(this, SIGNAL(sig_show()), dlg, SLOT(show()), Qt::QueuedConnection); 
259         dlg->do_update_params(); // update Extensions, directories
260
261         dialogs.append(dlg);
262         
263         //dlg->open();
264         //dlg->show();
265         //dlg->exec();
266         return;
267 }
268
269 void Menu_MetaClass::do_insert_history(QString path)
270 {
271         QStringList lst;
272         for(int i = 0; i < MAX_HISTORY ; i++) {
273                 if(action_recent_list[i] != nullptr) {
274                         QString tmpstr = action_recent_list[i]->text();
275                         lst.append(tmpstr);
276                 }
277         }
278         if(lst.at(0) == path) {
279                 // None changed.
280                 return;
281         }
282         QStringList lst2;
283         lst2.clear();
284         for(size_t i = 0 ; i < lst.size(); i++) {
285                 if(path != lst.at(i)) lst2.append(lst.at(i));
286         }
287         lst2.push_front(path);
288         do_update_histories(lst2);
289 }
290 void Menu_MetaClass::do_update_histories(QStringList lst)
291 {
292         QString tmps;
293         int ptr = 0;
294         for(int i = 0; i < lst.size(); i++) {
295                 if(i >= MAX_HISTORY) break;
296                 action_recent_list[i]->setText(lst.at(i));
297                 action_recent_list[i]->setVisible(true);
298                 ptr++;
299         }
300         for(int i = ptr; i < MAX_HISTORY; i++) {
301                 action_recent_list[i]->setText(QString::fromUtf8(""));
302                 action_recent_list[i]->setVisible(false);
303         }       
304 }
305
306
307 void Menu_MetaClass::do_clear_inner_media(void)
308 {
309         int ii;
310         inner_media_list.clear();
311         if(use_d88_menus) {
312                 for(ii = 0; ii < using_flags->get_max_d88_banks(); ii++) {
313                         if(action_select_media_list[ii] != nullptr) {
314                                 action_select_media_list[ii]->setText(QString::fromUtf8(""));
315                                 action_select_media_list[ii]->setVisible(false);
316                         }
317                 }
318         }
319 }
320
321
322 void Menu_MetaClass::do_update_inner_media(QStringList lst, int num)
323 {
324         QString tmps;
325         inner_media_list.clear();
326         emit sig_update_inner_fd(media_drive, inner_media_list, action_select_media_list, lst , num, use_d88_menus);
327 }
328
329 void Menu_MetaClass::do_update_inner_media_bubble(QStringList lst, int num)
330 {
331         QString tmps;
332         inner_media_list.clear();
333         emit sig_update_inner_bubble(media_drive, inner_media_list, action_select_media_list,
334                                                                  lst, num, use_d88_menus);
335 }
336
337 void Menu_MetaClass::create_pulldown_menu_sub(void)
338 {
339         action_insert = new Action_Control(p_wid, using_flags);
340         action_insert->setObjectName(QString::fromUtf8("action_insert_") + object_desc);
341         
342         struct CSP_Ui_Menu::DriveIndexPair tmp;
343         QVariant _tmp_ins;
344         
345         tmp.drive = media_drive;
346         tmp.index = 0;
347         _tmp_ins.setValue(tmp);
348         action_insert->setData(_tmp_ins);
349         
350         connect(action_insert, SIGNAL(triggered()), this, SLOT(do_open_dialog()), Qt::QueuedConnection);
351         action_insert->setIcon(icon_insert);
352         
353         action_eject = new Action_Control(p_wid, using_flags);
354         action_eject->setObjectName(QString::fromUtf8("action_eject_") + object_desc);
355
356         QVariant _tmp_eject;
357         tmp.drive = media_drive;
358         tmp.index = 0;
359         _tmp_eject.setValue(tmp);
360         action_eject->setData(_tmp_eject);
361
362         connect(action_eject, SIGNAL(triggered()), this, SLOT(do_eject_media()));
363         action_eject->setIcon(icon_eject);
364
365         
366         {
367                 QString tmps;
368                 int ii;
369                 action_group_recent = new QActionGroup(p_wid);
370                 action_group_recent->setExclusive(true);
371                 
372                 for(ii = 0; ii < MAX_HISTORY; ii++) {
373                         tmps = history.value(ii, "");
374                         action_recent_list[ii] = new Action_Control(p_wid, using_flags);
375                         struct CSP_Ui_Menu::DriveIndexPair tmp2;
376                         tmp2.drive = media_drive;
377                         tmp2.index = ii;
378                         QVariant _tmp2v;
379                         _tmp2v.setValue(tmp2);
380                         
381                         action_recent_list[ii]->setData(_tmp2v);
382                         action_recent_list[ii]->setText(tmps);
383                         
384                         action_group_recent->addAction(action_recent_list[ii]);
385                         if(!tmps.isEmpty()) {
386                                 action_recent_list[ii]->setVisible(true);
387                         } else {
388                                 action_recent_list[ii]->setVisible(false);
389                         }                       
390                 }
391         }
392         if(use_d88_menus) {
393                 int ii;
394                 QString tmps;
395                 action_group_inner_media = new QActionGroup(p_wid);
396                 action_group_inner_media->setExclusive(true);
397                 
398                 for(ii = 0; ii < using_flags->get_max_d88_banks(); ii++) {
399                         tmps = history.value(ii, "");
400                         action_select_media_list[ii] = new Action_Control(p_wid, using_flags);
401                         struct CSP_Ui_Menu::DriveIndexPair tmp2;
402                         tmp2.drive = media_drive;
403                         tmp2.index = ii;
404                         QVariant _tmp2v;
405                         _tmp2v.setValue(tmp2);
406                         action_select_media_list[ii]->setData(_tmp2v);
407                         
408                         action_select_media_list[ii]->setText(tmps);
409                         action_select_media_list[ii]->setCheckable(true);
410                         if(ii == 0) action_select_media_list[ii]->setChecked(true);
411                         action_group_inner_media->addAction(action_select_media_list[ii]);
412                         if(!tmps.isEmpty()) {
413                                 action_select_media_list[ii]->setVisible(true);
414                         } else {
415                                 action_select_media_list[ii]->setVisible(false);
416                         }                       
417                 }
418         }
419         if(use_write_protect) {
420                 action_group_protect = new QActionGroup(p_wid);
421                 action_group_protect->setExclusive(true);
422
423                 action_write_protect_on = new Action_Control(p_wid, using_flags);
424                 action_write_protect_on->setObjectName(QString::fromUtf8("action_write_protect_on_") + object_desc);
425                 action_write_protect_on->setCheckable(true);
426                 action_write_protect_on->setChecked(true);
427                 action_write_protect_on->setData(QVariant(media_drive));
428                 
429                 action_write_protect_off = new Action_Control(p_wid, using_flags);
430                 action_write_protect_off->setObjectName(QString::fromUtf8("action_write_protect_off_") + object_desc);
431                 action_write_protect_off->setCheckable(true);
432                 action_write_protect_off->setData(QVariant(media_drive));
433                 
434                 action_group_protect->addAction(action_write_protect_on);
435                 action_group_protect->addAction(action_write_protect_off);
436                 connect(action_write_protect_on, SIGNAL(triggered()), this, SLOT(do_write_protect_media()));
437                 connect(action_write_protect_off, SIGNAL(triggered()), this, SLOT(do_write_unprotect_media()));
438         }
439 }
440
441 // This is virtual function, pls.apply
442 void Menu_MetaClass::create_pulldown_menu_device_sub(void)
443 {
444         // Create device specific entries.
445 }
446
447 // This is virtual function, pls.apply
448 void Menu_MetaClass::connect_menu_device_sub(void)
449 {
450
451 }
452
453 //void Menu_MetaClass::setTitle(QString s)
454 //{
455 //      QMenu::setTitle(s);
456 //}
457
458 //QAction *Menu_MetaClass::menuAction()
459 //{
460 //      return QMenu::menuAction();
461 //}
462
463 void Menu_MetaClass::create_pulldown_menu(void)
464 {
465         int ii;
466         // Example:: Disk.
467         create_pulldown_menu_sub();
468         create_pulldown_menu_device_sub();
469         // Create 
470
471         menu_history = new QMenu(this);
472         menu_history->setObjectName(QString::fromUtf8("menu_history_") + object_desc);
473
474         if(use_d88_menus) {
475                 menu_inner_media = new QMenu(this);
476                 menu_inner_media->setObjectName(QString::fromUtf8("menu_inner_media_") + object_desc);
477                 for(ii = 0; ii < using_flags->get_max_d88_banks(); ii++) menu_inner_media->addAction(action_select_media_list[ii]);
478                 this->addAction(menu_inner_media->menuAction());
479         }
480         {
481                 menu_history = new QMenu(this);
482                 menu_history->setObjectName(QString::fromUtf8("menu_history_") + object_desc);
483                 for(ii = 0; ii < MAX_HISTORY; ii++) menu_history->addAction(action_recent_list[ii]);
484                 this->addAction(menu_history->menuAction());
485         }
486         if(use_write_protect) {
487                 this->addSeparator();
488                 menu_write_protect = new QMenu(this);
489         }
490         // Belows are setup of menu.
491         this->addAction(action_insert);
492         this->addAction(action_eject);
493
494         // Connect extra menus to this.
495         connect_menu_device_sub();
496         this->addSeparator();
497         
498         // More actions
499         this->addAction(menu_history->menuAction());
500         if(use_d88_menus) {
501                 this->addAction(menu_inner_media->menuAction());
502         }
503         if(use_write_protect) {
504                 this->addSeparator();
505                 this->addAction(menu_write_protect->menuAction());
506                 menu_write_protect->addAction(action_write_protect_on);
507                 menu_write_protect->addAction(action_write_protect_off);
508         }
509         // Do connect!
510         
511         for(ii = 0; ii < MAX_HISTORY; ii++) {
512                 connect(action_recent_list[ii], SIGNAL(triggered()),
513                                 this, SLOT(do_open_recent_media()));
514         }
515         if(use_d88_menus) {
516                 for(ii = 0; ii < using_flags->get_max_d88_banks(); ii++) {
517                         connect(action_select_media_list[ii], SIGNAL(triggered()),
518                                         this, SLOT(do_open_inner_media()));
519                 }
520         }
521 }
522
523 void Menu_MetaClass::retranslate_pulldown_menu_sub(void)
524 {
525         action_insert->setText(QApplication::translate("MenuMedia", "Insert", 0));
526         action_insert->setToolTip(QApplication::translate("MenuMedia", "Insert a virtual image file.", 0));
527         action_eject->setText(QApplication::translate("MenuMedia", "Eject", 0));
528         action_eject->setToolTip(QApplication::translate("MenuMedia", "Eject a inserted virtual image file.", 0));
529         if(use_write_protect) {
530                 menu_write_protect->setTitle(QApplication::translate("MenuMedia", "Write Protection", 0));
531                 menu_write_protect->setToolTipsVisible(true);
532                 action_write_protect_on->setText(QApplication::translate("MenuMedia", "On", 0));
533                 action_write_protect_on->setToolTip(QApplication::translate("MenuMedia", "Enable write protection.\nYou can't write any data to this media.", 0));
534                 action_write_protect_off->setText(QApplication::translate("MenuMedia", "Off", 0));
535                 action_write_protect_off->setToolTip(QApplication::translate("MenuMedia", "Disable write protection.\nYou *can* write datas to this media.", 0));
536         }
537         
538         if(use_d88_menus) {
539                 menu_inner_media->setTitle(QApplication::translate("MenuMedia", "Select D88 Image", 0));
540         } else {
541                 //menu_inner_media->setVisible(false);
542         }               
543         menu_history->setTitle(QApplication::translate("MenuMedia", "Recent opened", 0));
544
545 }
546
547 void Menu_MetaClass::retranslate_pulldown_menu_device_sub(void)
548 {
549 }
550
551 void Menu_MetaClass::retranslateUi(void)
552 {
553         retranslate_pulldown_menu_sub();
554         retranslate_pulldown_menu_device_sub();
555 }
556
557 void Menu_MetaClass::setEmu(EMU_TEMPLATE *p)
558 {
559         p_emu = p;
560 }
561