1 module examplewidgets.mainwindow;
2 
3 import qt.config;
4 import qt.core.coreevent;
5 import qt.core.string;
6 import qt.core.translator;
7 import qt.gui.action;
8 import qt.helpers;
9 import qt.widgets.mainwindow;
10 import qt.widgets.ui;
11 import qt.widgets.widget;
12 
13 // Using MainWindowUI instead of UIStruct!"mainwindow.ui" prevents a forward referencing error.
14 struct MainWindowUI
15 {
16     mixin(generateUICode(import("mainwindow.ui"), "examplewidgets"));
17 }
18 
19 immutable string[2][] languages = [
20     ["English", "en"],
21     ["Deutsch", "de"]
22 ];
23 
24 class MainWindow : QMainWindow
25 {
26     mixin(Q_OBJECT_D);
27 
28 public:
29     this(QWidget parent = null)
30     {
31         import core.stdcpp.new_;
32         import qt.core.coreapplication;
33         import qt.gui.actiongroup;
34         super(parent);
35         this.ui = cpp_new!(typeof(*ui));
36 
37         ui.setupUi(this);
38 
39         /* Create a menu for selecting the language.
40          * The menu will contain entries for English and German.
41          * Only some parts of the UI are translated as an example.
42          * English is the default and already used in the *.ui files.
43          * See https://doc.qt.io/qt-6/internationalization.html for
44          * general information about translating Qt applications. The
45          * translatable texts are first collected with the following
46          * commands:
47          * lupdate examples/examplewidgets/*.ui -locations none -no-obsolete -ts examples/examplewidgets/examplewidgets_en.ts
48          * lupdate examples/examplewidgets/*.ui -locations none -no-obsolete -ts examples/examplewidgets/examplewidgets_de.ts
49          *
50          * The translations can then be changed with linguist (https://doc.qt.io/qt-6/qtlinguist-index.html).
51          * No changes are used for English, because that is the default.
52          * The *.ts files now have to be converted to *.qm files, which
53          * are used by the application:
54          * lrelease examples/examplewidgets/examplewidgets*.ts
55          *
56          * The last step would normally be part of the build process,
57          * but the repository already contains the *.qm files for this
58          * example.
59          */
60         QActionGroup actionGroupLanguage = cpp_new!QActionGroup(this);
61         foreach(lang; languages)
62         {
63             QString name = QString(lang[0]);
64             QAction action = actionGroupLanguage.addAction(name);
65             action.setCheckable(true);
66             action.setData(QString(lang[1]));
67         }
68         ui.menuLanguage.addActions(actionGroupLanguage.actions());
69         actionGroupLanguage.actions()[0].setChecked(true);
70         connect(actionGroupLanguage.signal!"triggered", this.slot!"onLanguageActionTriggered");
71 
72         translator = cpp_new!QTranslator(this);
73         QCoreApplication.instance().installTranslator(translator);
74     }
75     ~this()
76     {
77         import core.stdcpp.new_;
78 
79         cpp_delete(ui);
80     }
81 
82 private /+ slots +/:
83     @QSlot final void on_actionAbout_Qt_triggered()
84     {
85         import qt.widgets.messagebox;
86 
87         QMessageBox.aboutQt(this);
88     }
89 
90     @QSlot final void on_actionSystem_Info_triggered()
91     {
92         import qt.core.sysinfo;
93         import qt.widgets.messagebox;
94 
95         QString text = QString.create;
96         text ~= "Hostname: " ~ QSysInfo.machineHostName() ~ "\n";
97         text ~= "Pretty Product Name: " ~ QSysInfo.prettyProductName() ~ "\n";
98         text ~= "Product: " ~ QSysInfo.productType() ~ " " ~ QSysInfo.productVersion() ~ "\n";
99         text ~= "Kernel: " ~ QSysInfo.kernelType() ~ " " ~ QSysInfo.kernelVersion() ~ "\n";
100         text ~= "Build ABI: " ~ QSysInfo.buildAbi() ~ "\n";
101         text ~= "CPU Architecture: " ~ QSysInfo.buildCpuArchitecture() ~ "\n";
102         text ~= "Current CPU Architecture: " ~ QSysInfo.currentCpuArchitecture();
103         QMessageBox.information(this, QString("System Info"), text);
104     }
105 
106     @QSlot final void onLanguageActionTriggered(QAction action)
107     {
108         QString lang = action.data().toString();
109         QString filename = "examplewidgets_" ~ lang;
110         QString dir = QString("examples/examplewidgets");
111         /* Change the used translation file. The will also trigger
112          * the LanguageChange event for all widgets and is used to
113          * retranslate the UIs.
114          */
115         translator.load(filename, dir);
116     }
117 
118 protected:
119     override extern(C++) void changeEvent(QEvent event)
120     {
121         if(event.type() == QEvent.Type.LanguageChange)
122             ui.retranslateUi(this);
123         QMainWindow.changeEvent(event);
124     }
125 
126 private:
127     MainWindowUI* ui;
128     QTranslator translator;
129 }