The development environment (IDE) of Gambas sets in the menu bar under 'File' in the menu 'Recently opened' a menu list of k menus, which changes dynamically at runtime of the development environment. The list can be empty or contain entries whose number is limited. A menu with such properties is called dynamic menu.
Figure 13.3.2.1: Menu with menu list in the Gambas IDE
Planning the use of a dynamic menu requires, among other things, clear answers to the following questions:
(F1) Which menu in the menu structure should be equipped with a dynamic menu?
(F2) What will be saved in the menu list - recognizable by the sign >?
(F3) In which form should the entries in the menu list of the menu selected with (F1) be saved?
(F4) Is the selected menu not displayed or only deactivated if the menu list is empty?
(F5) What is the maximum number of entries to include in the menu list?
(F6) Should the entries in the menu list be sorted?
The above 6 questions are answered project-related in the following project DynMenu:
Figure 13.3.2.1.1.1: Menu with menu list (project DynMenu)
In a project, the preliminary considerations described in Section 13.3.2.1 are implemented when using a dynamic menu. This program has been in use since the beginning of the first publications of chapters of the online book on gambas-buch. de by the authors, when extensive tables have to be converted from a document - written with LibreOffice Writer - into the DokuWiki format.
The procedures that create an instance of the Settings class and configure the Settings object, as well as importing and saving the paths of the recently opened table files, are stored in a module MS.module.
[1] ' Gambas module file [2] ' MS = Module & Settings [3] [4] Private hFile As File [5] Public pSettings As Settings [6] Public Matrix As New String[] [7] Public ShortMatrix As New String[] [8] Public Const iLastNumber As Integer = 5 [9] [10] Public Sub Init() [11] Dim sSettingsPath, sSlotName, sSettingsFileName As String [12] [13] sSlotName = "LastFiles" [14] sSettingsPath = Application.Path &/ sSlotName [15] sSettingsFileName = "lastfiles.conf" [16] [17] If Not Exist(sSettingsPath) Then [18] Mkdir sSettingsPath [19] Endif [20] If Not Exist(sSettingsPath &/ sSettingsFileName) Then [21] hFile = Open (sSettingsPath &/ sSettingsFileName) For Create [22] hFile.Close [23] Endif ' Not Exist(..) [24] [25] ' Ein Settings-Objekt erblickt das Licht im Speicher ... [26] pSettings = New Settings(sSettingsPath &/ sSettingsFileName, "Dateiliste") [27] [28] End ' Init() [29] [30] Public Sub GetLastListFromSettings() [31] Dim iCount As Integer [32] [33] pSettings.Reload() ' optional [34] Matrix.Clear [35] ShortMatrix.Clear [36] iCount = 0 [37] [38] While pSettings["FileList" & "/File" & Str(iCount)] <> Null [39] If Exist(pSettings["FileList" & "/File" & Str(iCount)]) Then ' Existiert diese Datei? [40] Matrix.Add(pSettings["FileList" & "/File" & Str(iCount)]) ' Datei-Pfad in Matrix speichern [41] ' Datei-Name in ShortMatrix speichern [42] ShortMatrix.Add(File.Name(pSettings["FileList" & "/File" & Str(iCount)])) [43] Endif ' File.Exist? [44] Inc iCount [45] Wend ' <> NULL [46] [47] End ' GetLastListFromSettings() [48] [49] Public Sub SetLastListToSettings() [50] Dim iCount As Integer [51] [52] pSettings.Clear [53] For iCount = 0 To Matrix.Max [54] pSettings[sSlotName & "/File" & Str(iCount)] = Matrix[iCount] [55] ' Die maximal 5 Schlüssel-Wert-Paare unter dem Slot "LastFiles" werden generiert [56] Next ' iCount [57] pSettings.Save ' Update der Konfigurationsdatei 'lastfiles.conf' [58] [59] End ' SetLastListToSettings()
The complete project can be found in the download area. Here, the source code - stored in the file FMain. class - is only played back and commented on in excerpts:
[1] ' Gambas class file [2] [3] Public fFile As File [4] Public sCurrentFilePath As String [5] [6] Public Sub Form_Open() [7] [8] FMain.Center [9] FMain.Resizable = False [10] mnu1ConvertTable.Enabled = False [11] mnu1SaveTable.Enabled = False [12] mnu2CenteredTable.Checked = False [13] btnReset.Enabled = False [14] [15] MS.Init() [16] MS.GetLastListFromSettings() [17] UpdateMenu() [18] [19] End ' Form_Open() [20] [21] Public Sub UpdateMenu() [22] Dim MenuItem As Menu [23] Dim sFileName As String [24] [25] mnu1LastFiles.Children.Clear ' Alle alten Einträge in der Menüliste von mnu1LastFiles löschen [26] If MS.ShortMatrix.Count = 0 Then ' Wenn die Menüliste leer ist ... [27] mnu1LastFiles.Visible = False ' dann ist das Menü 'mnu1LastFiles' nicht sichtbar [28] Else [29] ' MenüListe für das Menü 'mnu1LastFiles' erzeugen [30] For Each sFileName In MS.ShortMatrix [31] MenuItem = New Menu(mnu1LastFiles) As "mnuLast" ' EventName ist 'mnuLast'! [32] MenuItem.Text = sFileName [33] MenuItem.Picture = Picture["icon:/16/insert-text"] [34] Next ' sFileName [35] Endif ' MS.ShortMatrix.Count = 0? [36] [37] End ' UpdateMenu [38] [39] Public Sub mnuLast_Click() [40] Dim iIndex As Integer [41] [42] If MS.ShortMatrix.Find(Last.Text) <> -1 Then [43] iIndex = MS.ShortMatrix.Find(Last.Text) [44] sCurrentFilePath = MS.Matrix[iIndex] [45] ' Alternative: sCurrentFilePath = MS.Matrix[MS.ShortMatrix.Find(Last.Text)] [46] fFile = Open sCurrentFilePath For Input [47] Reset() [48] mnu1ConvertTable.Enabled = True [49] ShowTable() [50] Endif ' Find? [51] [52] End ' mnu1Last_Click [53] [54] Public Function OpenTable() As Boolean [55] [56] Dialog.Title = "Importieren Sie eine Tabellen-Text-Datei!" [57] Dialog.Filter = ["*.txt", "Text-Dateien"] [58] [59] If Dialog.OpenFile(False) = True Then ' Multiselect = False (Standard) [60] Message.Info("Das Öffnen der Tabellen-Datei wurde abgebrochen!") [61] Return False ' Cancel-Button gedrückt [62] Else [63] fFile = Open Dialog.Path For Input [64] If Lof(fFile) = 0 Then [65] Message.Info("Die Text-Datei ist leer!") [66] fFile.Close [67] Return False [68] Endif ' Lof(fFile) = 0? [69] Endif ' Dialog.OpenFile(False) = True [70] [71] sCurrentFilePath = Dialog.Path ' Der Variablen 'sCurrentFilePath' wird der DialogPfad zugewiesen [72] [73] If Not MS.Matrix.Exist(Dialog.Path) Then ' Gibt es diese Datei nicht in der Matrix ... [74] If MS.Matrix.Count = MS.iLastNumber Then ' und sind schon 5 Elemente im Array Matrix, [75] MS.Matrix.Remove(0) ' dann das 1. Element im Array Matrix löschen [76] MS.ShortMatrix.Remove(0) ' sowie das 1. Element im Array ShortMatrix löschen. [77] Endif ' MS.Matrix.Count = MS.iLastNumber? [78] MS.Matrix.Add(Dialog.Path) ' Datei-Pfad wird am Ende vom Array 'Matrix' eingefügt [79] MS.ShortMatrix.Add(File.Name(Dialog.Path)) ' Datei-Name wird am Ende von 'ShortMatrix' eingefügt [80] UpdateMenu() ' Die Menüliste wird erneuert [81] Endif ' Matrix.Exist? [82] Wait [83] Reset() [84] mnu1ConvertTable.Enabled = True [85] Return True [86] [87] End ' OpenTable() [88] [89] ... [90] [91] Public Sub Form_Close() [92] MS.SetLastListToSettings() [93] Try fFile.Close [94] End ' Form_Close
Additional comments:
Extract from the source code of the procedure GetLastListFromSettings():
[1] While pSettings["FileList" & "/File" & Str(icount)] <> Null [2] If Exist(pSettings["FileList" & "/File" & Str(icount)]) Then ' Existiert diese Datei? [3] Matrix.Add(pSettings["FileList" & "/File" & Str(icount)]) ' Datei-Pfad in Matrix speichern [4] ' Datei-Name in ShortMatrix speichern [5] ShortMatrix.Add(File.Name(pSettings["FileList" & "/File" & Str(icount)])) [6] Endif ' File.Exist? [7] Inc icount [8] Wend ' <> NULL
This is the content of the configuration file lastfiles.conf at a certain point in time:
# Dateiliste [FileList] File0="/home/hans/k12.3.4_tab.txt" File1="/home/hans/k22.3.2_tab.txt" File2="/home/hans/k3.7_tab.txt"
Die Entwicklungsumgebung (IDE) von Gambas setzt in der Menüleiste unter 'Datei' im Menü 'Zuletzt geöffnet' eine Menüliste aus k Menüs ein, die sich zur Laufzeit der Entwicklungsumgebung dynamisch ändert. Die Liste kann leer sein oder Einträge enthalten, deren Anzahl jedoch begrenzt ist. Ein Menü mit derartigen Eigenschaften nennt man dynamisches Menü.
Abbildung 13.3.2.1: Menü mit Menüliste in der IDE von Gambas
Die Planung des Einsatzes eines dynamischen Menüs erfordert u.a eindeutige Antworten auf die folgenden Fragen:
(F1) Welches Menü in der Menüstruktur soll mit einem dynamischen Menü ausgestattet werden?
(F2) Was wird in der Menüliste – am Zeichen > erkennbar – gespeichert werden?
(F3) In welcher Form sollen die Einträge in der Menüliste des bei (F1) ausgewählten Menüs gespeichert werden?
(F4) Wird das ausgewählte Menü nicht angezeigt oder nur deaktiviert, wenn die Menüliste leer ist?
(F5) Wie viel Einträge soll die Menüliste maximal aufnehmen?
(F6) Sollen die Einträge in der Menüliste sortiert werden?
Die o.a. 6 Fragen werden im folgenden Projekt DynMenu projektbezogen beantwortet:
Abbildung 13.3.2.1.1: Menü mit Menüliste (Projekt DynMenu)
In einem Projekt werden die im Abschnitt 13.3.2.1 beschriebenen Vorüberlegungen beim Einsatz eines dynamischen Menüs umgesetzt. Dieses Programm ist seit Beginn der ersten Veröffentlichungen von Kapiteln des Online-Buches auf gambas-buch.de bei den Autoren im Einsatz, wenn umfangreiche Tabellen aus einem Dokument – geschrieben mit LibreOffice Writer – in das DokuWiki-Format konvertiert werden müssen.
Die Prozeduren, die eine Instanz der Settings-Klasse anlegen und das Settings-Objekt konfigurieren sowie das Auslesen und das Speichern der Pfade der zuletzt geöffneten Tabellendateien realisieren, sind in ein Modul MS.module ausgelagert.
[1] ' Gambas module file [2] ' MS = Module & Settings [3] [4] Private hFile As File [5] Public pSettings As Settings [6] Public Matrix As New String[] [7] Public ShortMatrix As New String[] [8] Public Const iLastNumber As Integer = 5 [9] [10] Public Sub Init() [11] Dim sSettingsPath, sSlotName, sSettingsFileName As String [12] [13] sSlotName = "LastFiles" [14] sSettingsPath = Application.Path &/ sSlotName [15] sSettingsFileName = "lastfiles.conf" [16] [17] If Not Exist(sSettingsPath) Then [18] Mkdir sSettingsPath [19] Endif [20] If Not Exist(sSettingsPath &/ sSettingsFileName) Then [21] hFile = Open (sSettingsPath &/ sSettingsFileName) For Create [22] hFile.Close [23] Endif ' Not Exist(..) [24] [25] ' Ein Settings-Objekt erblickt das Licht im Speicher ... [26] pSettings = New Settings(sSettingsPath &/ sSettingsFileName, "Dateiliste") [27] [28] End ' Init() [29] [30] Public Sub GetLastListFromSettings() [31] Dim iCount As Integer [32] [33] pSettings.Reload() ' optional [34] Matrix.Clear [35] ShortMatrix.Clear [36] iCount = 0 [37] [38] While pSettings["FileList" & "/File" & Str(iCount)] <> Null [39] If Exist(pSettings["FileList" & "/File" & Str(iCount)]) Then ' Existiert diese Datei? [40] Matrix.Add(pSettings["FileList" & "/File" & Str(iCount)]) ' Datei-Pfad in Matrix speichern [41] ' Datei-Name in ShortMatrix speichern [42] ShortMatrix.Add(File.Name(pSettings["FileList" & "/File" & Str(iCount)])) [43] Endif ' File.Exist? [44] Inc iCount [45] Wend ' <> NULL [46] [47] End ' GetLastListFromSettings() [48] [49] Public Sub SetLastListToSettings() [50] Dim iCount As Integer [51] [52] pSettings.Clear [53] For iCount = 0 To Matrix.Max [54] pSettings[sSlotName & "/File" & Str(iCount)] = Matrix[iCount] [55] ' Die maximal 5 Schlüssel-Wert-Paare unter dem Slot "LastFiles" werden generiert [56] Next ' iCount [57] pSettings.Save ' Update der Konfigurationsdatei 'lastfiles.conf' [58] [59] End ' SetLastListToSettings()
Das vollständige Projekt finden Sie im Downloadbereich. Hier wird der Quelltext – gespeichert in der Datei FMain.class – nur in Auszügen wiedergegeben und kommentiert:
[1] ' Gambas class file [2] [3] Public fFile As File [4] Public sCurrentFilePath As String [5] [6] Public Sub Form_Open() [7] [8] FMain.Center [9] FMain.Resizable = False [10] mnu1ConvertTable.Enabled = False [11] mnu1SaveTable.Enabled = False [12] mnu2CenteredTable.Checked = False [13] btnReset.Enabled = False [14] [15] MS.Init() [16] MS.GetLastListFromSettings() [17] UpdateMenu() [18] [19] End ' Form_Open() [20] [21] Public Sub UpdateMenu() [22] Dim MenuItem As Menu [23] Dim sFileName As String [24] [25] mnu1LastFiles.Children.Clear ' Alle alten Einträge in der Menüliste von mnu1LastFiles löschen [26] If MS.ShortMatrix.Count = 0 Then ' Wenn die Menüliste leer ist ... [27] mnu1LastFiles.Visible = False ' dann ist das Menü 'mnu1LastFiles' nicht sichtbar [28] Else [29] ' MenüListe für das Menü 'mnu1LastFiles' erzeugen [30] For Each sFileName In MS.ShortMatrix [31] MenuItem = New Menu(mnu1LastFiles) As "mnuLast" ' EventName ist 'mnuLast'! [32] MenuItem.Text = sFileName [33] MenuItem.Picture = Picture["icon:/16/insert-text"] [34] Next ' sFileName [35] Endif ' MS.ShortMatrix.Count = 0? [36] [37] End ' UpdateMenu [38] [39] Public Sub mnuLast_Click() [40] Dim iIndex As Integer [41] [42] If MS.ShortMatrix.Find(Last.Text) <> -1 Then [43] iIndex = MS.ShortMatrix.Find(Last.Text) [44] sCurrentFilePath = MS.Matrix[iIndex] [45] ' Alternative: sCurrentFilePath = MS.Matrix[MS.ShortMatrix.Find(Last.Text)] [46] fFile = Open sCurrentFilePath For Input [47] Reset() [48] mnu1ConvertTable.Enabled = True [49] ShowTable() [50] Endif ' Find? [51] [52] End ' mnu1Last_Click [53] [54] Public Function OpenTable() As Boolean [55] [56] Dialog.Title = "Importieren Sie eine Tabellen-Text-Datei!" [57] Dialog.Filter = ["*.txt", "Text-Dateien"] [58] [59] If Dialog.OpenFile(False) = True Then ' Multiselect = False (Standard) [60] Message.Info("Das Öffnen der Tabellen-Datei wurde abgebrochen!") [61] Return False ' Cancel-Button gedrückt [62] Else [63] fFile = Open Dialog.Path For Input [64] If Lof(fFile) = 0 Then [65] Message.Info("Die Text-Datei ist leer!") [66] fFile.Close [67] Return False [68] Endif ' Lof(fFile) = 0? [69] Endif ' Dialog.OpenFile(False) = True [70] [71] sCurrentFilePath = Dialog.Path ' Der Variablen 'sCurrentFilePath' wird der DialogPfad zugewiesen [72] [73] If Not MS.Matrix.Exist(Dialog.Path) Then ' Gibt es diese Datei nicht in der Matrix ... [74] If MS.Matrix.Count = MS.iLastNumber Then ' und sind schon 5 Elemente im Array Matrix, [75] MS.Matrix.Remove(0) ' dann das 1. Element im Array Matrix löschen [76] MS.ShortMatrix.Remove(0) ' sowie das 1. Element im Array ShortMatrix löschen. [77] Endif ' MS.Matrix.Count = MS.iLastNumber? [78] MS.Matrix.Add(Dialog.Path) ' Datei-Pfad wird am Ende vom Array 'Matrix' eingefügt [79] MS.ShortMatrix.Add(File.Name(Dialog.Path)) ' Datei-Name wird am Ende von 'ShortMatrix' eingefügt [80] UpdateMenu() ' Die Menüliste wird erneuert [81] Endif ' Matrix.Exist? [82] Wait [83] Reset() [84] mnu1ConvertTable.Enabled = True [85] Return True [86] [87] End ' OpenTable() [88] [89] ... [90] [91] Public Sub Form_Close() [92] MS.SetLastListToSettings() [93] Try fFile.Close [94] End ' Form_Close
Ergänzende Kommentare:
Ausschnitt aus dem Quelltext der Prozedur GetLastListFromSettings():
[1] While pSettings["FileList" & "/File" & Str(icount)] <> Null [2] If Exist(pSettings["FileList" & "/File" & Str(icount)]) Then ' Existiert diese Datei? [3] Matrix.Add(pSettings["FileList" & "/File" & Str(icount)]) ' Datei-Pfad in Matrix speichern [4] ' Datei-Name in ShortMatrix speichern [5] ShortMatrix.Add(File.Name(pSettings["FileList" & "/File" & Str(icount)])) [6] Endif ' File.Exist? [7] Inc icount [8] Wend ' <> NULL
Das ist der Inhalt der Konfigurationsdatei lastfiles.conf zu einem bestimmten Zeitpunkt:
# Dateiliste [FileList] File0="/home/hans/k12.3.4_tab.txt" File1="/home/hans/k22.3.2_tab.txt" File2="/home/hans/k3.7_tab.txt"